From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
To: ffmpeg-devel@ffmpeg.org
Subject: Re: [FFmpeg-devel] [PATCH 1/5] avformat/matroskaenc: Support rotations
Date: Wed, 9 Aug 2023 11:26:11 +0200
Message-ID: <AS8P250MB0744C4272A07E6257ED4201E8F12A@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM> (raw)
In-Reply-To: <AS8P250MB0744E8BE1C2515319ABA75A08F0FA@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM>
Andreas Rheinhardt:
> Matroska supports orthogonal transformations (both pure rotations
> as well as reflections) via its 3D-projection elements, namely
> ProjectionPoseYaw (for a horizontal reflection) as well as
> ProjectionPoseRoll (for rotations). This commit adds support
> for this.
>
> Support for this in the demuxer has been added in
> 937bb6bbc1e8654633737e69e403e95a37113058 and
> the sample used in the matroska-dovi-write-config8 FATE-test
> includes a displaymatrix indicating a rotation which is now
> properly written and read, thereby providing coverage for
> the relevant code in the muxer as well as the demuxer.
>
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
> ---
> Honestly, I am not really sure how to handle the floating-point
> inaccuracies here (in atan2).
>
> libavformat/matroskaenc.c | 100 +++++++++++++++++----
> tests/ref/fate/matroska-dovi-write-config8 | 13 ++-
> 2 files changed, 94 insertions(+), 19 deletions(-)
>
> diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
> index 41e13b273d..c1f40b26e6 100644
> --- a/libavformat/matroskaenc.c
> +++ b/libavformat/matroskaenc.c
> @@ -1403,25 +1403,75 @@ static void mkv_write_video_color(EbmlWriter *writer, const AVStream *st,
> }
>
> #define MAX_VIDEO_PROJECTION_ELEMS 6
> -static void mkv_write_video_projection(AVFormatContext *s, EbmlWriter *writer,
> - const AVStream *st, uint8_t private[])
> +static void mkv_handle_rotation(void *logctx, const AVStream *st,
> + double *yaw, double *roll)
> +{
> + const int32_t *matrix =
> + (const int32_t*)av_stream_get_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
> +
> + if (!matrix)
> + return;
> +
> + /* Check whether this is an affine transformation */
> + if (matrix[2] || matrix[5])
> + goto ignore;
> +
> + /* This together with the checks below test whether
> + * the upper-left 2x2 matrix is nonsingular. */
> + if (!matrix[0] && !matrix[1])
> + goto ignore;
> +
> + /* We ignore the translation part of the matrix (matrix[6] and matrix[7])
> + * as well as any scaling, i.e. we only look at the upper left 2x2 matrix.
> + * We only accept matrices that are an exact multiple of an orthogonal one.
> + * Apart from the multiple, every such matrix can be obtained by
> + * potentially flipping in the x-direction (corresponding to yaw = 180)
> + * followed by a rotation of (say) an angle phi in the counterclockwise
> + * direction. The upper-left 2x2 matrix then looks like this:
> + * | (+/-)cos(phi) (-/+)sin(phi) |
> + * scale * | |
> + * | sin(phi) cos(phi) |
> + * The first set of signs in the first row apply in case of no flipping,
> + * the second set applies in case of flipping. */
> +
> + /* The casts to int64_t are needed because -INT32_MIN doesn't fit
> + * in an int32_t. */
> + if (matrix[0] == matrix[4] && -(int64_t)matrix[1] == matrix[3]) {
> + /* No flipping case */
> + *yaw = 0;
> + } else if (-(int64_t)matrix[0] == matrix[4] && matrix[1] == matrix[3]) {
> + /* Horizontal flip */
> + *yaw = 180;
> + } else {
> +ignore:
> + av_log(logctx, AV_LOG_INFO, "Ignoring display matrix indicating "
> + "non-orthogonal transformation.\n");
> + return;
> + }
> + *roll = 180 / M_PI * atan2(matrix[3], matrix[4]);
> +
> + /* We do not write a ProjectionType element indicating "rectangular",
> + * because this is the default value. */
> +}
> +
> +static int mkv_handle_spherical(void *logctx, EbmlWriter *writer,
> + const AVStream *st, uint8_t private[],
> + double *yaw, double *pitch, double *roll)
> {
> const AVSphericalMapping *spherical =
> (const AVSphericalMapping *)av_stream_get_side_data(st, AV_PKT_DATA_SPHERICAL,
> NULL);
>
> if (!spherical)
> - return;
> + return 0;
>
> if (spherical->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
> spherical->projection != AV_SPHERICAL_EQUIRECTANGULAR_TILE &&
> spherical->projection != AV_SPHERICAL_CUBEMAP) {
> - av_log(s, AV_LOG_WARNING, "Unknown projection type\n");
> - return;
> + av_log(logctx, AV_LOG_WARNING, "Unknown projection type\n");
> + return 0;
> }
>
> - ebml_writer_open_master(writer, MATROSKA_ID_VIDEOPROJECTION);
> -
> switch (spherical->projection) {
> case AV_SPHERICAL_EQUIRECTANGULAR:
> case AV_SPHERICAL_EQUIRECTANGULAR_TILE:
> @@ -1455,17 +1505,33 @@ static void mkv_write_video_projection(AVFormatContext *s, EbmlWriter *writer,
> av_assert0(0);
> }
>
> - if (spherical->yaw)
> - ebml_writer_add_float(writer, MATROSKA_ID_VIDEOPROJECTIONPOSEYAW,
> - (double) spherical->yaw / (1 << 16));
> - if (spherical->pitch)
> - ebml_writer_add_float(writer, MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH,
> - (double) spherical->pitch / (1 << 16));
> - if (spherical->roll)
> - ebml_writer_add_float(writer, MATROSKA_ID_VIDEOPROJECTIONPOSEROLL,
> - (double) spherical->roll / (1 << 16));
> + *yaw = (double) spherical->yaw / (1 << 16);
> + *pitch = (double) spherical->pitch / (1 << 16);
> + *roll = (double) spherical->roll / (1 << 16);
>
> - ebml_writer_close_master(writer);
> + return 1; /* Projection included */
> +}
> +
> +static void mkv_write_video_projection(void *logctx, EbmlWriter *wr,
> + const AVStream *st, uint8_t private[])
> +{
> + double yaw = 0, pitch = 0, roll = 0;
> + int ret;
> +
> + ebml_writer_open_master(wr, MATROSKA_ID_VIDEOPROJECTION);
> +
> + ret = mkv_handle_spherical(logctx, wr, st, private, &yaw, &pitch, &roll);
> + if (!ret)
> + mkv_handle_rotation(logctx, st, &yaw, &roll);
> +
> + if (yaw)
> + ebml_writer_add_float(wr, MATROSKA_ID_VIDEOPROJECTIONPOSEYAW, yaw);
> + if (pitch)
> + ebml_writer_add_float(wr, MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH, pitch);
> + if (roll)
> + ebml_writer_add_float(wr, MATROSKA_ID_VIDEOPROJECTIONPOSEROLL, roll);
> +
> + ebml_writer_close_or_discard_master(wr);
> }
>
> #define MAX_FIELD_ORDER_ELEMS 2
> diff --git a/tests/ref/fate/matroska-dovi-write-config8 b/tests/ref/fate/matroska-dovi-write-config8
> index bb22563eee..58eb454865 100644
> --- a/tests/ref/fate/matroska-dovi-write-config8
> +++ b/tests/ref/fate/matroska-dovi-write-config8
> @@ -1,5 +1,5 @@
> -09ff3c0a038eec0cdf4773929b24f41a *tests/data/fate/matroska-dovi-write-config8.matroska
> -3600606 tests/data/fate/matroska-dovi-write-config8.matroska
> +80d2b23a6f27ab28b02a907b37b9649c *tests/data/fate/matroska-dovi-write-config8.matroska
> +3600620 tests/data/fate/matroska-dovi-write-config8.matroska
> #extradata 0: 551, 0xa18acf66
> #extradata 1: 2, 0x00340022
> #tb 0: 1/1000
> @@ -46,6 +46,15 @@
> 1, 395, 395, 23, 439, 0x7d85e4c9
> [STREAM]
> [SIDE_DATA]
> +side_data_type=Display Matrix
> +displaymatrix=
> +00000000: 0 65536 0
> +00000001: -65536 0 0
> +00000002: 0 0 1073741824
> +
> +rotation=-90
> +[/SIDE_DATA]
> +[SIDE_DATA]
> side_data_type=DOVI configuration record
> dv_version_major=1
> dv_version_minor=0
Will apply patches 1-5 of this patchset tomorrow unless there are
objections. Notice that I slightly modified the test added in 3/5 to now
also set a creation_time metadata to test a previously untested codepath.
- 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".
prev parent reply other threads:[~2023-08-09 9:25 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-06 23:04 Andreas Rheinhardt
2023-08-06 23:06 ` [FFmpeg-devel] [PATCH 2/5] avformat/matroskaenc: Don't reserve unnecessarily many EBML elements Andreas Rheinhardt
2023-08-06 23:06 ` [FFmpeg-devel] [PATCH 3/5] fate/matroska: Add ALAC remux test Andreas Rheinhardt
2023-08-06 23:06 ` [FFmpeg-devel] [PATCH 4/5] avformat/matroskaenc: Don't pretend to support unsupported codecs Andreas Rheinhardt
2023-08-06 23:06 ` [FFmpeg-devel] [PATCH 5/5] avformat/matroskaenc: Don't pretend to be able to mux RV30 Andreas Rheinhardt
2023-08-08 16:40 ` [FFmpeg-devel] [PATCH 06/15] avformat/matroskaenc: Hoist check out of loop Andreas Rheinhardt
2023-08-10 7:48 ` Andreas Rheinhardt
2023-08-08 16:40 ` [FFmpeg-devel] [PATCH 07/15] avformat/matroskaenc: Remove unnecessary check Andreas Rheinhardt
2023-08-08 16:40 ` [FFmpeg-devel] [PATCH 08/15] avformat/matroskaenc: Use proper AVIOContext Andreas Rheinhardt
2023-08-08 16:40 ` [FFmpeg-devel] [PATCH 09/15] avformat/matroskaenc: Use dedicated pointer for accesses Andreas Rheinhardt
2023-08-08 16:40 ` [FFmpeg-devel] [PATCH 10/15] avformat/matroskaenc: Avoid allocations when writing Dynamic HDR10+ Andreas Rheinhardt
2023-08-08 16:40 ` [FFmpeg-devel] [PATCH 11/15] avformat/dovi_isom: Don't use AVFormatContext* for logctx Andreas Rheinhardt
2023-08-08 16:40 ` [FFmpeg-devel] [PATCH 12/15] avformat/matroskaenc: Add const where appropriate Andreas Rheinhardt
2023-08-08 16:40 ` [FFmpeg-devel] [PATCH 13/15] avformat/matroskaenc: Don't reserve space for HDR10+ when unnecessary Andreas Rheinhardt
2023-08-08 16:40 ` [FFmpeg-devel] [PATCH 14/15] avformat/matroskaenc: Reindent after the previous commit Andreas Rheinhardt
2023-08-08 16:40 ` [FFmpeg-devel] [PATCH 15/15] avformat/matroskaenc: Don't write \0 unnecessarily Andreas Rheinhardt
2023-08-09 9:26 ` Andreas Rheinhardt [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=AS8P250MB0744C4272A07E6257ED4201E8F12A@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM \
--to=andreas.rheinhardt@outlook.com \
--cc=ffmpeg-devel@ffmpeg.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
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