[FFmpeg-cvslog] libx264: Pass the reordered_opaque field through the encoder
Martin Storsjö
git at videolan.org
Wed Feb 20 19:07:54 EET 2019
ffmpeg | branch: master | Martin Storsjö <martin at martin.st> | Thu Oct 11 16:03:10 2018 +0300| [80f85a95da293e9894c071b440c5a2e002e26ede] | committer: Martin Storsjö
libx264: Pass the reordered_opaque field through the encoder
libx264 does have a field for opaque data to pass along with frames
through the encoder, but it is a pointer, while the libavcodec
reordered_opaque field is an int64_t. Therefore, allocate an array
within the libx264 wrapper, where reordered_opaque values in flight
are stored, and pass a pointer to this array to libx264.
Update the public libavcodec documentation for the AVCodecContext
field to explain this usage, and add a codec capability that allows
detecting whether an encoder handles this field.
Signed-off-by: Martin Storsjö <martin at martin.st>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=80f85a95da293e9894c071b440c5a2e002e26ede
---
libavcodec/avcodec.h | 12 +++++++++++-
libavcodec/libx264.c | 33 +++++++++++++++++++++++++++++++--
libavcodec/version.h | 2 +-
3 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index fb8e34e7d5..727e1c411d 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -900,6 +900,13 @@ typedef struct RcOverride{
#define AV_CODEC_CAP_HYBRID (1 << 18)
/**
+ * This codec takes the reordered_opaque field from input AVFrames
+ * and returns it in the corresponding field in AVCodecContext after
+ * encoding.
+ */
+#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE (1 << 19)
+
+/**
* Pan Scan area.
* This specifies the area which should be displayed.
* Note there may be multiple such areas for one frame.
@@ -2297,7 +2304,10 @@ typedef struct AVCodecContext {
/**
* opaque 64-bit number (generally a PTS) that will be reordered and
* output in AVFrame.reordered_opaque
- * - encoding: unused
+ * - encoding: Set by libavcodec to the reordered_opaque of the input
+ * frame corresponding to the last returned packet. Only
+ * supported by encoders with the
+ * AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability.
* - decoding: Set by user.
*/
int64_t reordered_opaque;
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 3dc53aaf38..f30a4ccad1 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -85,6 +85,9 @@ typedef struct X264Context {
int noise_reduction;
char *x264_params;
+
+ int nb_reordered_opaque, next_reordered_opaque;
+ int64_t *reordered_opaque;
} X264Context;
static void X264_log(void *p, int level, const char *fmt, va_list args)
@@ -240,6 +243,7 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
x264_nal_t *nal;
int nnal, i, ret;
x264_picture_t pic_out;
+ int64_t *out_opaque;
x264_picture_init( &x4->pic );
x4->pic.img.i_csp = x4->params.i_csp;
@@ -259,6 +263,11 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
x4->pic.i_pts = frame->pts;
+ x4->reordered_opaque[x4->next_reordered_opaque] = frame->reordered_opaque;
+ x4->pic.opaque = &x4->reordered_opaque[x4->next_reordered_opaque];
+ x4->next_reordered_opaque++;
+ x4->next_reordered_opaque %= x4->nb_reordered_opaque;
+
switch (frame->pict_type) {
case AV_PICTURE_TYPE_I:
x4->pic.i_type = x4->forced_idr ? X264_TYPE_IDR
@@ -288,6 +297,15 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
pkt->pts = pic_out.i_pts;
pkt->dts = pic_out.i_dts;
+ out_opaque = pic_out.opaque;
+ if (out_opaque >= x4->reordered_opaque &&
+ out_opaque < &x4->reordered_opaque[x4->nb_reordered_opaque]) {
+ ctx->reordered_opaque = *out_opaque;
+ } else {
+ // Unexpected opaque pointer on picture output
+ ctx->reordered_opaque = 0;
+ }
+
#if FF_API_CODED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
switch (pic_out.i_type) {
@@ -331,6 +349,7 @@ static av_cold int X264_close(AVCodecContext *avctx)
av_freep(&avctx->extradata);
av_freep(&x4->sei);
+ av_freep(&x4->reordered_opaque);
if (x4->enc) {
x264_encoder_close(x4->enc);
@@ -663,6 +682,14 @@ FF_ENABLE_DEPRECATION_WARNINGS
cpb_props->max_bitrate = x4->params.rc.i_vbv_max_bitrate * 1000;
cpb_props->avg_bitrate = x4->params.rc.i_bitrate * 1000;
+ // Overestimate the reordered opaque buffer size, in case a runtime
+ // reconfigure would increase the delay (which it shouldn't).
+ x4->nb_reordered_opaque = x264_encoder_maximum_delayed_frames(x4->enc) + 17;
+ x4->reordered_opaque = av_malloc_array(x4->nb_reordered_opaque,
+ sizeof(*x4->reordered_opaque));
+ if (!x4->reordered_opaque)
+ return AVERROR(ENOMEM);
+
return 0;
}
@@ -850,7 +877,8 @@ AVCodec ff_libx264_encoder = {
.init = X264_init,
.encode2 = X264_frame,
.close = X264_close,
- .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_class = &class,
.defaults = x264_defaults,
.init_static_data = X264_init_static,
@@ -877,7 +905,8 @@ AVCodec ff_libx262_encoder = {
.init = X264_init,
.encode2 = X264_frame,
.close = X264_close,
- .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS |
+ AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
.priv_class = &X262_class,
.defaults = x264_defaults,
.pix_fmts = pix_fmts_8bit,
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 32486a83c1..29ff4d3ad0 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -28,7 +28,7 @@
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 58
-#define LIBAVCODEC_VERSION_MINOR 10
+#define LIBAVCODEC_VERSION_MINOR 11
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
More information about the ffmpeg-cvslog
mailing list