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)
|
if (ret == AVERROR_EOF)
|
||||||
avci->draining_done = 1;
|
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;
|
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)
|
static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
|
||||||
{
|
{
|
||||||
const AVHWAccel *hwaccel = avctx->hwaccel;
|
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;
|
avctx->sw_pix_fmt = avctx->pix_fmt;
|
||||||
|
|
||||||
ret = avctx->get_buffer2(avctx, frame, flags);
|
ret = avctx->get_buffer2(avctx, frame, flags);
|
||||||
if (ret >= 0)
|
if (ret < 0)
|
||||||
validate_avframe_allocation(avctx, frame);
|
goto end;
|
||||||
|
|
||||||
|
validate_avframe_allocation(avctx, frame);
|
||||||
|
|
||||||
|
ret = ff_attach_decode_data(frame);
|
||||||
|
if (ret < 0)
|
||||||
|
goto end;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions &&
|
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions &&
|
||||||
|
@ -21,8 +21,17 @@
|
|||||||
#ifndef AVCODEC_DECODE_H
|
#ifndef AVCODEC_DECODE_H
|
||||||
#define AVCODEC_DECODE_H
|
#define AVCODEC_DECODE_H
|
||||||
|
|
||||||
|
#include "libavutil/buffer.h"
|
||||||
|
|
||||||
#include "avcodec.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.
|
* 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);
|
void ff_decode_bsfs_uninit(AVCodecContext *avctx);
|
||||||
|
|
||||||
|
int ff_attach_decode_data(AVFrame *frame);
|
||||||
|
|
||||||
#endif /* AVCODEC_DECODE_H */
|
#endif /* AVCODEC_DECODE_H */
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
|
#include "decode.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include "libavutil/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);
|
av_frame_move_ref(out, in);
|
||||||
|
|
||||||
|
err = ff_attach_decode_data(out);
|
||||||
|
if (err < 0) {
|
||||||
|
av_frame_unref(out);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
*got_frame = 1;
|
*got_frame = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user