Discussion:
[libav-devel] [PATCH 1/2] libavutil: Undeprecate the AVFrame reordered_opaque field
Martin Storsjö
2018-10-25 12:45:20 UTC
Permalink
This was marked as deprecated (but only in the doxygen, not with an
actual deprecation attribute) in 81c623fae05 in 2011, but was
undeprecated in ad1ee5fa7.
---
libavutil/frame.h | 1 -
libavutil/version.h | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/libavutil/frame.h b/libavutil/frame.h
index ff3fe46dd6..c7240ebe9b 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -295,7 +295,6 @@ typedef struct AVFrame {
* that time,
* the decoder reorders values as needed and sets AVFrame.reordered_opaque
* to exactly one of the values provided by the user through AVCodecContext.reordered_opaque
- * @deprecated in favor of pkt_pts
*/
int64_t reordered_opaque;

diff --git a/libavutil/version.h b/libavutil/version.h
index 4a9fffef43..e5fbd4ca81 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -55,7 +55,7 @@

#define LIBAVUTIL_VERSION_MAJOR 56
#define LIBAVUTIL_VERSION_MINOR 7
-#define LIBAVUTIL_VERSION_MICRO 0
+#define LIBAVUTIL_VERSION_MICRO 1

#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
LIBAVUTIL_VERSION_MINOR, \
--
2.17.1 (Apple Git-112)
Martin Storsjö
2018-10-25 12:45:21 UTC
Permalink
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.
---
libavcodec/avcodec.h | 12 +++++++++++-
libavcodec/libx264.c | 31 +++++++++++++++++++++++++++++--
2 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index fb8e34e7d5..727e1c411d 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -899,6 +899,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.
@@ -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..c852858db8 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,12 @@ 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;

+ x4->nb_reordered_opaque = x264_encoder_maximum_delayed_frames(x4->enc) + 1;
+ 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 +875,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 +903,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,
--
2.17.1 (Apple Git-112)
Martin Storsjö
2018-10-25 12:52:16 UTC
Permalink
Post by Martin Storsjö
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.
---
libavcodec/avcodec.h | 12 +++++++++++-
libavcodec/libx264.c | 31 +++++++++++++++++++++++++++++--
2 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index fb8e34e7d5..727e1c411d 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -899,6 +899,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)
This obviously needs a minor bump, I'll add one locally.

// Martin
Luca Barbato
2018-10-26 16:01:11 UTC
Permalink
Post by Martin Storsjö
This was marked as deprecated (but only in the doxygen, not with an
actual deprecation attribute) in 81c623fae05 in 2011, but was
undeprecated in ad1ee5fa7.
---
libavutil/frame.h | 1 -
libavutil/version.h | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
The set is probably fine.

lu

Loading...