PR #25168 opened by rajeshgk
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25168
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25168.patch

## Summary

MOV/MP4 files may contain both `sv3d` and `vexu` spherical projection metadata.

Currently, parsing either box unconditionally allocates a new spherical 
mapping, potentially discarding orientation information parsed from the 
preceding box.

This patch reuses the existing spherical mapping when available, preserving 
orientation metadata such as yaw, pitch, and roll.

It also handles conflicting projection information from `vexu` with a warning.

## Changes

- Preserve existing spherical mapping metadata when processing `sv3d` and 
`vexu` boxes.
- Avoid unnecessary replacement of an already allocated spherical mapping.
- Add a FATE regression test covering combined `sv3d` and `vexu` metadata.

## Regression testing

Tested against FFmpeg master.

Before the fix, the reproducer reports:

- Yaw: 0
- Pitch: 0
- Roll: 0

After the fix:

- Yaw: 45
- Pitch: 30
- Roll: 15

Validation completed:

- `make fate-mov-spherical-vexu-orientation` — PASS
- `git diff --check` — PASS
- FFmpeg `patcheck` — PASS (non-blocking advisory)

## FATE sample

The regression test uses `mov/spherical-vexu-orientation.mp4` (1,818 bytes).

SHA-256:
`0010a2578048b8099dd35058b6c14bd7085155d03dd7639308e1eccdbcc733d5`

The sample has been requested for inclusion in the external FFmpeg FATE samples 
repository. Acceptance and availability are pending.

## Related issue

OpenShot/libopenshot#964

Signed-off-by: Rajesh Gopinath Kumar


From 69e2fdb27a9c24c56252fe78e483ad30870fc65a Mon Sep 17 00:00:00 2001
From: Rajesh Gopinath Kumar <[email protected]>
Date: Sun, 18 Oct 2026 00:31:54 -0500
Subject: [PATCH] avformat/mov: preserve spherical metadata across sv3d and
 vexu boxes

MOV files may contain both sv3d and vexu projection metadata.
Currently, parsing either box allocates a new spherical mapping,
potentially discarding metadata parsed from an earlier box.

Reuse the existing spherical mapping when available to preserve
orientation information such as yaw, pitch and roll.

When vexu specifies a conflicting projection, retain the existing
mapping and emit a warning.

Add a FATE regression test covering an MP4 containing both boxes.

Signed-off-by: Rajesh Gopinath Kumar 
<[email protected]>
---
 libavformat/mov.c                             | 25 +++++++++++++------
 tests/fate/mov.mak                            |  5 ++++
 tests/ref/fate/mov-spherical-vexu-orientation |  9 +++++++
 3 files changed, 31 insertions(+), 8 deletions(-)
 create mode 100644 tests/ref/fate/mov-spherical-vexu-orientation

diff --git a/libavformat/mov.c b/libavformat/mov.c
index f7c12922d9..3bdaf3f01b 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -7343,9 +7343,11 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
         return 0;
     }
 
-    sc->spherical = av_spherical_alloc(&sc->spherical_size);
-    if (!sc->spherical)
-        return AVERROR(ENOMEM);
+    if (!sc->spherical) {
+        sc->spherical = av_spherical_alloc(&sc->spherical_size);
+        if (!sc->spherical)
+            return AVERROR(ENOMEM);
+    }
 
     sc->spherical->projection = projection;
 
@@ -7427,11 +7429,18 @@ static int mov_read_vexu_proj(MOVContext *c, 
AVIOContext *pb, MOVAtom atom)
         return AVERROR_INVALIDDATA;
     }
 
-    sc->spherical = av_spherical_alloc(&sc->spherical_size);
-    if (!sc->spherical)
-        return AVERROR(ENOMEM);
-
-    sc->spherical->projection = projection;
+    if (sc->spherical) {
+        if (sc->spherical->projection != projection) {
+            av_log(c->fc, AV_LOG_WARNING,
+                   "Conflicting spherical projection metadata; "
+                   "preserving existing spherical mapping\n");
+        }
+    } else {
+        sc->spherical = av_spherical_alloc(&sc->spherical_size);
+        if (!sc->spherical)
+            return AVERROR(ENOMEM);
+        sc->spherical->projection = projection;
+    }
 
     return 0;
 }
diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak
index e36ddff7ed..741a33c6f0 100644
--- a/tests/fate/mov.mak
+++ b/tests/fate/mov.mak
@@ -62,6 +62,11 @@ fate-ffprobe-show-groups-tmcd: CMD = run 
ffprobe$(PROGSSUF)$(EXESUF) -v error -s
 FATE_MOV_FASTSTART = fate-mov-faststart-4gb-overflow \
 
 FATE_SAMPLES_FFMPEG += $(FATE_MOV-yes) $(FATE_MOV_REMUX-yes)
+# Preserve sv3d orientation when vexu metadata is also present.
+# Requires MOV demuxing, not H.264 decoding.
+FATE_MOV_FFPROBE-$(CONFIG_MOV_DEMUXER) += fate-mov-spherical-vexu-orientation
+fate-mov-spherical-vexu-orientation: CMD = run ffprobe$(PROGSSUF)$(EXESUF) 
-show_entries stream_side_data_list -select_streams v -v 0 
$(TARGET_SAMPLES)/mov/spherical-vexu-orientation.mp4
+
 FATE_SAMPLES_FFPROBE += $(FATE_MOV_FFPROBE-yes)
 FATE_SAMPLES_FASTSTART += $(FATE_MOV_FASTSTART)
 
diff --git a/tests/ref/fate/mov-spherical-vexu-orientation 
b/tests/ref/fate/mov-spherical-vexu-orientation
new file mode 100644
index 0000000000..f12df13b34
--- /dev/null
+++ b/tests/ref/fate/mov-spherical-vexu-orientation
@@ -0,0 +1,9 @@
+[STREAM]
+[SIDE_DATA]
+side_data_type=Spherical Mapping
+projection=equirectangular
+yaw=45
+pitch=30
+roll=15
+[/SIDE_DATA]
+[/STREAM]
-- 
2.54.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to