summaryrefslogtreecommitdiffstats
path: root/libavcodec/decode.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2017-10-13 18:59:17 +0200
committerTimo Rothenpieler <timo@rothenpieler.org>2017-11-10 16:56:54 +0100
commit9f1cfd88af88a7d7d5c56a368a46639dfdfdef75 (patch)
tree3577d988bb3635da5ee09bb506591205577026c2 /libavcodec/decode.c
parent1fa3a9a31de11a2dee0efc75b89862e80ab3c90f (diff)
downloadffmpeg-streaming-9f1cfd88af88a7d7d5c56a368a46639dfdfdef75.zip
ffmpeg-streaming-9f1cfd88af88a7d7d5c56a368a46639dfdfdef75.tar.gz
decode: add a method for attaching lavc-internal data to frames
Use the AVFrame.private_ref field. This new struct will be useful in the following commits. Merges Libav commit 359a8a3e2d1194b52b6c386f94fd0929567dfb67.
Diffstat (limited to 'libavcodec/decode.c')
-rw-r--r--libavcodec/decode.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 86fe5ae..0f215d6 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -613,6 +613,16 @@ static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame)
if (ret == AVERROR_EOF)
avci->draining_done = 1;
+ /* free the per-frame decode data */
+ if (!ret) {
+ /* the only case where decode data is not set should be decoders
+ * that do not call ff_get_buffer() */
+ av_assert0((frame->private_ref && frame->private_ref->size == sizeof(FrameDecodeData)) ||
+ !(avctx->codec->capabilities & AV_CODEC_CAP_DR1));
+
+ av_buffer_unref(&frame->private_ref);
+ }
+
return ret;
}
@@ -1552,6 +1562,37 @@ static void validate_avframe_allocation(AVCodecContext *avctx, AVFrame *frame)
}
}
+static void decode_data_free(void *opaque, uint8_t *data)
+{
+ FrameDecodeData *fdd = (FrameDecodeData*)data;
+
+ av_freep(&fdd);
+}
+
+int ff_attach_decode_data(AVFrame *frame)
+{
+ AVBufferRef *fdd_buf;
+ FrameDecodeData *fdd;
+
+ av_assert1(!frame->private_ref);
+ av_buffer_unref(&frame->private_ref);
+
+ fdd = av_mallocz(sizeof(*fdd));
+ if (!fdd)
+ return AVERROR(ENOMEM);
+
+ fdd_buf = av_buffer_create((uint8_t*)fdd, sizeof(*fdd), decode_data_free,
+ NULL, AV_BUFFER_FLAG_READONLY);
+ if (!fdd_buf) {
+ av_freep(&fdd);
+ return AVERROR(ENOMEM);
+ }
+
+ frame->private_ref = fdd_buf;
+
+ return 0;
+}
+
static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
{
const AVHWAccel *hwaccel = avctx->hwaccel;
@@ -1588,8 +1629,14 @@ static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
avctx->sw_pix_fmt = avctx->pix_fmt;
ret = avctx->get_buffer2(avctx, frame, flags);
- if (ret >= 0)
- validate_avframe_allocation(avctx, frame);
+ if (ret < 0)
+ goto end;
+
+ validate_avframe_allocation(avctx, frame);
+
+ ret = ff_attach_decode_data(frame);
+ if (ret < 0)
+ goto end;
end:
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions &&
OpenPOWER on IntegriCloud