This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit 70e948e2e502c310e5854b961303b8babb2ae065
Author:     Kacper Michajłow <[email protected]>
AuthorDate: Sun Sep 27 16:03:32 2026 +0200
Commit:     Kacper Michajłow <[email protected]>
CommitDate: Tue Sep 29 22:15:33 2026 +0200

    swresample/rematrix: recognize the stereo downmix pair in custom layouts
    
    The pair is mixed like stereo if the other side has no such channels.
    It was only recognized as the native layout, so a custom layout with
    the pair in another order or next to unused channels was rejected for
    the lack of a front channel.
    
    Signed-off-by: Kacper Michajłow <[email protected]>
---
 libswresample/rematrix.c                   | 36 ++++++++++++++++++++----------
 tests/fate/libswresample.mak               |  8 +++++++
 tests/ref/fate/swr-rematrix-downmix-input  |  6 +++++
 tests/ref/fate/swr-rematrix-downmix-output |  3 +++
 4 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c
index fa976b7f7c..7a0ea88682 100644
--- a/libswresample/rematrix.c
+++ b/libswresample/rematrix.c
@@ -132,6 +132,28 @@ static int clean_layout(AVChannelLayout *out, const 
AVChannelLayout *in, void *s
     return 0;
 }
 
+/**
+ * Stereo downmix channels are mixed like stereo, unless the other layout has
+ * such channels as well. The channels keep their places.
+ */
+static void clean_downmix(AVChannelLayout *ch_layout, const AVChannelLayout 
*other)
+{
+    if (av_channel_layout_subset(ch_layout, ~(uint64_t)0) != 
AV_CH_LAYOUT_STEREO_DOWNMIX ||
+        av_channel_layout_subset(other, AV_CH_LAYOUT_STEREO_DOWNMIX))
+        return;
+
+    if (ch_layout->order == AV_CHANNEL_ORDER_NATIVE) {
+        ch_layout->u.mask = AV_CH_LAYOUT_STEREO;
+    } else if (ch_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
+        for (int i = 0; i < ch_layout->nb_channels; i++) {
+            if (ch_layout->u.map[i].id == AV_CHAN_STEREO_LEFT)
+                ch_layout->u.map[i].id = AV_CHAN_FRONT_LEFT;
+            else if (ch_layout->u.map[i].id == AV_CHAN_STEREO_RIGHT)
+                ch_layout->u.map[i].id = AV_CHAN_FRONT_RIGHT;
+        }
+    }
+}
+
 static int sane_layout(const AVChannelLayout *ch_layout) {
     if(ch_layout->nb_channels >= SWR_CH_MAX)
         return 0;
@@ -605,18 +627,8 @@ av_cold int swr_build_matrix2(const AVChannelLayout 
*in_layout, const AVChannelL
     if (ret < 0)
         goto fail;
 
-    if(   !av_channel_layout_compare(&out_ch_layout, 
&(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX)
-       && !av_channel_layout_subset(&in_ch_layout, AV_CH_LAYOUT_STEREO_DOWNMIX)
-    ) {
-        av_channel_layout_uninit(&out_ch_layout);
-        out_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
-    }
-    if(   !av_channel_layout_compare(&in_ch_layout, 
&(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX)
-       && !av_channel_layout_subset(&out_ch_layout, 
AV_CH_LAYOUT_STEREO_DOWNMIX)
-    ) {
-        av_channel_layout_uninit(&in_ch_layout);
-        in_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
-    }
+    clean_downmix(&out_ch_layout, &in_ch_layout);
+    clean_downmix(&in_ch_layout, &out_ch_layout);
 
     if(!av_channel_layout_check(&in_ch_layout)) {
         av_log(log_context, AV_LOG_ERROR, "Input channel layout is invalid\n");
diff --git a/tests/fate/libswresample.mak b/tests/fate/libswresample.mak
index e918bd7b46..98cd890e38 100644
--- a/tests/fate/libswresample.mak
+++ b/tests/fate/libswresample.mak
@@ -1158,6 +1158,14 @@ FATE_SWR_REMATRIX-$(CONFIG_SWRESAMPLE) += 
fate-swr-rematrix-unused-mono-output
 fate-swr-rematrix-unused-mono-output: libswresample/tests/rematrix$(EXESUF)
 fate-swr-rematrix-unused-mono-output: CMD = run 
libswresample/tests/rematrix$(EXESUF) stereo UNSD+FR
 
+FATE_SWR_REMATRIX-$(CONFIG_SWRESAMPLE) += fate-swr-rematrix-downmix-input
+fate-swr-rematrix-downmix-input: libswresample/tests/rematrix$(EXESUF)
+fate-swr-rematrix-downmix-input: CMD = run 
libswresample/tests/rematrix$(EXESUF) DR+DL 5.1
+
+FATE_SWR_REMATRIX-$(CONFIG_SWRESAMPLE) += fate-swr-rematrix-downmix-output
+fate-swr-rematrix-downmix-output: libswresample/tests/rematrix$(EXESUF)
+fate-swr-rematrix-downmix-output: CMD = run 
libswresample/tests/rematrix$(EXESUF) 5.1 DR+UNSD+DL
+
 FATE_SWR += $(FATE_SWR_REMATRIX-yes)
 fate-swr-rematrix: $(FATE_SWR_REMATRIX-yes)
 
diff --git a/tests/ref/fate/swr-rematrix-downmix-input 
b/tests/ref/fate/swr-rematrix-downmix-input
new file mode 100644
index 0000000000..254405fb7a
--- /dev/null
+++ b/tests/ref/fate/swr-rematrix-downmix-input
@@ -0,0 +1,6 @@
+[FL] = { .DR = 0.000000, .DL = 1.000000, },
+[FR] = { .DR = 1.000000, .DL = 0.000000, },
+[FC] = { .DR = 0.000000, .DL = 0.000000, },
+[LFE] = { .DR = 0.000000, .DL = 0.000000, },
+[BL] = { .DR = 0.000000, .DL = 0.000000, },
+[BR] = { .DR = 0.000000, .DL = 0.000000, },
diff --git a/tests/ref/fate/swr-rematrix-downmix-output 
b/tests/ref/fate/swr-rematrix-downmix-output
new file mode 100644
index 0000000000..a96b879ca9
--- /dev/null
+++ b/tests/ref/fate/swr-rematrix-downmix-output
@@ -0,0 +1,3 @@
+[DR] = { .FL = 0.000000, .FR = 1.000000, .FC = 0.707107, .LFE = 0.000000, .BL 
= 0.000000, .BR = 0.707107, },
+[UNSD1] = { .FL = 0.000000, .FR = 0.000000, .FC = 0.000000, .LFE = 0.000000, 
.BL = 0.000000, .BR = 0.000000, },
+[DL] = { .FL = 1.000000, .FR = 0.000000, .FC = 0.707107, .LFE = 0.000000, .BL 
= 0.707107, .BR = 0.000000, },

-- 
To stop receiving notification emails like this one, please contact
[email protected].
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to