Commit c7ad544c1f for ffmpeg

commit c7ad544c1fa32fc7ecac55174d045368243d8e9d
Author: Kacper Michajłow <kasper93@gmail.com>
Date:   Sun Sep 27 16:04:59 2026 +0200

    swresample/rematrix: don't check channels that are only reordered

    Layouts with the same channels in another order need a matrix, but
    nothing is mixed. The checks for channels that can be mixed rejected
    them anyway, for example BL+BR to BR+BL.

    Signed-off-by: Kacper Michajłow <kasper93@gmail.com>

diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c
index 252a28603e..3bec10360e 100644
--- a/libswresample/rematrix.c
+++ b/libswresample/rematrix.c
@@ -154,7 +154,7 @@ static void clean_downmix(AVChannelLayout *ch_layout, const AVChannelLayout *oth
     }
 }

-static int sane_layout(const AVChannelLayout *ch_layout) {
+static int sane_layout(const AVChannelLayout *ch_layout, int mixed) {
     if(ch_layout->nb_channels > SWR_CH_MAX)
         return 0;
     if(ch_layout->order == AV_CHANNEL_ORDER_CUSTOM)
@@ -168,6 +168,8 @@ static int sane_layout(const AVChannelLayout *ch_layout) {
         }
     else if (ch_layout->order != AV_CHANNEL_ORDER_NATIVE)
         return 0;
+    if (!mixed)
+        return 1;
     uint64_t mask = av_channel_layout_subset(ch_layout, ~(uint64_t)0);
     if(!(mask & AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker
         return 0;
@@ -618,7 +620,7 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL
                               double rematrix_volume, double *matrix_param,
                               ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding, void *log_context)
 {
-    int i, j, ret;
+    int i, j, ret, mixed;
     AVChannelLayout in_ch_layout = { 0 }, out_ch_layout = { 0 };
     char buf[128];

@@ -630,12 +632,16 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL
     clean_downmix(&out_ch_layout, &in_ch_layout);
     clean_downmix(&in_ch_layout, &out_ch_layout);

+    /* the same channels on both sides change their places at most */
+    mixed = av_channel_layout_subset(&in_ch_layout,  ~(uint64_t)0) !=
+            av_channel_layout_subset(&out_ch_layout, ~(uint64_t)0);
+
     if(!av_channel_layout_check(&in_ch_layout)) {
         av_log(log_context, AV_LOG_ERROR, "Input channel layout is invalid\n");
         ret = AVERROR(EINVAL);
         goto fail;
     }
-    if(!sane_layout(&in_ch_layout)) {
+    if(!sane_layout(&in_ch_layout, mixed)) {
         av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf));
         av_log(log_context, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf);
         ret = AVERROR(EINVAL);
@@ -647,7 +653,7 @@ av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelL
         ret = AVERROR(EINVAL);
         goto fail;
     }
-    if(!sane_layout(&out_ch_layout)) {
+    if(!sane_layout(&out_ch_layout, mixed)) {
         av_channel_layout_describe(&out_ch_layout, buf, sizeof(buf));
         av_log(log_context, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf);
         ret = AVERROR(EINVAL);
diff --git a/tests/fate/libswresample.mak b/tests/fate/libswresample.mak
index 71f8335cca..27a48a790b 100644
--- a/tests/fate/libswresample.mak
+++ b/tests/fate/libswresample.mak
@@ -1173,6 +1173,14 @@ FATE_SWR_REMATRIX-$(CONFIG_SWRESAMPLE) += fate-swr-rematrix-unused-64
 fate-swr-rematrix-unused-64: libswresample/tests/rematrix$(EXESUF)
 fate-swr-rematrix-unused-64: CMD = run libswresample/tests/rematrix$(EXESUF) 5.1 $(FATE_SWR_UNUSED_31)+FL+FR+$(FATE_SWR_UNUSED_31)

+FATE_SWR_REMATRIX-$(CONFIG_SWRESAMPLE) += fate-swr-rematrix-reorder
+fate-swr-rematrix-reorder: libswresample/tests/rematrix$(EXESUF)
+fate-swr-rematrix-reorder: CMD = run libswresample/tests/rematrix$(EXESUF) BL+BR BR+BL
+
+FATE_SWR_REMATRIX-$(CONFIG_SWRESAMPLE) += fate-swr-rematrix-reorder-unused
+fate-swr-rematrix-reorder-unused: libswresample/tests/rematrix$(EXESUF)
+fate-swr-rematrix-reorder-unused: CMD = run libswresample/tests/rematrix$(EXESUF) FC+UNSD+FL FL+FC+UNSD
+
 FATE_SWR += $(FATE_SWR_REMATRIX-yes)
 fate-swr-rematrix: $(FATE_SWR_REMATRIX-yes)

diff --git a/tests/ref/fate/swr-rematrix-reorder b/tests/ref/fate/swr-rematrix-reorder
new file mode 100644
index 0000000000..b80b9f3c05
--- /dev/null
+++ b/tests/ref/fate/swr-rematrix-reorder
@@ -0,0 +1,2 @@
+[BR] = { .BL = 0.000000, .BR = 1.000000, },
+[BL] = { .BL = 1.000000, .BR = 0.000000, },
diff --git a/tests/ref/fate/swr-rematrix-reorder-unused b/tests/ref/fate/swr-rematrix-reorder-unused
new file mode 100644
index 0000000000..2db5a874a8
--- /dev/null
+++ b/tests/ref/fate/swr-rematrix-reorder-unused
@@ -0,0 +1,3 @@
+[FL] = { .FC = 0.000000, .UNSD1 = 0.000000, .FL = 1.000000, },
+[FC] = { .FC = 1.000000, .UNSD1 = 0.000000, .FL = 0.000000, },
+[UNSD2] = { .FC = 0.000000, .UNSD1 = 0.000000, .FL = 0.000000, },