GNOME Bugzilla – Bug 680262
[0.11] decodebin: 3gp preroll regression caused by pad blocking changes
Last modified: 2012-07-24 09:05:03 UTC
3gp files don't preroll for me now. It's stuck in: Starting program: /home/tpm/gst/0.11/gstreamer/tools/.libs/lt-gst-launch-1.0 file:///home/tpm/samples/private/nokia//3GP/MPEG4_VGA_15fps_AMRNB.3gp \! decodebin \! fakesink -v [Thread debugging using libthread_db enabled] Setting pipeline to PAUSED ... Pipeline is PREROLLING ... /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstQTDemux:qtdemux0.GstPad:sink: caps = application/x-3gp, profile=(string)basic /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstMultiQueue:multiqueue0.GstPad:sink_0: caps = video/mpeg, mpegversion=(int)4, systemstream=(boolean)false, profile=(string)simple, level=(string)4a, codec_data=(buffer)000001b004000001b24e4558545245414d494e4720434f52504f524154494f4e000001b509000001000000012000845d4c30fa114043c1463f, width=(int)640, height=(int)480, framerate=(fraction)15/1, pixel-aspect-ratio=(fraction)1/1 /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstMultiQueue:multiqueue0.GstPad:sink_0: caps = video/mpeg, mpegversion=(int)4, systemstream=(boolean)false, profile=(string)simple, level=(string)4a, codec_data=(buffer)000001b004000001b24e4558545245414d494e4720434f52504f524154494f4e000001b509000001000000012000845d4c30fa114043c1463f, width=(int)640, height=(int)480, framerate=(fraction)15/1, pixel-aspect-ratio=(fraction)1/1 /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstMultiQueue:multiqueue0.GstPad:sink_0: caps = video/mpeg, mpegversion=(int)4, systemstream=(boolean)false, profile=(string)simple, level=(string)4a, codec_data=(buffer)000001b004000001b24e4558545245414d494e4720434f52504f524154494f4e000001b509000001000000012000845d4c30fa114043c1463f, width=(int)640, height=(int)480, framerate=(fraction)15/1, pixel-aspect-ratio=(fraction)1/1 /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstMultiQueue:multiqueue0.GstPad:sink_1: caps = audio/AMR, codec_data=(buffer)0000001164616d724e5854520081ff0008, rate=(int)8000, channels=(int)1 /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstMultiQueue:multiqueue0.GstPad:src_1: caps = audio/AMR, codec_data=(buffer)0000001164616d724e5854520081ff0008, rate=(int)8000, channels=(int)1 /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstAmrnbDec:amrnbdec0.GstPad:src: caps = audio/x-raw, format=(string)S16LE, layout=(string)interleaved, rate=(int)8000, channels=(int)1 ^C Program received signal SIGINT, Interrupt. 0x00007ffff68baa93 in *__GI___poll (fds=<optimized out>, nfds=<optimized out>, timeout=250) at ../sysdeps/unix/sysv/linux/poll.c:87 87 ../sysdeps/unix/sysv/linux/poll.c: No such file or directory. (gdb) thread apply all bt
+ Trace 230538
I believe this was introduced by: commit c5901cebcabc966dd65f70080feec79bb26b4645 Author: Edward Hervey <edward.hervey@collabora.co.uk> Date: Wed Jul 18 15:24:00 2012 +0200 decodebin: Block on caps event A caps event is also used to establish that a stream has prerolled. Without this, we end up allowing negotiation queries to fail, ending in decoders (and other elements) to not be configured right from the start with the most optimal settings.
Steps to reproduce: $ wget -O /tmp/342095-hello.3gp 'https://bugzilla.gnome.org/attachment.cgi?id=65660' $ gst-discoverer-1.0 /tmp/342095-hello.3gp Works: $ gst-launch-1.0 filesrc location=/tmp/342095-hello.3gp ! qtdemux name=d d. ! queue ! avdec_h263 ! xvimagesink d. ! queue ! amrnbdec ! pulsesink Does not work: $ gst-launch-1.0 filesrc location=/tmp/342095-hello.3gp ! decodebin name=d d. ! queue ! avdec_h263 ! xvimagesink d. ! queue ! amrnbdec ! pulsesink
> Does not work: > $ gst-launch-1.0 filesrc location=/tmp/342095-hello.3gp ! decodebin name=d d. > ! queue ! avdec_h263 ! xvimagesink d. ! queue ! amrnbdec ! pulsesink Sorry, what I meant was: Does not work: $ gst-launch-1.0 filesrc location= /tmp/342095-hello.3gp ! decodebin name=d d. ! queue ! pulsesink d. ! queue ! xvimagesink
The problem is due to blocking on CAPS event, which blocks decoder streaming threads, which then blocks the ALLOCATION queries from demuxers and therefore making the demuxer streaming thread block. I tried a variant where I would mark a stream as completed (and potentially exposing the group) when we see a CAPS event, but then letting the event through (i.e. not blocking the streaming thread). This could be interesting for speeding up pre-rolling, since you don't need to wait for data to arrive on all final pads, but only caps. The problem is that it still potentially lets ALLOCATION queries go through unlinked pads and fail for the first buffer. If the audio stream sends CAPS event before the video stream sends ALLOCATION queries, then you have the optimal scenario. Else it'll be the same as previously. I'd much prefer to figure out the ideal solution where it never ends up doing an ALLOCATION query on an unlinked pads.... but it seems hard with the current decodebin/playbin design and interaction
Created attachment 219551 [details] [review] decodebin2: Mark streams as complete on CAPS event but don't block This allows the following use-cases to expose the group and pads before an ALLOCATION query comes through: * Single stream use-cases * Multi stream use-cases where all streams sent the CAPS event before the first ALLOCATION query Some cases will still make the initial ALLOCATION query fail though, which isn't optimal, but not fatal (it will recover when pads are exposed, a RECONFIGURE event is sent upstream and elements can re-send an ALLOCATION query which will reach downstream elements).
commit 2f37ba60a2838f072150b4443184ef0a3047a497 Author: Edward Hervey <edward.hervey@collabora.co.uk> Date: Tue Jul 24 10:45:58 2012 +0200 decodebin2: Mark streams as complete on CAPS event but don't block This allows the following use-cases to expose the group and pads before an ALLOCATION query comes through: * Single stream use-cases * Multi stream use-cases where all streams sent the CAPS event before the first ALLOCATION query Some cases will still make the initial ALLOCATION query fail though, which isn't optimal, but not fatal (it will recover when pads are exposed, a RECONFIGURE event is sent upstream and elements can re-send an ALLOCATION query which will reach downstream elements). https://bugzilla.gnome.org/show_bug.cgi?id=680262