summaryrefslogtreecommitdiff
path: root/libavcodec/libx264.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2022-07-12 11:25:09 +0200
committerAnton Khirnov <anton@khirnov.net>2023-01-29 09:18:14 +0100
commit5c0348f3d61ce850fa33fe79b5d2bc49f7b52683 (patch)
tree95866baba0e6ced127e90c906d791cb60b8d02cc /libavcodec/libx264.c
parentd0c8ca961d7d4a496f212283781ba74623bf8c3f (diff)
downloadffmpeg-5c0348f3d61ce850fa33fe79b5d2bc49f7b52683.tar.gz
lavc: add a codec flag for propagating opaque from frames to packets
This is intended to be a more convenient replacement for reordered_opaque. Add support for it in the two encoders that offer AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE: libx264 and libx265. Other encoders will be supported in future commits.
Diffstat (limited to 'libavcodec/libx264.c')
-rw-r--r--libavcodec/libx264.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 2bbd9044b6..6d22a1726e 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -21,6 +21,7 @@
#include "config_components.h"
+#include "libavutil/buffer.h"
#include "libavutil/eval.h"
#include "libavutil/internal.h"
#include "libavutil/opt.h"
@@ -51,6 +52,9 @@
typedef struct X264Opaque {
int64_t reordered_opaque;
int64_t wallclock;
+
+ void *frame_opaque;
+ AVBufferRef *frame_opaque_ref;
} X264Opaque;
typedef struct X264Context {
@@ -133,6 +137,11 @@ static void X264_log(void *p, int level, const char *fmt, va_list args)
av_vlog(p, level_map[level], fmt, args);
}
+static void opaque_uninit(X264Opaque *o)
+{
+ av_buffer_unref(&o->frame_opaque_ref);
+ memset(o, 0, sizeof(*o));
+}
static int encode_nals(AVCodecContext *ctx, AVPacket *pkt,
const x264_nal_t *nals, int nnal)
@@ -440,6 +449,15 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
pic->i_pts = frame->pts;
+ opaque_uninit(opaque);
+
+ if (ctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+ opaque->frame_opaque = frame->opaque;
+ ret = av_buffer_replace(&opaque->frame_opaque_ref, frame->opaque_ref);
+ if (ret < 0)
+ goto fail;
+ }
+
opaque->reordered_opaque = frame->reordered_opaque;
opaque->wallclock = wallclock;
if (ctx->export_side_data & AV_CODEC_EXPORT_DATA_PRFT)
@@ -594,6 +612,14 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
out_opaque < &x4->reordered_opaque[x4->nb_reordered_opaque]) {
ctx->reordered_opaque = out_opaque->reordered_opaque;
wallclock = out_opaque->wallclock;
+
+ if (ctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+ pkt->opaque = out_opaque->frame_opaque;
+ pkt->opaque_ref = out_opaque->frame_opaque_ref;
+ out_opaque->frame_opaque_ref = NULL;
+ }
+
+ opaque_uninit(out_opaque);
} else {
// Unexpected opaque pointer on picture output
av_log(ctx, AV_LOG_ERROR, "Unexpected opaque pointer; "
@@ -634,6 +660,9 @@ static av_cold int X264_close(AVCodecContext *avctx)
X264Context *x4 = avctx->priv_data;
av_freep(&x4->sei);
+
+ for (int i = 0; i < x4->nb_reordered_opaque; i++)
+ opaque_uninit(&x4->reordered_opaque[i]);
av_freep(&x4->reordered_opaque);
#if X264_BUILD >= 161