[gst-devel] ffdec and QoS
Wim Taymans
wim.taymans at gmail.com
Tue Jun 9 19:50:29 CEST 2009
On Tue, 2009-06-09 at 19:18 +0200, Arnout Vandecappelle wrote:
> Hoi all,
>
> I've been struggling with QoS events for a while now, and I don't find a way out...
>
> I have a pipeline like this:
> souphttpsrc location=... do-timestamp=true ! mpeg4videoparse ! ffdec_mpeg4 ! \
> videoscale ! fakesink sync=true qos=true
>
> The ffmpeg decoder element usually buffers one frame internally. Unfortunately, this makes
> the sink generate QoS events that causes basetransform to drop frames.
>
> Here is some pruned debug output to indicate the problem:
>
> # A frame is pushed in the decoder, but it is buffered.
> 0:00:00.752352 ffmpeg gstffmpegdec.c:897:gst_ffmpegdec_get_buffer:<ffdec_mpeg40> getting buffer, apply pts 517907675
> 0:00:00.754003 ffmpeg gstffmpegdec.c:1600:gst_ffmpegdec_video_frame:<ffdec_mpeg40> after decode: len 10006, have_data 0
> 0:00:00.754047 ffmpeg gstffmpegdec.c:2099:gst_ffmpegdec_frame:<ffdec_mpeg40> We didn't get a decoded buffer
>
> # 200ms later, the next frame arrives, the previous one is decoded
> 0:00:00.966332 ffmpeg gstffmpegdec.c:897:gst_ffmpegdec_get_buffer:<ffdec_mpeg40> getting buffer, apply pts 633476686
> 0:00:00.967236 ffmpeg gstffmpegdec.c:1600:gst_ffmpegdec_video_frame:<ffdec_mpeg40> after decode: len 1512, have_data 288
> 0:00:00.967269 ffmpeg gstffmpegdec.c:1614:gst_ffmpegdec_video_frame:<ffdec_mpeg40> ts-handler: pts 517907675
> 0:00:00.969201 GST_QOS gstbasesink.c:2542:gst_base_sink_do_render_stats:<fakesink0> avg_render: 0:00:00.000042465
> 0:00:00.969219 GST_QOS gstbasesink.c:2346:gst_base_sink_perform_qos:<fakesink0> start: 0:00:00.517907675, entered 0:00:00.850296431, left 0:00:00.850296431, pt:
> 99:99:99.999999999, duration 0:00:00.000000000,jitter 332388756
> 0:00:00.969238 GST_QOS gstbasesink.c:2351:gst_base_sink_perform_qos:<fakesink0> avg_duration: 99:99:99.999999999, avg_pt: 99:99:99.999999999, avg_rate: -1
> 0:00:00.969255 GST_QOS gstbasesink.c:2386:gst_base_sink_perform_qos:<fakesink0> updated: avg_duration: 0:00:00.000000000, avg_pt: 99:99:99.999999999, avg_rate: -1
> # no QoS event is sent yet...
>
> # Again 200ms later, the next frame arrives, the previous one is decoded
> 0:00:01.188664 ffmpeg gstffmpegdec.c:897:gst_ffmpegdec_get_buffer:<ffdec_mpeg40> getting buffer, apply pts 848446910
> 0:00:01.189441 ffmpeg gstffmpegdec.c:1600:gst_ffmpegdec_video_frame:<ffdec_mpeg40> after decode: len 1339, have_data 288
> 0:00:01.189483 ffmpeg gstffmpegdec.c:1614:gst_ffmpegdec_video_frame:<ffdec_mpeg40> ts-handler: pts 633476686
> 0:00:01.189669 GST_QOS gstbasesink.c:2542:gst_base_sink_do_render_stats:<fakesink0> avg_render: 0:00:00.000043914
> 0:00:01.189684 GST_QOS gstbasesink.c:2346:gst_base_sink_perform_qos:<fakesink0> start: 0:00:00.633476686, entered 0:00:01.070752257, left 0:00:01.070752257, pt:
> 0:00:00.220455826, duration 0:00:00.000000000,jitter 437275571
> 0:00:01.189700 GST_QOS gstbasesink.c:2351:gst_base_sink_perform_qos:<fakesink0> avg_duration: 0:00:00.000000000, avg_pt: 99:99:99.999999999, avg_rate: -1
> 0:00:01.189718 GST_QOS gstbasesink.c:2386:gst_base_sink_perform_qos:<fakesink0> updated: avg_duration: 0:00:00.000000000, avg_pt: 0:00:00.220455826, avg_rate: 0
> # Now, a QoS event is sent.
> 0:00:01.189732 GST_QOS gstbasesink.c:2278:gst_base_sink_send_qos:<fakesink0> qos: proportion: 0.000000, diff 437275571, timestamp 0:00:00.633476686
> 0:00:01.189759 GST_QOS gstbasetransform.c:2331:gst_base_transform_update_qos:<videoscale0> qos: proportion: 0.000000, diff 437275571, timestamp 0:00:00.633476686
>
> # Again 200ms later, the next frame arrives, the previous one is decoded.
> 0:00:01.352582 ffmpeg gstffmpegdec.c:1274:gst_ffmpegdec_do_qos:<ffdec_mpeg40> QOS: qostime 0:00:01.070718163, earliest 0:00:01.070752257
> 0:00:01.352631 ffmpeg gstffmpegdec.c:1331:gst_ffmpegdec_do_qos:<ffdec_mpeg40> QOS: hurry up, diff 34094 >= 0
> 0:00:01.352676 ffmpeg gstffmpegdec.c:897:gst_ffmpegdec_get_buffer:<ffdec_mpeg40> getting buffer, apply pts 1070718163
> 0:00:01.353261 ffmpeg gstffmpegdec.c:1600:gst_ffmpegdec_video_frame:<ffdec_mpeg40> after decode: len 1395, have_data 288
> 0:00:01.353282 ffmpeg gstffmpegdec.c:1614:gst_ffmpegdec_video_frame:<ffdec_mpeg40> ts-handler: pts 848446910
>
> # The timestamp of this frame is earlier than the time that the previous
> # one was rendered, so basetransform drops it.
> 0:00:01.353402 GST_QOS gstbasetransform.c:1862:gst_base_transform_handle_buffer:<videoscale0> skipping transform: qostime 0:00:00.848446910 <= 0:00:01.070752257
>
> # And this story repeats itself.
> 0:00:01.608276 ffmpeg gstffmpegdec.c:1274:gst_ffmpegdec_do_qos:<ffdec_mpeg40> QOS: qostime 0:00:01.234701170, earliest 0:00:01.070752257
> 0:00:01.608329 ffmpeg gstffmpegdec.c:1311:gst_ffmpegdec_do_qos:<ffdec_mpeg40> QOS: normal mode 0 < 0.4
> 0:00:01.608371 ffmpeg gstffmpegdec.c:897:gst_ffmpegdec_get_buffer:<ffdec_mpeg40> getting buffer, apply pts 1234701170
> 0:00:01.608943 ffmpeg gstffmpegdec.c:1600:gst_ffmpegdec_video_frame:<ffdec_mpeg40> after decode: len 1352, have_data 288
> 0:00:01.608963 ffmpeg gstffmpegdec.c:1614:gst_ffmpegdec_video_frame:<ffdec_mpeg40> ts-handler: pts 1070718163
> 0:00:01.609079 GST_QOS gstbasetransform.c:1862:gst_base_transform_handle_buffer:<videoscale0> skipping transform: qostime 0:00:01.070718163 <= 0:00:01.070752257
>
> # The next frame will pass basetransform because we have caught up with the
> # previous rendering time
>
>
> One problem is that the framerate is unknown; with a correct framerate, the
> buffers have a duration and this gives a more accurate estimate of the expected
> rendering time of the next buffer. However, even so, small differences in
> decoding time may still make a buffer seem late (e.g. add 200ms to the first
> dropped buffer, above).
>
> The core of the problem, I think, is that the QoS handling doesn't take
> into account pipeline latency. It just assumes that throughput = 1/latency
> and doesn't seem to take into account that data can be buffered in the
> pipeline.
>
QoS does take latency into account (or else RTSP or RTP streams would
never play). It's probably that ffmpeg totally does not specify its
latency and thus it seems that buffers are simply arriving too late.
Adding a meaningful reply to the LATENCY query in ffmpeg will likely
solve this.
Wim
> Does anyone have any idea how to solve this? (Except for disabling qos, of
> course...)
>
> Regards,
> Arnout
More information about the gstreamer-devel
mailing list