[FFmpeg-devel] [PATCH v2 06/18] cbs_h264: Implement fill and extract for display orientation SEI message
Mark Thompson
sw at jkqxz.net
Sun Feb 21 21:51:13 EET 2021
---
libavcodec/cbs_h2645.c | 79 ++++++++++++++++++++++++++++++++++++++++++
libavcodec/cbs_sei.c | 2 ++
2 files changed, 81 insertions(+)
diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c
index ecd2001816..c01d243455 100644
--- a/libavcodec/cbs_h2645.c
+++ b/libavcodec/cbs_h2645.c
@@ -18,6 +18,7 @@
#include "libavutil/attributes.h"
#include "libavutil/avassert.h"
+#include "libavutil/display.h"
#include "libavutil/mastering_display_metadata.h"
#include "bytestream.h"
@@ -1683,6 +1684,83 @@ static const SEIMessageTypeDescriptor cbs_sei_common_types[] = {
SEI_MESSAGE_TYPE_END,
};
+static void cbs_h264_fill_sei_display_orientation
+ (H264RawSEIDisplayOrientation *disp, const int32_t matrix[9])
+{
+ double dmatrix[9];
+ int hflip, vflip, i;
+ double scale_x, scale_y, angle;
+ uint16_t rotation;
+
+ if (matrix[2] != 0 || matrix[5] != 0 ||
+ matrix[6] != 0 || matrix[7] != 0) {
+ // Not representable.
+ goto cancel;
+ }
+
+ 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)) {
+ // Not representable.
+ goto cancel;
+ }
+ if (angle < 0.0)
+ angle += 2 * M_PI;
+ rotation = (uint16_t)lrint(angle * 32768.0 / M_PI);
+
+ if (!hflip && !vflip && rotation == 0) {
+ // This is the identity transformation, so rather than setting
+ // values for a new display orientation we should instead cancel
+ // any previous message.
+ cancel:
+ *disp = (H264RawSEIDisplayOrientation) {
+ .display_orientation_cancel_flag = 1,
+ };
+ } else {
+ *disp = (H264RawSEIDisplayOrientation) {
+ .hor_flip = hflip,
+ .ver_flip = vflip,
+ .anticlockwise_rotation = rotation,
+ .display_orientation_repetition_period = 1,
+ };
+ }
+}
+
+static void cbs_h264_extract_sei_display_orientation
+ (int32_t matrix[9], const H264RawSEIDisplayOrientation *disp)
+{
+ if (disp->display_orientation_cancel_flag) {
+ // Set identity matrix.
+ av_display_rotation_set(matrix, 0.0);
+ } else {
+ av_display_rotation_set(matrix,
+ disp->anticlockwise_rotation *
+ 360.0 / 65536.0);
+ av_display_matrix_flip(matrix, disp->hor_flip, disp->ver_flip);
+ }
+}
+
static const SEIMessageTypeDescriptor cbs_sei_h264_types[] = {
{
SEI_TYPE_BUFFERING_PERIOD,
@@ -1719,6 +1797,7 @@ static const SEIMessageTypeDescriptor cbs_sei_h264_types[] = {
1, 0,
sizeof(H264RawSEIDisplayOrientation),
SEI_MESSAGE_RW(h264, sei_display_orientation),
+ SEI_MESSAGE_FE(h264, sei_display_orientation),
},
SEI_MESSAGE_TYPE_END
};
diff --git a/libavcodec/cbs_sei.c b/libavcodec/cbs_sei.c
index a5990205d0..27b5997e47 100644
--- a/libavcodec/cbs_sei.c
+++ b/libavcodec/cbs_sei.c
@@ -384,6 +384,8 @@ static const SEIMetadata cbs_sei_metadata[] = {
SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME },
{ CBS_METADATA_CONTENT_LIGHT_LEVEL,
SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO },
+ { CBS_METADATA_DISPLAY_MATRIX,
+ SEI_TYPE_DISPLAY_ORIENTATION },
};
static const SEIMessageTypeDescriptor *cbs_sei_find_type_from_metadata
--
2.30.0
More information about the ffmpeg-devel
mailing list