diff options
author | Mark Nauwelaerts <mnauw@users.sourceforge.net> | 2013-11-26 20:57:37 +0100 |
---|---|---|
committer | Mark Nauwelaerts <mnauw@users.sourceforge.net> | 2013-11-26 20:57:37 +0100 |
commit | fa5865c0cdab48c6701fdf6f437ccaea3ab3286a (patch) | |
tree | a5e82bc3eca1705058316ea26f5fb88190b77563 | |
parent | 2ec4008ea5f3296f50d56b11422ed5d56de6692b (diff) |
avviddec: discard unused input frames
... to avoid these piling up in list of pending frames.
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=693772
-rw-r--r-- | ext/libav/gstavviddec.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/ext/libav/gstavviddec.c b/ext/libav/gstavviddec.c index 689cdeb..fe541f5 100644 --- a/ext/libav/gstavviddec.c +++ b/ext/libav/gstavviddec.c @@ -575,6 +575,11 @@ gst_ffmpegviddec_get_buffer (AVCodecContext * context, AVFrame * picture) if (G_UNLIKELY (frame == NULL)) goto no_frame; + /* now it has a buffer allocated, so it is real and will also + * be _released */ + GST_VIDEO_CODEC_FRAME_FLAG_UNSET (frame, + GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY); + if (G_UNLIKELY (frame->output_buffer != NULL)) goto duplicate_frame; @@ -1252,6 +1257,41 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec, GST_VIDEO_BUFFER_FLAG_INTERLACED); } + /* cleaning time */ + /* so we decoded this frame, frames preceding it in decoding order + * that still do not have a buffer allocated seem rather useless, + * and can be discarded, due to e.g. misparsed bogus frame + * or non-keyframe in skipped decoding, ... + * In any case, not likely to be seen again, so discard those, + * before they pile up and/or mess with timestamping */ + { + GList *l, *ol; + GstVideoDecoder *dec = GST_VIDEO_DECODER (ffmpegdec); + gboolean old = TRUE; + + ol = l = gst_video_decoder_get_frames (dec); + while (l) { + GstVideoCodecFrame *tmp = l->data; + + if (tmp == frame) + old = FALSE; + + if (old && GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (tmp)) { + GST_LOG_OBJECT (dec, + "discarding ghost frame %p (#%d) PTS:%" GST_TIME_FORMAT " DTS:%" + GST_TIME_FORMAT, tmp, tmp->system_frame_number, + GST_TIME_ARGS (tmp->pts), GST_TIME_ARGS (tmp->dts)); + /* drop extra ref and remove from frame list */ + gst_video_decoder_release_frame (dec, tmp); + } else { + /* drop extra ref we got */ + gst_video_codec_frame_unref (tmp); + } + l = l->next; + } + g_list_free (ol); + } + *ret = gst_video_decoder_finish_frame (GST_VIDEO_DECODER (ffmpegdec), out_frame); @@ -1387,6 +1427,10 @@ gst_ffmpegviddec_handle_frame (GstVideoDecoder * decoder, return GST_FLOW_ERROR; } + /* treat frame as void until a buffer is requested for it */ + GST_VIDEO_CODEC_FRAME_FLAG_SET (frame, + GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY); + bdata = minfo.data; bsize = minfo.size; |