Commit 9ff448c18a for ffmpeg

commit 9ff448c18aea3e20f417ceb4eae814c91feac66e
Author: Kacper Michajłow <kasper93@gmail.com>
Date:   Mon Oct 26 14:41:19 2026 +0100

    swscale/ppc: check the CPU flags outside the AltiVec files

    The PPC init functions run on every CPU to check whether AltiVec and VSX
    are available, so they must not be built with the AltiVec and VSX flags
    that the code next to them needs. Move the checks to swscale.c,
    yuv2rgb.c and yuv2yuv.c, which hold no AltiVec code and call init
    functions in the AltiVec and VSX files after them.

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

diff --git a/libswscale/ppc/Makefile b/libswscale/ppc/Makefile
index 7d28e71bd2..fa786e05a6 100644
--- a/libswscale/ppc/Makefile
+++ b/libswscale/ppc/Makefile
@@ -1,5 +1,7 @@
-OBJS += ppc/swscale_altivec.o                                           \
+OBJS += ppc/swscale.o                                                   \
+        ppc/swscale_altivec.o                                           \
         ppc/yuv2rgb.o                                                   \
         ppc/yuv2rgb_altivec.o                                           \
+        ppc/yuv2yuv.o                                                   \
         ppc/yuv2yuv_altivec.o                                           \
         ppc/swscale_vsx.o
diff --git a/libswscale/ppc/swscale.c b/libswscale/ppc/swscale.c
new file mode 100644
index 0000000000..736babfb2b
--- /dev/null
+++ b/libswscale/ppc/swscale.c
@@ -0,0 +1,33 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/ppc/cpu.h"
+
+#include "libswscale/swscale_internal.h"
+
+av_cold void ff_sws_init_swscale_ppc(SwsInternal *c)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    if (PPC_ALTIVEC(cpu_flags))
+        ff_sws_init_swscale_altivec(c);
+    if (PPC_VSX(cpu_flags))
+        ff_sws_init_swscale_vsx(c);
+}
diff --git a/libswscale/ppc/swscale_altivec.c b/libswscale/ppc/swscale_altivec.c
index 3112c6cb71..2838641755 100644
--- a/libswscale/ppc/swscale_altivec.c
+++ b/libswscale/ppc/swscale_altivec.c
@@ -27,7 +27,6 @@
 #include "libswscale/swscale.h"
 #include "libswscale/swscale_internal.h"
 #include "libavutil/attributes.h"
-#include "libavutil/cpu.h"
 #include "libavutil/intfloat.h"
 #include "yuv2rgb_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
@@ -230,14 +229,11 @@ yuv2plane1_float(yuv2plane1_float_bswap_altivec, uint32_t, BE)

 #endif /* HAVE_ALTIVEC */

-av_cold void ff_sws_init_swscale_ppc(SwsInternal *c)
+av_cold void ff_sws_init_swscale_altivec(SwsInternal *c)
 {
 #if HAVE_ALTIVEC
     enum AVPixelFormat dstFormat = c->opts.dst_format;

-    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
-        return;
-
 #if HAVE_BIGENDIAN
     if (c->srcBpc == 8 && c->dstBpc <= 14) {
         c->hyScale = c->hcScale = hScale_real_altivec;
@@ -280,6 +276,4 @@ av_cold void ff_sws_init_swscale_ppc(SwsInternal *c)
         }
     }
 #endif /* HAVE_ALTIVEC */
-
-    ff_sws_init_swscale_vsx(c);
 }
diff --git a/libswscale/ppc/swscale_vsx.c b/libswscale/ppc/swscale_vsx.c
index 8bbe6cde65..e8c797c3fc 100644
--- a/libswscale/ppc/swscale_vsx.c
+++ b/libswscale/ppc/swscale_vsx.c
@@ -2023,9 +2023,6 @@ av_cold void ff_sws_init_swscale_vsx(SwsInternal *c)
     const int cpu_flags = av_get_cpu_flags();
     const unsigned char power8 = HAVE_POWER8 && cpu_flags & AV_CPU_FLAG_POWER8;

-    if (!(cpu_flags & AV_CPU_FLAG_VSX))
-        return;
-
 #if !HAVE_BIGENDIAN
     if (c->srcBpc == 8) {
         if (c->dstBpc <= 14) {
diff --git a/libswscale/ppc/yuv2rgb.c b/libswscale/ppc/yuv2rgb.c
index a4735b734f..1482214581 100644
--- a/libswscale/ppc/yuv2rgb.c
+++ b/libswscale/ppc/yuv2rgb.c
@@ -19,11 +19,36 @@
 #include "config.h"

 #include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
 #include "libavutil/error.h"
 #include "libavutil/mem.h"
+#include "libavutil/ppc/cpu.h"

 #include "libswscale/swscale_internal.h"

+av_cold SwsFunc ff_yuv2rgb_init_ppc(SwsInternal *c)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    if (PPC_ALTIVEC(cpu_flags))
+        return ff_yuv2rgb_init_altivec(c);
+
+    return NULL;
+}
+
+av_cold void ff_yuv2rgb_init_tables_ppc(SwsInternal *c,
+                                        const int inv_table[4],
+                                        int brightness,
+                                        int contrast,
+                                        int saturation)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    if (PPC_ALTIVEC(cpu_flags))
+        ff_yuv2rgb_init_tables_altivec(c, inv_table, brightness, contrast,
+                                       saturation);
+}
+
 #if HAVE_ALTIVEC
 av_cold int ff_sws_init_altivec_bufs(SwsInternal *c)
 {
diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
index 7822ff102a..c75f8833a0 100644
--- a/libswscale/ppc/yuv2rgb_altivec.c
+++ b/libswscale/ppc/yuv2rgb_altivec.c
@@ -95,7 +95,6 @@
 #include "libswscale/swscale.h"
 #include "libswscale/swscale_internal.h"
 #include "libavutil/attributes.h"
-#include "libavutil/cpu.h"
 #include "libavutil/mem_internal.h"
 #include "libavutil/pixdesc.h"
 #include "yuv2rgb_altivec.h"
@@ -561,12 +560,9 @@ static int altivec_uyvy_rgb32(SwsInternal *c, const unsigned char *const *in,
  *
  * So we just fall back to the C codes for this.
  */
-av_cold SwsFunc ff_yuv2rgb_init_ppc(SwsInternal *c)
+av_cold SwsFunc ff_yuv2rgb_init_altivec(SwsInternal *c)
 {
 #if HAVE_ALTIVEC
-    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
-        return NULL;
-
     /*
      * and this seems not to matter too much I tried a bunch of
      * videos with abnormal widths and MPlayer crashes elsewhere.
@@ -632,11 +628,11 @@ av_cold SwsFunc ff_yuv2rgb_init_ppc(SwsInternal *c)
     return NULL;
 }

-av_cold void ff_yuv2rgb_init_tables_ppc(SwsInternal *c,
-                                        const int inv_table[4],
-                                        int brightness,
-                                        int contrast,
-                                        int saturation)
+av_cold void ff_yuv2rgb_init_tables_altivec(SwsInternal *c,
+                                            const int inv_table[4],
+                                            int brightness,
+                                            int contrast,
+                                            int saturation)
 {
 #if HAVE_ALTIVEC
     SwsInternalAltivec *const a = sws_internal_altivec(c);
@@ -646,9 +642,6 @@ av_cold void ff_yuv2rgb_init_tables_ppc(SwsInternal *c,
         vector signed short vec;
     } buf;

-    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
-        return;
-
     buf.tmp[0] = ((0xffffLL) * contrast >> 8) >> 9;                               // cy
     buf.tmp[1] = -256 * brightness;                                               // oy
     buf.tmp[2] =   (inv_table[0] >> 3) * (contrast >> 16) * (saturation >> 16);   // crv
diff --git a/libswscale/ppc/yuv2yuv.c b/libswscale/ppc/yuv2yuv.c
new file mode 100644
index 0000000000..4f8cb81196
--- /dev/null
+++ b/libswscale/ppc/yuv2yuv.c
@@ -0,0 +1,31 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/ppc/cpu.h"
+
+#include "libswscale/swscale_internal.h"
+
+av_cold void ff_get_unscaled_swscale_ppc(SwsInternal *c)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    if (PPC_ALTIVEC(cpu_flags))
+        ff_get_unscaled_swscale_altivec(c);
+}
diff --git a/libswscale/ppc/yuv2yuv_altivec.c b/libswscale/ppc/yuv2yuv_altivec.c
index 3e3bbea23a..6fa94f5add 100644
--- a/libswscale/ppc/yuv2yuv_altivec.c
+++ b/libswscale/ppc/yuv2yuv_altivec.c
@@ -25,7 +25,6 @@

 #include "config.h"
 #include "libavutil/attributes.h"
-#include "libavutil/cpu.h"
 #include "libswscale/swscale.h"
 #include "libswscale/swscale_internal.h"

@@ -185,12 +184,9 @@ static int yv12touyvy_unscaled_altivec(SwsInternal *c, const uint8_t *const src[

 #endif /* HAVE_ALTIVEC */

-av_cold void ff_get_unscaled_swscale_ppc(SwsInternal *c)
+av_cold void ff_get_unscaled_swscale_altivec(SwsInternal *c)
 {
 #if HAVE_ALTIVEC
-    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
-        return;
-
     if (!(c->opts.src_w & 15) && !(c->opts.flags & SWS_BITEXACT) &&
         c->opts.src_format == AV_PIX_FMT_YUV420P) {
         enum AVPixelFormat dstFormat = c->opts.dst_format;
diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
index 78b4d6bfd3..ba069ccd89 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -723,6 +723,8 @@ int ff_yuv2rgb_c_init_tables(SwsInternal *c, const int inv_table[4],
                              int contrast, int saturation);
 void ff_yuv2rgb_init_tables_ppc(SwsInternal *c, const int inv_table[4],
                                 int brightness, int contrast, int saturation);
+void ff_yuv2rgb_init_tables_altivec(SwsInternal *c, const int inv_table[4],
+                                    int brightness, int contrast, int saturation);

 void ff_updateMMXDitherTables(SwsInternal *c, int dstY);

@@ -741,6 +743,7 @@ av_cold int ff_sws_fill_st428_tables(SwsInternal *c);

 SwsFunc ff_yuv2rgb_init_x86(SwsInternal *c);
 SwsFunc ff_yuv2rgb_init_ppc(SwsInternal *c);
+SwsFunc ff_yuv2rgb_init_altivec(SwsInternal *c);
 SwsFunc ff_yuv2rgb_init_loongarch(SwsInternal *c);
 SwsFunc ff_yuv2rgb_init_aarch64(SwsInternal *c);

@@ -1012,6 +1015,7 @@ int ff_sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter,
  */
 void ff_get_unscaled_swscale(SwsInternal *c);
 void ff_get_unscaled_swscale_ppc(SwsInternal *c);
+void ff_get_unscaled_swscale_altivec(SwsInternal *c);
 void ff_get_unscaled_swscale_arm(SwsInternal *c);
 void ff_get_unscaled_swscale_aarch64(SwsInternal *c);
 void ff_get_unscaled_swscale_loongarch(SwsInternal *c);
@@ -1034,6 +1038,7 @@ void ff_sws_init_output_funcs(SwsInternal *c,
                               yuv2packedX_fn *yuv2packedX,
                               yuv2anyX_fn *yuv2anyX);
 void ff_sws_init_swscale_ppc(SwsInternal *c);
+void ff_sws_init_swscale_altivec(SwsInternal *c);
 void ff_sws_init_swscale_vsx(SwsInternal *c);
 void ff_sws_init_swscale_x86(SwsInternal *c);
 void ff_sws_init_swscale_aarch64(SwsInternal *c);