<div dir="ltr">Hi,<div>I am trying to make a pipeline that takes a transport stream in, demuxes it, does some transcoding, remuxes, and sends it to a sink.</div><div>I can make it work if I only have video in the pipeline or if I only have audio but once I add both, the application hangs. Here is my source code (I removed all the error checking for emailing to reduce line length):</div>
<div><br></div><div><div>struct custom_data</div><div>{</div><div>    GstElement *video_decoder;</div><div>    GstElement *audio_decoder;</div><div>};</div></div><div><br></div><div><div><div>void</div><div>link_to_multiplexer(</div>
<div>    GstElement *tolink_element,</div><div>    GstElement *mux)</div><div>{</div><div>    GstCaps          *pad_caps = NULL;</div><div>    GstPad           *pad;</div><div>    GstPad           *tolink_pad;</div><div>    GstPadLinkReturn  ret;</div>
<div><br></div><div>    tolink_pad = gst_element_get_static_pad(tolink_element, "src");</div><div>    pad_caps   = gst_pad_query_caps(tolink_pad, NULL);</div><div>    pad        = gst_element_get_compatible_pad(mux, tolink_pad, pad_caps);</div>
<div>    gst_caps_unref(pad_caps);</div><div><br></div><div>    ret = gst_pad_link(tolink_pad, pad);</div><div>    gst_object_unref(GST_OBJECT(pad));</div><div>    g_print("A new pad %s was created and linked to %s\n", gst_pad_get_name(tolink_pad), gst_pad_get_name(pad));</div>
<div>}<br></div></div><div><br></div><div><div>static void on_pad_added(</div><div>    GstElement *src,</div><div>    GstPad *new_pad,</div><div>    struct custom_data *data)</div><div>{</div><div>    GstCaps          *new_pad_caps = NULL;</div>
<div>    GstStructure     *new_pad_struct = NULL;</div><div>    const gchar      *new_pad_type = NULL;</div><div>    GstPad           *decode_pad = NULL;</div><div>    GstPadLinkReturn  ret;</div><div><br></div><div>    g_print("Received new pad '%s' from '%s':\n", GST_PAD_NAME(new_pad),</div>
<div>            GST_ELEMENT_NAME(src));</div><div><br></div><div>    /* Check the new pad's type */</div><div>    new_pad_caps   = gst_pad_query_caps(new_pad, NULL);</div><div>    new_pad_struct = gst_caps_get_structure(new_pad_caps, 0);</div>
<div>    new_pad_type   = gst_structure_get_name(new_pad_struct);</div><div><br></div><div>    g_print("New pad type is %s\n", new_pad_type);</div><div>    if (g_str_has_prefix(new_pad_type, "video/mpeg"))</div>
<div>    {</div><div>        decode_pad = gst_element_get_static_pad(data->video_decoder, "sink");</div><div>    }</div><div>    else if (g_str_has_prefix(new_pad_type, "audio/x-ac3"))</div><div>    {</div>
<div>        decode_pad = gst_element_get_static_pad(data->audio_decoder, "sink");</div><div>    }</div><div>    if (!gst_pad_is_linked(decode_pad))</div><div>    {</div><div>        ret = gst_pad_link(new_pad, decode_pad);</div>
<div>    }</div><div><br></div><div>    gst_caps_unref(new_pad_caps);</div><div>    gst_object_unref(decode_pad);</div><div>}</div></div></div><div><br></div><div><div>int</div><div>main(int argc, char **argv)</div><div>{</div>
<div>    GstElement *source;</div><div>    GstElement *pipeline;</div><div>    GstElement *sink;</div><div>    GstElement *demux;</div><div>    GstElement *mux;</div><div>    GstElement *v_dec;</div><div>    GstElement *x264_enc;</div>
<div>    GstElement *a_dec;</div><div>    GstElement *a_convert;</div><div>    GstElement *aac_enc;</div><div>    struct custom_data data;</div><div><br></div><div>    GstBus     *bus;</div><div>    GstMessage *msg;</div>
<div>    gboolean terminate = FALSE;</div><div><br></div><div>    gst_init (&argc, &argv);</div><div><br></div><div>    source    = gst_element_factory_make("filesrc", "file-source");</div><div>
    demux     = gst_element_factory_make("tsdemux", "demux");</div><div>    v_dec     = gst_element_factory_make("mpeg2dec", "video_decoder");</div><div>    x264_enc  = gst_element_factory_make("x264enc", "h264_encoder");</div>
<div>    a_dec     = gst_element_factory_make("a52dec", "audio_decoder");</div><div>    a_convert = gst_element_factory_make("audioconvert", "audio_converter");</div><div>    aac_enc   = gst_element_factory_make("faac", "aac_encoder");</div>
<div>    mux       = gst_element_factory_make("mpegtsmux", "muxer");</div><div>    sink      = gst_element_factory_make("hlssink", "hls_sink");</div><div><br></div><div>    data.video_decoder = v_dec;</div>
<div>    data.audio_decoder = a_dec;</div><div><br></div><div>    pipeline = gst_pipeline_new("test-pipeline");</div><div><br></div><div>    g_object_set(G_OBJECT(source), "location", "stream_1.ts", NULL);</div>
<div><br></div><div>    gst_bin_add_many(GST_BIN(pipeline), source, demux, x264_enc, v_dec, a_dec, aac_enc, a_convert, mux, sink, NULL);</div><div><br></div><div>    gst_element_link(source, demux);</div><div>    gst_element_link_many(a_dec, a_convert, aac_enc, NULL);</div>
<div>    link_to_multiplexer(x264_enc, mux);</div><div>    link_to_multiplexer(aac_enc, mux);</div><div><br></div><div>    gst_element_link(v_dec, x264_enc);</div><div>    gst_element_link(mux, sink);</div><div><br></div>
<div>    g_signal_connect(demux, "pad-added", G_CALLBACK(on_pad_added), &data);</div><div><br></div><div>    gst_element_set_state(pipeline, GST_STATE_PLAYING);</div><div><br></div><div>    /* Listen to the bus */</div>
<div>    bus = gst_element_get_bus(pipeline);</div><div>    do</div><div>    {</div><div>        msg = gst_bus_timed_pop(bus, 0);</div><div><br></div><div>        /* Parse message */</div><div>        if (msg != NULL)</div>
<div>        {</div><div>            switch (GST_MESSAGE_TYPE(msg))</div><div>            {</div><div>                case GST_MESSAGE_ERROR:</div><div>                case GST_MESSAGE_EOS:</div><div>                    terminate = TRUE;</div>
<div>                    break;</div><div>                case GST_MESSAGE_STATE_CHANGED:</div><div>                    if (GST_MESSAGE_SRC(msg) == GST_OBJECT(pipeline))</div><div>                    {</div><div>                        GstState old_state, new_state, pending_state;</div>
<div><br></div><div>                        gst_message_parse_state_changed(msg, &old_state, &new_state, &pending_state);</div><div>                        g_print("Pipeline state changed from %s to %s:\n",</div>
<div>                        gst_element_state_get_name(old_state), gst_element_state_get_name(new_state));</div><div>                    }</div><div>                    break;</div><div>                default:</div><div>
                g_printerr("New bus message: %s.\n", gst_message_type_get_name(GST_MESSAGE_TYPE(msg)));</div><div>                break;</div><div>            }</div><div>            gst_message_unref(msg);</div>
<div>        }</div><div>    } while (!terminate);</div><div><br></div><div>    /* Free resources */</div><div>    gst_object_unref(bus);</div><div>    gst_element_set_state(pipeline, GST_STATE_NULL);</div><div>    gst_object_unref(pipeline);</div>
<div><br></div><div>    return 0;</div><div>}</div></div><div><br></div><div>Here is my output when it hangs:</div><div><br></div><div><div>A new pad src was created and linked to sink_65</div><div>A new pad src was created and linked to sink_66</div>
<div>Pipeline state changed from NULL to READY:</div><div>New bus message: stream-status.</div><div>New bus message: stream-status.</div><div>New bus message: element.</div><div>New bus message: element.</div><div>Received new pad 'video_01e1' from 'demux':</div>
<div>New pad type is video/mpeg</div><div>New bus message: latency.</div><div>New bus message: qos.</div><div>New bus message: qos.</div><div>New bus message: latency.</div><div>Received new pad 'audio_01e2' from 'demux':</div>
<div>New pad type is audio/x-ac3</div><div>New bus message: tag.</div></div><div>(Hangs here)</div><div><br></div><div>Here is my output if I detach the audio from the muxer and only let the video flow all the way through:</div>
<div><br></div><div><div>A new pad src was created and linked to sink_65</div><div>Pipeline state changed from NULL to READY:</div><div>New bus message: stream-status.</div><div>New bus message: stream-status.</div><div>New bus message: element.</div>
<div>New bus message: element.</div><div>Received new pad 'video_01e1' from 'demux':</div><div>New pad type is video/mpeg</div><div>New bus message: latency.</div><div>New bus message: qos.</div><div>New bus message: qos.</div>
<div>New bus message: latency.</div><div>Received new pad 'audio_01e2' from 'demux':</div><div>New pad type is audio/x-ac3</div><div>Received new pad 'audio_01e3' from 'demux':</div><div>New pad type is audio/x-ac3</div>
<div>Pad is already linked.</div><div>New bus message: tag.</div><div>New bus message: stream-start.</div><div>Pipeline state changed from READY to PAUSED:</div><div>New bus message: async-done.</div><div>New bus message: new-clock.</div>
<div>Pipeline state changed from PAUSED to PLAYING:</div></div><div>(Program reads whole transport stream and successfully completes)</div><div><br></div><div>Could please help me determine why adding the audio to the muxer causes the program to hang?</div>
<div><br></div><div><br></div></div>