Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
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 359a8a3.
- Loading branch information
Showing
with
67 additions
and
2 deletions.
-
+49
−2
libavcodec/decode.c
-
+11
−0
libavcodec/decode.h
-
+7
−0
libavcodec/wrapped_avframe.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 && |
|
|
|
|
|
@@ -21,8 +21,17 @@ |
|
|
#ifndef AVCODEC_DECODE_H |
|
|
#define AVCODEC_DECODE_H |
|
|
|
|
|
#include "libavutil/buffer.h" |
|
|
|
|
|
#include "avcodec.h" |
|
|
|
|
|
/** |
|
|
* This struct stores per-frame lavc-internal data and is attached to it via |
|
|
* private_ref. |
|
|
*/ |
|
|
typedef struct FrameDecodeData { |
|
|
} FrameDecodeData; |
|
|
|
|
|
/** |
|
|
* Called by decoders to get the next packet for decoding. |
|
|
* |
|
|
@@ -36,4 +45,6 @@ int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt); |
|
|
|
|
|
void ff_decode_bsfs_uninit(AVCodecContext *avctx); |
|
|
|
|
|
int ff_attach_decode_data(AVFrame *frame); |
|
|
|
|
|
#endif /* AVCODEC_DECODE_H */ |
|
|
@@ -25,6 +25,7 @@ |
|
|
*/ |
|
|
|
|
|
#include "avcodec.h" |
|
|
#include "decode.h" |
|
|
#include "internal.h" |
|
|
|
|
|
#include "libavutil/internal.h" |
|
|
@@ -98,6 +99,12 @@ static int wrapped_avframe_decode(AVCodecContext *avctx, void *data, |
|
|
|
|
|
av_frame_move_ref(out, in); |
|
|
|
|
|
err = ff_attach_decode_data(out); |
|
|
if (err < 0) { |
|
|
av_frame_unref(out); |
|
|
return err; |
|
|
} |
|
|
|
|
|
*got_frame = 1; |
|
|
return 0; |
|
|
} |
|
|
|