<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>