[FFmpeg-devel] [PATCH v2 11/18] h264_metadata_bsf: Simplify display orientation handling

Mark Thompson sw at jkqxz.net
Sun Feb 21 21:51:18 EET 2021


The case where the user supplies new value directly as options still
requires a bit of special handling.
---
 libavcodec/h264_metadata_bsf.c | 118 ++++++---------------------------
 1 file changed, 21 insertions(+), 97 deletions(-)

diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
index 6673a32601..6511c4b776 100644
--- a/libavcodec/h264_metadata_bsf.c
+++ b/libavcodec/h264_metadata_bsf.c
@@ -25,6 +25,7 @@
 #include "cbs.h"
 #include "cbs_bsf.h"
 #include "cbs_h264.h"
+#include "cbs_metadata.h"
 #include "h264.h"
 #include "h264_levels.h"
 #include "h264_sei.h"
@@ -75,7 +76,6 @@ typedef struct H264MetadataContext {
     int display_orientation;
     double rotate;
     int flip;
-    H264RawSEIDisplayOrientation display_orientation_payload;
 
     int level;
 } H264MetadataContext;
@@ -328,122 +328,46 @@ static int h264_metadata_handle_display_orientation(AVBSFContext *bsf,
                                                     int seek_point)
 {
     H264MetadataContext *ctx = bsf->priv_data;
-    SEIRawMessage *message;
     int err;
 
-    message = NULL;
-    while (ff_cbs_sei_find_message(ctx->common.output, au,
-                                   SEI_TYPE_DISPLAY_ORIENTATION,
-                                   &message) == 0) {
-        H264RawSEIDisplayOrientation *disp = message->payload;
-        int32_t *matrix;
-
-        matrix = av_malloc(9 * sizeof(int32_t));
-        if (!matrix)
-            return AVERROR(ENOMEM);
-
-        av_display_rotation_set(matrix,
-                                disp->anticlockwise_rotation *
-                                180.0 / 65536.0);
-        av_display_matrix_flip(matrix, disp->hor_flip, disp->ver_flip);
-
-        // If there are multiple display orientation messages in an
-        // access unit, then the last one added to the packet (i.e.
-        // the first one in the access unit) will prevail.
-        err = av_packet_add_side_data(pkt, AV_PKT_DATA_DISPLAYMATRIX,
-                                      (uint8_t*)matrix,
-                                      9 * sizeof(int32_t));
-        if (err < 0) {
-            av_log(bsf, AV_LOG_ERROR, "Failed to attach extracted "
-                   "displaymatrix side data to packet.\n");
-            av_free(matrix);
-            return AVERROR(ENOMEM);
-        }
-    }
-
-    if (ctx->display_orientation == BSF_ELEMENT_REMOVE ||
-        ctx->display_orientation == BSF_ELEMENT_INSERT) {
-        ff_cbs_sei_delete_message_type(ctx->common.output, au,
-                                       SEI_TYPE_DISPLAY_ORIENTATION);
-    }
-
-    if (ctx->display_orientation == BSF_ELEMENT_INSERT) {
-        H264RawSEIDisplayOrientation *disp =
-            &ctx->display_orientation_payload;
+    if (ctx->display_orientation != BSF_ELEMENT_INSERT) {
+        err = ff_cbs_bsf_apply_metadata(bsf, pkt, au,
+                                        CBS_METADATA_DISPLAY_MATRIX,
+                                        ctx->display_orientation);
+        if (err < 0)
+            return err;
+    } else {
+        int32_t matrix[9];
         uint8_t *data;
         int size;
         int write = 0;
 
+        ff_cbs_sei_delete_message_type(ctx->common.output, au,
+                                       SEI_TYPE_DISPLAY_ORIENTATION);
+
         data = av_packet_get_side_data(pkt, AV_PKT_DATA_DISPLAYMATRIX, &size);
         if (data && size >= 9 * sizeof(int32_t)) {
-            int32_t matrix[9];
-            double dmatrix[9];
-            int hflip, vflip, i;
-            double scale_x, scale_y, angle;
-
-            memcpy(matrix, data, sizeof(matrix));
-
-            for (i = 0; i < 9; i++)
-                dmatrix[i] = matrix[i] / 65536.0;
-
-            // Extract scale factors.
-            scale_x = hypot(dmatrix[0], dmatrix[3]);
-            scale_y = hypot(dmatrix[1], dmatrix[4]);
-
-            // Select flips to make the main diagonal positive.
-            hflip = dmatrix[0] < 0.0;
-            vflip = dmatrix[4] < 0.0;
-            if (hflip)
-                scale_x = -scale_x;
-            if (vflip)
-                scale_y = -scale_y;
-
-            // Rescale.
-            for (i = 0; i < 9; i += 3) {
-                dmatrix[i]     /= scale_x;
-                dmatrix[i + 1] /= scale_y;
-            }
-
-            // Extract rotation.
-            angle = atan2(dmatrix[3], dmatrix[0]);
-
-            if (!(angle >= -M_PI && angle <= M_PI) ||
-                matrix[2] != 0.0 || matrix[5] != 0.0 ||
-                matrix[6] != 0.0 || matrix[7] != 0.0) {
-                av_log(bsf, AV_LOG_WARNING, "Input display matrix is not "
-                       "representable in H.264 parameters.\n");
-            } else {
-                disp->hor_flip = hflip;
-                disp->ver_flip = vflip;
-                disp->anticlockwise_rotation =
-                    (uint16_t)rint((angle >= 0.0 ? angle
-                                                 : angle + 2 * M_PI) *
-                                   32768.0 / M_PI);
-                write = 1;
-            }
+            memcpy(matrix, data, 9 * sizeof(int32_t));
+            write = 1;
         }
 
         if (seek_point) {
             if (!isnan(ctx->rotate)) {
-                disp->anticlockwise_rotation =
-                    (uint16_t)rint((ctx->rotate >= 0.0 ? ctx->rotate
-                                                       : ctx->rotate + 360.0) *
-                                   65536.0 / 360.0);
+                av_display_rotation_set(matrix, ctx->rotate);
                 write = 1;
             }
             if (ctx->flip) {
-                disp->hor_flip = !!(ctx->flip & FLIP_HORIZONTAL);
-                disp->ver_flip = !!(ctx->flip & FLIP_VERTICAL);
+                av_display_matrix_flip(matrix,
+                                       !!(ctx->flip & FLIP_HORIZONTAL),
+                                       !!(ctx->flip & FLIP_VERTICAL));
                 write = 1;
             }
         }
 
         if (write) {
-            disp->display_orientation_repetition_period = 1;
-
-            err = ff_cbs_sei_add_message(ctx->common.output, au, 1,
-                                         SEI_TYPE_DISPLAY_ORIENTATION,
-                                         disp, NULL);
+            err = ff_cbs_sei_insert_metadata(ctx->common.output, au,
+                                             CBS_METADATA_DISPLAY_MATRIX,
+                                             matrix);
             if (err < 0) {
                 av_log(bsf, AV_LOG_ERROR, "Failed to add display orientation "
                        "SEI message to access unit.\n");
-- 
2.30.0



More information about the ffmpeg-devel mailing list