mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
lavc/decode: allow using AV_CODEC_FLAG_COPY_OPAQUE for decoding
Use it to propagate AVPacket.opaque[_ref] to corresponding AVFrame fields. This is a more convenient alternative to reordered_opaque.
This commit is contained in:
parent
82da22066c
commit
d02340b9e3
@ -14,6 +14,9 @@ libavutil: 2021-04-27
|
||||
|
||||
API changes, most recent first:
|
||||
|
||||
2023-0x-xx - xxxxxxxxxx - lavc 59.63.100
|
||||
Allow AV_CODEC_FLAG_COPY_OPAQUE to be used with decoders.
|
||||
|
||||
2023-01-29 - xxxxxxxxxx - lavc 59.59.100 - avcodec.h
|
||||
Add AV_CODEC_FLAG_COPY_OPAQUE and AV_CODEC_FLAG_FRAME_DURATION.
|
||||
|
||||
|
@ -242,9 +242,15 @@ typedef struct RcOverride{
|
||||
*/
|
||||
#define AV_CODEC_FLAG_RECON_FRAME (1 << 6)
|
||||
/**
|
||||
* @par decoding
|
||||
* Request the decoder to propagate each packets AVPacket.opaque and
|
||||
* AVPacket.opaque_ref to its corresponding output AVFrame.
|
||||
*
|
||||
* @par encoding:
|
||||
* Request the encoder to propagate each frame's AVFrame.opaque and
|
||||
* AVFrame.opaque_ref values to its corresponding output AVPacket.
|
||||
*
|
||||
* @par
|
||||
* May only be set on encoders that have the
|
||||
* @ref AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability flag.
|
||||
*
|
||||
@ -265,6 +271,9 @@ typedef struct RcOverride{
|
||||
* .
|
||||
* When an output packet contains multiple frames, the opaque values will be
|
||||
* taken from the first of those.
|
||||
*
|
||||
* @note
|
||||
* The converse holds for decoders, with frames and packets switched.
|
||||
*/
|
||||
#define AV_CODEC_FLAG_COPY_OPAQUE (1 << 7)
|
||||
/**
|
||||
|
@ -1291,7 +1291,8 @@ static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame)
|
||||
return av_packet_unpack_dictionary(side_metadata, size, frame_md);
|
||||
}
|
||||
|
||||
int ff_decode_frame_props_from_pkt(AVFrame *frame, const AVPacket *pkt)
|
||||
int ff_decode_frame_props_from_pkt(const AVCodecContext *avctx,
|
||||
AVFrame *frame, const AVPacket *pkt)
|
||||
{
|
||||
static const struct {
|
||||
enum AVPacketSideDataType packet;
|
||||
@ -1336,6 +1337,13 @@ int ff_decode_frame_props_from_pkt(AVFrame *frame, const AVPacket *pkt)
|
||||
frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD);
|
||||
}
|
||||
|
||||
if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
|
||||
int ret = av_buffer_replace(&frame->opaque_ref, pkt->opaque_ref);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
frame->opaque = pkt->opaque;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1344,7 +1352,7 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
|
||||
const AVPacket *pkt = avctx->internal->last_pkt_props;
|
||||
|
||||
if (!(ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) {
|
||||
int ret = ff_decode_frame_props_from_pkt(frame, pkt);
|
||||
int ret = ff_decode_frame_props_from_pkt(avctx, frame, pkt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
frame->pkt_size = (int)(intptr_t)pkt->opaque;
|
||||
|
@ -72,7 +72,8 @@ int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt);
|
||||
/**
|
||||
* Set various frame properties from the provided packet.
|
||||
*/
|
||||
int ff_decode_frame_props_from_pkt(AVFrame *frame, const AVPacket *pkt);
|
||||
int ff_decode_frame_props_from_pkt(const AVCodecContext *avctx,
|
||||
AVFrame *frame, const AVPacket *pkt);
|
||||
|
||||
/**
|
||||
* Set various frame properties from the codec context / packet data.
|
||||
|
@ -288,6 +288,11 @@ static void libdav1d_flush(AVCodecContext *c)
|
||||
dav1d_flush(dav1d->c);
|
||||
}
|
||||
|
||||
typedef struct OpaqueData {
|
||||
void *pkt_orig_opaque;
|
||||
int64_t reordered_opaque;
|
||||
} OpaqueData;
|
||||
|
||||
static void libdav1d_data_free(const uint8_t *data, void *opaque) {
|
||||
AVBufferRef *buf = opaque;
|
||||
|
||||
@ -307,6 +312,7 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
|
||||
Dav1dData *data = &dav1d->data;
|
||||
Dav1dPicture pic = { 0 }, *p = &pic;
|
||||
AVPacket *pkt;
|
||||
OpaqueData *od = NULL;
|
||||
#if FF_DAV1D_VERSION_AT_LEAST(5,1)
|
||||
enum Dav1dEventFlags event_flags = 0;
|
||||
#endif
|
||||
@ -333,17 +339,19 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
|
||||
}
|
||||
|
||||
pkt->buf = NULL;
|
||||
pkt->opaque = NULL;
|
||||
|
||||
if (c->reordered_opaque != AV_NOPTS_VALUE) {
|
||||
pkt->opaque = av_memdup(&c->reordered_opaque,
|
||||
sizeof(c->reordered_opaque));
|
||||
if (!pkt->opaque) {
|
||||
if (c->reordered_opaque != AV_NOPTS_VALUE ||
|
||||
(pkt->opaque && (c->flags & AV_CODEC_FLAG_COPY_OPAQUE))) {
|
||||
od = av_mallocz(sizeof(*od));
|
||||
if (!od) {
|
||||
av_packet_free(&pkt);
|
||||
dav1d_data_unref(data);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
od->pkt_orig_opaque = pkt->opaque;
|
||||
od->reordered_opaque = c->reordered_opaque;
|
||||
}
|
||||
pkt->opaque = od;
|
||||
|
||||
res = dav1d_data_wrap_user_data(data, (const uint8_t *)pkt,
|
||||
libdav1d_user_data_free, pkt);
|
||||
@ -423,13 +431,20 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
|
||||
ff_set_sar(c, frame->sample_aspect_ratio);
|
||||
|
||||
pkt = (AVPacket *)p->m.user_data.data;
|
||||
if (pkt->opaque)
|
||||
memcpy(&frame->reordered_opaque, pkt->opaque, sizeof(frame->reordered_opaque));
|
||||
od = pkt->opaque;
|
||||
if (od && od->reordered_opaque != AV_NOPTS_VALUE)
|
||||
frame->reordered_opaque = od->reordered_opaque;
|
||||
else
|
||||
frame->reordered_opaque = AV_NOPTS_VALUE;
|
||||
|
||||
// restore the original user opaque value for
|
||||
// ff_decode_frame_props_from_pkt()
|
||||
pkt->opaque = od ? od->pkt_orig_opaque : NULL;
|
||||
av_freep(&od);
|
||||
|
||||
// match timestamps and packet size
|
||||
res = ff_decode_frame_props_from_pkt(frame, pkt);
|
||||
res = ff_decode_frame_props_from_pkt(c, frame, pkt);
|
||||
pkt->opaque = NULL;
|
||||
if (res < 0)
|
||||
goto fail;
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
#include "version_major.h"
|
||||
|
||||
#define LIBAVCODEC_VERSION_MINOR 62
|
||||
#define LIBAVCODEC_VERSION_MINOR 63
|
||||
#define LIBAVCODEC_VERSION_MICRO 100
|
||||
|
||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||
|
Loading…
Reference in New Issue
Block a user