|
|
|
@ -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 && |
|
|
|
|