demux/remux pipeline hangs when audio is added
Carah Smith
carah29ingress at gmail.com
Wed Oct 2 10:19:19 PDT 2013
Hi,
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.
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):
struct custom_data
{
GstElement *video_decoder;
GstElement *audio_decoder;
};
void
link_to_multiplexer(
GstElement *tolink_element,
GstElement *mux)
{
GstCaps *pad_caps = NULL;
GstPad *pad;
GstPad *tolink_pad;
GstPadLinkReturn ret;
tolink_pad = gst_element_get_static_pad(tolink_element, "src");
pad_caps = gst_pad_query_caps(tolink_pad, NULL);
pad = gst_element_get_compatible_pad(mux, tolink_pad, pad_caps);
gst_caps_unref(pad_caps);
ret = gst_pad_link(tolink_pad, pad);
gst_object_unref(GST_OBJECT(pad));
g_print("A new pad %s was created and linked to %s\n",
gst_pad_get_name(tolink_pad), gst_pad_get_name(pad));
}
static void on_pad_added(
GstElement *src,
GstPad *new_pad,
struct custom_data *data)
{
GstCaps *new_pad_caps = NULL;
GstStructure *new_pad_struct = NULL;
const gchar *new_pad_type = NULL;
GstPad *decode_pad = NULL;
GstPadLinkReturn ret;
g_print("Received new pad '%s' from '%s':\n", GST_PAD_NAME(new_pad),
GST_ELEMENT_NAME(src));
/* Check the new pad's type */
new_pad_caps = gst_pad_query_caps(new_pad, NULL);
new_pad_struct = gst_caps_get_structure(new_pad_caps, 0);
new_pad_type = gst_structure_get_name(new_pad_struct);
g_print("New pad type is %s\n", new_pad_type);
if (g_str_has_prefix(new_pad_type, "video/mpeg"))
{
decode_pad = gst_element_get_static_pad(data->video_decoder,
"sink");
}
else if (g_str_has_prefix(new_pad_type, "audio/x-ac3"))
{
decode_pad = gst_element_get_static_pad(data->audio_decoder,
"sink");
}
if (!gst_pad_is_linked(decode_pad))
{
ret = gst_pad_link(new_pad, decode_pad);
}
gst_caps_unref(new_pad_caps);
gst_object_unref(decode_pad);
}
int
main(int argc, char **argv)
{
GstElement *source;
GstElement *pipeline;
GstElement *sink;
GstElement *demux;
GstElement *mux;
GstElement *v_dec;
GstElement *x264_enc;
GstElement *a_dec;
GstElement *a_convert;
GstElement *aac_enc;
struct custom_data data;
GstBus *bus;
GstMessage *msg;
gboolean terminate = FALSE;
gst_init (&argc, &argv);
source = gst_element_factory_make("filesrc", "file-source");
demux = gst_element_factory_make("tsdemux", "demux");
v_dec = gst_element_factory_make("mpeg2dec", "video_decoder");
x264_enc = gst_element_factory_make("x264enc", "h264_encoder");
a_dec = gst_element_factory_make("a52dec", "audio_decoder");
a_convert = gst_element_factory_make("audioconvert", "audio_converter");
aac_enc = gst_element_factory_make("faac", "aac_encoder");
mux = gst_element_factory_make("mpegtsmux", "muxer");
sink = gst_element_factory_make("hlssink", "hls_sink");
data.video_decoder = v_dec;
data.audio_decoder = a_dec;
pipeline = gst_pipeline_new("test-pipeline");
g_object_set(G_OBJECT(source), "location", "stream_1.ts", NULL);
gst_bin_add_many(GST_BIN(pipeline), source, demux, x264_enc, v_dec,
a_dec, aac_enc, a_convert, mux, sink, NULL);
gst_element_link(source, demux);
gst_element_link_many(a_dec, a_convert, aac_enc, NULL);
link_to_multiplexer(x264_enc, mux);
link_to_multiplexer(aac_enc, mux);
gst_element_link(v_dec, x264_enc);
gst_element_link(mux, sink);
g_signal_connect(demux, "pad-added", G_CALLBACK(on_pad_added), &data);
gst_element_set_state(pipeline, GST_STATE_PLAYING);
/* Listen to the bus */
bus = gst_element_get_bus(pipeline);
do
{
msg = gst_bus_timed_pop(bus, 0);
/* Parse message */
if (msg != NULL)
{
switch (GST_MESSAGE_TYPE(msg))
{
case GST_MESSAGE_ERROR:
case GST_MESSAGE_EOS:
terminate = TRUE;
break;
case GST_MESSAGE_STATE_CHANGED:
if (GST_MESSAGE_SRC(msg) == GST_OBJECT(pipeline))
{
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed(msg, &old_state,
&new_state, &pending_state);
g_print("Pipeline state changed from %s to %s:\n",
gst_element_state_get_name(old_state),
gst_element_state_get_name(new_state));
}
break;
default:
g_printerr("New bus message: %s.\n",
gst_message_type_get_name(GST_MESSAGE_TYPE(msg)));
break;
}
gst_message_unref(msg);
}
} while (!terminate);
/* Free resources */
gst_object_unref(bus);
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
return 0;
}
Here is my output when it hangs:
A new pad src was created and linked to sink_65
A new pad src was created and linked to sink_66
Pipeline state changed from NULL to READY:
New bus message: stream-status.
New bus message: stream-status.
New bus message: element.
New bus message: element.
Received new pad 'video_01e1' from 'demux':
New pad type is video/mpeg
New bus message: latency.
New bus message: qos.
New bus message: qos.
New bus message: latency.
Received new pad 'audio_01e2' from 'demux':
New pad type is audio/x-ac3
New bus message: tag.
(Hangs here)
Here is my output if I detach the audio from the muxer and only let the
video flow all the way through:
A new pad src was created and linked to sink_65
Pipeline state changed from NULL to READY:
New bus message: stream-status.
New bus message: stream-status.
New bus message: element.
New bus message: element.
Received new pad 'video_01e1' from 'demux':
New pad type is video/mpeg
New bus message: latency.
New bus message: qos.
New bus message: qos.
New bus message: latency.
Received new pad 'audio_01e2' from 'demux':
New pad type is audio/x-ac3
Received new pad 'audio_01e3' from 'demux':
New pad type is audio/x-ac3
Pad is already linked.
New bus message: tag.
New bus message: stream-start.
Pipeline state changed from READY to PAUSED:
New bus message: async-done.
New bus message: new-clock.
Pipeline state changed from PAUSED to PLAYING:
(Program reads whole transport stream and successfully completes)
Could please help me determine why adding the audio to the muxer causes the
program to hang?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20131002/d23fb434/attachment-0001.html>
More information about the gstreamer-devel
mailing list