diff options
author | Anton Khirnov <anton@khirnov.net> | 2017-10-13 18:59:17 +0200 |
---|---|---|
committer | Timo Rothenpieler <timo@rothenpieler.org> | 2017-11-10 16:56:54 +0100 |
commit | 9f1cfd88af88a7d7d5c56a368a46639dfdfdef75 (patch) | |
tree | 3577d988bb3635da5ee09bb506591205577026c2 /libavcodec/decode.c | |
parent | 1fa3a9a31de11a2dee0efc75b89862e80ab3c90f (diff) | |
download | ffmpeg-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.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 86fe5aef52..0f215d6915 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 && |