mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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
.
This commit is contained in:
parent
1fa3a9a31d
commit
9f1cfd88af
@ -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,9 +1629,15 @@ 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)
|
||||
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 &&
|
||||
!(avctx->codec->caps_internal & FF_CODEC_CAP_EXPORTS_CROPPING)) {
|
||||
|
@ -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…
Reference in New Issue
Block a user