GNOME Bugzilla – Bug 646012
unable to mux h.264 live stream buffers produced by flvdemux
Last modified: 2011-04-04 10:08:51 UTC
I have a pipeline that demuxes h.264 from a live rtmp stream into an mp4 container. It works fine with my lower-bitrate base-profile streams, but chokes on my high-profile stream, apparently because qtmux isn't getting the buffer durations it needs. This stream plays just fine if I pipe it into a decoder and imagesink, but qtmux fails: gst-launch -e rtmpsrc location=rtmp://mystream ! flvdemux name=demux demux.video ! queue max-size-time=5000000000 max-size-buffers=0 ! h264parse ! mp4mux ! filesink location=foo.mp4 Setting pipeline to PAUSED ... Pipeline is PREROLLING ... Pipeline is PREROLLED ... Setting pipeline to PLAYING ... New clock: GstSystemClock ERROR: from element /GstPipeline:pipeline0/GstMP4Mux:mux: Could not multiplex stream. Additional debug info: gstqtmux.c(1802): gst_qt_mux_add_buffer (): /GstPipeline:pipeline0/GstMP4Mux:mux: Received buffer without timestamp/duration. Execution ended after 3092134 ns. Setting pipeline to PAUSED ... Setting pipeline to READY ... Setting pipeline to NULL ... Freeing pipeline ... Using fakesink -v reveals that buffers produced by flvdemux have no duration: gst-launch -e rtmpsrc location=rtmp://mystream ! flvdemux name=demux demux.video ! queue max-size-time=5000000000 max-size-buffers=0 ! h264parse ! fakesink -v Setting pipeline to PAUSED ... Pipeline is PREROLLING ... /GstPipeline:pipeline0/GstFlvDemux:demux.GstPad:video: caps = video/x-h264, pixel-aspect-ratio=(fraction)1/1, codec_data=(buffer)0164001fffe100196764001facec05005bb0110000030001773594000f1831380001000468eaef2c /GstPipeline:pipeline0/GstQueue:queue0.GstPad:sink: caps = video/x-h264, pixel-aspect-ratio=(fraction)1/1, codec_data=(buffer)0164001fffe100196764001facec05005bb0110000030001773594000f1831380001000468eaef2c /GstPipeline:pipeline0/GstQueue:queue0.GstPad:src: caps = video/x-h264, pixel-aspect-ratio=(fraction)1/1, codec_data=(buffer)0164001fffe100196764001facec05005bb0110000030001773594000f1831380001000468eaef2c /GstPipeline:pipeline0/GstQueue:queue0.GstPad:src: caps = video/x-h264, pixel-aspect-ratio=(fraction)1/1, codec_data=(buffer)0164001fffe100196764001facec05005bb0110000030001773594000f1831380001000468eaef2c /GstPipeline:pipeline0/GstH264Parse:h264parse0.GstPad:sink: caps = video/x-h264, pixel-aspect-ratio=(fraction)1/1, codec_data=(buffer)0164001fffe100196764001facec05005bb0110000030001773594000f1831380001000468eaef2c /GstPipeline:pipeline0/GstH264Parse:h264parse0.GstPad:src: caps = video/x-h264, pixel-aspect-ratio=(fraction)1/1, codec_data=(buffer)0164001fffe100196764001facec05005bb0110000030001773594000f1831380001000468eaef2c, width=(int)1280, height=(int)720, stream-format=(string)avc, alignment=(string)au /GstPipeline:pipeline0/GstFakeSink:fakesink0.GstPad:sink: caps = video/x-h264, pixel-aspect-ratio=(fraction)1/1, codec_data=(buffer)0164001fffe100196764001facec05005bb0110000030001773594000f1831380001000468eaef2c, width=(int)1280, height=(int)720, stream-format=(string)avc, alignment=(string)au /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "preroll ******* " /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "event ******* E (type: 118, taglist, video-codec=(string)\"H.264/AVC\\ Video\";) 0x89ee6c8" /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "event ******* E (type: 102, GstEventNewsegment, update=(boolean)false, rate=(double)1, applied-rate=(double)1, format=(GstFormat)GST_FORMAT_TIME, start=(gint64)33000000, stop=(gint64)-1, position=(gint64)33000000;) 0x89ee6f0" Pipeline is PREROLLED ... Setting pipeline to PLAYING ... /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain ******* < (21852 bytes, timestamp: 0:00:00.033000000, duration: none, offset: 0, offset_end: 1, flags: 33) 0x8b6f730" New clock: GstSystemClock /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain ******* < (21852 bytes, timestamp: 0:00:01.165000000, duration: none, offset: 1, offset_end: 2, flags: 1) 0x8b6f410" /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain ******* < (13453 bytes, timestamp: 0:00:01.199000000, duration: none, offset: 2, offset_end: 3, flags: 1) 0x8b6f5f0" /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain ******* < (11798 bytes, timestamp: 0:00:01.232000000, duration: none, offset: 3, offset_end: 4, flags: 1) 0x8b6f818" /GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain ******* < (10086 bytes, timestamp: 0:00:01.265000000, duration: none, offset: 4, offset_end: 5, flags: 1) 0x8b6f908" [...snip...] I get the same failed result with and without h264parse. fraxinas and MikeS on #gstreamer suggested that I file a bug report, and that making flvdemux or h264parse produce the missing durations might be trivial for someone familiar with writing gstreamer plugins.
Created attachment 184510 [details] live stream sample for reproducing the error
The live stream in question uses an flv container, so I saved a sample of it to an .flv file (attached). The following pipeline reproduces the error with that file: gst-launch -e filesrc location=hd-stream-flvdemux-duration-none.flv ! flvdemux name=demux demux.video ! queue max-size-time=5000000000 max-size-buffers=0 ! h264parse ! mp4mux ! filesink location=foo.mp4
The problem here is that the timestamps are not ascending (though the above fragment does not illustrate it), and that in combination with missing duration leads to qtmux complaints. This non-ascending makes it not so trivial to add missing duration (either in flvdemux or in h264parse), and a not-so-trivial way to deal with this is already incorporated in qtmux (since as you noticed it is the only? one having a problem). The not-so-trivial way can be used with qtmux dts-method=reorder (or qtmux dts-method=asc) (see also qtmux documentation). There may be arguments for making one of those the default method ...
I'd like to give those options a try (with mp4mux). The dts-method property does not exist in my version. In what version of plugins-bad does it appear?
Should be in 0.10.21 (and as such this likely dup of bug #638288).
h264parse should add the duration to the buffers whenever possible nonetheless
Marking as duplicate (as explained above). *** This bug has been marked as a duplicate of bug 638288 ***