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 359a8a3e2d.
pull/272/head
Anton Khirnov 7 years ago committed by Timo Rothenpieler
parent 1fa3a9a31d
commit 9f1cfd88af
  1. 51
      libavcodec/decode.c
  2. 11
      libavcodec/decode.h
  3. 7
      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;
}

Loading…
Cancel
Save