From c7d5be2b69fe1f3472150acdcd68ed0eac28ee59 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 18 Jan 2008 17:48:21 +0000 Subject: [PATCH] ext/ffmpeg/gstffmpegdec.c: Flush delayed frames on DISCONT if we have them. Original commit message from CVS: * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_drain), (gst_ffmpegdec_sink_event), (gst_ffmpegdec_chain): Flush delayed frames on DISCONT if we have them. --- ChangeLog | 6 +++++ common | 2 +- ext/ffmpeg/gstffmpegdec.c | 56 ++++++++++++++++++++++----------------- 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index de437878e3..d38e840d79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-01-18 Wim Taymans + + * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_drain), + (gst_ffmpegdec_sink_event), (gst_ffmpegdec_chain): + Flush delayed frames on DISCONT if we have them. + 2008-01-18 Wim Taymans * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_video_frame), diff --git a/common b/common index 9aa2dcf8d6..b6bd1a35b6 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 9aa2dcf8d6855932e9e91006d6be96f55fd9f1a3 +Subproject commit b6bd1a35b641237d016496039e474dee4230de76 diff --git a/ext/ffmpeg/gstffmpegdec.c b/ext/ffmpeg/gstffmpegdec.c index c105a790b6..ee9627b557 100644 --- a/ext/ffmpeg/gstffmpegdec.c +++ b/ext/ffmpeg/gstffmpegdec.c @@ -1743,6 +1743,34 @@ no_codec: } } +static void +gst_ffmpegdec_drain (GstFFMpegDec * ffmpegdec) +{ + GstFFMpegDecClass *oclass; + + oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec)); + + if (oclass->in_plugin->capabilities & CODEC_CAP_DELAY) { + gint have_data, len, try = 0; + + GST_LOG_OBJECT (ffmpegdec, + "codec has delay capabilities, calling until ffmpeg has drained everything"); + + do { + GstFlowReturn ret; + + len = gst_ffmpegdec_frame (ffmpegdec, NULL, 0, &have_data, + GST_CLOCK_TIME_NONE, GST_CLOCK_TIME_NONE, &ret); + if (len < 0 || have_data == 0) + break; + } while (try++ < 10); + } + if (ffmpegdec->segment.rate < 0.0) { + /* if we have some queued frames for reverse playback, flush them now */ + flush_queued (ffmpegdec); + } +} + static void gst_ffmpegdec_flush_pcache (GstFFMpegDec * ffmpegdec) { @@ -1776,25 +1804,7 @@ gst_ffmpegdec_sink_event (GstPad * pad, GstEvent * event) switch (GST_EVENT_TYPE (event)) { case GST_EVENT_EOS: { - if (oclass->in_plugin->capabilities & CODEC_CAP_DELAY) { - gint have_data, len, try = 0; - - GST_LOG_OBJECT (ffmpegdec, - "codec has delay capabilities, calling until ffmpeg has drained everything"); - - do { - GstFlowReturn ret; - - len = gst_ffmpegdec_frame (ffmpegdec, NULL, 0, &have_data, - GST_CLOCK_TIME_NONE, GST_CLOCK_TIME_NONE, &ret); - if (len < 0 || have_data == 0) - break; - } while (try++ < 10); - } - if (ffmpegdec->segment.rate < 0.0) { - /* if we have some queued frames for reverse playback, flush them now */ - flush_queued (ffmpegdec); - } + gst_ffmpegdec_drain (ffmpegdec); break; } case GST_EVENT_FLUSH_STOP: @@ -1921,17 +1931,13 @@ gst_ffmpegdec_chain (GstPad * pad, GstBuffer * inbuf) * case of a network error, better show the errors than to drop all data.. */ if (G_UNLIKELY (discont)) { GST_DEBUG_OBJECT (ffmpegdec, "received DISCONT"); + /* drain what we have queued */ + gst_ffmpegdec_drain (ffmpegdec); gst_ffmpegdec_flush_pcache (ffmpegdec); avcodec_flush_buffers (ffmpegdec->context); ffmpegdec->waiting_for_key = TRUE; ffmpegdec->discont = TRUE; ffmpegdec->next_ts = GST_CLOCK_TIME_NONE; - - /* flush on discont */ - if (ffmpegdec->segment.rate < 0.0) { - /* flush out queued reverse frames */ - ret = flush_queued (ffmpegdec); - } } oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));