Browse Source

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.
tags/n4.0
Anton Khirnov Timo Rothenpieler 8 years ago
parent
commit
9f1cfd88af
3 changed files with 67 additions and 2 deletions
  1. +49
    -2
      libavcodec/decode.c
  2. +11
    -0
      libavcodec/decode.h
  3. +7
    -0
      libavcodec/wrapped_avframe.c

+ 49
- 2
libavcodec/decode.c View File

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


+ 11
- 0
libavcodec/decode.h View File

@@ -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 */

+ 7
- 0
libavcodec/wrapped_avframe.c View File

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