Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame
@ 2022-11-27 17:03 Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 02/30] lavc/libx264: reindent after previous commit Anton Khirnov
                   ` (28 more replies)
  0 siblings, 29 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

X264_frame() is currently too large and complex.
---
 libavcodec/libx264.c | 45 +++++++++++++++++++++++++++++---------------
 1 file changed, 30 insertions(+), 15 deletions(-)

diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index ca0b5a145b..009cad4bdf 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -333,19 +333,20 @@ static enum AVPixelFormat csp_to_pixfmt(int csp)
     return AV_PIX_FMT_NONE;
 }
 
-static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
-                      int *got_packet)
+static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
+                       x264_picture_t **ppic)
 {
     X264Context *x4 = ctx->priv_data;
-    x264_nal_t *nal;
-    int nnal, i, ret;
-    x264_picture_t pic_out = {0};
-    int pict_type;
-    int bit_depth;
+    x264_sei_t *sei = &x4->pic.extra_sei;
+    unsigned int sei_data_size = 0;
     int64_t wallclock = 0;
-    X264Opaque *out_opaque;
+    int bit_depth, ret;
     AVFrameSideData *sd;
 
+    *ppic = NULL;
+    if (!frame)
+        return 0;
+
     x264_picture_init( &x4->pic );
     x4->pic.img.i_csp   = x4->params.i_csp;
 #if X264_BUILD >= 153
@@ -357,11 +358,7 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
         x4->pic.img.i_csp |= X264_CSP_HIGH_DEPTH;
     x4->pic.img.i_plane = avfmt2_num_planes(ctx->pix_fmt);
 
-    if (frame) {
-        x264_sei_t *sei = &x4->pic.extra_sei;
-        unsigned int sei_data_size = 0;
-
-        for (i = 0; i < x4->pic.img.i_plane; i++) {
+        for (int i = 0; i < x4->pic.img.i_plane; i++) {
             x4->pic.img.plane[i]    = frame->data[i];
             x4->pic.img.i_stride[i] = frame->linesize[i];
         }
@@ -512,10 +509,28 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
                 sei->num_payloads++;
             }
         }
-    }
+
+    *ppic = &x4->pic;
+    return 0;
+}
+
+static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
+                      int *got_packet)
+{
+    X264Context *x4 = ctx->priv_data;
+    x264_nal_t *nal;
+    int nnal, ret;
+    x264_picture_t pic_out = {0}, *pic_in;
+    int pict_type;
+    int64_t wallclock = 0;
+    X264Opaque *out_opaque;
+
+    ret = setup_frame(ctx, frame, &pic_in);
+    if (ret < 0)
+        return ret;
 
     do {
-        if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0)
+        if (x264_encoder_encode(x4->enc, &nal, &nnal, pic_in, &pic_out) < 0)
             return AVERROR_EXTERNAL;
 
         if (nnal && (ctx->flags & AV_CODEC_FLAG_RECON_FRAME)) {
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 02/30] lavc/libx264: reindent after previous commit
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 03/30] lavc/libx264: use a local variable for input frame in setup_frame() Anton Khirnov
                   ` (27 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libx264.c | 260 +++++++++++++++++++++----------------------
 1 file changed, 130 insertions(+), 130 deletions(-)

diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 009cad4bdf..36c36d0e09 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -358,157 +358,157 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
         x4->pic.img.i_csp |= X264_CSP_HIGH_DEPTH;
     x4->pic.img.i_plane = avfmt2_num_planes(ctx->pix_fmt);
 
-        for (int i = 0; i < x4->pic.img.i_plane; i++) {
-            x4->pic.img.plane[i]    = frame->data[i];
-            x4->pic.img.i_stride[i] = frame->linesize[i];
-        }
-
-        x4->pic.i_pts  = frame->pts;
-
-        x4->reordered_opaque[x4->next_reordered_opaque].reordered_opaque = frame->reordered_opaque;
-        x4->reordered_opaque[x4->next_reordered_opaque].wallclock = wallclock;
-        if (ctx->export_side_data & AV_CODEC_EXPORT_DATA_PRFT)
-            x4->reordered_opaque[x4->next_reordered_opaque].wallclock = av_gettime();
-        x4->pic.opaque = &x4->reordered_opaque[x4->next_reordered_opaque];
-        x4->next_reordered_opaque++;
-        x4->next_reordered_opaque %= x4->nb_reordered_opaque;
+    for (int i = 0; i < x4->pic.img.i_plane; i++) {
+        x4->pic.img.plane[i]    = frame->data[i];
+        x4->pic.img.i_stride[i] = frame->linesize[i];
+    }
 
-        switch (frame->pict_type) {
-        case AV_PICTURE_TYPE_I:
-            x4->pic.i_type = x4->forced_idr > 0 ? X264_TYPE_IDR
-                                                : X264_TYPE_KEYFRAME;
-            break;
-        case AV_PICTURE_TYPE_P:
-            x4->pic.i_type = X264_TYPE_P;
-            break;
-        case AV_PICTURE_TYPE_B:
-            x4->pic.i_type = X264_TYPE_B;
-            break;
-        default:
-            x4->pic.i_type = X264_TYPE_AUTO;
-            break;
-        }
-        reconfig_encoder(ctx, frame);
+    x4->pic.i_pts  = frame->pts;
 
-        if (x4->a53_cc) {
-            void *sei_data;
-            size_t sei_size;
+    x4->reordered_opaque[x4->next_reordered_opaque].reordered_opaque = frame->reordered_opaque;
+    x4->reordered_opaque[x4->next_reordered_opaque].wallclock = wallclock;
+    if (ctx->export_side_data & AV_CODEC_EXPORT_DATA_PRFT)
+        x4->reordered_opaque[x4->next_reordered_opaque].wallclock = av_gettime();
+    x4->pic.opaque = &x4->reordered_opaque[x4->next_reordered_opaque];
+    x4->next_reordered_opaque++;
+    x4->next_reordered_opaque %= x4->nb_reordered_opaque;
 
-            ret = ff_alloc_a53_sei(frame, 0, &sei_data, &sei_size);
-            if (ret < 0) {
+    switch (frame->pict_type) {
+    case AV_PICTURE_TYPE_I:
+        x4->pic.i_type = x4->forced_idr > 0 ? X264_TYPE_IDR
+                                            : X264_TYPE_KEYFRAME;
+        break;
+    case AV_PICTURE_TYPE_P:
+        x4->pic.i_type = X264_TYPE_P;
+        break;
+    case AV_PICTURE_TYPE_B:
+        x4->pic.i_type = X264_TYPE_B;
+        break;
+    default:
+        x4->pic.i_type = X264_TYPE_AUTO;
+        break;
+    }
+    reconfig_encoder(ctx, frame);
+
+    if (x4->a53_cc) {
+        void *sei_data;
+        size_t sei_size;
+
+        ret = ff_alloc_a53_sei(frame, 0, &sei_data, &sei_size);
+        if (ret < 0) {
+            av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
+        } else if (sei_data) {
+            x4->pic.extra_sei.payloads = av_mallocz(sizeof(x4->pic.extra_sei.payloads[0]));
+            if (x4->pic.extra_sei.payloads == NULL) {
                 av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
-            } else if (sei_data) {
-                x4->pic.extra_sei.payloads = av_mallocz(sizeof(x4->pic.extra_sei.payloads[0]));
-                if (x4->pic.extra_sei.payloads == NULL) {
-                    av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
-                    av_free(sei_data);
-                } else {
-                    x4->pic.extra_sei.sei_free = av_free;
-
-                    x4->pic.extra_sei.payloads[0].payload_size = sei_size;
-                    x4->pic.extra_sei.payloads[0].payload = sei_data;
-                    x4->pic.extra_sei.num_payloads = 1;
-                    x4->pic.extra_sei.payloads[0].payload_type = 4;
-                }
+                av_free(sei_data);
+            } else {
+                x4->pic.extra_sei.sei_free = av_free;
+
+                x4->pic.extra_sei.payloads[0].payload_size = sei_size;
+                x4->pic.extra_sei.payloads[0].payload = sei_data;
+                x4->pic.extra_sei.num_payloads = 1;
+                x4->pic.extra_sei.payloads[0].payload_type = 4;
             }
         }
+    }
 
-        sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
-        if (sd) {
-            if (x4->params.rc.i_aq_mode == X264_AQ_NONE) {
-                if (!x4->roi_warned) {
-                    x4->roi_warned = 1;
-                    av_log(ctx, AV_LOG_WARNING, "Adaptive quantization must be enabled to use ROI encoding, skipping ROI.\n");
+    sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
+    if (sd) {
+        if (x4->params.rc.i_aq_mode == X264_AQ_NONE) {
+            if (!x4->roi_warned) {
+                x4->roi_warned = 1;
+                av_log(ctx, AV_LOG_WARNING, "Adaptive quantization must be enabled to use ROI encoding, skipping ROI.\n");
+            }
+        } else {
+            if (frame->interlaced_frame == 0) {
+                int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE;
+                int mby = (frame->height + MB_SIZE - 1) / MB_SIZE;
+                int qp_range = 51 + 6 * (bit_depth - 8);
+                int nb_rois;
+                const AVRegionOfInterest *roi;
+                uint32_t roi_size;
+                float *qoffsets;
+
+                roi = (const AVRegionOfInterest*)sd->data;
+                roi_size = roi->self_size;
+                if (!roi_size || sd->size % roi_size != 0) {
+                    free_picture(ctx);
+                    av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n");
+                    return AVERROR(EINVAL);
                 }
-            } else {
-                if (frame->interlaced_frame == 0) {
-                    int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE;
-                    int mby = (frame->height + MB_SIZE - 1) / MB_SIZE;
-                    int qp_range = 51 + 6 * (bit_depth - 8);
-                    int nb_rois;
-                    const AVRegionOfInterest *roi;
-                    uint32_t roi_size;
-                    float *qoffsets;
-
-                    roi = (const AVRegionOfInterest*)sd->data;
-                    roi_size = roi->self_size;
-                    if (!roi_size || sd->size % roi_size != 0) {
-                        free_picture(ctx);
-                        av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n");
-                        return AVERROR(EINVAL);
-                    }
-                    nb_rois = sd->size / roi_size;
+                nb_rois = sd->size / roi_size;
+
+                qoffsets = av_calloc(mbx * mby, sizeof(*qoffsets));
+                if (!qoffsets) {
+                    free_picture(ctx);
+                    return AVERROR(ENOMEM);
+                }
+                // This list must be iterated in reverse because the first
+                // region in the list applies when regions overlap.
+                for (int i = nb_rois - 1; i >= 0; i--) {
+                    int startx, endx, starty, endy;
+                    float qoffset;
 
-                    qoffsets = av_calloc(mbx * mby, sizeof(*qoffsets));
-                    if (!qoffsets) {
+                    roi = (const AVRegionOfInterest*)(sd->data + roi_size * i);
+
+                    starty = FFMIN(mby, roi->top / MB_SIZE);
+                    endy   = FFMIN(mby, (roi->bottom + MB_SIZE - 1)/ MB_SIZE);
+                    startx = FFMIN(mbx, roi->left / MB_SIZE);
+                    endx   = FFMIN(mbx, (roi->right + MB_SIZE - 1)/ MB_SIZE);
+
+                    if (roi->qoffset.den == 0) {
+                        av_free(qoffsets);
                         free_picture(ctx);
-                        return AVERROR(ENOMEM);
+                        av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.qoffset.den must not be zero.\n");
+                        return AVERROR(EINVAL);
                     }
-                    // This list must be iterated in reverse because the first
-                    // region in the list applies when regions overlap.
-                    for (int i = nb_rois - 1; i >= 0; i--) {
-                        int startx, endx, starty, endy;
-                        float qoffset;
-
-                        roi = (const AVRegionOfInterest*)(sd->data + roi_size * i);
-
-                        starty = FFMIN(mby, roi->top / MB_SIZE);
-                        endy   = FFMIN(mby, (roi->bottom + MB_SIZE - 1)/ MB_SIZE);
-                        startx = FFMIN(mbx, roi->left / MB_SIZE);
-                        endx   = FFMIN(mbx, (roi->right + MB_SIZE - 1)/ MB_SIZE);
-
-                        if (roi->qoffset.den == 0) {
-                            av_free(qoffsets);
-                            free_picture(ctx);
-                            av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.qoffset.den must not be zero.\n");
-                            return AVERROR(EINVAL);
-                        }
-                        qoffset = roi->qoffset.num * 1.0f / roi->qoffset.den;
-                        qoffset = av_clipf(qoffset * qp_range, -qp_range, +qp_range);
+                    qoffset = roi->qoffset.num * 1.0f / roi->qoffset.den;
+                    qoffset = av_clipf(qoffset * qp_range, -qp_range, +qp_range);
 
-                        for (int y = starty; y < endy; y++) {
-                            for (int x = startx; x < endx; x++) {
-                                qoffsets[x + y*mbx] = qoffset;
-                            }
+                    for (int y = starty; y < endy; y++) {
+                        for (int x = startx; x < endx; x++) {
+                            qoffsets[x + y*mbx] = qoffset;
                         }
                     }
+                }
 
-                    x4->pic.prop.quant_offsets = qoffsets;
-                    x4->pic.prop.quant_offsets_free = av_free;
-                } else {
-                    if (!x4->roi_warned) {
-                        x4->roi_warned = 1;
-                        av_log(ctx, AV_LOG_WARNING, "interlaced_frame not supported for ROI encoding yet, skipping ROI.\n");
-                    }
+                x4->pic.prop.quant_offsets = qoffsets;
+                x4->pic.prop.quant_offsets_free = av_free;
+            } else {
+                if (!x4->roi_warned) {
+                    x4->roi_warned = 1;
+                    av_log(ctx, AV_LOG_WARNING, "interlaced_frame not supported for ROI encoding yet, skipping ROI.\n");
                 }
             }
         }
+    }
 
-        if (x4->udu_sei) {
-            for (int j = 0; j < frame->nb_side_data; j++) {
-                AVFrameSideData *side_data = frame->side_data[j];
-                void *tmp;
-                x264_sei_payload_t *sei_payload;
-                if (side_data->type != AV_FRAME_DATA_SEI_UNREGISTERED)
-                    continue;
-                tmp = av_fast_realloc(sei->payloads, &sei_data_size, (sei->num_payloads + 1) * sizeof(*sei_payload));
-                if (!tmp) {
-                    free_picture(ctx);
-                    return AVERROR(ENOMEM);
-                }
-                sei->payloads = tmp;
-                sei->sei_free = av_free;
-                sei_payload = &sei->payloads[sei->num_payloads];
-                sei_payload->payload = av_memdup(side_data->data, side_data->size);
-                if (!sei_payload->payload) {
-                    free_picture(ctx);
-                    return AVERROR(ENOMEM);
-                }
-                sei_payload->payload_size = side_data->size;
-                sei_payload->payload_type = SEI_TYPE_USER_DATA_UNREGISTERED;
-                sei->num_payloads++;
+    if (x4->udu_sei) {
+        for (int j = 0; j < frame->nb_side_data; j++) {
+            AVFrameSideData *side_data = frame->side_data[j];
+            void *tmp;
+            x264_sei_payload_t *sei_payload;
+            if (side_data->type != AV_FRAME_DATA_SEI_UNREGISTERED)
+                continue;
+            tmp = av_fast_realloc(sei->payloads, &sei_data_size, (sei->num_payloads + 1) * sizeof(*sei_payload));
+            if (!tmp) {
+                free_picture(ctx);
+                return AVERROR(ENOMEM);
+            }
+            sei->payloads = tmp;
+            sei->sei_free = av_free;
+            sei_payload = &sei->payloads[sei->num_payloads];
+            sei_payload->payload = av_memdup(side_data->data, side_data->size);
+            if (!sei_payload->payload) {
+                free_picture(ctx);
+                return AVERROR(ENOMEM);
             }
+            sei_payload->payload_size = side_data->size;
+            sei_payload->payload_type = SEI_TYPE_USER_DATA_UNREGISTERED;
+            sei->num_payloads++;
         }
+    }
 
     *ppic = &x4->pic;
     return 0;
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 03/30] lavc/libx264: use a local variable for input frame in setup_frame()
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 02/30] lavc/libx264: reindent after previous commit Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 04/30] lavc/libx264: factor out setting up ROI Anton Khirnov
                   ` (26 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libx264.c | 50 ++++++++++++++++++++++----------------------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 36c36d0e09..8f03eecabf 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -337,7 +337,8 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
                        x264_picture_t **ppic)
 {
     X264Context *x4 = ctx->priv_data;
-    x264_sei_t *sei = &x4->pic.extra_sei;
+    x264_picture_t *pic = &x4->pic;
+    x264_sei_t     *sei = &pic->extra_sei;
     unsigned int sei_data_size = 0;
     int64_t wallclock = 0;
     int bit_depth, ret;
@@ -347,45 +348,44 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
     if (!frame)
         return 0;
 
-    x264_picture_init( &x4->pic );
-    x4->pic.img.i_csp   = x4->params.i_csp;
+    x264_picture_init(pic);
+    pic->img.i_csp   = x4->params.i_csp;
 #if X264_BUILD >= 153
     bit_depth = x4->params.i_bitdepth;
 #else
     bit_depth = x264_bit_depth;
 #endif
     if (bit_depth > 8)
-        x4->pic.img.i_csp |= X264_CSP_HIGH_DEPTH;
-    x4->pic.img.i_plane = avfmt2_num_planes(ctx->pix_fmt);
+        pic->img.i_csp |= X264_CSP_HIGH_DEPTH;
+    pic->img.i_plane = avfmt2_num_planes(ctx->pix_fmt);
 
-    for (int i = 0; i < x4->pic.img.i_plane; i++) {
-        x4->pic.img.plane[i]    = frame->data[i];
-        x4->pic.img.i_stride[i] = frame->linesize[i];
+    for (int i = 0; i < pic->img.i_plane; i++) {
+        pic->img.plane[i]    = frame->data[i];
+        pic->img.i_stride[i] = frame->linesize[i];
     }
 
-    x4->pic.i_pts  = frame->pts;
+    pic->i_pts  = frame->pts;
 
     x4->reordered_opaque[x4->next_reordered_opaque].reordered_opaque = frame->reordered_opaque;
     x4->reordered_opaque[x4->next_reordered_opaque].wallclock = wallclock;
     if (ctx->export_side_data & AV_CODEC_EXPORT_DATA_PRFT)
         x4->reordered_opaque[x4->next_reordered_opaque].wallclock = av_gettime();
-    x4->pic.opaque = &x4->reordered_opaque[x4->next_reordered_opaque];
+    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 > 0 ? X264_TYPE_IDR
-                                            : X264_TYPE_KEYFRAME;
+        pic->i_type = x4->forced_idr > 0 ? X264_TYPE_IDR : X264_TYPE_KEYFRAME;
         break;
     case AV_PICTURE_TYPE_P:
-        x4->pic.i_type = X264_TYPE_P;
+        pic->i_type = X264_TYPE_P;
         break;
     case AV_PICTURE_TYPE_B:
-        x4->pic.i_type = X264_TYPE_B;
+        pic->i_type = X264_TYPE_B;
         break;
     default:
-        x4->pic.i_type = X264_TYPE_AUTO;
+        pic->i_type = X264_TYPE_AUTO;
         break;
     }
     reconfig_encoder(ctx, frame);
@@ -398,17 +398,17 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
         if (ret < 0) {
             av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
         } else if (sei_data) {
-            x4->pic.extra_sei.payloads = av_mallocz(sizeof(x4->pic.extra_sei.payloads[0]));
-            if (x4->pic.extra_sei.payloads == NULL) {
+            pic->extra_sei.payloads = av_mallocz(sizeof(pic->extra_sei.payloads[0]));
+            if (pic->extra_sei.payloads == NULL) {
                 av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
                 av_free(sei_data);
             } else {
-                x4->pic.extra_sei.sei_free = av_free;
+                pic->extra_sei.sei_free = av_free;
 
-                x4->pic.extra_sei.payloads[0].payload_size = sei_size;
-                x4->pic.extra_sei.payloads[0].payload = sei_data;
-                x4->pic.extra_sei.num_payloads = 1;
-                x4->pic.extra_sei.payloads[0].payload_type = 4;
+                pic->extra_sei.payloads[0].payload_size = sei_size;
+                pic->extra_sei.payloads[0].payload = sei_data;
+                pic->extra_sei.num_payloads = 1;
+                pic->extra_sei.payloads[0].payload_type = 4;
             }
         }
     }
@@ -473,8 +473,8 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
                     }
                 }
 
-                x4->pic.prop.quant_offsets = qoffsets;
-                x4->pic.prop.quant_offsets_free = av_free;
+                pic->prop.quant_offsets = qoffsets;
+                pic->prop.quant_offsets_free = av_free;
             } else {
                 if (!x4->roi_warned) {
                     x4->roi_warned = 1;
@@ -510,7 +510,7 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
         }
     }
 
-    *ppic = &x4->pic;
+    *ppic = pic;
     return 0;
 }
 
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 04/30] lavc/libx264: factor out setting up ROI
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 02/30] lavc/libx264: reindent after previous commit Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 03/30] lavc/libx264: use a local variable for input frame in setup_frame() Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 05/30] lavc/libx264: reindent after previous commit Anton Khirnov
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libx264.c | 143 +++++++++++++++++++++++--------------------
 1 file changed, 77 insertions(+), 66 deletions(-)

diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 8f03eecabf..470e9bc8c7 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -333,6 +333,79 @@ static enum AVPixelFormat csp_to_pixfmt(int csp)
     return AV_PIX_FMT_NONE;
 }
 
+static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic, int bit_depth,
+                     const AVFrame *frame, const uint8_t *data, size_t size)
+{
+    X264Context *x4 = ctx->priv_data;
+
+        if (x4->params.rc.i_aq_mode == X264_AQ_NONE) {
+            if (!x4->roi_warned) {
+                x4->roi_warned = 1;
+                av_log(ctx, AV_LOG_WARNING, "Adaptive quantization must be enabled to use ROI encoding, skipping ROI.\n");
+            }
+        } else {
+            if (frame->interlaced_frame == 0) {
+                int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE;
+                int mby = (frame->height + MB_SIZE - 1) / MB_SIZE;
+                int qp_range = 51 + 6 * (bit_depth - 8);
+                int nb_rois;
+                const AVRegionOfInterest *roi;
+                uint32_t roi_size;
+                float *qoffsets;
+
+                roi = (const AVRegionOfInterest*)data;
+                roi_size = roi->self_size;
+                if (!roi_size || size % roi_size != 0) {
+                    av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n");
+                    return AVERROR(EINVAL);
+                }
+                nb_rois = size / roi_size;
+
+                qoffsets = av_calloc(mbx * mby, sizeof(*qoffsets));
+                if (!qoffsets)
+                    return AVERROR(ENOMEM);
+
+                // This list must be iterated in reverse because the first
+                // region in the list applies when regions overlap.
+                for (int i = nb_rois - 1; i >= 0; i--) {
+                    int startx, endx, starty, endy;
+                    float qoffset;
+
+                    roi = (const AVRegionOfInterest*)(data + roi_size * i);
+
+                    starty = FFMIN(mby, roi->top / MB_SIZE);
+                    endy   = FFMIN(mby, (roi->bottom + MB_SIZE - 1)/ MB_SIZE);
+                    startx = FFMIN(mbx, roi->left / MB_SIZE);
+                    endx   = FFMIN(mbx, (roi->right + MB_SIZE - 1)/ MB_SIZE);
+
+                    if (roi->qoffset.den == 0) {
+                        av_free(qoffsets);
+                        av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.qoffset.den must not be zero.\n");
+                        return AVERROR(EINVAL);
+                    }
+                    qoffset = roi->qoffset.num * 1.0f / roi->qoffset.den;
+                    qoffset = av_clipf(qoffset * qp_range, -qp_range, +qp_range);
+
+                    for (int y = starty; y < endy; y++) {
+                        for (int x = startx; x < endx; x++) {
+                            qoffsets[x + y*mbx] = qoffset;
+                        }
+                    }
+                }
+
+                pic->prop.quant_offsets = qoffsets;
+                pic->prop.quant_offsets_free = av_free;
+            } else {
+                if (!x4->roi_warned) {
+                    x4->roi_warned = 1;
+                    av_log(ctx, AV_LOG_WARNING, "interlaced_frame not supported for ROI encoding yet, skipping ROI.\n");
+                }
+            }
+        }
+
+    return 0;
+}
+
 static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
                        x264_picture_t **ppic)
 {
@@ -415,72 +488,10 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
 
     sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
     if (sd) {
-        if (x4->params.rc.i_aq_mode == X264_AQ_NONE) {
-            if (!x4->roi_warned) {
-                x4->roi_warned = 1;
-                av_log(ctx, AV_LOG_WARNING, "Adaptive quantization must be enabled to use ROI encoding, skipping ROI.\n");
-            }
-        } else {
-            if (frame->interlaced_frame == 0) {
-                int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE;
-                int mby = (frame->height + MB_SIZE - 1) / MB_SIZE;
-                int qp_range = 51 + 6 * (bit_depth - 8);
-                int nb_rois;
-                const AVRegionOfInterest *roi;
-                uint32_t roi_size;
-                float *qoffsets;
-
-                roi = (const AVRegionOfInterest*)sd->data;
-                roi_size = roi->self_size;
-                if (!roi_size || sd->size % roi_size != 0) {
-                    free_picture(ctx);
-                    av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n");
-                    return AVERROR(EINVAL);
-                }
-                nb_rois = sd->size / roi_size;
-
-                qoffsets = av_calloc(mbx * mby, sizeof(*qoffsets));
-                if (!qoffsets) {
-                    free_picture(ctx);
-                    return AVERROR(ENOMEM);
-                }
-                // This list must be iterated in reverse because the first
-                // region in the list applies when regions overlap.
-                for (int i = nb_rois - 1; i >= 0; i--) {
-                    int startx, endx, starty, endy;
-                    float qoffset;
-
-                    roi = (const AVRegionOfInterest*)(sd->data + roi_size * i);
-
-                    starty = FFMIN(mby, roi->top / MB_SIZE);
-                    endy   = FFMIN(mby, (roi->bottom + MB_SIZE - 1)/ MB_SIZE);
-                    startx = FFMIN(mbx, roi->left / MB_SIZE);
-                    endx   = FFMIN(mbx, (roi->right + MB_SIZE - 1)/ MB_SIZE);
-
-                    if (roi->qoffset.den == 0) {
-                        av_free(qoffsets);
-                        free_picture(ctx);
-                        av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.qoffset.den must not be zero.\n");
-                        return AVERROR(EINVAL);
-                    }
-                    qoffset = roi->qoffset.num * 1.0f / roi->qoffset.den;
-                    qoffset = av_clipf(qoffset * qp_range, -qp_range, +qp_range);
-
-                    for (int y = starty; y < endy; y++) {
-                        for (int x = startx; x < endx; x++) {
-                            qoffsets[x + y*mbx] = qoffset;
-                        }
-                    }
-                }
-
-                pic->prop.quant_offsets = qoffsets;
-                pic->prop.quant_offsets_free = av_free;
-            } else {
-                if (!x4->roi_warned) {
-                    x4->roi_warned = 1;
-                    av_log(ctx, AV_LOG_WARNING, "interlaced_frame not supported for ROI encoding yet, skipping ROI.\n");
-                }
-            }
+        ret = setup_roi(ctx, pic, bit_depth, frame, sd->data, sd->size);
+        if (ret < 0) {
+            free_picture(ctx);
+            return ret;
         }
     }
 
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 05/30] lavc/libx264: reindent after previous commit
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (2 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 04/30] lavc/libx264: factor out setting up ROI Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 06/30] lavc/libx264: unify cleanup in setup_frame() Anton Khirnov
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libx264.c | 104 +++++++++++++++++++++----------------------
 1 file changed, 52 insertions(+), 52 deletions(-)

diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 470e9bc8c7..1e9ca73cdf 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -338,70 +338,70 @@ static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic, int bit_depth,
 {
     X264Context *x4 = ctx->priv_data;
 
-        if (x4->params.rc.i_aq_mode == X264_AQ_NONE) {
-            if (!x4->roi_warned) {
-                x4->roi_warned = 1;
-                av_log(ctx, AV_LOG_WARNING, "Adaptive quantization must be enabled to use ROI encoding, skipping ROI.\n");
+    if (x4->params.rc.i_aq_mode == X264_AQ_NONE) {
+        if (!x4->roi_warned) {
+            x4->roi_warned = 1;
+            av_log(ctx, AV_LOG_WARNING, "Adaptive quantization must be enabled to use ROI encoding, skipping ROI.\n");
+        }
+    } else {
+        if (frame->interlaced_frame == 0) {
+            int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE;
+            int mby = (frame->height + MB_SIZE - 1) / MB_SIZE;
+            int qp_range = 51 + 6 * (bit_depth - 8);
+            int nb_rois;
+            const AVRegionOfInterest *roi;
+            uint32_t roi_size;
+            float *qoffsets;
+
+            roi = (const AVRegionOfInterest*)data;
+            roi_size = roi->self_size;
+            if (!roi_size || size % roi_size != 0) {
+                av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n");
+                return AVERROR(EINVAL);
             }
-        } else {
-            if (frame->interlaced_frame == 0) {
-                int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE;
-                int mby = (frame->height + MB_SIZE - 1) / MB_SIZE;
-                int qp_range = 51 + 6 * (bit_depth - 8);
-                int nb_rois;
-                const AVRegionOfInterest *roi;
-                uint32_t roi_size;
-                float *qoffsets;
-
-                roi = (const AVRegionOfInterest*)data;
-                roi_size = roi->self_size;
-                if (!roi_size || size % roi_size != 0) {
-                    av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n");
-                    return AVERROR(EINVAL);
-                }
-                nb_rois = size / roi_size;
+            nb_rois = size / roi_size;
 
-                qoffsets = av_calloc(mbx * mby, sizeof(*qoffsets));
-                if (!qoffsets)
-                    return AVERROR(ENOMEM);
+            qoffsets = av_calloc(mbx * mby, sizeof(*qoffsets));
+            if (!qoffsets)
+                return AVERROR(ENOMEM);
 
-                // This list must be iterated in reverse because the first
-                // region in the list applies when regions overlap.
-                for (int i = nb_rois - 1; i >= 0; i--) {
-                    int startx, endx, starty, endy;
-                    float qoffset;
+            // This list must be iterated in reverse because the first
+            // region in the list applies when regions overlap.
+            for (int i = nb_rois - 1; i >= 0; i--) {
+                int startx, endx, starty, endy;
+                float qoffset;
 
-                    roi = (const AVRegionOfInterest*)(data + roi_size * i);
+                roi = (const AVRegionOfInterest*)(data + roi_size * i);
 
-                    starty = FFMIN(mby, roi->top / MB_SIZE);
-                    endy   = FFMIN(mby, (roi->bottom + MB_SIZE - 1)/ MB_SIZE);
-                    startx = FFMIN(mbx, roi->left / MB_SIZE);
-                    endx   = FFMIN(mbx, (roi->right + MB_SIZE - 1)/ MB_SIZE);
+                starty = FFMIN(mby, roi->top / MB_SIZE);
+                endy   = FFMIN(mby, (roi->bottom + MB_SIZE - 1)/ MB_SIZE);
+                startx = FFMIN(mbx, roi->left / MB_SIZE);
+                endx   = FFMIN(mbx, (roi->right + MB_SIZE - 1)/ MB_SIZE);
 
-                    if (roi->qoffset.den == 0) {
-                        av_free(qoffsets);
-                        av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.qoffset.den must not be zero.\n");
-                        return AVERROR(EINVAL);
-                    }
-                    qoffset = roi->qoffset.num * 1.0f / roi->qoffset.den;
-                    qoffset = av_clipf(qoffset * qp_range, -qp_range, +qp_range);
+                if (roi->qoffset.den == 0) {
+                    av_free(qoffsets);
+                    av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.qoffset.den must not be zero.\n");
+                    return AVERROR(EINVAL);
+                }
+                qoffset = roi->qoffset.num * 1.0f / roi->qoffset.den;
+                qoffset = av_clipf(qoffset * qp_range, -qp_range, +qp_range);
 
-                    for (int y = starty; y < endy; y++) {
-                        for (int x = startx; x < endx; x++) {
-                            qoffsets[x + y*mbx] = qoffset;
-                        }
+                for (int y = starty; y < endy; y++) {
+                    for (int x = startx; x < endx; x++) {
+                        qoffsets[x + y*mbx] = qoffset;
                     }
                 }
+            }
 
-                pic->prop.quant_offsets = qoffsets;
-                pic->prop.quant_offsets_free = av_free;
-            } else {
-                if (!x4->roi_warned) {
-                    x4->roi_warned = 1;
-                    av_log(ctx, AV_LOG_WARNING, "interlaced_frame not supported for ROI encoding yet, skipping ROI.\n");
-                }
+            pic->prop.quant_offsets = qoffsets;
+            pic->prop.quant_offsets_free = av_free;
+        } else {
+            if (!x4->roi_warned) {
+                x4->roi_warned = 1;
+                av_log(ctx, AV_LOG_WARNING, "interlaced_frame not supported for ROI encoding yet, skipping ROI.\n");
             }
         }
+    }
 
     return 0;
 }
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 06/30] lavc/libx264: unify cleanup in setup_frame()
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (3 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 05/30] lavc/libx264: reindent after previous commit Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 07/30] lavc/libx264: do not ignore memory allocation errors Anton Khirnov
                   ` (23 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libx264.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 1e9ca73cdf..f776d65588 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -489,10 +489,8 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
     sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
     if (sd) {
         ret = setup_roi(ctx, pic, bit_depth, frame, sd->data, sd->size);
-        if (ret < 0) {
-            free_picture(ctx);
-            return ret;
-        }
+        if (ret < 0)
+            goto fail;
     }
 
     if (x4->udu_sei) {
@@ -504,16 +502,16 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
                 continue;
             tmp = av_fast_realloc(sei->payloads, &sei_data_size, (sei->num_payloads + 1) * sizeof(*sei_payload));
             if (!tmp) {
-                free_picture(ctx);
-                return AVERROR(ENOMEM);
+                ret = AVERROR(ENOMEM);
+                goto fail;
             }
             sei->payloads = tmp;
             sei->sei_free = av_free;
             sei_payload = &sei->payloads[sei->num_payloads];
             sei_payload->payload = av_memdup(side_data->data, side_data->size);
             if (!sei_payload->payload) {
-                free_picture(ctx);
-                return AVERROR(ENOMEM);
+                ret = AVERROR(ENOMEM);
+                goto fail;
             }
             sei_payload->payload_size = side_data->size;
             sei_payload->payload_type = SEI_TYPE_USER_DATA_UNREGISTERED;
@@ -523,6 +521,11 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
 
     *ppic = pic;
     return 0;
+
+fail:
+    free_picture(ctx);
+    *ppic = NULL;
+    return ret;
 }
 
 static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 07/30] lavc/libx264: do not ignore memory allocation errors
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (4 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 06/30] lavc/libx264: unify cleanup in setup_frame() Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 08/30] lavc/libx264: reindent after previous commit Anton Khirnov
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libx264.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index f776d65588..8b4b986f12 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -468,21 +468,22 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
         size_t sei_size;
 
         ret = ff_alloc_a53_sei(frame, 0, &sei_data, &sei_size);
-        if (ret < 0) {
-            av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
-        } else if (sei_data) {
+        if (ret < 0)
+            goto fail;
+
+        if (sei_data) {
             pic->extra_sei.payloads = av_mallocz(sizeof(pic->extra_sei.payloads[0]));
             if (pic->extra_sei.payloads == NULL) {
-                av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
-                av_free(sei_data);
-            } else {
+                ret = AVERROR(ENOMEM);
+                goto fail;
+            }
+
                 pic->extra_sei.sei_free = av_free;
 
                 pic->extra_sei.payloads[0].payload_size = sei_size;
                 pic->extra_sei.payloads[0].payload = sei_data;
                 pic->extra_sei.num_payloads = 1;
                 pic->extra_sei.payloads[0].payload_type = 4;
-            }
         }
     }
 
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 08/30] lavc/libx264: reindent after previous commit
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (5 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 07/30] lavc/libx264: do not ignore memory allocation errors Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 09/30] lavc/libx264: reorder control flow in setup_roi() to reduce nesting depth Anton Khirnov
                   ` (21 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libx264.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 8b4b986f12..f0f8990cf9 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -478,12 +478,12 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
                 goto fail;
             }
 
-                pic->extra_sei.sei_free = av_free;
+            pic->extra_sei.sei_free = av_free;
 
-                pic->extra_sei.payloads[0].payload_size = sei_size;
-                pic->extra_sei.payloads[0].payload = sei_data;
-                pic->extra_sei.num_payloads = 1;
-                pic->extra_sei.payloads[0].payload_type = 4;
+            pic->extra_sei.payloads[0].payload_size = sei_size;
+            pic->extra_sei.payloads[0].payload = sei_data;
+            pic->extra_sei.num_payloads = 1;
+            pic->extra_sei.payloads[0].payload_type = 4;
         }
     }
 
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 09/30] lavc/libx264: reorder control flow in setup_roi() to reduce nesting depth
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (6 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 08/30] lavc/libx264: reindent after previous commit Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 10/30] lavc/libx264: reindent after previous commit Anton Khirnov
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libx264.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index f0f8990cf9..342d07a829 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -338,13 +338,6 @@ static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic, int bit_depth,
 {
     X264Context *x4 = ctx->priv_data;
 
-    if (x4->params.rc.i_aq_mode == X264_AQ_NONE) {
-        if (!x4->roi_warned) {
-            x4->roi_warned = 1;
-            av_log(ctx, AV_LOG_WARNING, "Adaptive quantization must be enabled to use ROI encoding, skipping ROI.\n");
-        }
-    } else {
-        if (frame->interlaced_frame == 0) {
             int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE;
             int mby = (frame->height + MB_SIZE - 1) / MB_SIZE;
             int qp_range = 51 + 6 * (bit_depth - 8);
@@ -353,6 +346,20 @@ static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic, int bit_depth,
             uint32_t roi_size;
             float *qoffsets;
 
+    if (x4->params.rc.i_aq_mode == X264_AQ_NONE) {
+        if (!x4->roi_warned) {
+            x4->roi_warned = 1;
+            av_log(ctx, AV_LOG_WARNING, "Adaptive quantization must be enabled to use ROI encoding, skipping ROI.\n");
+        }
+        return 0;
+    } else if (frame->interlaced_frame) {
+        if (!x4->roi_warned) {
+            x4->roi_warned = 1;
+            av_log(ctx, AV_LOG_WARNING, "interlaced_frame not supported for ROI encoding yet, skipping ROI.\n");
+        }
+        return 0;
+    }
+
             roi = (const AVRegionOfInterest*)data;
             roi_size = roi->self_size;
             if (!roi_size || size % roi_size != 0) {
@@ -395,13 +402,6 @@ static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic, int bit_depth,
 
             pic->prop.quant_offsets = qoffsets;
             pic->prop.quant_offsets_free = av_free;
-        } else {
-            if (!x4->roi_warned) {
-                x4->roi_warned = 1;
-                av_log(ctx, AV_LOG_WARNING, "interlaced_frame not supported for ROI encoding yet, skipping ROI.\n");
-            }
-        }
-    }
 
     return 0;
 }
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 10/30] lavc/libx264: reindent after previous commit
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (7 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 09/30] lavc/libx264: reorder control flow in setup_roi() to reduce nesting depth Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 11/30] lavc/libx264: use a local variable to shorten code Anton Khirnov
                   ` (19 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libx264.c | 94 ++++++++++++++++++++++----------------------
 1 file changed, 47 insertions(+), 47 deletions(-)

diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 342d07a829..1819809a48 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -338,13 +338,13 @@ static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic, int bit_depth,
 {
     X264Context *x4 = ctx->priv_data;
 
-            int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE;
-            int mby = (frame->height + MB_SIZE - 1) / MB_SIZE;
-            int qp_range = 51 + 6 * (bit_depth - 8);
-            int nb_rois;
-            const AVRegionOfInterest *roi;
-            uint32_t roi_size;
-            float *qoffsets;
+    int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE;
+    int mby = (frame->height + MB_SIZE - 1) / MB_SIZE;
+    int qp_range = 51 + 6 * (bit_depth - 8);
+    int nb_rois;
+    const AVRegionOfInterest *roi;
+    uint32_t roi_size;
+    float *qoffsets;
 
     if (x4->params.rc.i_aq_mode == X264_AQ_NONE) {
         if (!x4->roi_warned) {
@@ -360,48 +360,48 @@ static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic, int bit_depth,
         return 0;
     }
 
-            roi = (const AVRegionOfInterest*)data;
-            roi_size = roi->self_size;
-            if (!roi_size || size % roi_size != 0) {
-                av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n");
-                return AVERROR(EINVAL);
-            }
-            nb_rois = size / roi_size;
-
-            qoffsets = av_calloc(mbx * mby, sizeof(*qoffsets));
-            if (!qoffsets)
-                return AVERROR(ENOMEM);
-
-            // This list must be iterated in reverse because the first
-            // region in the list applies when regions overlap.
-            for (int i = nb_rois - 1; i >= 0; i--) {
-                int startx, endx, starty, endy;
-                float qoffset;
-
-                roi = (const AVRegionOfInterest*)(data + roi_size * i);
-
-                starty = FFMIN(mby, roi->top / MB_SIZE);
-                endy   = FFMIN(mby, (roi->bottom + MB_SIZE - 1)/ MB_SIZE);
-                startx = FFMIN(mbx, roi->left / MB_SIZE);
-                endx   = FFMIN(mbx, (roi->right + MB_SIZE - 1)/ MB_SIZE);
-
-                if (roi->qoffset.den == 0) {
-                    av_free(qoffsets);
-                    av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.qoffset.den must not be zero.\n");
-                    return AVERROR(EINVAL);
-                }
-                qoffset = roi->qoffset.num * 1.0f / roi->qoffset.den;
-                qoffset = av_clipf(qoffset * qp_range, -qp_range, +qp_range);
-
-                for (int y = starty; y < endy; y++) {
-                    for (int x = startx; x < endx; x++) {
-                        qoffsets[x + y*mbx] = qoffset;
-                    }
-                }
+    roi = (const AVRegionOfInterest*)data;
+    roi_size = roi->self_size;
+    if (!roi_size || size % roi_size != 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n");
+        return AVERROR(EINVAL);
+    }
+    nb_rois = size / roi_size;
+
+    qoffsets = av_calloc(mbx * mby, sizeof(*qoffsets));
+    if (!qoffsets)
+        return AVERROR(ENOMEM);
+
+    // This list must be iterated in reverse because the first
+    // region in the list applies when regions overlap.
+    for (int i = nb_rois - 1; i >= 0; i--) {
+        int startx, endx, starty, endy;
+        float qoffset;
+
+        roi = (const AVRegionOfInterest*)(data + roi_size * i);
+
+        starty = FFMIN(mby, roi->top / MB_SIZE);
+        endy   = FFMIN(mby, (roi->bottom + MB_SIZE - 1)/ MB_SIZE);
+        startx = FFMIN(mbx, roi->left / MB_SIZE);
+        endx   = FFMIN(mbx, (roi->right + MB_SIZE - 1)/ MB_SIZE);
+
+        if (roi->qoffset.den == 0) {
+            av_free(qoffsets);
+            av_log(ctx, AV_LOG_ERROR, "AVRegionOfInterest.qoffset.den must not be zero.\n");
+            return AVERROR(EINVAL);
+        }
+        qoffset = roi->qoffset.num * 1.0f / roi->qoffset.den;
+        qoffset = av_clipf(qoffset * qp_range, -qp_range, +qp_range);
+
+        for (int y = starty; y < endy; y++) {
+            for (int x = startx; x < endx; x++) {
+                qoffsets[x + y*mbx] = qoffset;
             }
+        }
+    }
 
-            pic->prop.quant_offsets = qoffsets;
-            pic->prop.quant_offsets_free = av_free;
+    pic->prop.quant_offsets = qoffsets;
+    pic->prop.quant_offsets_free = av_free;
 
     return 0;
 }
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 11/30] lavc/libx264: use a local variable to shorten code
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (8 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 10/30] lavc/libx264: reindent after previous commit Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 12/30] lavc/libx264: print an error on invalid opaque pointer Anton Khirnov
                   ` (18 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libx264.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 1819809a48..b680e2098e 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -410,6 +410,7 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
                        x264_picture_t **ppic)
 {
     X264Context *x4 = ctx->priv_data;
+    X264Opaque  *opaque = &x4->reordered_opaque[x4->next_reordered_opaque];
     x264_picture_t *pic = &x4->pic;
     x264_sei_t     *sei = &pic->extra_sei;
     unsigned int sei_data_size = 0;
@@ -439,11 +440,13 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
 
     pic->i_pts  = frame->pts;
 
-    x4->reordered_opaque[x4->next_reordered_opaque].reordered_opaque = frame->reordered_opaque;
-    x4->reordered_opaque[x4->next_reordered_opaque].wallclock = wallclock;
+    opaque->reordered_opaque = frame->reordered_opaque;
+    opaque->wallclock = wallclock;
     if (ctx->export_side_data & AV_CODEC_EXPORT_DATA_PRFT)
-        x4->reordered_opaque[x4->next_reordered_opaque].wallclock = av_gettime();
-    pic->opaque = &x4->reordered_opaque[x4->next_reordered_opaque];
+        opaque->wallclock = av_gettime();
+
+    pic->opaque = opaque;
+
     x4->next_reordered_opaque++;
     x4->next_reordered_opaque %= x4->nb_reordered_opaque;
 
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 12/30] lavc/libx264: print an error on invalid opaque pointer
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (9 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 11/30] lavc/libx264: use a local variable to shorten code Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 13/30] lavc/libx264: zero reordered opaque on alloc Anton Khirnov
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libx264.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index b680e2098e..e8ca3d896b 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -596,6 +596,8 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
         wallclock = out_opaque->wallclock;
     } else {
         // Unexpected opaque pointer on picture output
+        av_log(ctx, AV_LOG_ERROR, "Unexpected opaque pointer; "
+               "this is a bug, please report it.\n");
         ctx->reordered_opaque = 0;
     }
 
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 13/30] lavc/libx264: zero reordered opaque on alloc
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (10 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 12/30] lavc/libx264: print an error on invalid opaque pointer Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 14/30] lavc/libx264: do not leave an invalid array size on alloc error Anton Khirnov
                   ` (16 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

This is safer.
---
 libavcodec/libx264.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index e8ca3d896b..a1b044d4e9 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -1105,8 +1105,8 @@ static av_cold int X264_init(AVCodecContext *avctx)
     // 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));
+    x4->reordered_opaque    = av_calloc(x4->nb_reordered_opaque,
+                                        sizeof(*x4->reordered_opaque));
     if (!x4->reordered_opaque)
         return AVERROR(ENOMEM);
 
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 14/30] lavc/libx264: do not leave an invalid array size on alloc error
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (11 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 13/30] lavc/libx264: zero reordered opaque on alloc Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 15/30] lavc/libx265: restructure handling reordered_opaque Anton Khirnov
                   ` (15 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libx264.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index a1b044d4e9..2bbd9044b6 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -1107,8 +1107,10 @@ static av_cold int X264_init(AVCodecContext *avctx)
     x4->nb_reordered_opaque = x264_encoder_maximum_delayed_frames(x4->enc) + 17;
     x4->reordered_opaque    = av_calloc(x4->nb_reordered_opaque,
                                         sizeof(*x4->reordered_opaque));
-    if (!x4->reordered_opaque)
+    if (!x4->reordered_opaque) {
+        x4->nb_reordered_opaque = 0;
         return AVERROR(ENOMEM);
+    }
 
     return 0;
 }
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 15/30] lavc/libx265: restructure handling reordered_opaque
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (12 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 14/30] lavc/libx264: do not leave an invalid array size on alloc error Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 16/30] lavc: add a codec flag for propagating opaque from frames to packets Anton Khirnov
                   ` (14 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

Current code stores a pointer to allocated data in libx265 and frees it
when the encoded packet is retrieved. This will leak if the packet is
never retrieved, e.g. if the encoder is closed without being flushed.

Restructure the code such that only indices to an array stored in our
private data are given to libx265. This ensures no allocated memory can
be lost.
---
 libavcodec/libx265.c | 85 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 73 insertions(+), 12 deletions(-)

diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c
index e87dea604d..25de3c669b 100644
--- a/libavcodec/libx265.c
+++ b/libavcodec/libx265.c
@@ -27,6 +27,7 @@
 #include <x265.h>
 #include <float.h>
 
+#include "libavutil/avassert.h"
 #include "libavutil/internal.h"
 #include "libavutil/common.h"
 #include "libavutil/opt.h"
@@ -39,6 +40,12 @@
 #include "atsc_a53.h"
 #include "sei.h"
 
+typedef struct ReorderedData {
+    int64_t reordered_opaque;
+
+    int in_use;
+} ReorderedData;
+
 typedef struct libx265Context {
     const AVClass *class;
 
@@ -59,6 +66,9 @@ typedef struct libx265Context {
     int udu_sei;
     int a53_cc;
 
+    ReorderedData *rd;
+    int         nb_rd;
+
     /**
      * If the encoder does not support ROI then warn the first time we
      * encounter a frame with ROI side data.
@@ -81,6 +91,40 @@ static int is_keyframe(NalUnitType naltype)
     }
 }
 
+static int rd_get(libx265Context *ctx)
+{
+    const int add = 16;
+
+    ReorderedData *tmp;
+    int idx;
+
+    for (int i = 0; i < ctx->nb_rd; i++)
+        if (!ctx->rd[i].in_use) {
+            ctx->rd[i].in_use = 1;
+            return i;
+        }
+
+    tmp = av_realloc_array(ctx->rd, ctx->nb_rd + add, sizeof(*ctx->rd));
+    if (!tmp)
+        return AVERROR(ENOMEM);
+    memset(tmp + ctx->nb_rd, 0, sizeof(*tmp) * add);
+
+    ctx->rd     = tmp;
+    ctx->nb_rd += add;
+
+    idx                 = ctx->nb_rd - add;
+    ctx->rd[idx].in_use = 1;
+
+    return idx;
+}
+
+static void rd_release(libx265Context *ctx, int idx)
+{
+    av_assert0(idx >= 0 && idx < ctx->nb_rd);
+
+    memset(&ctx->rd[idx], 0, sizeof(ctx->rd[idx]));
+}
+
 static av_cold int libx265_encode_close(AVCodecContext *avctx)
 {
     libx265Context *ctx = avctx->priv_data;
@@ -88,6 +132,8 @@ static av_cold int libx265_encode_close(AVCodecContext *avctx)
     ctx->api->param_free(ctx->params);
     av_freep(&ctx->sei_data);
 
+    av_freep(&ctx->rd);
+
     if (ctx->encoder)
         ctx->api->encoder_close(ctx->encoder);
 
@@ -499,12 +545,18 @@ static av_cold int libx265_encode_set_roi(libx265Context *ctx, const AVFrame *fr
     return 0;
 }
 
-static void free_picture(x265_picture *pic)
+static void free_picture(libx265Context *ctx, x265_picture *pic)
 {
     x265_sei *sei = &pic->userSEI;
     for (int i = 0; i < sei->numPayloads; i++)
         av_free(sei->payloads[i].payload);
-    av_freep(&pic->userData);
+
+    if (pic->userData) {
+        int idx = (int)(intptr_t)pic->userData - 1;
+        rd_release(ctx, idx);
+        pic->userData = NULL;
+    }
+
     av_freep(&pic->quantOffsets);
     sei->numPayloads = 0;
 }
@@ -549,13 +601,18 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
             return ret;
 
         if (pic->reordered_opaque) {
-            x265pic.userData = av_malloc(sizeof(pic->reordered_opaque));
-            if (!x265pic.userData) {
-                free_picture(&x265pic);
-                return AVERROR(ENOMEM);
+            ReorderedData *rd;
+            int rd_idx = rd_get(ctx);
+
+            if (rd_idx < 0) {
+                free_picture(ctx, &x265pic);
+                return rd_idx;
             }
 
-            memcpy(x265pic.userData, &pic->reordered_opaque, sizeof(pic->reordered_opaque));
+            x265pic.userData = (void*)(intptr_t)(rd_idx + 1);
+
+            rd = &ctx->rd[rd_idx];
+            rd->reordered_opaque = pic->reordered_opaque;
         }
 
         if (ctx->a53_cc) {
@@ -574,7 +631,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         (sei->numPayloads + 1) * sizeof(*sei_payload));
                 if (!tmp) {
                     av_free(sei_data);
-                    free_picture(&x265pic);
+                    free_picture(ctx, &x265pic);
                     return AVERROR(ENOMEM);
                 }
                 ctx->sei_data = tmp;
@@ -600,7 +657,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         &ctx->sei_data_size,
                         (sei->numPayloads + 1) * sizeof(*sei_payload));
                 if (!tmp) {
-                    free_picture(&x265pic);
+                    free_picture(ctx, &x265pic);
                     return AVERROR(ENOMEM);
                 }
                 ctx->sei_data = tmp;
@@ -608,7 +665,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                 sei_payload = &sei->payloads[sei->numPayloads];
                 sei_payload->payload = av_memdup(side_data->data, side_data->size);
                 if (!sei_payload->payload) {
-                    free_picture(&x265pic);
+                    free_picture(ctx, &x265pic);
                     return AVERROR(ENOMEM);
                 }
                 sei_payload->payloadSize = side_data->size;
@@ -680,8 +737,12 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     ff_side_data_set_encoder_stats(pkt, x265pic_out.frameData.qp * FF_QP2LAMBDA, NULL, 0, pict_type);
 
     if (x265pic_out.userData) {
-        memcpy(&avctx->reordered_opaque, x265pic_out.userData, sizeof(avctx->reordered_opaque));
-        av_freep(&x265pic_out.userData);
+        int idx = (int)(intptr_t)x265pic_out.userData - 1;
+        ReorderedData *rd = &ctx->rd[idx];
+
+        avctx->reordered_opaque = rd->reordered_opaque;
+
+        rd_release(ctx, idx);
     } else
         avctx->reordered_opaque = 0;
 
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 16/30] lavc: add a codec flag for propagating opaque from frames to packets
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (13 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 15/30] lavc/libx265: restructure handling reordered_opaque Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 17/30] lavc: support AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE in all no-delay encoders Anton Khirnov
                   ` (13 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

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.
---
 doc/APIchanges             |  3 +++
 libavcodec/avcodec.h       |  8 ++++++++
 libavcodec/encode.c        |  7 +++++++
 libavcodec/libx264.c       | 31 ++++++++++++++++++++++++++++
 libavcodec/libx265.c       | 41 ++++++++++++++++++++++++++++----------
 libavcodec/options_table.h |  1 +
 libavcodec/version.h       |  2 +-
 7 files changed, 81 insertions(+), 12 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index ab7ce15fae..a3c9819e32 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -14,6 +14,9 @@ libavutil:     2021-04-27
 
 API changes, most recent first:
 
+2022-12-xx - xxxxxxxxxx - lavc 59.55.100 - avcodec.h
+  Add AV_CODEC_FLAG_COPY_OPAQUE.
+
 2022-11-xx - xxxxxxxxxx - lavu 57.43.100 - tx.h
   Add AV_TX_FLOAT_DCT, AV_TX_DOUBLE_DCT and AV_TX_INT32_DCT.
 
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 3edd8e2636..79558786ee 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -241,6 +241,14 @@ typedef struct RcOverride{
  * AV_CODEC_CAP_ENCODER_RECON_FRAME capability.
  */
 #define AV_CODEC_FLAG_RECON_FRAME     (1 <<  6)
+/**
+ * Request the encoder to propagate each frame's AVFrame.opaque and
+ * AVFrame.opaque_ref values to its corresponding output AVPacket.
+ *
+ * May only be set on encoders that have the
+ * @ref AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability flag.
+ */
+#define AV_CODEC_FLAG_COPY_OPAQUE     (1 <<  7)
 /**
  * Use internal 2pass ratecontrol in first pass mode.
  */
diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index fbe2c97cd6..7e2d54ae9b 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -634,6 +634,13 @@ int ff_encode_preinit(AVCodecContext *avctx)
         return AVERROR(EINVAL);
     }
 
+    if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE &&
+        !(avctx->codec->capabilities & AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE)) {
+        av_log(avctx, AV_LOG_ERROR, "The copy_opaque flag is set, but the "
+               "encoder does not support it.\n");
+        return AVERROR(EINVAL);
+    }
+
     switch (avctx->codec_type) {
     case AVMEDIA_TYPE_VIDEO: ret = encode_preinit_video(avctx); break;
     case AVMEDIA_TYPE_AUDIO: ret = encode_preinit_audio(avctx); break;
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 2bbd9044b6..8944a7df36 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,17 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
 
     pic->i_pts  = frame->pts;
 
+    opaque_uninit(opaque);
+
+    opaque->frame_opaque = frame->opaque;
+    if (frame->opaque_ref && ctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+        opaque->frame_opaque_ref = av_buffer_ref(frame->opaque_ref);
+        if (!opaque->frame_opaque_ref) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+    }
+
     opaque->reordered_opaque = frame->reordered_opaque;
     opaque->wallclock = wallclock;
     if (ctx->export_side_data & AV_CODEC_EXPORT_DATA_PRFT)
@@ -594,6 +614,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 +662,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
diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c
index 25de3c669b..7ba547a7e7 100644
--- a/libavcodec/libx265.c
+++ b/libavcodec/libx265.c
@@ -28,6 +28,7 @@
 #include <float.h>
 
 #include "libavutil/avassert.h"
+#include "libavutil/buffer.h"
 #include "libavutil/internal.h"
 #include "libavutil/common.h"
 #include "libavutil/opt.h"
@@ -43,6 +44,9 @@
 typedef struct ReorderedData {
     int64_t reordered_opaque;
 
+    void        *frame_opaque;
+    AVBufferRef *frame_opaque_ref;
+
     int in_use;
 } ReorderedData;
 
@@ -121,7 +125,7 @@ static int rd_get(libx265Context *ctx)
 static void rd_release(libx265Context *ctx, int idx)
 {
     av_assert0(idx >= 0 && idx < ctx->nb_rd);
-
+    av_buffer_unref(&ctx->rd[idx].frame_opaque_ref);
     memset(&ctx->rd[idx], 0, sizeof(ctx->rd[idx]));
 }
 
@@ -132,6 +136,8 @@ static av_cold int libx265_encode_close(AVCodecContext *avctx)
     ctx->api->param_free(ctx->params);
     av_freep(&ctx->sei_data);
 
+    for (int i = 0; i < ctx->nb_rd; i++)
+        rd_release(ctx, i);
     av_freep(&ctx->rd);
 
     if (ctx->encoder)
@@ -582,6 +588,9 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     sei->numPayloads = 0;
 
     if (pic) {
+        ReorderedData *rd;
+        int rd_idx;
+
         for (i = 0; i < 3; i++) {
            x265pic.planes[i] = pic->data[i];
            x265pic.stride[i] = pic->linesize[i];
@@ -600,21 +609,25 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         if (ret < 0)
             return ret;
 
-        if (pic->reordered_opaque) {
-            ReorderedData *rd;
-            int rd_idx = rd_get(ctx);
+        rd_idx = rd_get(ctx);
+        if (rd_idx < 0) {
+            free_picture(ctx, &x265pic);
+            return rd_idx;
+        }
+        rd = &ctx->rd[rd_idx];
 
-            if (rd_idx < 0) {
+        rd->reordered_opaque = pic->reordered_opaque;
+        rd->frame_opaque     = pic->opaque;
+        if (pic->opaque_ref && avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+            rd->frame_opaque_ref = av_buffer_ref(pic->opaque_ref);
+            if (!rd->frame_opaque_ref) {
                 free_picture(ctx, &x265pic);
-                return rd_idx;
+                return AVERROR(ENOMEM);
             }
-
-            x265pic.userData = (void*)(intptr_t)(rd_idx + 1);
-
-            rd = &ctx->rd[rd_idx];
-            rd->reordered_opaque = pic->reordered_opaque;
         }
 
+        x265pic.userData = (void*)(intptr_t)(rd_idx + 1);
+
         if (ctx->a53_cc) {
             void *sei_data;
             size_t sei_size;
@@ -742,6 +755,12 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 
         avctx->reordered_opaque = rd->reordered_opaque;
 
+        if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+            pkt->opaque          = rd->frame_opaque;
+            pkt->opaque_ref      = rd->frame_opaque_ref;
+            rd->frame_opaque_ref = NULL;
+        }
+
         rd_release(ctx, idx);
     } else
         avctx->reordered_opaque = 0;
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index cd02f5096f..ad41dc7bed 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -58,6 +58,7 @@ static const AVOption avcodec_options[] = {
 {"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"},
 {"qscale", "use fixed qscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, "flags"},
 {"recon_frame", "export reconstructed frames", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_RECON_FRAME}, .unit = "flags"},
+{"copy_opaque", "propagate opaque values", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_COPY_OPAQUE}, .unit = "flags"},
 {"pass1", "use internal 2-pass ratecontrol in first  pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, "flags"},
 {"pass2", "use internal 2-pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"},
 {"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"},
diff --git a/libavcodec/version.h b/libavcodec/version.h
index d149bc6c46..9f42f09f4e 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
 
 #include "version_major.h"
 
-#define LIBAVCODEC_VERSION_MINOR  54
+#define LIBAVCODEC_VERSION_MINOR  55
 #define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 17/30] lavc: support AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE in all no-delay encoders
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (14 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 16/30] lavc: add a codec flag for propagating opaque from frames to packets Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:43   ` Michael Niedermayer
  2022-11-27 20:00   ` James Almer
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 18/30] lavc/encode: pass through frame durations to encoded packets Anton Khirnov
                   ` (12 subsequent siblings)
  28 siblings, 2 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/ac3enc_fixed.c       |  2 +-
 libavcodec/ac3enc_float.c       |  2 +-
 libavcodec/adpcmenc.c           |  3 ++-
 libavcodec/alacenc.c            |  3 ++-
 libavcodec/aliaspixenc.c        |  2 +-
 libavcodec/aptxenc.c            |  4 ++--
 libavcodec/asvenc.c             |  4 ++--
 libavcodec/avuienc.c            |  3 ++-
 libavcodec/bitpacked_enc.c      |  3 ++-
 libavcodec/bmpenc.c             |  2 +-
 libavcodec/cfhdenc.c            |  3 ++-
 libavcodec/cinepakenc.c         |  2 +-
 libavcodec/cljrenc.c            |  2 +-
 libavcodec/cngenc.c             |  2 +-
 libavcodec/dcaenc.c             |  3 ++-
 libavcodec/dfpwmenc.c           |  3 ++-
 libavcodec/dnxhdenc.c           |  2 +-
 libavcodec/dvenc.c              |  3 ++-
 libavcodec/eac3enc.c            |  2 +-
 libavcodec/encode.c             | 12 ++++++++++++
 libavcodec/exrenc.c             |  3 ++-
 libavcodec/fitsenc.c            |  2 +-
 libavcodec/flashsv2enc.c        |  2 +-
 libavcodec/flashsvenc.c         |  2 +-
 libavcodec/flvenc.c             |  1 +
 libavcodec/g722enc.c            |  3 ++-
 libavcodec/g723_1enc.c          |  2 +-
 libavcodec/g726.c               |  6 ++++--
 libavcodec/gif.c                |  2 +-
 libavcodec/h261enc.c            |  1 +
 libavcodec/hapenc.c             |  3 ++-
 libavcodec/hdrenc.c             |  3 ++-
 libavcodec/huffyuvenc.c         |  6 ++++--
 libavcodec/ituh263enc.c         |  3 ++-
 libavcodec/j2kenc.c             |  2 +-
 libavcodec/jpeglsenc.c          |  3 ++-
 libavcodec/lclenc.c             |  3 ++-
 libavcodec/libcodec2.c          |  3 ++-
 libavcodec/libgsmenc.c          |  4 ++--
 libavcodec/libilbc.c            |  3 ++-
 libavcodec/libjxlenc.c          |  3 ++-
 libavcodec/libopenh264enc.c     |  3 ++-
 libavcodec/libopenjpegenc.c     |  3 ++-
 libavcodec/libvo-amrwbenc.c     |  3 ++-
 libavcodec/libwebpenc.c         |  2 +-
 libavcodec/libxvid.c            |  2 +-
 libavcodec/ljpegenc.c           |  3 ++-
 libavcodec/magicyuvenc.c        |  3 ++-
 libavcodec/mjpegenc.c           |  4 +++-
 libavcodec/mpegaudioenc_fixed.c |  2 +-
 libavcodec/mpegaudioenc_float.c |  2 +-
 libavcodec/msmpeg4enc.c         |  3 +++
 libavcodec/msvideo1enc.c        |  1 +
 libavcodec/pamenc.c             |  2 +-
 libavcodec/pcm-blurayenc.c      |  2 +-
 libavcodec/pcm-dvdenc.c         |  3 ++-
 libavcodec/pcm.c                |  3 ++-
 libavcodec/pcxenc.c             |  2 +-
 libavcodec/pngenc.c             |  3 ++-
 libavcodec/pnmenc.c             | 12 ++++++------
 libavcodec/proresenc_anatoliy.c |  6 ++++--
 libavcodec/proresenc_kostya.c   |  3 ++-
 libavcodec/qoienc.c             |  3 ++-
 libavcodec/qtrleenc.c           |  2 +-
 libavcodec/r210enc.c            |  6 +++---
 libavcodec/rawenc.c             |  3 ++-
 libavcodec/roqvideoenc.c        |  2 +-
 libavcodec/rpzaenc.c            |  2 +-
 libavcodec/rv10enc.c            |  1 +
 libavcodec/rv20enc.c            |  1 +
 libavcodec/s302menc.c           |  3 ++-
 libavcodec/sbcenc.c             |  3 ++-
 libavcodec/sgienc.c             |  2 +-
 libavcodec/smcenc.c             |  2 +-
 libavcodec/snowenc.c            |  2 +-
 libavcodec/sonic.c              |  6 ++++--
 libavcodec/speedhqenc.c         |  1 +
 libavcodec/sunrastenc.c         |  2 +-
 libavcodec/svq1enc.c            |  2 +-
 libavcodec/targaenc.c           |  2 +-
 libavcodec/tiffenc.c            |  3 ++-
 libavcodec/ttaenc.c             |  3 ++-
 libavcodec/utvideoenc.c         |  3 ++-
 libavcodec/v210enc.c            |  3 ++-
 libavcodec/v308enc.c            |  2 +-
 libavcodec/v408enc.c            |  4 ++--
 libavcodec/v410enc.c            |  2 +-
 libavcodec/vaapi_encode_mjpeg.c |  3 ++-
 libavcodec/vbnenc.c             |  3 ++-
 libavcodec/vc2enc.c             |  3 ++-
 libavcodec/wavpackenc.c         |  3 ++-
 libavcodec/wbmpenc.c            |  3 ++-
 libavcodec/wmaenc.c             |  4 ++--
 libavcodec/wmv2enc.c            |  1 +
 libavcodec/wrapped_avframe.c    |  1 +
 libavcodec/xbmenc.c             |  2 +-
 libavcodec/xfaceenc.c           |  2 +-
 libavcodec/xwdenc.c             |  2 +-
 libavcodec/y41penc.c            |  2 +-
 libavcodec/yuv4enc.c            |  2 +-
 libavcodec/zmbvenc.c            |  2 +-
 101 files changed, 180 insertions(+), 107 deletions(-)

diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c
index 5a5f1cc2e9..88dfd66b91 100644
--- a/libavcodec/ac3enc_fixed.c
+++ b/libavcodec/ac3enc_fixed.c
@@ -112,7 +112,7 @@ const FFCodec ff_ac3_fixed_encoder = {
     CODEC_LONG_NAME("ATSC A/52A (AC-3)"),
     .p.type          = AVMEDIA_TYPE_AUDIO,
     .p.id            = AV_CODEC_ID_AC3,
-    .p.capabilities  = AV_CODEC_CAP_DR1,
+    .p.capabilities  = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size  = sizeof(AC3EncodeContext),
     .init            = ac3_fixed_encode_init,
     FF_CODEC_ENCODE_CB(ff_ac3_fixed_encode_frame),
diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c
index 4c4d18ce56..ae351a535e 100644
--- a/libavcodec/ac3enc_float.c
+++ b/libavcodec/ac3enc_float.c
@@ -116,7 +116,7 @@ const FFCodec ff_ac3_encoder = {
     CODEC_LONG_NAME("ATSC A/52A (AC-3)"),
     .p.type          = AVMEDIA_TYPE_AUDIO,
     .p.id            = AV_CODEC_ID_AC3,
-    .p.capabilities  = AV_CODEC_CAP_DR1,
+    .p.capabilities  = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size  = sizeof(AC3EncodeContext),
     .init            = ff_ac3_float_encode_init,
     FF_CODEC_ENCODE_CB(ff_ac3_float_encode_frame),
diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c
index 57709b19a1..63afffc58f 100644
--- a/libavcodec/adpcmenc.c
+++ b/libavcodec/adpcmenc.c
@@ -1003,7 +1003,8 @@ const FFCodec ff_ ## name_ ## _encoder = {                                 \
     .p.id           = id_,                                                 \
     .p.sample_fmts  = sample_fmts_,                                        \
     .p.ch_layouts   = ch_layouts,                                          \
-    .p.capabilities = capabilities_ | AV_CODEC_CAP_DR1,                    \
+    .p.capabilities = capabilities_ | AV_CODEC_CAP_DR1 |                   \
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,               \
     .p.priv_class   = &adpcm_encoder_class,                                \
     .priv_data_size = sizeof(ADPCMEncodeContext),                          \
     .init           = adpcm_encode_init,                                   \
diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c
index 0f685d71d6..9598e5861e 100644
--- a/libavcodec/alacenc.c
+++ b/libavcodec/alacenc.c
@@ -653,7 +653,8 @@ const FFCodec ff_alac_encoder = {
     CODEC_LONG_NAME("ALAC (Apple Lossless Audio Codec)"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_ALAC,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(AlacEncodeContext),
     .p.priv_class   = &alacenc_class,
     .init           = alac_encode_init,
diff --git a/libavcodec/aliaspixenc.c b/libavcodec/aliaspixenc.c
index 6593d3f047..90d2a63319 100644
--- a/libavcodec/aliaspixenc.c
+++ b/libavcodec/aliaspixenc.c
@@ -106,7 +106,7 @@ const FFCodec ff_alias_pix_encoder = {
     CODEC_LONG_NAME("Alias/Wavefront PIX image"),
     .p.type    = AVMEDIA_TYPE_VIDEO,
     .p.id      = AV_CODEC_ID_ALIAS_PIX,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_BGR24, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
diff --git a/libavcodec/aptxenc.c b/libavcodec/aptxenc.c
index 5fc0378f5d..6deebaf2cb 100644
--- a/libavcodec/aptxenc.c
+++ b/libavcodec/aptxenc.c
@@ -271,7 +271,7 @@ const FFCodec ff_aptx_encoder = {
     CODEC_LONG_NAME("aptX (Audio Processing Technology for Bluetooth)"),
     .p.type                = AVMEDIA_TYPE_AUDIO,
     .p.id                  = AV_CODEC_ID_APTX,
-    .p.capabilities        = AV_CODEC_CAP_DR1,
+    .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size        = sizeof(AptXEncContext),
     .init                  = aptx_encode_init,
     FF_CODEC_ENCODE_CB(aptx_encode_frame),
@@ -290,7 +290,7 @@ const FFCodec ff_aptx_hd_encoder = {
     CODEC_LONG_NAME("aptX HD (Audio Processing Technology for Bluetooth)"),
     .p.type                = AVMEDIA_TYPE_AUDIO,
     .p.id                  = AV_CODEC_ID_APTX_HD,
-    .p.capabilities        = AV_CODEC_CAP_DR1,
+    .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size        = sizeof(AptXEncContext),
     .init                  = aptx_encode_init,
     FF_CODEC_ENCODE_CB(aptx_encode_frame),
diff --git a/libavcodec/asvenc.c b/libavcodec/asvenc.c
index 9da7cbb986..4a14bcf8fa 100644
--- a/libavcodec/asvenc.c
+++ b/libavcodec/asvenc.c
@@ -362,7 +362,7 @@ const FFCodec ff_asv1_encoder = {
     CODEC_LONG_NAME("ASUS V1"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_ASV1,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(ASVEncContext),
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_frame),
@@ -377,7 +377,7 @@ const FFCodec ff_asv2_encoder = {
     CODEC_LONG_NAME("ASUS V2"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_ASV2,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(ASVEncContext),
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_frame),
diff --git a/libavcodec/avuienc.c b/libavcodec/avuienc.c
index 0b82848cb3..8a093d3d19 100644
--- a/libavcodec/avuienc.c
+++ b/libavcodec/avuienc.c
@@ -96,7 +96,8 @@ const FFCodec ff_avui_encoder = {
     CODEC_LONG_NAME("Avid Meridien Uncompressed"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_AVUI,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_UYVY422, AV_PIX_FMT_NONE },
     .init         = avui_encode_init,
     FF_CODEC_ENCODE_CB(avui_encode_frame),
diff --git a/libavcodec/bitpacked_enc.c b/libavcodec/bitpacked_enc.c
index ca4d5c887d..3c4e11293d 100644
--- a/libavcodec/bitpacked_enc.c
+++ b/libavcodec/bitpacked_enc.c
@@ -110,7 +110,8 @@ const FFCodec ff_bitpacked_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_BITPACKED,
     .priv_data_size = sizeof(struct BitpackedContext),
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV422P10,
diff --git a/libavcodec/bmpenc.c b/libavcodec/bmpenc.c
index abf644bd99..3e3ca324ea 100644
--- a/libavcodec/bmpenc.c
+++ b/libavcodec/bmpenc.c
@@ -161,7 +161,7 @@ const FFCodec ff_bmp_encoder = {
     CODEC_LONG_NAME("BMP (Windows and OS/2 bitmap)"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_BMP,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .init           = bmp_encode_init,
     FF_CODEC_ENCODE_CB(bmp_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
diff --git a/libavcodec/cfhdenc.c b/libavcodec/cfhdenc.c
index 0fca46ef3a..61053bd8b5 100644
--- a/libavcodec/cfhdenc.c
+++ b/libavcodec/cfhdenc.c
@@ -851,7 +851,8 @@ const FFCodec ff_cfhd_encoder = {
     CODEC_LONG_NAME("GoPro CineForm HD"),
     .p.type           = AVMEDIA_TYPE_VIDEO,
     .p.id             = AV_CODEC_ID_CFHD,
-    .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                        AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size   = sizeof(CFHDEncContext),
     .p.priv_class     = &cfhd_class,
     .init             = cfhd_encode_init,
diff --git a/libavcodec/cinepakenc.c b/libavcodec/cinepakenc.c
index c05449e89c..f15325ad0d 100644
--- a/libavcodec/cinepakenc.c
+++ b/libavcodec/cinepakenc.c
@@ -1219,7 +1219,7 @@ const FFCodec ff_cinepak_encoder = {
     CODEC_LONG_NAME("Cinepak"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_CINEPAK,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(CinepakEncContext),
     .init           = cinepak_encode_init,
     FF_CODEC_ENCODE_CB(cinepak_encode_frame),
diff --git a/libavcodec/cljrenc.c b/libavcodec/cljrenc.c
index c1f8810a5a..d658931520 100644
--- a/libavcodec/cljrenc.c
+++ b/libavcodec/cljrenc.c
@@ -113,7 +113,7 @@ const FFCodec ff_cljr_encoder = {
     CODEC_LONG_NAME("Cirrus Logic AccuPak"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_CLJR,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(CLJRContext),
     FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P,
diff --git a/libavcodec/cngenc.c b/libavcodec/cngenc.c
index ff40017f0d..596d6f8c2a 100644
--- a/libavcodec/cngenc.c
+++ b/libavcodec/cngenc.c
@@ -101,7 +101,7 @@ const FFCodec ff_comfortnoise_encoder = {
     CODEC_LONG_NAME("RFC 3389 comfort noise generator"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_COMFORT_NOISE,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(CNGContext),
     .init           = cng_encode_init,
     FF_CODEC_ENCODE_CB(cng_encode_frame),
diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c
index 4cab54ef1b..c731d79381 100644
--- a/libavcodec/dcaenc.c
+++ b/libavcodec/dcaenc.c
@@ -1315,7 +1315,8 @@ const FFCodec ff_dca_encoder = {
     CODEC_LONG_NAME("DCA (DTS Coherent Acoustics)"),
     .p.type                = AVMEDIA_TYPE_AUDIO,
     .p.id                  = AV_CODEC_ID_DTS,
-    .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL,
+    .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL |
+                             AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size        = sizeof(DCAEncContext),
     .init                  = encode_init,
     .close                 = encode_close,
diff --git a/libavcodec/dfpwmenc.c b/libavcodec/dfpwmenc.c
index 7f465a446e..5318b04a39 100644
--- a/libavcodec/dfpwmenc.c
+++ b/libavcodec/dfpwmenc.c
@@ -116,5 +116,6 @@ const FFCodec ff_dfpwm_encoder = {
     .init            = dfpwm_enc_init,
     FF_CODEC_ENCODE_CB(dfpwm_enc_frame),
     .p.sample_fmts   = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_NONE},
-    .p.capabilities  = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE,
+    .p.capabilities  = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE |
+                       AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
 };
diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c
index b7dc54f86a..176bf972d8 100644
--- a/libavcodec/dnxhdenc.c
+++ b/libavcodec/dnxhdenc.c
@@ -1359,7 +1359,7 @@ const FFCodec ff_dnxhd_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_DNXHD,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
-                      AV_CODEC_CAP_SLICE_THREADS,
+                      AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(DNXHDEncContext),
     .init           = dnxhd_encode_init,
     FF_CODEC_ENCODE_CB(dnxhd_encode_picture),
diff --git a/libavcodec/dvenc.c b/libavcodec/dvenc.c
index 4c747ef71f..8f5fa050b0 100644
--- a/libavcodec/dvenc.c
+++ b/libavcodec/dvenc.c
@@ -1239,7 +1239,8 @@ const FFCodec ff_dvvideo_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_DVVIDEO,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
-                      AV_CODEC_CAP_SLICE_THREADS,
+                      AV_CODEC_CAP_SLICE_THREADS                    |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(DVEncContext),
     .init           = dvvideo_encode_init,
     FF_CODEC_ENCODE_CB(dvvideo_encode_frame),
diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c
index 78d4f1399a..ab9eda261f 100644
--- a/libavcodec/eac3enc.c
+++ b/libavcodec/eac3enc.c
@@ -254,7 +254,7 @@ const FFCodec ff_eac3_encoder = {
     CODEC_LONG_NAME("ATSC A/52 E-AC-3"),
     .p.type          = AVMEDIA_TYPE_AUDIO,
     .p.id            = AV_CODEC_ID_EAC3,
-    .p.capabilities  = AV_CODEC_CAP_DR1,
+    .p.capabilities  = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size  = sizeof(AC3EncodeContext),
     .init            = ff_ac3_float_encode_init,
     FF_CODEC_ENCODE_CB(ff_ac3_float_encode_frame),
diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 7e2d54ae9b..e4270b6c34 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -220,6 +220,18 @@ int ff_encode_encode_cb(AVCodecContext *avctx, AVPacket *avpkt,
                     avpkt->duration = ff_samples_to_time_base(avctx,
                                                               frame->nb_samples);
             }
+
+            avctx->reordered_opaque = frame->reordered_opaque;
+            if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+                avpkt->opaque = frame->opaque;
+                if (frame->opaque_ref) {
+                    avpkt->opaque_ref = av_buffer_ref(frame->opaque_ref);
+                    if (!avpkt->opaque_ref) {
+                        ret = AVERROR(ENOMEM);
+                        goto unref;
+                    }
+                }
+            }
         }
 
         // dts equals pts unless there is reordering
diff --git a/libavcodec/exrenc.c b/libavcodec/exrenc.c
index 10ed876888..36327f498c 100644
--- a/libavcodec/exrenc.c
+++ b/libavcodec/exrenc.c
@@ -547,7 +547,8 @@ const FFCodec ff_exr_encoder = {
     .p.priv_class   = &exr_class,
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_EXR,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_frame),
     .close          = encode_close,
diff --git a/libavcodec/fitsenc.c b/libavcodec/fitsenc.c
index ac910499e5..12952278ac 100644
--- a/libavcodec/fitsenc.c
+++ b/libavcodec/fitsenc.c
@@ -114,7 +114,7 @@ const FFCodec ff_fits_encoder = {
     CODEC_LONG_NAME("Flexible Image Transport System"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_FITS,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     FF_CODEC_ENCODE_CB(fits_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_GBRAP16BE,
                                                      AV_PIX_FMT_GBRP16BE,
diff --git a/libavcodec/flashsv2enc.c b/libavcodec/flashsv2enc.c
index 668ca6a85f..46e24a9c1e 100644
--- a/libavcodec/flashsv2enc.c
+++ b/libavcodec/flashsv2enc.c
@@ -915,7 +915,7 @@ const FFCodec ff_flashsv2_encoder = {
     CODEC_LONG_NAME("Flash Screen Video Version 2"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_FLASHSV2,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(FlashSV2Context),
     .init           = flashsv2_encode_init,
     FF_CODEC_ENCODE_CB(flashsv2_encode_frame),
diff --git a/libavcodec/flashsvenc.c b/libavcodec/flashsvenc.c
index 3a35876d9c..6192bc25db 100644
--- a/libavcodec/flashsvenc.c
+++ b/libavcodec/flashsvenc.c
@@ -251,7 +251,7 @@ const FFCodec ff_flashsv_encoder = {
     CODEC_LONG_NAME("Flash Screen Video"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_FLASHSV,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(FlashSVContext),
     .init           = flashsv_encode_init,
     FF_CODEC_ENCODE_CB(flashsv_encode_frame),
diff --git a/libavcodec/flvenc.c b/libavcodec/flvenc.c
index b49ca2e0d5..1ebe6e8736 100644
--- a/libavcodec/flvenc.c
+++ b/libavcodec/flvenc.c
@@ -105,4 +105,5 @@ const FFCodec ff_flv_encoder = {
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
                                                      AV_PIX_FMT_NONE},
+    .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
 };
diff --git a/libavcodec/g722enc.c b/libavcodec/g722enc.c
index bc08211b1d..47811cee4d 100644
--- a/libavcodec/g722enc.c
+++ b/libavcodec/g722enc.c
@@ -375,7 +375,8 @@ const FFCodec ff_adpcm_g722_encoder = {
     CODEC_LONG_NAME("G.722 ADPCM"),
     .p.type          = AVMEDIA_TYPE_AUDIO,
     .p.id            = AV_CODEC_ID_ADPCM_G722,
-    .p.capabilities  = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
+    .p.capabilities  = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME |
+                       AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size  = sizeof(G722Context),
     .init            = g722_encode_init,
     .close           = g722_encode_close,
diff --git a/libavcodec/g723_1enc.c b/libavcodec/g723_1enc.c
index 8466067185..be80153130 100644
--- a/libavcodec/g723_1enc.c
+++ b/libavcodec/g723_1enc.c
@@ -1241,7 +1241,7 @@ const FFCodec ff_g723_1_encoder = {
     CODEC_LONG_NAME("G.723.1"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_G723_1,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(G723_1_Context),
     .init           = g723_1_encode_init,
     FF_CODEC_ENCODE_CB(g723_1_encode_frame),
diff --git a/libavcodec/g726.c b/libavcodec/g726.c
index 7bbb7f900c..6c5638760d 100644
--- a/libavcodec/g726.c
+++ b/libavcodec/g726.c
@@ -405,7 +405,8 @@ const FFCodec ff_adpcm_g726_encoder = {
     CODEC_LONG_NAME("G.726 ADPCM"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_ADPCM_G726,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(G726Context),
     .init           = g726_encode_init,
     FF_CODEC_ENCODE_CB(g726_encode_frame),
@@ -422,7 +423,8 @@ const FFCodec ff_adpcm_g726le_encoder = {
     CODEC_LONG_NAME("G.726 little endian ADPCM (\"right-justified\")"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_ADPCM_G726LE,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(G726Context),
     .init           = g726_encode_init,
     FF_CODEC_ENCODE_CB(g726_encode_frame),
diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index 7e717d8220..e17ead0f82 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -553,7 +553,7 @@ const FFCodec ff_gif_encoder = {
     CODEC_LONG_NAME("GIF (Graphics Interchange Format)"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_GIF,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(GIFContext),
     .init           = gif_encode_init,
     FF_CODEC_ENCODE_CB(gif_encode_frame),
diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index e8ea357cbb..6c80809bca 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -413,4 +413,5 @@ const FFCodec ff_h261_encoder = {
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
                                                      AV_PIX_FMT_NONE },
+    .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
 };
diff --git a/libavcodec/hapenc.c b/libavcodec/hapenc.c
index a890dc6492..7de7358e3d 100644
--- a/libavcodec/hapenc.c
+++ b/libavcodec/hapenc.c
@@ -351,7 +351,8 @@ const FFCodec ff_hap_encoder = {
     CODEC_LONG_NAME("Vidvox Hap"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_HAP,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(HapContext),
     .p.priv_class   = &hapenc_class,
     .init           = hap_init,
diff --git a/libavcodec/hdrenc.c b/libavcodec/hdrenc.c
index d8c3111c93..40d283ee61 100644
--- a/libavcodec/hdrenc.c
+++ b/libavcodec/hdrenc.c
@@ -177,7 +177,8 @@ const FFCodec ff_hdr_encoder = {
     .priv_data_size = sizeof(HDREncContext),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_RADIANCE_HDR,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .init           = hdr_encode_init,
     FF_CODEC_ENCODE_CB(hdr_encode_frame),
     .close          = hdr_encode_close,
diff --git a/libavcodec/huffyuvenc.c b/libavcodec/huffyuvenc.c
index db274e37ad..72d6246ebe 100644
--- a/libavcodec/huffyuvenc.c
+++ b/libavcodec/huffyuvenc.c
@@ -1082,7 +1082,8 @@ const FFCodec ff_huffyuv_encoder = {
     CODEC_LONG_NAME("Huffyuv / HuffYUV"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_HUFFYUV,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(HYuvEncContext),
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_frame),
@@ -1101,7 +1102,8 @@ const FFCodec ff_ffvhuff_encoder = {
     CODEC_LONG_NAME("Huffyuv FFmpeg variant"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_FFVHUFF,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(HYuvEncContext),
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_frame),
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index 22e5a8368d..719effa41d 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -903,6 +903,7 @@ const FFCodec ff_h263_encoder = {
     .p.id           = AV_CODEC_ID_H263,
     .p.pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE},
     .p.priv_class   = &h263_class,
+    .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_mpv_encode_init,
@@ -933,7 +934,7 @@ const FFCodec ff_h263p_encoder = {
     .p.id           = AV_CODEC_ID_H263P,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
     .p.priv_class   = &h263p_class,
-    .p.capabilities = AV_CODEC_CAP_SLICE_THREADS,
+    .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_mpv_encode_init,
diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c
index e883d5deb7..6406f90ac2 100644
--- a/libavcodec/j2kenc.c
+++ b/libavcodec/j2kenc.c
@@ -1835,7 +1835,7 @@ const FFCodec ff_jpeg2000_encoder = {
     CODEC_LONG_NAME("JPEG 2000"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_JPEG2000,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(Jpeg2000EncoderContext),
     .init           = j2kenc_init,
     FF_CODEC_ENCODE_CB(encode_frame),
diff --git a/libavcodec/jpeglsenc.c b/libavcodec/jpeglsenc.c
index 5ee39ac2d6..53394102df 100644
--- a/libavcodec/jpeglsenc.c
+++ b/libavcodec/jpeglsenc.c
@@ -476,7 +476,8 @@ const FFCodec ff_jpegls_encoder = {
     CODEC_LONG_NAME("JPEG-LS"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_JPEGLS,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(JPEGLSContext),
     .p.priv_class   = &jpegls_class,
     .init           = encode_jpegls_init,
diff --git a/libavcodec/lclenc.c b/libavcodec/lclenc.c
index 2c9add5215..dd5eed9d63 100644
--- a/libavcodec/lclenc.c
+++ b/libavcodec/lclenc.c
@@ -156,7 +156,8 @@ const FFCodec ff_zlib_encoder = {
     CODEC_LONG_NAME("LCL (LossLess Codec Library) ZLIB"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_ZLIB,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(LclEncContext),
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_frame),
diff --git a/libavcodec/libcodec2.c b/libavcodec/libcodec2.c
index 5728d915c2..83f68e85c7 100644
--- a/libavcodec/libcodec2.c
+++ b/libavcodec/libcodec2.c
@@ -197,7 +197,8 @@ const FFCodec ff_libcodec2_encoder = {
     CODEC_LONG_NAME("codec2 encoder using libcodec2"),
     .p.type                 = AVMEDIA_TYPE_AUDIO,
     .p.id                   = AV_CODEC_ID_CODEC2,
-    .p.capabilities         = AV_CODEC_CAP_DR1,
+    .p.capabilities         = AV_CODEC_CAP_DR1 |
+                              AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .p.supported_samplerates = (const int[]){ 8000, 0 },
     .p.sample_fmts          = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE },
     .p.ch_layouts           = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_MONO, { 0 } },
diff --git a/libavcodec/libgsmenc.c b/libavcodec/libgsmenc.c
index bd3b1420aa..640954491a 100644
--- a/libavcodec/libgsmenc.c
+++ b/libavcodec/libgsmenc.c
@@ -122,7 +122,7 @@ const FFCodec ff_libgsm_encoder = {
     CODEC_LONG_NAME("libgsm GSM"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_GSM,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .init           = libgsm_encode_init,
     FF_CODEC_ENCODE_CB(libgsm_encode_frame),
     .close          = libgsm_encode_close,
@@ -141,7 +141,7 @@ const FFCodec ff_libgsm_ms_encoder = {
     CODEC_LONG_NAME("libgsm GSM Microsoft variant"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_GSM_MS,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .init           = libgsm_encode_init,
     FF_CODEC_ENCODE_CB(libgsm_encode_frame),
     .close          = libgsm_encode_close,
diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c
index 9ef6e16bc5..0787b5c313 100644
--- a/libavcodec/libilbc.c
+++ b/libavcodec/libilbc.c
@@ -126,7 +126,8 @@ const FFCodec ff_libilbc_decoder = {
     .priv_data_size = sizeof(ILBCDecContext),
     .init           = ilbc_decode_init,
     FF_CODEC_DECODE_CB(ilbc_decode_frame),
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .p.priv_class   = &ilbc_dec_class,
 };
 
diff --git a/libavcodec/libjxlenc.c b/libavcodec/libjxlenc.c
index 0793ed251b..06581b268d 100644
--- a/libavcodec/libjxlenc.c
+++ b/libavcodec/libjxlenc.c
@@ -467,7 +467,8 @@ const FFCodec ff_libjxl_encoder = {
     .init             = libjxl_encode_init,
     FF_CODEC_ENCODE_CB(libjxl_encode_frame),
     .close            = libjxl_encode_close,
-    .p.capabilities   = AV_CODEC_CAP_OTHER_THREADS,
+    .p.capabilities   = AV_CODEC_CAP_OTHER_THREADS |
+                        AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal    = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
                         FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_INIT_CLEANUP |
                         FF_CODEC_CAP_ICC_PROFILES,
diff --git a/libavcodec/libopenh264enc.c b/libavcodec/libopenh264enc.c
index bbd6969568..6934fd481c 100644
--- a/libavcodec/libopenh264enc.c
+++ b/libavcodec/libopenh264enc.c
@@ -456,7 +456,8 @@ const FFCodec ff_libopenh264_encoder = {
     CODEC_LONG_NAME("OpenH264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_H264,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_OTHER_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_OTHER_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(SVCContext),
     .init           = svc_encode_init,
     FF_CODEC_ENCODE_CB(svc_encode_frame),
diff --git a/libavcodec/libopenjpegenc.c b/libavcodec/libopenjpegenc.c
index 6f77780391..009c7a4377 100644
--- a/libavcodec/libopenjpegenc.c
+++ b/libavcodec/libopenjpegenc.c
@@ -763,7 +763,8 @@ const FFCodec ff_libopenjpeg_encoder = {
     .priv_data_size = sizeof(LibOpenJPEGContext),
     .init           = libopenjpeg_encode_init,
     FF_CODEC_ENCODE_CB(libopenjpeg_encode_frame),
-    .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48,
         AV_PIX_FMT_RGBA64, AV_PIX_FMT_GBR24P,
diff --git a/libavcodec/libvo-amrwbenc.c b/libavcodec/libvo-amrwbenc.c
index 76a6b69994..02b8941a6d 100644
--- a/libavcodec/libvo-amrwbenc.c
+++ b/libavcodec/libvo-amrwbenc.c
@@ -144,7 +144,8 @@ const FFCodec ff_libvo_amrwbenc_encoder = {
     CODEC_LONG_NAME("Android VisualOn AMR-WB (Adaptive Multi-Rate Wide-Band)"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_AMR_WB,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .p.priv_class   = &amrwb_class,
     .p.wrapper_name = "libvo_amrwbenc",
     .caps_internal  = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
diff --git a/libavcodec/libwebpenc.c b/libavcodec/libwebpenc.c
index ee5795f041..d6edd86603 100644
--- a/libavcodec/libwebpenc.c
+++ b/libavcodec/libwebpenc.c
@@ -92,7 +92,7 @@ const FFCodec ff_libwebp_encoder = {
     CODEC_LONG_NAME("libwebp WebP image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_WEBP,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .p.pix_fmts     = ff_libwebpenc_pix_fmts,
     .p.priv_class   = &ff_libwebpenc_class,
     .p.wrapper_name = "libwebp",
diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c
index 4e04b3c098..aba875b6b8 100644
--- a/libavcodec/libxvid.c
+++ b/libavcodec/libxvid.c
@@ -902,7 +902,7 @@ const FFCodec ff_libxvid_encoder = {
     CODEC_LONG_NAME("libxvidcore MPEG-4 part 2"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_MPEG4,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(struct xvid_context),
     .init           = xvid_encode_init,
     FF_CODEC_ENCODE_CB(xvid_encode_frame),
diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c
index 81c52a7c78..aa62beac71 100644
--- a/libavcodec/ljpegenc.c
+++ b/libavcodec/ljpegenc.c
@@ -316,7 +316,8 @@ const FFCodec ff_ljpeg_encoder = {
     CODEC_LONG_NAME("Lossless JPEG"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_LJPEG,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(LJpegEncContext),
     .p.priv_class   = &ljpeg_class,
     .init           = ljpeg_encode_init,
diff --git a/libavcodec/magicyuvenc.c b/libavcodec/magicyuvenc.c
index 7f9ff72834..9e41c1b0fe 100644
--- a/libavcodec/magicyuvenc.c
+++ b/libavcodec/magicyuvenc.c
@@ -569,7 +569,8 @@ const FFCodec ff_magicyuv_encoder = {
     CODEC_LONG_NAME("MagicYUV video"),
     .p.type           = AVMEDIA_TYPE_VIDEO,
     .p.id             = AV_CODEC_ID_MAGICYUV,
-    .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                        AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size   = sizeof(MagicYUVContext),
     .p.priv_class     = &magicyuv_class,
     .init             = magy_encode_init,
diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index eafe7130e2..508772987f 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -651,7 +651,8 @@ const FFCodec ff_mjpeg_encoder = {
     .init           = ff_mpv_encode_init,
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
     .close          = mjpeg_encode_close,
-    .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_ICC_PROFILES,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P,
@@ -685,5 +686,6 @@ const FFCodec ff_amv_encoder = {
         AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_NONE
     },
     .p.priv_class   = &amv_class,
+    .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
 };
 #endif
diff --git a/libavcodec/mpegaudioenc_fixed.c b/libavcodec/mpegaudioenc_fixed.c
index afbffe766b..a523b5d533 100644
--- a/libavcodec/mpegaudioenc_fixed.c
+++ b/libavcodec/mpegaudioenc_fixed.c
@@ -28,7 +28,7 @@ const FFCodec ff_mp2fixed_encoder = {
     CODEC_LONG_NAME("MP2 fixed point (MPEG audio layer 2)"),
     .p.type                = AVMEDIA_TYPE_AUDIO,
     .p.id                  = AV_CODEC_ID_MP2,
-    .p.capabilities        = AV_CODEC_CAP_DR1,
+    .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size        = sizeof(MpegAudioContext),
     .init                  = MPA_encode_init,
     FF_CODEC_ENCODE_CB(MPA_encode_frame),
diff --git a/libavcodec/mpegaudioenc_float.c b/libavcodec/mpegaudioenc_float.c
index 212709c291..6a13d09573 100644
--- a/libavcodec/mpegaudioenc_float.c
+++ b/libavcodec/mpegaudioenc_float.c
@@ -29,7 +29,7 @@ const FFCodec ff_mp2_encoder = {
     CODEC_LONG_NAME("MP2 (MPEG audio layer 2)"),
     .p.type                = AVMEDIA_TYPE_AUDIO,
     .p.id                  = AV_CODEC_ID_MP2,
-    .p.capabilities        = AV_CODEC_CAP_DR1,
+    .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size        = sizeof(MpegAudioContext),
     .init                  = MPA_encode_init,
     FF_CODEC_ENCODE_CB(MPA_encode_frame),
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index 9b6e5efa0c..737a7f7dce 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -684,6 +684,7 @@ const FFCodec ff_msmpeg4v2_encoder = {
     .p.id           = AV_CODEC_ID_MSMPEG4V2,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
     .p.priv_class   = &ff_mpv_enc_class,
+    .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
     .priv_data_size = sizeof(MSMPEG4EncContext),
     .init           = ff_mpv_encode_init,
@@ -698,6 +699,7 @@ const FFCodec ff_msmpeg4v3_encoder = {
     .p.id           = AV_CODEC_ID_MSMPEG4V3,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
     .p.priv_class   = &ff_mpv_enc_class,
+    .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
     .priv_data_size = sizeof(MSMPEG4EncContext),
     .init           = ff_mpv_encode_init,
@@ -712,6 +714,7 @@ const FFCodec ff_wmv1_encoder = {
     .p.id           = AV_CODEC_ID_WMV1,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
     .p.priv_class   = &ff_mpv_enc_class,
+    .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
     .priv_data_size = sizeof(MSMPEG4EncContext),
     .init           = ff_mpv_encode_init,
diff --git a/libavcodec/msvideo1enc.c b/libavcodec/msvideo1enc.c
index a349b42ca0..36cfd39a85 100644
--- a/libavcodec/msvideo1enc.c
+++ b/libavcodec/msvideo1enc.c
@@ -307,6 +307,7 @@ const FFCodec ff_msvideo1_encoder = {
     CODEC_LONG_NAME("Microsoft Video-1"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_MSVIDEO1,
+    .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(Msvideo1EncContext),
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_frame),
diff --git a/libavcodec/pamenc.c b/libavcodec/pamenc.c
index 7d01e89f74..45ec29ccb3 100644
--- a/libavcodec/pamenc.c
+++ b/libavcodec/pamenc.c
@@ -133,7 +133,7 @@ const FFCodec ff_pam_encoder = {
     CODEC_LONG_NAME("PAM (Portable AnyMap) image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PAM,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     FF_CODEC_ENCODE_CB(pam_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA,
diff --git a/libavcodec/pcm-blurayenc.c b/libavcodec/pcm-blurayenc.c
index 62e86e722f..bfbfa91d7a 100644
--- a/libavcodec/pcm-blurayenc.c
+++ b/libavcodec/pcm-blurayenc.c
@@ -304,5 +304,5 @@ const FFCodec ff_pcm_bluray_encoder = {
         { 0 } },
     .p.sample_fmts         = (const enum AVSampleFormat[]) {
         AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE },
-    .p.capabilities        = AV_CODEC_CAP_DR1,
+    .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
 };
diff --git a/libavcodec/pcm-dvdenc.c b/libavcodec/pcm-dvdenc.c
index 011d0a2f00..a2e5cbdc2e 100644
--- a/libavcodec/pcm-dvdenc.c
+++ b/libavcodec/pcm-dvdenc.c
@@ -176,7 +176,8 @@ const FFCodec ff_pcm_dvd_encoder = {
     CODEC_LONG_NAME("PCM signed 16|20|24-bit big-endian for DVD media"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_PCM_DVD,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(PCMDVDContext),
     .init           = pcm_dvd_encode_init,
     FF_CODEC_ENCODE_CB(pcm_dvd_encode_frame),
diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c
index ee36a364c8..23955ba2dd 100644
--- a/libavcodec/pcm.c
+++ b/libavcodec/pcm.c
@@ -553,7 +553,8 @@ const FFCodec ff_ ## name_ ## _encoder = {                                  \
     CODEC_LONG_NAME(long_name_),                                            \
     .p.type       = AVMEDIA_TYPE_AUDIO,                                     \
     .p.id         = AV_CODEC_ID_ ## id_,                                    \
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE,    \
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE | \
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,                \
     .init         = pcm_encode_init,                                        \
     FF_CODEC_ENCODE_CB(pcm_encode_frame),                                   \
     .p.sample_fmts = (const enum AVSampleFormat[]){ sample_fmt_,             \
diff --git a/libavcodec/pcxenc.c b/libavcodec/pcxenc.c
index 509158ba0f..cf9b41b752 100644
--- a/libavcodec/pcxenc.c
+++ b/libavcodec/pcxenc.c
@@ -197,7 +197,7 @@ const FFCodec ff_pcx_encoder = {
     CODEC_LONG_NAME("PC Paintbrush PCX image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PCX,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     FF_CODEC_ENCODE_CB(pcx_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24,
diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index ca1a186ca8..d1448bd0cd 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -1196,7 +1196,8 @@ const FFCodec ff_png_encoder = {
     CODEC_LONG_NAME("PNG (Portable Network Graphics) image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PNG,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(PNGEncContext),
     .init           = png_enc_init,
     .close          = png_enc_close,
diff --git a/libavcodec/pnmenc.c b/libavcodec/pnmenc.c
index c998dd410c..1eca2556da 100644
--- a/libavcodec/pnmenc.c
+++ b/libavcodec/pnmenc.c
@@ -227,7 +227,7 @@ const FFCodec ff_pgm_encoder = {
     CODEC_LONG_NAME("PGM (Portable GrayMap) image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PGM,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     FF_CODEC_ENCODE_CB(pnm_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_NONE
@@ -241,7 +241,7 @@ const FFCodec ff_pgmyuv_encoder = {
     CODEC_LONG_NAME("PGMYUV (Portable GrayMap YUV) image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PGMYUV,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     FF_CODEC_ENCODE_CB(pnm_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P16BE, AV_PIX_FMT_NONE
@@ -255,7 +255,7 @@ const FFCodec ff_ppm_encoder = {
     CODEC_LONG_NAME("PPM (Portable PixelMap) image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PPM,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     FF_CODEC_ENCODE_CB(pnm_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB48BE, AV_PIX_FMT_NONE
@@ -269,7 +269,7 @@ const FFCodec ff_pbm_encoder = {
     CODEC_LONG_NAME("PBM (Portable BitMap) image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PBM,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     FF_CODEC_ENCODE_CB(pnm_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_MONOWHITE,
                                                   AV_PIX_FMT_NONE },
@@ -282,7 +282,7 @@ const FFCodec ff_pfm_encoder = {
     CODEC_LONG_NAME("PFM (Portable FloatMap) image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PFM,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     FF_CODEC_ENCODE_CB(pnm_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_GBRPF32LE,
                                                     AV_PIX_FMT_GRAYF32LE,
@@ -307,7 +307,7 @@ const FFCodec ff_phm_encoder = {
     CODEC_LONG_NAME("PHM (Portable HalfFloatMap) image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PHM,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(PHMEncContext),
     .init           = phm_enc_init,
     FF_CODEC_ENCODE_CB(pnm_encode_frame),
diff --git a/libavcodec/proresenc_anatoliy.c b/libavcodec/proresenc_anatoliy.c
index bd1b70cc5d..09196c7aa1 100644
--- a/libavcodec/proresenc_anatoliy.c
+++ b/libavcodec/proresenc_anatoliy.c
@@ -944,7 +944,8 @@ const FFCodec ff_prores_aw_encoder = {
     CODEC_LONG_NAME("Apple ProRes"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PRORES,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .p.pix_fmts     = pix_fmts,
     .priv_data_size = sizeof(ProresContext),
     .init           = prores_encode_init,
@@ -960,7 +961,8 @@ const FFCodec ff_prores_encoder = {
     CODEC_LONG_NAME("Apple ProRes"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_PRORES,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .p.pix_fmts     = pix_fmts,
     .priv_data_size = sizeof(ProresContext),
     .init           = prores_encode_init,
diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c
index 5b38437d0a..1940e0378a 100644
--- a/libavcodec/proresenc_kostya.c
+++ b/libavcodec/proresenc_kostya.c
@@ -1428,7 +1428,8 @@ const FFCodec ff_prores_ks_encoder = {
     .init           = encode_init,
     .close          = encode_close,
     FF_CODEC_ENCODE_CB(encode_frame),
-    .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .p.pix_fmts     = (const enum AVPixelFormat[]) {
                           AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
                           AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE
diff --git a/libavcodec/qoienc.c b/libavcodec/qoienc.c
index 6d574e0da9..b9efdc2fa5 100644
--- a/libavcodec/qoienc.c
+++ b/libavcodec/qoienc.c
@@ -131,7 +131,8 @@ const FFCodec ff_qoi_encoder = {
     CODEC_LONG_NAME("QOI (Quite OK Image format) image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_QOI,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     FF_CODEC_ENCODE_CB(qoi_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB24,
diff --git a/libavcodec/qtrleenc.c b/libavcodec/qtrleenc.c
index 855494d3df..3d51fcf843 100644
--- a/libavcodec/qtrleenc.c
+++ b/libavcodec/qtrleenc.c
@@ -404,7 +404,7 @@ const FFCodec ff_qtrle_encoder = {
     CODEC_LONG_NAME("QuickTime Animation (RLE) video"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_QTRLE,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(QtrleEncContext),
     .init           = qtrle_encode_init,
     FF_CODEC_ENCODE_CB(qtrle_encode_frame),
diff --git a/libavcodec/r210enc.c b/libavcodec/r210enc.c
index d87f42ce4a..91e3452874 100644
--- a/libavcodec/r210enc.c
+++ b/libavcodec/r210enc.c
@@ -96,7 +96,7 @@ const FFCodec ff_r210_encoder = {
     CODEC_LONG_NAME("Uncompressed RGB 10-bit"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_R210,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = pix_fmt,
@@ -108,7 +108,7 @@ const FFCodec ff_r10k_encoder = {
     CODEC_LONG_NAME("AJA Kona 10-bit RGB Codec"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_R10K,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = pix_fmt,
@@ -120,7 +120,7 @@ const FFCodec ff_avrp_encoder = {
     CODEC_LONG_NAME("Avid 1:1 10-bit RGB Packer"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_AVRP,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_frame),
     .p.pix_fmts     = pix_fmt,
diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c
index c2643e6d80..8c577006d9 100644
--- a/libavcodec/rawenc.c
+++ b/libavcodec/rawenc.c
@@ -86,7 +86,8 @@ const FFCodec ff_rawvideo_encoder = {
     CODEC_LONG_NAME("raw video"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_RAWVIDEO,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .init           = raw_encode_init,
     FF_CODEC_ENCODE_CB(raw_encode),
 };
diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c
index 273686a147..c25aa39b73 100644
--- a/libavcodec/roqvideoenc.c
+++ b/libavcodec/roqvideoenc.c
@@ -1122,7 +1122,7 @@ const FFCodec ff_roq_encoder = {
     CODEC_LONG_NAME("id RoQ video"),
     .p.type               = AVMEDIA_TYPE_VIDEO,
     .p.id                 = AV_CODEC_ID_ROQ,
-    .p.capabilities       = AV_CODEC_CAP_DR1,
+    .p.capabilities       = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size       = sizeof(RoqEncContext),
     .init                 = roq_encode_init,
     FF_CODEC_ENCODE_CB(roq_encode_frame),
diff --git a/libavcodec/rpzaenc.c b/libavcodec/rpzaenc.c
index 1ea579d2d3..da9500e424 100644
--- a/libavcodec/rpzaenc.c
+++ b/libavcodec/rpzaenc.c
@@ -873,7 +873,7 @@ const FFCodec ff_rpza_encoder = {
     CODEC_LONG_NAME("QuickTime video (RPZA)"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_RPZA,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(RpzaContext),
     .p.priv_class   = &rpza_class,
     .init           = rpza_encode_init,
diff --git a/libavcodec/rv10enc.c b/libavcodec/rv10enc.c
index d0704c5a4b..d19d693e18 100644
--- a/libavcodec/rv10enc.c
+++ b/libavcodec/rv10enc.c
@@ -71,6 +71,7 @@ const FFCodec ff_rv10_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_RV10,
     .p.priv_class   = &ff_mpv_enc_class,
+    .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_mpv_encode_init,
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
diff --git a/libavcodec/rv20enc.c b/libavcodec/rv20enc.c
index a6bacacb48..c7149fb267 100644
--- a/libavcodec/rv20enc.c
+++ b/libavcodec/rv20enc.c
@@ -68,6 +68,7 @@ const FFCodec ff_rv20_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_RV20,
     .p.priv_class   = &ff_mpv_enc_class,
+    .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_mpv_encode_init,
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
diff --git a/libavcodec/s302menc.c b/libavcodec/s302menc.c
index 3bd657f945..4b8996f9ac 100644
--- a/libavcodec/s302menc.c
+++ b/libavcodec/s302menc.c
@@ -176,7 +176,8 @@ const FFCodec ff_s302m_encoder = {
     .p.type                = AVMEDIA_TYPE_AUDIO,
     .p.id                  = AV_CODEC_ID_S302M,
     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL |
-                             AV_CODEC_CAP_VARIABLE_FRAME_SIZE,
+                             AV_CODEC_CAP_VARIABLE_FRAME_SIZE             |
+                             AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size        = sizeof(S302MEncContext),
     .init                  = s302m_encode_init,
     FF_CODEC_ENCODE_CB(s302m_encode2_frame),
diff --git a/libavcodec/sbcenc.c b/libavcodec/sbcenc.c
index 721c97e1ea..fccb0e3ea3 100644
--- a/libavcodec/sbcenc.c
+++ b/libavcodec/sbcenc.c
@@ -348,7 +348,8 @@ const FFCodec ff_sbc_encoder = {
     CODEC_LONG_NAME("SBC (low-complexity subband codec)"),
     .p.type                = AVMEDIA_TYPE_AUDIO,
     .p.id                  = AV_CODEC_ID_SBC,
-    .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
+    .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME |
+                             AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size        = sizeof(SBCEncContext),
     .init                  = sbc_encode_init,
     FF_CODEC_ENCODE_CB(sbc_encode_frame),
diff --git a/libavcodec/sgienc.c b/libavcodec/sgienc.c
index 901e0a74f9..5bbb72c03a 100644
--- a/libavcodec/sgienc.c
+++ b/libavcodec/sgienc.c
@@ -275,7 +275,7 @@ const FFCodec ff_sgi_encoder = {
     CODEC_LONG_NAME("SGI image"),
     .p.type    = AVMEDIA_TYPE_VIDEO,
     .p.id      = AV_CODEC_ID_SGI,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(SgiContext),
     .p.priv_class = &sgi_class,
     .init      = encode_init,
diff --git a/libavcodec/smcenc.c b/libavcodec/smcenc.c
index a2d224bd09..159049f254 100644
--- a/libavcodec/smcenc.c
+++ b/libavcodec/smcenc.c
@@ -573,7 +573,7 @@ const FFCodec ff_smc_encoder = {
     CODEC_LONG_NAME("QuickTime Graphics (SMC)"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_SMC,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(SMCContext),
     .init           = smc_encode_init,
     FF_CODEC_ENCODE_CB(smc_encode_frame),
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 7fad95b69a..749c8067d2 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -1935,7 +1935,7 @@ const FFCodec ff_snow_encoder = {
     CODEC_LONG_NAME("Snow"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_SNOW,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(SnowContext),
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_frame),
diff --git a/libavcodec/sonic.c b/libavcodec/sonic.c
index 77bdb418a7..62e6193ac6 100644
--- a/libavcodec/sonic.c
+++ b/libavcodec/sonic.c
@@ -1096,7 +1096,8 @@ const FFCodec ff_sonic_encoder = {
     CODEC_LONG_NAME("Sonic"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_SONIC,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(SonicContext),
     .init           = sonic_encode_init,
     FF_CODEC_ENCODE_CB(sonic_encode_frame),
@@ -1112,7 +1113,8 @@ const FFCodec ff_sonic_ls_encoder = {
     CODEC_LONG_NAME("Sonic lossless"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_SONIC_LS,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(SonicContext),
     .init           = sonic_encode_init,
     FF_CODEC_ENCODE_CB(sonic_encode_frame),
diff --git a/libavcodec/speedhqenc.c b/libavcodec/speedhqenc.c
index 7269e345d3..5b4ff4c139 100644
--- a/libavcodec/speedhqenc.c
+++ b/libavcodec/speedhqenc.c
@@ -288,6 +288,7 @@ const FFCodec ff_speedhq_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_SPEEDHQ,
     .p.priv_class   = &ff_mpv_enc_class,
+    .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(SpeedHQEncContext),
     .init           = ff_mpv_encode_init,
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
diff --git a/libavcodec/sunrastenc.c b/libavcodec/sunrastenc.c
index 9b82f9921a..b2d57f7235 100644
--- a/libavcodec/sunrastenc.c
+++ b/libavcodec/sunrastenc.c
@@ -213,7 +213,7 @@ const FFCodec ff_sunrast_encoder = {
     CODEC_LONG_NAME("Sun Rasterfile image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_SUNRAST,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(SUNRASTContext),
     .init           = sunrast_encode_init,
     FF_CODEC_ENCODE_CB(sunrast_encode_frame),
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index 8f09e634a5..e3ea0c1e47 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -752,7 +752,7 @@ const FFCodec ff_svq1_encoder = {
     CODEC_LONG_NAME("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_SVQ1,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(SVQ1EncContext),
     .p.priv_class   = &svq1enc_class,
     .init           = svq1_encode_init,
diff --git a/libavcodec/targaenc.c b/libavcodec/targaenc.c
index bb3cb93187..d9c500b97d 100644
--- a/libavcodec/targaenc.c
+++ b/libavcodec/targaenc.c
@@ -207,7 +207,7 @@ const FFCodec ff_targa_encoder = {
     CODEC_LONG_NAME("Truevision Targa image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_TARGA,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(TargaContext),
     .p.priv_class   = &targa_class,
     .init           = targa_encode_init,
diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c
index 6dfbdaeb40..06d7dcc99d 100644
--- a/libavcodec/tiffenc.c
+++ b/libavcodec/tiffenc.c
@@ -574,7 +574,8 @@ const FFCodec ff_tiff_encoder = {
     CODEC_LONG_NAME("TIFF image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_TIFF,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(TiffEncoderContext),
     .init           = encode_init,
     .close          = encode_close,
diff --git a/libavcodec/ttaenc.c b/libavcodec/ttaenc.c
index d41d2e6fa5..db79c38b43 100644
--- a/libavcodec/ttaenc.c
+++ b/libavcodec/ttaenc.c
@@ -204,7 +204,8 @@ const FFCodec ff_tta_encoder = {
     CODEC_LONG_NAME("TTA (True Audio)"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_TTA,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(TTAEncContext),
     .init           = tta_encode_init,
     .close          = tta_encode_close,
diff --git a/libavcodec/utvideoenc.c b/libavcodec/utvideoenc.c
index d4388da8ba..6e87bbc2b6 100644
--- a/libavcodec/utvideoenc.c
+++ b/libavcodec/utvideoenc.c
@@ -648,7 +648,8 @@ const FFCodec ff_utvideo_encoder = {
     CODEC_LONG_NAME("Ut Video"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_UTVIDEO,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(UtvideoContext),
     .p.priv_class   = &utvideo_class,
     .init           = utvideo_encode_init,
diff --git a/libavcodec/v210enc.c b/libavcodec/v210enc.c
index abbbf4ff9d..2a30ed77da 100644
--- a/libavcodec/v210enc.c
+++ b/libavcodec/v210enc.c
@@ -112,7 +112,8 @@ const FFCodec ff_v210_encoder = {
     CODEC_LONG_NAME("Uncompressed 4:2:2 10-bit"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_V210,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(V210EncContext),
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_frame),
diff --git a/libavcodec/v308enc.c b/libavcodec/v308enc.c
index 78e33c0a8a..68f9c3310b 100644
--- a/libavcodec/v308enc.c
+++ b/libavcodec/v308enc.c
@@ -75,7 +75,7 @@ const FFCodec ff_v308_encoder = {
     CODEC_LONG_NAME("Uncompressed packed 4:4:4"),
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_V308,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .init         = v308_encode_init,
     FF_CODEC_ENCODE_CB(v308_encode_frame),
     .p.pix_fmts   = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE },
diff --git a/libavcodec/v408enc.c b/libavcodec/v408enc.c
index 514f41be4e..1faac7cc36 100644
--- a/libavcodec/v408enc.c
+++ b/libavcodec/v408enc.c
@@ -94,7 +94,7 @@ const FFCodec ff_ayuv_encoder = {
     CODEC_LONG_NAME("Uncompressed packed MS 4:4:4:4"),
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_AYUV,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .init         = v408_encode_init,
     FF_CODEC_ENCODE_CB(v408_encode_frame),
     .p.pix_fmts   = pix_fmt,
@@ -107,7 +107,7 @@ const FFCodec ff_v408_encoder = {
     CODEC_LONG_NAME("Uncompressed packed QT 4:4:4:4"),
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_V408,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .init         = v408_encode_init,
     FF_CODEC_ENCODE_CB(v408_encode_frame),
     .p.pix_fmts   = pix_fmt,
diff --git a/libavcodec/v410enc.c b/libavcodec/v410enc.c
index bad13c371a..89ee3a7278 100644
--- a/libavcodec/v410enc.c
+++ b/libavcodec/v410enc.c
@@ -79,7 +79,7 @@ const FFCodec ff_v410_encoder = {
     CODEC_LONG_NAME("Uncompressed 4:4:4 10-bit"),
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_V410,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .init         = v410_encode_init,
     FF_CODEC_ENCODE_CB(v410_encode_frame),
     .p.pix_fmts   = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV444P10, AV_PIX_FMT_NONE },
diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c
index 5ef93cd102..cb7588b94b 100644
--- a/libavcodec/vaapi_encode_mjpeg.c
+++ b/libavcodec/vaapi_encode_mjpeg.c
@@ -574,7 +574,8 @@ const FFCodec ff_mjpeg_vaapi_encoder = {
     FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet),
     .close          = &vaapi_encode_mjpeg_close,
     .p.priv_class   = &vaapi_encode_mjpeg_class,
-    .p.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DR1 |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal  = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
                       FF_CODEC_CAP_INIT_CLEANUP,
     .defaults       = vaapi_encode_mjpeg_defaults,
diff --git a/libavcodec/vbnenc.c b/libavcodec/vbnenc.c
index 45101382a3..7ce91863d7 100644
--- a/libavcodec/vbnenc.c
+++ b/libavcodec/vbnenc.c
@@ -153,7 +153,8 @@ const FFCodec ff_vbn_encoder = {
     CODEC_LONG_NAME("Vizrt Binary Image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_VBN,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .p.priv_class   = &vbnenc_class,
     .init           = vbn_init,
     FF_CODEC_ENCODE_CB(vbn_encode),
diff --git a/libavcodec/vc2enc.c b/libavcodec/vc2enc.c
index 82d11462aa..d978c67a3b 100644
--- a/libavcodec/vc2enc.c
+++ b/libavcodec/vc2enc.c
@@ -1228,7 +1228,8 @@ const FFCodec ff_vc2_encoder = {
     CODEC_LONG_NAME("SMPTE VC-2"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_DIRAC,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
     .priv_data_size = sizeof(VC2EncContext),
     .init           = vc2_encode_init,
diff --git a/libavcodec/wavpackenc.c b/libavcodec/wavpackenc.c
index bdb536382f..3d2d45360d 100644
--- a/libavcodec/wavpackenc.c
+++ b/libavcodec/wavpackenc.c
@@ -2963,7 +2963,8 @@ const FFCodec ff_wavpack_encoder = {
     CODEC_LONG_NAME("WavPack"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_WAVPACK,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(WavPackEncodeContext),
     .p.priv_class   = &wavpack_encoder_class,
     .init           = wavpack_encode_init,
diff --git a/libavcodec/wbmpenc.c b/libavcodec/wbmpenc.c
index 25fac746fc..abb66b4ca9 100644
--- a/libavcodec/wbmpenc.c
+++ b/libavcodec/wbmpenc.c
@@ -80,7 +80,8 @@ const FFCodec ff_wbmp_encoder = {
     CODEC_LONG_NAME("WBMP (Wireless Application Protocol Bitmap) image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_WBMP,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     FF_CODEC_ENCODE_CB(wbmp_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]){
         AV_PIX_FMT_MONOBLACK,
diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c
index 2c647af13b..80ff696be6 100644
--- a/libavcodec/wmaenc.c
+++ b/libavcodec/wmaenc.c
@@ -440,7 +440,7 @@ const FFCodec ff_wmav1_encoder = {
     CODEC_LONG_NAME("Windows Media Audio 1"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_WMAV1,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(WMACodecContext),
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_superframe),
@@ -456,7 +456,7 @@ const FFCodec ff_wmav2_encoder = {
     CODEC_LONG_NAME("Windows Media Audio 2"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_WMAV2,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(WMACodecContext),
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_superframe),
diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index 05f993525d..6d991909fb 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -242,6 +242,7 @@ const FFCodec ff_wmv2_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_WMV2,
     .p.priv_class   = &ff_mpv_enc_class,
+    .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(WMV2EncContext),
     .init           = wmv2_encode_init,
     FF_CODEC_ENCODE_CB(ff_mpv_encode_picture),
diff --git a/libavcodec/wrapped_avframe.c b/libavcodec/wrapped_avframe.c
index c9579848e6..0278ea42ba 100644
--- a/libavcodec/wrapped_avframe.c
+++ b/libavcodec/wrapped_avframe.c
@@ -109,6 +109,7 @@ const FFCodec ff_wrapped_avframe_encoder = {
     CODEC_LONG_NAME("AVFrame to AVPacket passthrough"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_WRAPPED_AVFRAME,
+    .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     FF_CODEC_ENCODE_CB(wrapped_avframe_encode),
 };
 
diff --git a/libavcodec/xbmenc.c b/libavcodec/xbmenc.c
index 664c6599bf..cd8b73afa3 100644
--- a/libavcodec/xbmenc.c
+++ b/libavcodec/xbmenc.c
@@ -82,7 +82,7 @@ const FFCodec ff_xbm_encoder = {
     CODEC_LONG_NAME("XBM (X BitMap) image"),
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_XBM,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     FF_CODEC_ENCODE_CB(xbm_encode_frame),
     .p.pix_fmts   = (const enum AVPixelFormat[]) { AV_PIX_FMT_MONOWHITE,
                                                    AV_PIX_FMT_NONE },
diff --git a/libavcodec/xfaceenc.c b/libavcodec/xfaceenc.c
index 7125f1f085..4998d42ea5 100644
--- a/libavcodec/xfaceenc.c
+++ b/libavcodec/xfaceenc.c
@@ -216,7 +216,7 @@ const FFCodec ff_xface_encoder = {
     CODEC_LONG_NAME("X-face image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_XFACE,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_MONOWHITE, AV_PIX_FMT_NONE },
     .priv_data_size = sizeof(XFaceContext),
     FF_CODEC_ENCODE_CB(xface_encode_frame),
diff --git a/libavcodec/xwdenc.c b/libavcodec/xwdenc.c
index 6c588f3acc..08554d8632 100644
--- a/libavcodec/xwdenc.c
+++ b/libavcodec/xwdenc.c
@@ -216,7 +216,7 @@ const FFCodec ff_xwd_encoder = {
     CODEC_LONG_NAME("XWD (X Window Dump) image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_XWD,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     FF_CODEC_ENCODE_CB(xwd_encode_frame),
     .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGRA,
                                                  AV_PIX_FMT_RGBA,
diff --git a/libavcodec/y41penc.c b/libavcodec/y41penc.c
index d3ef88c2ce..e86769da66 100644
--- a/libavcodec/y41penc.c
+++ b/libavcodec/y41penc.c
@@ -82,7 +82,7 @@ const FFCodec ff_y41p_encoder = {
     CODEC_LONG_NAME("Uncompressed YUV 4:1:1 12-bit"),
     .p.type       = AVMEDIA_TYPE_VIDEO,
     .p.id         = AV_CODEC_ID_Y41P,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .init         = y41p_encode_init,
     FF_CODEC_ENCODE_CB(y41p_encode_frame),
     .p.pix_fmts   = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P,
diff --git a/libavcodec/yuv4enc.c b/libavcodec/yuv4enc.c
index 27e786dd54..8123260d5d 100644
--- a/libavcodec/yuv4enc.c
+++ b/libavcodec/yuv4enc.c
@@ -64,7 +64,7 @@ const FFCodec ff_yuv4_encoder = {
     CODEC_LONG_NAME("Uncompressed packed 4:2:0"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_YUV4,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
     FF_CODEC_ENCODE_CB(yuv4_encode_frame),
 };
diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c
index c12f783d5a..d20330568d 100644
--- a/libavcodec/zmbvenc.c
+++ b/libavcodec/zmbvenc.c
@@ -416,7 +416,7 @@ const FFCodec ff_zmbv_encoder = {
     CODEC_LONG_NAME("Zip Motion Blocks Video"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_ZMBV,
-    .p.capabilities = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(ZmbvEncContext),
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_frame),
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 18/30] lavc/encode: pass through frame durations to encoded packets
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (15 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 17/30] lavc: support AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE in all no-delay encoders Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 19/30] lavc/librav1e: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE Anton Khirnov
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

The generic code can only handle the no-delay case. Encoders with delay
need to be handled individually, which will be done in the following
commits.
---
 doc/APIchanges             |  2 +-
 libavcodec/avcodec.h       |  7 +++++++
 libavcodec/encode.c        | 14 ++++++++++++--
 libavcodec/options_table.h |  1 +
 4 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index a3c9819e32..4ae5571f71 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,7 +15,7 @@ libavutil:     2021-04-27
 API changes, most recent first:
 
 2022-12-xx - xxxxxxxxxx - lavc 59.55.100 - avcodec.h
-  Add AV_CODEC_FLAG_COPY_OPAQUE.
+  Add AV_CODEC_FLAG_COPY_OPAQUE and AV_CODEC_FLAG_FRAME_DURATION.
 
 2022-11-xx - xxxxxxxxxx - lavu 57.43.100 - tx.h
   Add AV_TX_FLOAT_DCT, AV_TX_DOUBLE_DCT and AV_TX_INT32_DCT.
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 79558786ee..a31d413179 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -249,6 +249,13 @@ typedef struct RcOverride{
  * @ref AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability flag.
  */
 #define AV_CODEC_FLAG_COPY_OPAQUE     (1 <<  7)
+/**
+ * Signal to the encoder that the values of AVFrame.duration are valid and
+ * should be used (typically for transferring them to output packets).
+ *
+ * If this flag is not set, frame durations are ignored.
+ */
+#define AV_CODEC_FLAG_FRAME_DURATION  (1 <<  8)
 /**
  * Use internal 2pass ratecontrol in first pass mode.
  */
diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index e4270b6c34..00b7a7dde8 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -215,10 +215,13 @@ int ff_encode_encode_cb(AVCodecContext *avctx, AVPacket *avpkt,
             if (avpkt->pts == AV_NOPTS_VALUE)
                 avpkt->pts = frame->pts;
 
-            if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {
-                if (!avpkt->duration)
+            if (!avpkt->duration) {
+                if (frame->duration)
+                    avpkt->duration = frame->duration;
+                else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {
                     avpkt->duration = ff_samples_to_time_base(avctx,
                                                               frame->nb_samples);
+                }
             }
 
             avctx->reordered_opaque = frame->reordered_opaque;
@@ -454,6 +457,13 @@ FF_ENABLE_DEPRECATION_WARNINGS
             return ret;
     }
 
+    // unset frame duration unless AV_CODEC_FLAG_FRAME_DURATION is set,
+    // since otherwise we cannot be sure that whatever value it has is in the
+    // right timebase, so we would produce an incorrect value, which is worse
+    // than none at all
+    if (!(avctx->flags & AV_CODEC_FLAG_FRAME_DURATION))
+        dst->duration = 0;
+
     return 0;
 }
 
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index ad41dc7bed..011314db96 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -59,6 +59,7 @@ static const AVOption avcodec_options[] = {
 {"qscale", "use fixed qscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, "flags"},
 {"recon_frame", "export reconstructed frames", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_RECON_FRAME}, .unit = "flags"},
 {"copy_opaque", "propagate opaque values", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_COPY_OPAQUE}, .unit = "flags"},
+{"frame_duration", "use frame durations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_FRAME_DURATION}, .unit = "flags"},
 {"pass1", "use internal 2-pass ratecontrol in first  pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, "flags"},
 {"pass2", "use internal 2-pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"},
 {"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"},
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 19/30] lavc/librav1e: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (16 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 18/30] lavc/encode: pass through frame durations to encoded packets Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 20/30] lavc/nvenc: " Anton Khirnov
                   ` (10 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/librav1e.c | 61 +++++++++++++++++++++++++++++++++++++------
 1 file changed, 53 insertions(+), 8 deletions(-)

diff --git a/libavcodec/librav1e.c b/libavcodec/librav1e.c
index 4f424caf5b..669bfd5428 100644
--- a/libavcodec/librav1e.c
+++ b/libavcodec/librav1e.c
@@ -22,6 +22,7 @@
 
 #include <rav1e.h>
 
+#include "libavutil/buffer.h"
 #include "libavutil/internal.h"
 #include "libavutil/avassert.h"
 #include "libavutil/base64.h"
@@ -53,6 +54,15 @@ typedef struct librav1eContext {
     int tile_cols;
 } librav1eContext;
 
+typedef struct FrameData {
+    int64_t pts;
+    int64_t duration;
+    int64_t reordered_opaque;
+
+    void        *frame_opaque;
+    AVBufferRef *frame_opaque_ref;
+} FrameData;
+
 static inline RaPixelRange range_map(enum AVPixelFormat pix_fmt, enum AVColorRange range)
 {
     switch (pix_fmt) {
@@ -420,11 +430,23 @@ end:
     return ret;
 }
 
+static void frame_data_free(void *data)
+{
+    FrameData *fd = data;
+
+    if (!fd)
+        return;
+
+    av_buffer_unref(&fd->frame_opaque_ref);
+    av_free(data);
+}
+
 static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
 {
     librav1eContext *ctx = avctx->priv_data;
     RaFrame *rframe = ctx->rframe;
     RaPacket *rpkt = NULL;
+    FrameData *fd;
     int ret;
 
     if (!rframe) {
@@ -437,18 +459,30 @@ static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
         if (frame->buf[0]) {
             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
 
-            int64_t *pts = av_malloc(sizeof(int64_t));
-            if (!pts) {
+            fd = av_mallocz(sizeof(*fd));
+            if (!fd) {
                 av_log(avctx, AV_LOG_ERROR, "Could not allocate PTS buffer.\n");
                 return AVERROR(ENOMEM);
             }
-            *pts = frame->pts;
+            fd->pts      = frame->pts;
+            fd->duration = frame->duration;
+            fd->reordered_opaque = frame->reordered_opaque;
+
+            fd->frame_opaque = frame->opaque;
+            if (frame->opaque_ref && avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+                fd->frame_opaque_ref = av_buffer_ref(frame->opaque_ref);
+                if (!fd->frame_opaque_ref) {
+                    frame_data_free(fd);
+                    av_frame_unref(frame);
+                    return AVERROR(ENOMEM);
+                }
+            }
 
             rframe = rav1e_frame_new(ctx->ctx);
             if (!rframe) {
                 av_log(avctx, AV_LOG_ERROR, "Could not allocate new rav1e frame.\n");
                 av_frame_unref(frame);
-                av_freep(&pts);
+                frame_data_free(fd);
                 return AVERROR(ENOMEM);
             }
 
@@ -460,7 +494,7 @@ static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
                                        frame->linesize[i], bytes);
             }
             av_frame_unref(frame);
-            rav1e_frame_set_opaque(rframe, pts, av_free);
+            rav1e_frame_set_opaque(rframe, fd, frame_data_free);
         }
     }
 
@@ -536,8 +570,18 @@ retry:
     if (rpkt->frame_type == RA_FRAME_TYPE_KEY)
         pkt->flags |= AV_PKT_FLAG_KEY;
 
-    pkt->pts = pkt->dts = *((int64_t *) rpkt->opaque);
-    av_free(rpkt->opaque);
+    fd = rpkt->opaque;
+    pkt->pts = pkt->dts = fd->pts;
+    pkt->duration = fd->duration;
+    avctx->reordered_opaque = fd->reordered_opaque;
+
+    if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+        pkt->opaque          = fd->frame_opaque;
+        pkt->opaque_ref      = fd->frame_opaque_ref;
+        fd->frame_opaque_ref = NULL;
+    }
+
+    frame_data_free(fd);
 
     if (avctx->flags & AV_CODEC_FLAG_RECON_FRAME) {
         AVCodecInternal *avci = avctx->internal;
@@ -627,7 +671,8 @@ const FFCodec ff_librav1e_encoder = {
     .defaults       = librav1e_defaults,
     .p.pix_fmts     = librav1e_pix_fmts,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS |
-                      AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_RECON_FRAME,
+                      AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_RECON_FRAME |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal  = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
                       FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS,
     .p.wrapper_name = "librav1e",
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 20/30] lavc/nvenc: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (17 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 19/30] lavc/librav1e: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 21/30] lavc/adxenc: rescale packet duration according to timebase Anton Khirnov
                   ` (9 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/nvenc.c      | 102 ++++++++++++++++++++++++++++++++--------
 libavcodec/nvenc.h      |   2 +-
 libavcodec/nvenc_av1.c  |   3 +-
 libavcodec/nvenc_h264.c |   3 +-
 libavcodec/nvenc_hevc.c |   3 +-
 5 files changed, 89 insertions(+), 24 deletions(-)

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 9726c565d3..80f78155f2 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -28,6 +28,7 @@
 #include "av1.h"
 #endif
 
+#include "libavutil/buffer.h"
 #include "libavutil/hwcontext_cuda.h"
 #include "libavutil/hwcontext.h"
 #include "libavutil/cuda_check.h"
@@ -162,6 +163,23 @@ static int nvenc_print_error(AVCodecContext *avctx, NVENCSTATUS err,
     return ret;
 }
 
+typedef struct FrameData {
+    int64_t pts;
+    int64_t duration;
+    int64_t reordered_opaque;
+
+    void        *frame_opaque;
+    AVBufferRef *frame_opaque_ref;
+} FrameData;
+
+static void reorder_queue_flush(AVFifo *queue)
+{
+    FrameData fd;
+
+    while (av_fifo_read(queue, &fd, 1) >= 0)
+        av_buffer_unref(&fd.frame_opaque_ref);
+}
+
 typedef struct GUIDTuple {
     const GUID guid;
     int flags;
@@ -1743,8 +1761,8 @@ static av_cold int nvenc_setup_surfaces(AVCodecContext *avctx)
     if (!ctx->surfaces)
         return AVERROR(ENOMEM);
 
-    ctx->timestamp_list = av_fifo_alloc2(ctx->nb_surfaces, sizeof(int64_t), 0);
-    if (!ctx->timestamp_list)
+    ctx->reorder_queue = av_fifo_alloc2(ctx->nb_surfaces, sizeof(FrameData), 0);
+    if (!ctx->reorder_queue)
         return AVERROR(ENOMEM);
 
     ctx->unused_surface_queue = av_fifo_alloc2(ctx->nb_surfaces, sizeof(NvencSurface*), 0);
@@ -1828,7 +1846,8 @@ av_cold int ff_nvenc_encode_close(AVCodecContext *avctx)
         p_nvenc->nvEncEncodePicture(ctx->nvencoder, &params);
     }
 
-    av_fifo_freep2(&ctx->timestamp_list);
+    reorder_queue_flush(ctx->reorder_queue);
+    av_fifo_freep2(&ctx->reorder_queue);
     av_fifo_freep2(&ctx->output_surface_ready_queue);
     av_fifo_freep2(&ctx->output_surface_queue);
     av_fifo_freep2(&ctx->unused_surface_queue);
@@ -2172,18 +2191,45 @@ static void nvenc_codec_specific_pic_params(AVCodecContext *avctx,
     }
 }
 
-static inline void timestamp_queue_enqueue(AVFifo *queue, int64_t timestamp)
+static void reorder_queue_enqueue(AVFifo *queue, const AVCodecContext *avctx,
+                                  const AVFrame *frame, AVBufferRef **opaque_ref)
 {
-    av_fifo_write(queue, &timestamp, 1);
+    FrameData fd;
+
+    fd.pts              = frame->pts;
+    fd.duration         = frame->duration;
+    fd.reordered_opaque = frame->reordered_opaque;
+    fd.frame_opaque     = frame->opaque;
+    fd.frame_opaque_ref = *opaque_ref;
+
+    *opaque_ref = NULL;
+
+    av_fifo_write(queue, &fd, 1);
 }
 
-static inline int64_t timestamp_queue_dequeue(AVFifo *queue)
+static int64_t reorder_queue_dequeue(AVFifo *queue, AVCodecContext *avctx,
+                                     AVPacket *pkt)
 {
-    int64_t timestamp = AV_NOPTS_VALUE;
+    FrameData fd;
+
     // The following call might fail if the queue is empty.
-    av_fifo_read(queue, &timestamp, 1);
+    if (av_fifo_read(queue, &fd, 1) < 0)
+        return AV_NOPTS_VALUE;
+
+    if (pkt) {
+        avctx->reordered_opaque = fd.reordered_opaque;
+        pkt->duration           = fd.duration;
+
+        if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+            pkt->opaque             = fd.frame_opaque;
+            pkt->opaque_ref         = fd.frame_opaque_ref;
+            fd.frame_opaque_ref     = NULL;
+        }
+    }
+
+    av_buffer_unref(&fd.frame_opaque_ref);
 
-    return timestamp;
+    return fd.pts;
 }
 
 static int nvenc_set_timestamp(AVCodecContext *avctx,
@@ -2191,12 +2237,14 @@ static int nvenc_set_timestamp(AVCodecContext *avctx,
                                AVPacket *pkt)
 {
     NvencContext *ctx = avctx->priv_data;
+    int64_t dts;
 
     pkt->pts = params->outputTimeStamp;
 
+    dts = reorder_queue_dequeue(ctx->reorder_queue, avctx, pkt);
+
     if (avctx->codec_descriptor->props & AV_CODEC_PROP_REORDER) {
-        pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list);
-        pkt->dts -= FFMAX(ctx->encode_config.frameIntervalP - 1, 0) * FFMAX(avctx->ticks_per_frame, 1);
+        pkt->dts = dts - FFMAX(ctx->encode_config.frameIntervalP - 1, 0) * FFMAX(avctx->ticks_per_frame, 1);
     } else {
         pkt->dts = pkt->pts;
     }
@@ -2293,7 +2341,7 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur
     return 0;
 
 error:
-    timestamp_queue_dequeue(ctx->timestamp_list);
+    reorder_queue_dequeue(ctx->reorder_queue, avctx, NULL);
 
 error2:
     return res;
@@ -2523,6 +2571,8 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
     int sei_count = 0;
     int i;
 
+    AVBufferRef *opaque_ref = NULL;
+
     NvencContext *ctx = avctx->priv_data;
     NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
     NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;
@@ -2590,9 +2640,17 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
         pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
     }
 
+    // make a reference for enqueing in the reorder queue here,
+    // so that reorder_queue_enqueue() cannot fail
+    if (frame && frame->opaque_ref && avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+        opaque_ref = av_buffer_ref(frame->opaque_ref);
+        if (!opaque_ref)
+            return AVERROR(ENOMEM);
+    }
+
     res = nvenc_push_context(avctx);
     if (res < 0)
-        return res;
+        goto opaque_ref_fail;
 
     nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);
 
@@ -2601,17 +2659,17 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
 
     res = nvenc_pop_context(avctx);
     if (res < 0)
-        return res;
+        goto opaque_ref_fail;
 
     if (nv_status != NV_ENC_SUCCESS &&
-        nv_status != NV_ENC_ERR_NEED_MORE_INPUT)
-        return nvenc_print_error(avctx, nv_status, "EncodePicture failed!");
+        nv_status != NV_ENC_ERR_NEED_MORE_INPUT) {
+        res = nvenc_print_error(avctx, nv_status, "EncodePicture failed!");
+        goto opaque_ref_fail;
+    }
 
     if (frame && frame->buf[0]) {
         av_fifo_write(ctx->output_surface_queue, &in_surf, 1);
-
-        if (avctx->codec_descriptor->props & AV_CODEC_PROP_REORDER)
-            timestamp_queue_enqueue(ctx->timestamp_list, frame->pts);
+        reorder_queue_enqueue(ctx->reorder_queue, avctx, frame, &opaque_ref);
     }
 
     /* all the pending buffers are now ready for output */
@@ -2621,6 +2679,10 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
     }
 
     return 0;
+
+opaque_ref_fail:
+    av_buffer_unref(&opaque_ref);
+    return res;
 }
 
 int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
@@ -2679,5 +2741,5 @@ av_cold void ff_nvenc_encode_flush(AVCodecContext *avctx)
     NvencContext *ctx = avctx->priv_data;
 
     nvenc_send_frame(avctx, NULL);
-    av_fifo_reset2(ctx->timestamp_list);
+    reorder_queue_flush(ctx->reorder_queue);
 }
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index 05a7ac48b1..411c83aa94 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -171,7 +171,7 @@ typedef struct NvencContext
     AVFifo *unused_surface_queue;
     AVFifo *output_surface_queue;
     AVFifo *output_surface_ready_queue;
-    AVFifo *timestamp_list;
+    AVFifo *reorder_queue;
 
     NV_ENC_SEI_PAYLOAD *sei_data;
     int sei_data_size;
diff --git a/libavcodec/nvenc_av1.c b/libavcodec/nvenc_av1.c
index 2ed99d948b..2b349c7b61 100644
--- a/libavcodec/nvenc_av1.c
+++ b/libavcodec/nvenc_av1.c
@@ -181,7 +181,8 @@ const FFCodec ff_av1_nvenc_encoder = {
     .defaults       = defaults,
     .p.pix_fmts     = ff_nvenc_pix_fmts,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
-                      AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1,
+                      AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1 |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal  = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
                       FF_CODEC_CAP_INIT_CLEANUP,
     .p.wrapper_name = "nvenc",
diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
index a69358b03b..5dc2961c3b 100644
--- a/libavcodec/nvenc_h264.c
+++ b/libavcodec/nvenc_h264.c
@@ -232,7 +232,8 @@ const FFCodec ff_h264_nvenc_encoder = {
     .p.priv_class   = &h264_nvenc_class,
     .defaults       = defaults,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
-                      AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1,
+                      AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1 |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal  = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
                       FF_CODEC_CAP_INIT_CLEANUP,
     .p.pix_fmts     = ff_nvenc_pix_fmts,
diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
index 5ad423444a..1362a927c8 100644
--- a/libavcodec/nvenc_hevc.c
+++ b/libavcodec/nvenc_hevc.c
@@ -214,7 +214,8 @@ const FFCodec ff_hevc_nvenc_encoder = {
     .defaults       = defaults,
     .p.pix_fmts     = ff_nvenc_pix_fmts,
     .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
-                      AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1,
+                      AV_CODEC_CAP_ENCODER_FLUSH | AV_CODEC_CAP_DR1 |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal  = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
                       FF_CODEC_CAP_INIT_CLEANUP,
     .p.wrapper_name = "nvenc",
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 21/30] lavc/adxenc: rescale packet duration according to timebase
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (18 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 20/30] lavc/nvenc: " Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 22/30] lavc/adxenc: support AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE Anton Khirnov
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

The timebase does not always have to be 1/samplerate.
---
 libavcodec/adxenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/adxenc.c b/libavcodec/adxenc.c
index 153c91b852..e1bf344b01 100644
--- a/libavcodec/adxenc.c
+++ b/libavcodec/adxenc.c
@@ -184,7 +184,7 @@ static int adx_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
     }
 
     avpkt->pts = frame->pts;
-    avpkt->duration = frame->nb_samples;
+    avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
     *got_packet_ptr = 1;
     return 0;
 }
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 22/30] lavc/adxenc: support AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (19 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 21/30] lavc/adxenc: rescale packet duration according to timebase Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2023-01-04 16:26   ` Andreas Rheinhardt
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 23/30] lavc/ffv1enc: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE Anton Khirnov
                   ` (7 subsequent siblings)
  28 siblings, 1 reply; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/adxenc.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/libavcodec/adxenc.c b/libavcodec/adxenc.c
index e1bf344b01..9e0ceb61eb 100644
--- a/libavcodec/adxenc.c
+++ b/libavcodec/adxenc.c
@@ -185,6 +185,18 @@ static int adx_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
     avpkt->pts = frame->pts;
     avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
+
+    if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+        avpkt->opaque = frame->opaque;
+        if (frame->opaque_ref) {
+            avpkt->opaque_ref = av_buffer_ref(frame->opaque_ref);
+            if (!avpkt->opaque_ref)
+                return AVERROR(ENOMEM);
+        }
+    }
+
+    avctx->reordered_opaque = frame->reordered_opaque;
+
     *got_packet_ptr = 1;
     return 0;
 }
@@ -194,7 +206,8 @@ const FFCodec ff_adpcm_adx_encoder = {
     CODEC_LONG_NAME("SEGA CRI ADX ADPCM"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_ADPCM_ADX,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(ADXContext),
     .init           = adx_encode_init,
     FF_CODEC_ENCODE_CB(adx_encode_frame),
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 23/30] lavc/ffv1enc: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (20 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 22/30] lavc/adxenc: support AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2023-01-04 17:27   ` Andreas Rheinhardt
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 24/30] lavc/pngenc: " Anton Khirnov
                   ` (6 subsequent siblings)
  28 siblings, 1 reply; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/ffv1enc.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
index 0237ac48eb..553abb558f 100644
--- a/libavcodec/ffv1enc.c
+++ b/libavcodec/ffv1enc.c
@@ -1233,7 +1233,20 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     pkt->size   = buf_p - pkt->data;
     pkt->pts    =
     pkt->dts    = pict->pts;
+    pkt->duration = pict->duration;
     pkt->flags |= AV_PKT_FLAG_KEY * f->key_frame;
+
+    if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+        pkt->opaque = pict->opaque;
+        if (pict->opaque_ref) {
+            pkt->opaque_ref = av_buffer_ref(pict->opaque_ref);
+            if (!pkt->opaque_ref)
+                return AVERROR(ENOMEM);
+        }
+    }
+
+    avctx->reordered_opaque = pict->reordered_opaque;
+
     *got_packet = 1;
 
     return 0;
@@ -1272,7 +1285,8 @@ const FFCodec ff_ffv1_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_FFV1,
     .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
-                      AV_CODEC_CAP_SLICE_THREADS,
+                      AV_CODEC_CAP_SLICE_THREADS            |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(FFV1Context),
     .init           = encode_init,
     FF_CODEC_ENCODE_CB(encode_frame),
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 24/30] lavc/pngenc: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (21 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 23/30] lavc/ffv1enc: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 25/30] lavc/pngenc: stop setting dts unnecessarily for APNG Anton Khirnov
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/pngenc.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index d1448bd0cd..a54cfcdd69 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -977,6 +977,19 @@ static int encode_apng(AVCodecContext *avctx, AVPacket *pkt,
 
         memcpy(pkt->data, s->last_frame_packet, s->last_frame_packet_size);
         pkt->pts = pkt->dts = s->last_frame->pts;
+        pkt->duration = s->last_frame->duration;
+
+        if (s->last_frame->opaque_ref &&
+            avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+            pkt->opaque = s->last_frame->opaque;
+            if (s->last_frame->opaque_ref) {
+                pkt->opaque_ref = av_buffer_ref(s->last_frame->opaque_ref);
+                if (!pkt->opaque_ref)
+                    return AVERROR(ENOMEM);
+            }
+        }
+
+        avctx->reordered_opaque = s->last_frame->reordered_opaque;
     }
 
     if (pict) {
@@ -1219,7 +1232,8 @@ const FFCodec ff_apng_encoder = {
     CODEC_LONG_NAME("APNG (Animated Portable Network Graphics) image"),
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_APNG,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .priv_data_size = sizeof(PNGEncContext),
     .init           = png_enc_init,
     .close          = png_enc_close,
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 25/30] lavc/pngenc: stop setting dts unnecessarily for APNG
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (22 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 24/30] lavc/pngenc: " Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 26/30] lavc/libtheoraenc: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE Anton Khirnov
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

APNG is not marked as supporting reordering, so dts will be set from pts
by the generic code.
---
 libavcodec/pngenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index a54cfcdd69..009874cef5 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -976,7 +976,7 @@ static int encode_apng(AVCodecContext *avctx, AVPacket *pkt,
             return ret;
 
         memcpy(pkt->data, s->last_frame_packet, s->last_frame_packet_size);
-        pkt->pts = pkt->dts = s->last_frame->pts;
+        pkt->pts = s->last_frame->pts;
         pkt->duration = s->last_frame->duration;
 
         if (s->last_frame->opaque_ref &&
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 26/30] lavc/libtheoraenc: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (23 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 25/30] lavc/pngenc: stop setting dts unnecessarily for APNG Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 27/30] lavc/libtheoraenc: stop setting dts unnecessarily Anton Khirnov
                   ` (3 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libtheoraenc.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/libavcodec/libtheoraenc.c b/libavcodec/libtheoraenc.c
index da16c6372e..9b8404ce31 100644
--- a/libavcodec/libtheoraenc.c
+++ b/libavcodec/libtheoraenc.c
@@ -347,6 +347,19 @@ static int encode_frame(AVCodecContext* avc_context, AVPacket *pkt,
     // HACK: assumes no encoder delay, this is true until libtheora becomes
     // multithreaded (which will be disabled unless explicitly requested)
     pkt->pts = pkt->dts = frame->pts;
+    pkt->duration = frame->duration;
+
+    if (avc_context->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+        pkt->opaque = frame->opaque;
+        if (frame->opaque_ref) {
+            pkt->opaque_ref = av_buffer_ref(frame->opaque_ref);
+            if (!pkt->opaque_ref)
+                return AVERROR(ENOMEM);
+        }
+    }
+
+    avc_context->reordered_opaque = frame->reordered_opaque;
+
     if (!(o_packet.granulepos & h->keyframe_mask))
         pkt->flags |= AV_PKT_FLAG_KEY;
     *got_packet = 1;
@@ -373,7 +386,9 @@ const FFCodec ff_libtheora_encoder = {
     .p.type         = AVMEDIA_TYPE_VIDEO,
     .p.id           = AV_CODEC_ID_THEORA,
     .p.capabilities = AV_CODEC_CAP_DR1 |
-                      AV_CODEC_CAP_DELAY /* for statsfile summary */,
+                      /* for statsfile summary */
+                      AV_CODEC_CAP_DELAY |
+                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
     .caps_internal  = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
     .priv_data_size = sizeof(TheoraContext),
     .init           = encode_init,
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 27/30] lavc/libtheoraenc: stop setting dts unnecessarily
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (24 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 26/30] lavc/libtheoraenc: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 28/30] lavc/libx264: pass through frame durations to encoded packets Anton Khirnov
                   ` (2 subsequent siblings)
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

Theora is not marked as supporting reordering, so dts will be set from
pts by the generic code.
---
 libavcodec/libtheoraenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/libtheoraenc.c b/libavcodec/libtheoraenc.c
index 9b8404ce31..e36a948511 100644
--- a/libavcodec/libtheoraenc.c
+++ b/libavcodec/libtheoraenc.c
@@ -346,7 +346,7 @@ static int encode_frame(AVCodecContext* avc_context, AVPacket *pkt,
 
     // HACK: assumes no encoder delay, this is true until libtheora becomes
     // multithreaded (which will be disabled unless explicitly requested)
-    pkt->pts = pkt->dts = frame->pts;
+    pkt->pts = frame->pts;
     pkt->duration = frame->duration;
 
     if (avc_context->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 28/30] lavc/libx264: pass through frame durations to encoded packets
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (25 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 27/30] lavc/libtheoraenc: stop setting dts unnecessarily Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 29/30] lavc/libx265: " Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 30/30] lavc/libaomenc: " Anton Khirnov
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libx264.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 8944a7df36..b87db78fb4 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -52,6 +52,7 @@
 typedef struct X264Opaque {
     int64_t reordered_opaque;
     int64_t wallclock;
+    int64_t duration;
 
     void        *frame_opaque;
     AVBufferRef *frame_opaque_ref;
@@ -461,6 +462,7 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame *frame,
     }
 
     opaque->reordered_opaque = frame->reordered_opaque;
+    opaque->duration         = frame->duration;
     opaque->wallclock = wallclock;
     if (ctx->export_side_data & AV_CODEC_EXPORT_DATA_PRFT)
         opaque->wallclock = av_gettime();
@@ -614,6 +616,7 @@ 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;
+        pkt->duration = out_opaque->duration;
 
         if (ctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
             pkt->opaque                  = out_opaque->frame_opaque;
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 29/30] lavc/libx265: pass through frame durations to encoded packets
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (26 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 28/30] lavc/libx264: pass through frame durations to encoded packets Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 30/30] lavc/libaomenc: " Anton Khirnov
  28 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libx265.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c
index 7ba547a7e7..088ddef3fc 100644
--- a/libavcodec/libx265.c
+++ b/libavcodec/libx265.c
@@ -43,6 +43,7 @@
 
 typedef struct ReorderedData {
     int64_t reordered_opaque;
+    int64_t duration;
 
     void        *frame_opaque;
     AVBufferRef *frame_opaque_ref;
@@ -616,6 +617,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         }
         rd = &ctx->rd[rd_idx];
 
+        rd->duration         = pic->duration;
         rd->reordered_opaque = pic->reordered_opaque;
         rd->frame_opaque     = pic->opaque;
         if (pic->opaque_ref && avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
@@ -754,6 +756,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         ReorderedData *rd = &ctx->rd[idx];
 
         avctx->reordered_opaque = rd->reordered_opaque;
+        pkt->duration           = rd->duration;
 
         if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
             pkt->opaque          = rd->frame_opaque;
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [FFmpeg-devel] [PATCH 30/30] lavc/libaomenc: pass through frame durations to encoded packets
  2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
                   ` (27 preceding siblings ...)
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 29/30] lavc/libx265: " Anton Khirnov
@ 2022-11-27 17:03 ` Anton Khirnov
  2022-11-27 20:19   ` James Almer
  28 siblings, 1 reply; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 17:03 UTC (permalink / raw)
  To: ffmpeg-devel

---
 libavcodec/libaomenc.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
index bd576fdd3a..c117ca4ee6 100644
--- a/libavcodec/libaomenc.c
+++ b/libavcodec/libaomenc.c
@@ -1094,6 +1094,7 @@ static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame,
     }
     memcpy(pkt->data, cx_frame->buf, pkt->size);
     pkt->pts = pkt->dts = cx_frame->pts;
+    pkt->duration = cx_frame->duration;
 
     if (!!(cx_frame->flags & AOM_FRAME_IS_KEY)) {
         pkt->flags |= AV_PKT_FLAG_KEY;
@@ -1275,6 +1276,7 @@ static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
     AOMContext *ctx = avctx->priv_data;
     struct aom_image *rawimg = NULL;
     int64_t timestamp = 0;
+    unsigned long duration = 0;
     int res, coded_size;
     aom_enc_frame_flags_t flags = 0;
 
@@ -1287,6 +1289,8 @@ static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
         rawimg->stride[AOM_PLANE_U] = frame->linesize[1];
         rawimg->stride[AOM_PLANE_V] = frame->linesize[2];
         timestamp                   = frame->pts;
+        duration                    = frame->duration ? frame->duration :
+                                        avctx->ticks_per_frame;
         switch (frame->color_range) {
         case AVCOL_RANGE_MPEG:
             rawimg->range = AOM_CR_STUDIO_RANGE;
@@ -1300,8 +1304,7 @@ static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
             flags |= AOM_EFLAG_FORCE_KF;
     }
 
-    res = aom_codec_encode(&ctx->encoder, rawimg, timestamp,
-                           avctx->ticks_per_frame, flags);
+    res = aom_codec_encode(&ctx->encoder, rawimg, timestamp, duration, flags);
     if (res != AOM_CODEC_OK) {
         log_encoder_error(avctx, "Error encoding frame");
         return AVERROR_INVALIDDATA;
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [FFmpeg-devel] [PATCH 17/30] lavc: support AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE in all no-delay encoders
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 17/30] lavc: support AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE in all no-delay encoders Anton Khirnov
@ 2022-11-27 17:43   ` Michael Niedermayer
  2022-11-27 19:43     ` Anton Khirnov
  2022-11-27 20:00   ` James Almer
  1 sibling, 1 reply; 37+ messages in thread
From: Michael Niedermayer @ 2022-11-27 17:43 UTC (permalink / raw)
  To: FFmpeg development discussions and patches


[-- Attachment #1.1: Type: text/plain, Size: 1135 bytes --]

On Sun, Nov 27, 2022 at 06:03:38PM +0100, Anton Khirnov wrote:
> ---
[...]
> diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c
> index 9ef6e16bc5..0787b5c313 100644
> --- a/libavcodec/libilbc.c
> +++ b/libavcodec/libilbc.c
> @@ -126,7 +126,8 @@ const FFCodec ff_libilbc_decoder = {
                                               ^^^^^^^

>      .priv_data_size = sizeof(ILBCDecContext),
>      .init           = ilbc_decode_init,
>      FF_CODEC_DECODE_CB(ilbc_decode_frame),
                               ^^^^^^
> -    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
> +    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF |
> +                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,

I think you changed the wrong instance

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Old school: Use the lowest level language in which you can solve the problem
            conveniently.
New school: Use the highest level language in which the latest supercomputer
            can solve the problem without the user falling asleep waiting.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

[-- Attachment #2: Type: text/plain, Size: 251 bytes --]

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [FFmpeg-devel] [PATCH 17/30] lavc: support AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE in all no-delay encoders
  2022-11-27 17:43   ` Michael Niedermayer
@ 2022-11-27 19:43     ` Anton Khirnov
  0 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2022-11-27 19:43 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

Quoting Michael Niedermayer (2022-11-27 18:43:49)
> On Sun, Nov 27, 2022 at 06:03:38PM +0100, Anton Khirnov wrote:
> > ---
> [...]
> > diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c
> > index 9ef6e16bc5..0787b5c313 100644
> > --- a/libavcodec/libilbc.c
> > +++ b/libavcodec/libilbc.c
> > @@ -126,7 +126,8 @@ const FFCodec ff_libilbc_decoder = {
>                                                ^^^^^^^
> 
> >      .priv_data_size = sizeof(ILBCDecContext),
> >      .init           = ilbc_decode_init,
> >      FF_CODEC_DECODE_CB(ilbc_decode_frame),
>                                ^^^^^^
> > -    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
> > +    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF |
> > +                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
> 
> I think you changed the wrong instance

Good catch, fixed locally.
Of course it happens on one of the few codecs disabled in my builds.

-- 
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [FFmpeg-devel] [PATCH 17/30] lavc: support AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE in all no-delay encoders
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 17/30] lavc: support AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE in all no-delay encoders Anton Khirnov
  2022-11-27 17:43   ` Michael Niedermayer
@ 2022-11-27 20:00   ` James Almer
  1 sibling, 0 replies; 37+ messages in thread
From: James Almer @ 2022-11-27 20:00 UTC (permalink / raw)
  To: ffmpeg-devel

On 11/27/2022 2:03 PM, Anton Khirnov wrote:
> diff --git a/libavcodec/encode.c b/libavcodec/encode.c
> index 7e2d54ae9b..e4270b6c34 100644
> --- a/libavcodec/encode.c
> +++ b/libavcodec/encode.c
> @@ -220,6 +220,18 @@ int ff_encode_encode_cb(AVCodecContext *avctx, AVPacket *avpkt,
>                       avpkt->duration = ff_samples_to_time_base(avctx,
>                                                                 frame->nb_samples);
>               }
> +
> +            avctx->reordered_opaque = frame->reordered_opaque;
> +            if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
> +                avpkt->opaque = frame->opaque;
> +                if (frame->opaque_ref) {
> +                    avpkt->opaque_ref = av_buffer_ref(frame->opaque_ref);
> +                    if (!avpkt->opaque_ref) {
> +                        ret = AVERROR(ENOMEM);
> +                        goto unref;
> +                    }
> +                }

You could simplify this to simply

ret = av_buffer_replace(&avpkt->opaque_ref, frame->opaque_ref);
if (ret < 0)
     return ret;

Here and elsewhere you did the same thing. No need to check for 
frame->opaque_ref since av_buffer_replace() can handle NULL src, in 
which case for this scenario (where avpkt->opaque_ref is always NULL) it 
will be a no-op.

> +            }
>           }
>   
>           // dts equals pts unless there is reordering
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [FFmpeg-devel] [PATCH 30/30] lavc/libaomenc: pass through frame durations to encoded packets
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 30/30] lavc/libaomenc: " Anton Khirnov
@ 2022-11-27 20:19   ` James Almer
  2023-01-04 16:15     ` Anton Khirnov
  0 siblings, 1 reply; 37+ messages in thread
From: James Almer @ 2022-11-27 20:19 UTC (permalink / raw)
  To: ffmpeg-devel

On 11/27/2022 2:03 PM, Anton Khirnov wrote:
> ---
>   libavcodec/libaomenc.c | 7 +++++--
>   1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
> index bd576fdd3a..c117ca4ee6 100644
> --- a/libavcodec/libaomenc.c
> +++ b/libavcodec/libaomenc.c
> @@ -1094,6 +1094,7 @@ static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame,
>       }
>       memcpy(pkt->data, cx_frame->buf, pkt->size);
>       pkt->pts = pkt->dts = cx_frame->pts;
> +    pkt->duration = cx_frame->duration;
>   
>       if (!!(cx_frame->flags & AOM_FRAME_IS_KEY)) {
>           pkt->flags |= AV_PKT_FLAG_KEY;
> @@ -1275,6 +1276,7 @@ static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
>       AOMContext *ctx = avctx->priv_data;
>       struct aom_image *rawimg = NULL;
>       int64_t timestamp = 0;
> +    unsigned long duration = 0;

Why does aom_codec_encode() take an unsigned long as argument for this 
when timestamp is int64_t...

>       int res, coded_size;
>       aom_enc_frame_flags_t flags = 0;
>   
> @@ -1287,6 +1289,8 @@ static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
>           rawimg->stride[AOM_PLANE_U] = frame->linesize[1];
>           rawimg->stride[AOM_PLANE_V] = frame->linesize[2];
>           timestamp                   = frame->pts;
> +        duration                    = frame->duration ? frame->duration :
> +                                        avctx->ticks_per_frame;

Extremely unlikely, but on 32bit targets and Win64 this could end up in 
a truncated value.

>           switch (frame->color_range) {
>           case AVCOL_RANGE_MPEG:
>               rawimg->range = AOM_CR_STUDIO_RANGE;
> @@ -1300,8 +1304,7 @@ static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
>               flags |= AOM_EFLAG_FORCE_KF;
>       }
>   
> -    res = aom_codec_encode(&ctx->encoder, rawimg, timestamp,
> -                           avctx->ticks_per_frame, flags);
> +    res = aom_codec_encode(&ctx->encoder, rawimg, timestamp, duration, flags);
>       if (res != AOM_CODEC_OK) {
>           log_encoder_error(avctx, "Error encoding frame");
>           return AVERROR_INVALIDDATA;
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [FFmpeg-devel] [PATCH 30/30] lavc/libaomenc: pass through frame durations to encoded packets
  2022-11-27 20:19   ` James Almer
@ 2023-01-04 16:15     ` Anton Khirnov
  0 siblings, 0 replies; 37+ messages in thread
From: Anton Khirnov @ 2023-01-04 16:15 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

Quoting James Almer (2022-11-27 21:19:33)
> On 11/27/2022 2:03 PM, Anton Khirnov wrote:
> > ---
> >   libavcodec/libaomenc.c | 7 +++++--
> >   1 file changed, 5 insertions(+), 2 deletions(-)
> > 
> > diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
> > index bd576fdd3a..c117ca4ee6 100644
> > --- a/libavcodec/libaomenc.c
> > +++ b/libavcodec/libaomenc.c
> > @@ -1094,6 +1094,7 @@ static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame,
> >       }
> >       memcpy(pkt->data, cx_frame->buf, pkt->size);
> >       pkt->pts = pkt->dts = cx_frame->pts;
> > +    pkt->duration = cx_frame->duration;
> >   
> >       if (!!(cx_frame->flags & AOM_FRAME_IS_KEY)) {
> >           pkt->flags |= AV_PKT_FLAG_KEY;
> > @@ -1275,6 +1276,7 @@ static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
> >       AOMContext *ctx = avctx->priv_data;
> >       struct aom_image *rawimg = NULL;
> >       int64_t timestamp = 0;
> > +    unsigned long duration = 0;
> 
> Why does aom_codec_encode() take an unsigned long as argument for this 
> when timestamp is int64_t...

the ways of AOM are mysterious

> 
> >       int res, coded_size;
> >       aom_enc_frame_flags_t flags = 0;
> >   
> > @@ -1287,6 +1289,8 @@ static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
> >           rawimg->stride[AOM_PLANE_U] = frame->linesize[1];
> >           rawimg->stride[AOM_PLANE_V] = frame->linesize[2];
> >           timestamp                   = frame->pts;
> > +        duration                    = frame->duration ? frame->duration :
> > +                                        avctx->ticks_per_frame;
> 
> Extremely unlikely, but on 32bit targets and Win64 this could end up in 
> a truncated value.

I'll add a check.

-- 
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [FFmpeg-devel] [PATCH 22/30] lavc/adxenc: support AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 22/30] lavc/adxenc: support AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE Anton Khirnov
@ 2023-01-04 16:26   ` Andreas Rheinhardt
  0 siblings, 0 replies; 37+ messages in thread
From: Andreas Rheinhardt @ 2023-01-04 16:26 UTC (permalink / raw)
  To: ffmpeg-devel

Anton Khirnov:
> ---
>  libavcodec/adxenc.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/libavcodec/adxenc.c b/libavcodec/adxenc.c
> index e1bf344b01..9e0ceb61eb 100644
> --- a/libavcodec/adxenc.c
> +++ b/libavcodec/adxenc.c
> @@ -185,6 +185,18 @@ static int adx_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
>  
>      avpkt->pts = frame->pts;
>      avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
> +
> +    if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
> +        avpkt->opaque = frame->opaque;
> +        if (frame->opaque_ref) {
> +            avpkt->opaque_ref = av_buffer_ref(frame->opaque_ref);
> +            if (!avpkt->opaque_ref)
> +                return AVERROR(ENOMEM);
> +        }
> +    }
> +
> +    avctx->reordered_opaque = frame->reordered_opaque;

I don't like that you are adding this piece of code both here, in
encode.c, in ffv1enc.c, in pngenc.c and libtheoraenc.c. Why don't you
factor this out?

> +
>      *got_packet_ptr = 1;
>      return 0;
>  }
> @@ -194,7 +206,8 @@ const FFCodec ff_adpcm_adx_encoder = {
>      CODEC_LONG_NAME("SEGA CRI ADX ADPCM"),
>      .p.type         = AVMEDIA_TYPE_AUDIO,
>      .p.id           = AV_CODEC_ID_ADPCM_ADX,
> -    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
> +    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
> +                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
>      .priv_data_size = sizeof(ADXContext),
>      .init           = adx_encode_init,
>      FF_CODEC_ENCODE_CB(adx_encode_frame),

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [FFmpeg-devel] [PATCH 23/30] lavc/ffv1enc: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
  2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 23/30] lavc/ffv1enc: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE Anton Khirnov
@ 2023-01-04 17:27   ` Andreas Rheinhardt
  0 siblings, 0 replies; 37+ messages in thread
From: Andreas Rheinhardt @ 2023-01-04 17:27 UTC (permalink / raw)
  To: ffmpeg-devel

Anton Khirnov:
> ---
>  libavcodec/ffv1enc.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
> index 0237ac48eb..553abb558f 100644
> --- a/libavcodec/ffv1enc.c
> +++ b/libavcodec/ffv1enc.c
> @@ -1233,7 +1233,20 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
>      pkt->size   = buf_p - pkt->data;
>      pkt->pts    =
>      pkt->dts    = pict->pts;
> +    pkt->duration = pict->duration;
>      pkt->flags |= AV_PKT_FLAG_KEY * f->key_frame;
> +
> +    if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
> +        pkt->opaque = pict->opaque;
> +        if (pict->opaque_ref) {
> +            pkt->opaque_ref = av_buffer_ref(pict->opaque_ref);
> +            if (!pkt->opaque_ref)
> +                return AVERROR(ENOMEM);
> +        }
> +    }
> +
> +    avctx->reordered_opaque = pict->reordered_opaque;
> +
>      *got_packet = 1;
>  
>      return 0;
> @@ -1272,7 +1285,8 @@ const FFCodec ff_ffv1_encoder = {
>      .p.type         = AVMEDIA_TYPE_VIDEO,
>      .p.id           = AV_CODEC_ID_FFV1,
>      .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
> -                      AV_CODEC_CAP_SLICE_THREADS,
> +                      AV_CODEC_CAP_SLICE_THREADS            |
> +                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
>      .priv_data_size = sizeof(FFV1Context),
>      .init           = encode_init,
>      FF_CODEC_ENCODE_CB(encode_frame),

FFV1's does not have frame reordering (no AV_CODEC_PROP_REORDER for the
codec descriptor); the encoder just has the AV_CODEC_CAP_DELAY set to
write stats in case this was the first pass of a two-pass encoding (this
could actually be moved . Otherwise the encoder is a simple
one-in-one-out encoder with no delay at all. Something similar is true
for the FLAC encoder (it has the DELAY cap so that it can output a
side-data only packet with updated extradata when flushing) and adxenc.
Maybe we should have an internal capability to allow to set these
properties generically for these codecs, too?

- Andreas

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2023-01-04 17:26 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-27 17:03 [FFmpeg-devel] [PATCH 01/30] lavc/libx264: factor out setting up the input frame Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 02/30] lavc/libx264: reindent after previous commit Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 03/30] lavc/libx264: use a local variable for input frame in setup_frame() Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 04/30] lavc/libx264: factor out setting up ROI Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 05/30] lavc/libx264: reindent after previous commit Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 06/30] lavc/libx264: unify cleanup in setup_frame() Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 07/30] lavc/libx264: do not ignore memory allocation errors Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 08/30] lavc/libx264: reindent after previous commit Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 09/30] lavc/libx264: reorder control flow in setup_roi() to reduce nesting depth Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 10/30] lavc/libx264: reindent after previous commit Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 11/30] lavc/libx264: use a local variable to shorten code Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 12/30] lavc/libx264: print an error on invalid opaque pointer Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 13/30] lavc/libx264: zero reordered opaque on alloc Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 14/30] lavc/libx264: do not leave an invalid array size on alloc error Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 15/30] lavc/libx265: restructure handling reordered_opaque Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 16/30] lavc: add a codec flag for propagating opaque from frames to packets Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 17/30] lavc: support AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE in all no-delay encoders Anton Khirnov
2022-11-27 17:43   ` Michael Niedermayer
2022-11-27 19:43     ` Anton Khirnov
2022-11-27 20:00   ` James Almer
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 18/30] lavc/encode: pass through frame durations to encoded packets Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 19/30] lavc/librav1e: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 20/30] lavc/nvenc: " Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 21/30] lavc/adxenc: rescale packet duration according to timebase Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 22/30] lavc/adxenc: support AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE Anton Khirnov
2023-01-04 16:26   ` Andreas Rheinhardt
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 23/30] lavc/ffv1enc: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE Anton Khirnov
2023-01-04 17:27   ` Andreas Rheinhardt
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 24/30] lavc/pngenc: " Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 25/30] lavc/pngenc: stop setting dts unnecessarily for APNG Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 26/30] lavc/libtheoraenc: handle frame durations and AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 27/30] lavc/libtheoraenc: stop setting dts unnecessarily Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 28/30] lavc/libx264: pass through frame durations to encoded packets Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 29/30] lavc/libx265: " Anton Khirnov
2022-11-27 17:03 ` [FFmpeg-devel] [PATCH 30/30] lavc/libaomenc: " Anton Khirnov
2022-11-27 20:19   ` James Almer
2023-01-04 16:15     ` Anton Khirnov

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git