[FFmpeg-devel] [PATCH 21/27] h264_metadata_bsf: Simplify display orientation handling
Mark Thompson
sw at jkqxz.net
Fri Jan 1 23:35:31 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 f5f439018d..aae91a6e23 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,
- H264_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,
- H264_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,
+ H264_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,
- H264_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.29.2
More information about the ffmpeg-devel
mailing list