Asynchronously created pads from decodebin (how to deal with them?)

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

Asynchronously created pads from decodebin (how to deal with them?)

Zebediah Figura

I have been working on Wine's DirectShow interface to gstreamer.
Recently I've been trying to track down some intermittent crashes and
hangs, and I've managed to narrow down some of them to a certain problem.

Wine has a generic Quartz filter that decodes any form of media into raw
audio/video via decodebin. The code looks roughly like this:

// create decodebin pad and add it to our container bin
g_signal_connect(decodebin, "pad-added" G_CALLBACK(add_to_output_pads),
g_signal_connect(decodebin, "no-more-pads",
G_CALLBACK(signal_no_more_pads), ...);

gst_element_set_state(container, GST_STATE_PLAYING);
gst_element_get_state(container, NULL, NULL, -1);

if (output_pads > 0)
  // do processing
  ERR("GStreamer could not find any streams\n");

Essentially, we create the decodebin element, hook up our input data to
it, set the state to playing, wait for the "no-more-pads" signal, and
then call gst_element_get_state() to wait for the state change to finish
being processed as well. We fail creating our Quartz filter if decodebin
didn't return any source pads.

At least one test file, and possibly others, subverts some of the code's
subsequent assumptions by creating source pads asynchronously, *after*
the "no-more-pads" signal. In particular, an MPEG-1 systems container
with I420 video and layer-2 audio. The audio decoder comes from libav,
and seems to choke on the frames it is given—it spits out "mad1: No
valid frames decoded before end of stream" and fails setting the state.
(This part is a bug in libav—the file was generated using it.) The video
decoder, however, seems to have no problem parsing the stream, and
asynchronously adds a pad after the "no-more-pads" signal is sent.

I have, then, two questions: firstly, is this behaviour valid? and
secondly, is there a way to wait for decodebin to finish exposing all of
its pads?

If the answers are "yes" and "no" respectively, then it's easy enough to
fix our broken logic—which would seem to involve, among other things,
testing whether gst_element_get_state() returns GST_STATE_CHANGE_SUCCESS
rather than testing whether any source pads are created.

It would be preferable if the answer to the second question is "yes",
though, since in that case we would be able to e.g. render video even in
the absence of audio.

And if the answer to the first question is "no", well, then, I'll file a
bug report ;-)

Zebediah Figura

gstreamer-devel mailing list
[hidden email]

signature.asc (836 bytes) Download Attachment