summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeungha Yang <seungha.yang@navercorp.com>2019-10-24 00:25:28 +0900
committerTim-Philipp Müller <tim@centricular.com>2019-10-24 10:28:32 +0100
commit2e8296620bc22f97c34f876ab62902e7c3d89601 (patch)
tree7a51100aedb1c338d2a6e180ebf9369801a6aee3
parentfe08c26641592f058b6fa0da9a1f86fc0b24cb0c (diff)
downloadgst-libav-2e8296620bc22f97c34f876ab62902e7c3d89601.tar.gz
avviddec: Enforce allocate new AVFrame per input frame
... if ffmpeg would reuse the allocated AVBuffer. Reused AVFrame by the ffmpeg seems to break our decoding flow since the reused AVFrame holds the initial opaque data (GstVideoCodecFrame in this case), so we couldn't trace the our in/out frames. To enforce get_buffer() call per output frame, hold another reference to the AVBuffer in order to mark the AVBuffer as not writable. Fixes: https://gitlab.freedesktop.org/gstreamer/gst-libav/issues/62
-rw-r--r--ext/libav/gstavviddec.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/ext/libav/gstavviddec.c b/ext/libav/gstavviddec.c
index 374bd9e..58979d8 100644
--- a/ext/libav/gstavviddec.c
+++ b/ext/libav/gstavviddec.c
@@ -730,6 +730,12 @@ gst_ffmpegviddec_can_direct_render (GstFFMpegVidDec * ffmpegdec)
AV_CODEC_CAP_DR1);
}
+static void
+gst_ffmpegviddec_avbuffer_unref (AVBufferRef * avbuffer)
+{
+ av_buffer_unref (&avbuffer);
+}
+
/* called when ffmpeg wants us to allocate a buffer to write the decoded frame
* into. We try to give it memory from our pool */
static int
@@ -823,6 +829,16 @@ gst_ffmpegviddec_get_buffer2 (AVCodecContext * context, AVFrame * picture,
}
picture->buf[0] = av_buffer_create (NULL, 0, dummy_free_buffer, dframe, 0);
+ if ((flags & AV_GET_BUFFER_FLAG_REF) == AV_GET_BUFFER_FLAG_REF) {
+ /* decoder might reuse this AVFrame and it would result to no more
+ * get_buffer() call if the AVFrame's AVBuffer is writable
+ * (meaning that the refcount of AVBuffer == 1).
+ * To enforce get_buffer() for the every output frame, hold another ref here
+ */
+ gst_video_codec_frame_set_user_data (frame,
+ av_buffer_ref (picture->buf[0]),
+ (GDestroyNotify) gst_ffmpegviddec_avbuffer_unref);
+ }
GST_LOG_OBJECT (ffmpegdec, "returned frame %p", dframe->buffer);