Browse Source

decode: add a method for attaching lavc-internal data to frames

Use the AVFrame.opaque_ref field. The original user's opaque_ref is
wrapped in the lavc struct and then unwrapped before the frame is
returned to the caller.

This new struct will be useful in the following commits.
tags/n4.0
Anton Khirnov 8 years ago
parent
commit
359a8a3e2d
2 changed files with 70 additions and 0 deletions
  1. +57
    -0
      libavcodec/decode.c
  2. +13
    -0
      libavcodec/decode.h

+ 57
- 0
libavcodec/decode.c View File

@@ -406,6 +406,26 @@ static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame)
if (ret == AVERROR_EOF)
avci->draining_done = 1;

/* unwrap the per-frame decode data and restore the original opaque_ref*/
if (!ret) {
/* the only case where decode data is not set should be decoders
* that do not call ff_get_buffer() */
av_assert0((frame->opaque_ref && frame->opaque_ref->size == sizeof(FrameDecodeData)) ||
!(avctx->codec->capabilities & AV_CODEC_CAP_DR1));

if (frame->opaque_ref) {
FrameDecodeData *fdd;
AVBufferRef *user_opaque_ref;

fdd = (FrameDecodeData*)frame->opaque_ref->data;

user_opaque_ref = fdd->user_opaque_ref;
fdd->user_opaque_ref = NULL;
av_buffer_unref(&frame->opaque_ref);
frame->opaque_ref = user_opaque_ref;
}
}

return ret;
}

@@ -988,6 +1008,37 @@ FF_ENABLE_DEPRECATION_WARNINGS
return 0;
}

static void decode_data_free(void *opaque, uint8_t *data)
{
FrameDecodeData *fdd = (FrameDecodeData*)data;

av_buffer_unref(&fdd->user_opaque_ref);

av_freep(&fdd);
}

static int attach_decode_data(AVFrame *frame)
{
AVBufferRef *fdd_buf;
FrameDecodeData *fdd;

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);
}

fdd->user_opaque_ref = frame->opaque_ref;
frame->opaque_ref = fdd_buf;

return 0;
}

int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
{
const AVHWAccel *hwaccel = avctx->hwaccel;
@@ -1061,6 +1112,12 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
avctx->sw_pix_fmt = avctx->pix_fmt;

ret = avctx->get_buffer2(avctx, frame, flags);
if (ret < 0)
goto end;

ret = attach_decode_data(frame);
if (ret < 0)
goto end;

end:
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions &&


+ 13
- 0
libavcodec/decode.h View File

@@ -21,8 +21,21 @@
#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
* opaque_ref.
*/
typedef struct FrameDecodeData {
/**
* The original user-set opaque_ref.
*/
AVBufferRef *user_opaque_ref;
} FrameDecodeData;

/**
* Called by decoders to get the next packet for decoding.
*


Loading…
Cancel
Save