[ffmpeg] branch master updated (da9a6d51f5 -> f570fa787a)
This is an automated email from the git hooks/post-receive script. Git pushed a change to branch master in repository ffmpeg. from da9a6d51f5 avformat/mov: add support for multiple decryption keys new 76cb5691e8 swscale/utils: Move altivec init/free code to yuv2rgb_altivec.c new f570fa787a swscale/swscale_internal: Move altivec parts to ppc/ The 2 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "add" were already present in the repository and have only been added to this reference. Summary of changes: libswscale/ppc/yuv2rgb_altivec.c | 117 ++++++++++++++++++++++++++++++--------- libswscale/ppc/yuv2yuv_altivec.c | 1 + libswscale/swscale_internal.h | 22 +++----- libswscale/utils.c | 26 ++------- 4 files changed, 107 insertions(+), 59 deletions(-)
This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg. commit 76cb5691e84a53c9a6173c0e784525e5670b6b76 Author: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> AuthorDate: Tue Feb 24 15:16:35 2026 +0100 Commit: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> CommitDate: Sat Feb 28 09:56:01 2026 +0100 swscale/utils: Move altivec init/free code to yuv2rgb_altivec.c This is in preparation for removing the util_altivec.h inclusion in swscale_internal.h, which causes problems (on PPC) because it redefines bool to something different from stdbool.h. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libswscale/ppc/yuv2rgb_altivec.c | 31 +++++++++++++++++++++++++++++++ libswscale/swscale_internal.h | 3 +++ libswscale/utils.c | 24 ++++-------------------- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c index a6b6650e02..3efb33d22e 100644 --- a/libswscale/ppc/yuv2rgb_altivec.c +++ b/libswscale/ppc/yuv2rgb_altivec.c @@ -96,6 +96,8 @@ #include "libswscale/swscale_internal.h" #include "libavutil/attributes.h" #include "libavutil/cpu.h" +#include "libavutil/error.h" +#include "libavutil/mem.h" #include "libavutil/mem_internal.h" #include "libavutil/pixdesc.h" #include "yuv2rgb_altivec.h" @@ -871,4 +873,33 @@ YUV2PACKEDX_WRAPPER(rgba, AV_PIX_FMT_RGBA); YUV2PACKEDX_WRAPPER(rgb24, AV_PIX_FMT_RGB24); YUV2PACKEDX_WRAPPER(bgr24, AV_PIX_FMT_BGR24); +av_cold int ff_sws_init_altivec_bufs(SwsInternal *c) +{ + const SwsContext *const sws = &c->opts; + + c->vYCoeffsBank = av_malloc_array(sws->dst_h, c->vLumFilterSize * sizeof(*c->vYCoeffsBank)); + c->vCCoeffsBank = av_malloc_array(c->chrDstH, c->vChrFilterSize * sizeof(*c->vCCoeffsBank)); + if (!c->vYCoeffsBank || !c->vCCoeffsBank) + return AVERROR(ENOMEM); + + for (int i = 0; i < c->vLumFilterSize * sws->dst_h; ++i) { + short *p = (short *)&c->vYCoeffsBank[i]; + for (int j = 0; j < 8; ++j) + p[j] = c->vLumFilter[i]; + } + + for (int i = 0; i < c->vChrFilterSize * c->chrDstH; ++i) { + short *p = (short *)&c->vCCoeffsBank[i]; + for (int j = 0; j < 8; ++j) + p[j] = c->vChrFilter[i]; + } + + return 0; +} + +av_cold void ff_sws_free_altivec_bufs(SwsInternal *c) +{ + av_freep(&c->vYCoeffsBank); + av_freep(&c->vCCoeffsBank); +} #endif /* HAVE_ALTIVEC */ diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 81ec5ef0cc..d9fddb271b 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -1039,6 +1039,9 @@ void ff_sws_init_swscale_arm(SwsInternal *c); void ff_sws_init_swscale_loongarch(SwsInternal *c); void ff_sws_init_swscale_riscv(SwsInternal *c); +int ff_sws_init_altivec_bufs(SwsInternal *c); +void ff_sws_free_altivec_bufs(SwsInternal *c); + void ff_hyscale_fast_c(SwsInternal *c, int16_t *dst, int dstWidth, const uint8_t *src, int srcW, int xInc); void ff_hcscale_fast_c(SwsInternal *c, int16_t *dst1, int16_t *dst2, diff --git a/libswscale/utils.c b/libswscale/utils.c index 42b49a5cd5..4e6e503b75 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -1729,24 +1729,9 @@ av_cold int ff_sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter, goto fail; #if HAVE_ALTIVEC - c->vYCoeffsBank = av_malloc_array(sws->dst_h, c->vLumFilterSize * sizeof(*c->vYCoeffsBank)); - c->vCCoeffsBank = av_malloc_array(c->chrDstH, c->vChrFilterSize * sizeof(*c->vCCoeffsBank)); - if (c->vYCoeffsBank == NULL || c->vCCoeffsBank == NULL) - goto nomem; - - for (i = 0; i < c->vLumFilterSize * sws->dst_h; i++) { - int j; - short *p = (short *)&c->vYCoeffsBank[i]; - for (j = 0; j < 8; j++) - p[j] = c->vLumFilter[i]; - } - - for (i = 0; i < c->vChrFilterSize * c->chrDstH; i++) { - int j; - short *p = (short *)&c->vCCoeffsBank[i]; - for (j = 0; j < 8; j++) - p[j] = c->vChrFilter[i]; - } + ret = ff_sws_init_altivec_bufs(c); + if (ret < 0) + goto fail; #endif } @@ -2290,8 +2275,7 @@ void sws_freeContext(SwsContext *sws) av_freep(&c->hLumFilter); av_freep(&c->hChrFilter); #if HAVE_ALTIVEC - av_freep(&c->vYCoeffsBank); - av_freep(&c->vCCoeffsBank); + ff_sws_free_altivec_bufs(c); #endif av_freep(&c->vLumFilterPos);
This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg. commit f570fa787a813195775521ed28bf0ff302cc93b8 Author: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> AuthorDate: Tue Feb 24 16:41:07 2026 +0100 Commit: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> CommitDate: Sat Feb 28 09:56:01 2026 +0100 swscale/swscale_internal: Move altivec parts to ppc/ Up until now, several altivec-specific fields are directly put into SwsInternal #if HAVE_ALTIVEC is true. These fields are of altivec-specific vector types and therefore require altivec specific headers to be included. Unfortunately, said altivec specific headers redefine bool in a manner that is incompatible with stdbool. swscale/ops.h uses bool and this led graph.c and ops.c to disagree about the layout of structures from ops.h, leading to heap corruption [1], [2] in the sws-unscaled FATE test. Fix this by moving the altivec-specific parts out of SwsInternal and into a structure that extends SwsInternal and is allocated jointly with it. Said structure is local to yuv2rgb_altivec.c, because this is the only file accessing said fields. Should more files need them, an altivec-specific swscale header would need to be added. Thanks to jfiusdq <jfiusdq@proton.me> for analyzing the issue. [1]: https://fate.ffmpeg.org/report.cgi?slot=ppc64-linux-gcc-14.3-asan&time=20260224065643 [2]: https://fate.ffmpeg.org/report.cgi?slot=ppc64-linux-gcc-14.3&time=20260224051615 Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libswscale/ppc/yuv2rgb_altivec.c | 100 ++++++++++++++++++++++++++------------- libswscale/ppc/yuv2yuv_altivec.c | 1 + libswscale/swscale_internal.h | 19 +++----- libswscale/utils.c | 2 +- 4 files changed, 76 insertions(+), 46 deletions(-) diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c index 3efb33d22e..cad3f8d7c0 100644 --- a/libswscale/ppc/yuv2rgb_altivec.c +++ b/libswscale/ppc/yuv2rgb_altivec.c @@ -103,6 +103,34 @@ #include "yuv2rgb_altivec.h" #if HAVE_ALTIVEC +// util_altivec.h includes the system header altivec.h which redefines bool, +// making it incompatible with stdbool.h. It therefore must not be included +// before another one of our headers that may use bool. +#include "libavutil/ppc/util_altivec.h" +#include <assert.h> + +typedef struct SwsInternalAltivec { + SwsInternal c; + + vector signed short CY; + vector signed short CRV; + vector signed short CBU; + vector signed short CGU; + vector signed short CGV; + vector signed short OY; + vector unsigned short CSHIFT; + vector signed short *vYCoeffsBank, *vCCoeffsBank; +} SwsInternalAltivec; +// Check that the sizes of the types match. +// Note that given that SwsInternal is always allocated via av_malloc, +// every pointer to an SwsInternal is always sufficiently aligned. +static_assert(sizeof(SwsInternalAltivec) <= sizeof(SwsInternal) + SWSINTERNAL_ADDITIONAL_ASM_SIZE, + "SWSINTERNAL_ADDITIONAL_ASM_SIZE needs to be increased"); + +static inline SwsInternalAltivec *sws_internal_altivec(SwsInternal *c) +{ + return (SwsInternalAltivec*)c; +} #undef PROFILE_THE_BEAST #undef INC_SCALING @@ -259,25 +287,26 @@ static inline void cvtyuvtoRGB(SwsInternal *c, vector signed short Y, vector signed short *R, vector signed short *G, vector signed short *B) { + SwsInternalAltivec *const a = sws_internal_altivec(c); vector signed short vx, ux, uvx; - Y = vec_mradds(Y, c->CY, c->OY); + Y = vec_mradds(Y, a->CY, a->OY); U = vec_sub(U, (vector signed short) vec_splat((vector signed short) { 128 }, 0)); V = vec_sub(V, (vector signed short) vec_splat((vector signed short) { 128 }, 0)); - // ux = (CBU * (u << c->CSHIFT) + 0x4000) >> 15; - ux = vec_sl(U, c->CSHIFT); - *B = vec_mradds(ux, c->CBU, Y); + // ux = (CBU * (u << a->CSHIFT) + 0x4000) >> 15; + ux = vec_sl(U, a->CSHIFT); + *B = vec_mradds(ux, a->CBU, Y); - // vx = (CRV * (v << c->CSHIFT) + 0x4000) >> 15; - vx = vec_sl(V, c->CSHIFT); - *R = vec_mradds(vx, c->CRV, Y); + // vx = (CRV * (v << a->CSHIFT) + 0x4000) >> 15; + vx = vec_sl(V, a->CSHIFT); + *R = vec_mradds(vx, a->CRV, Y); // uvx = ((CGU * u) + (CGV * v)) >> 15; - uvx = vec_mradds(U, c->CGU, Y); - *G = vec_mradds(V, c->CGV, uvx); + uvx = vec_mradds(U, a->CGU, Y); + *G = vec_mradds(V, a->CGV, uvx); } /* @@ -301,6 +330,7 @@ static int altivec_ ## name(SwsInternal *c, const unsigned char *const *in, \ const int *instrides, int srcSliceY, int srcSliceH, \ unsigned char *const *oplanes, const int *outstrides) \ { \ + SwsInternalAltivec *const a = sws_internal_altivec(c); \ int w = c->opts.src_w; \ int h = srcSliceH; \ int i, j; \ @@ -318,13 +348,13 @@ static int altivec_ ## name(SwsInternal *c, const unsigned char *const *in, \ vector signed short R1, G1, B1; \ vector unsigned char R, G, B; \ \ - vector signed short lCY = c->CY; \ - vector signed short lOY = c->OY; \ - vector signed short lCRV = c->CRV; \ - vector signed short lCBU = c->CBU; \ - vector signed short lCGU = c->CGU; \ - vector signed short lCGV = c->CGV; \ - vector unsigned short lCSHIFT = c->CSHIFT; \ + vector signed short lCY = a->CY; \ + vector signed short lOY = a->OY; \ + vector signed short lCRV = a->CRV; \ + vector signed short lCBU = a->CBU; \ + vector signed short lCGU = a->CGU; \ + vector signed short lCGV = a->CGV; \ + vector unsigned short lCSHIFT = a->CSHIFT; \ \ const ubyte *y1i = in[0]; \ const ubyte *y2i = in[0] + instrides[0]; \ @@ -612,6 +642,8 @@ av_cold void ff_yuv2rgb_init_tables_ppc(SwsInternal *c, int saturation) { #if HAVE_ALTIVEC + SwsInternalAltivec *const a = sws_internal_altivec(c); + union { DECLARE_ALIGNED(16, signed short, tmp)[8]; vector signed short vec; @@ -627,13 +659,13 @@ av_cold void ff_yuv2rgb_init_tables_ppc(SwsInternal *c, buf.tmp[4] = -((inv_table[2] >> 1) * (contrast >> 16) * (saturation >> 16)); // cgu buf.tmp[5] = -((inv_table[3] >> 1) * (contrast >> 16) * (saturation >> 16)); // cgv - c->CSHIFT = (vector unsigned short) vec_splat_u16(2); - c->CY = vec_splat((vector signed short) buf.vec, 0); - c->OY = vec_splat((vector signed short) buf.vec, 1); - c->CRV = vec_splat((vector signed short) buf.vec, 2); - c->CBU = vec_splat((vector signed short) buf.vec, 3); - c->CGU = vec_splat((vector signed short) buf.vec, 4); - c->CGV = vec_splat((vector signed short) buf.vec, 5); + a->CSHIFT = (vector unsigned short) vec_splat_u16(2); + a->CY = vec_splat((vector signed short) buf.vec, 0); + a->OY = vec_splat((vector signed short) buf.vec, 1); + a->CRV = vec_splat((vector signed short) buf.vec, 2); + a->CBU = vec_splat((vector signed short) buf.vec, 3); + a->CGU = vec_splat((vector signed short) buf.vec, 4); + a->CGV = vec_splat((vector signed short) buf.vec, 5); return; #endif /* HAVE_ALTIVEC */ } @@ -653,6 +685,8 @@ static av_always_inline void yuv2packedX_altivec(SwsInternal *c, int dstW, int dstY, enum AVPixelFormat target) { + SwsInternalAltivec *const a = sws_internal_altivec(c); + int i, j; vector signed short X, X0, X1, Y0, U0, V0, Y1, U1, V1, U, V; vector signed short R0, G0, B0, R1, G1, B1; @@ -666,8 +700,8 @@ static av_always_inline void yuv2packedX_altivec(SwsInternal *c, vector signed short *YCoeffs, *CCoeffs; - YCoeffs = c->vYCoeffsBank + dstY * lumFilterSize; - CCoeffs = c->vCCoeffsBank + dstY * chrFilterSize; + YCoeffs = a->vYCoeffsBank + dstY * lumFilterSize; + CCoeffs = a->vCCoeffsBank + dstY * chrFilterSize; out = (vector unsigned char *) dest; @@ -876,20 +910,21 @@ YUV2PACKEDX_WRAPPER(bgr24, AV_PIX_FMT_BGR24); av_cold int ff_sws_init_altivec_bufs(SwsInternal *c) { const SwsContext *const sws = &c->opts; + SwsInternalAltivec *const a = sws_internal_altivec(c); - c->vYCoeffsBank = av_malloc_array(sws->dst_h, c->vLumFilterSize * sizeof(*c->vYCoeffsBank)); - c->vCCoeffsBank = av_malloc_array(c->chrDstH, c->vChrFilterSize * sizeof(*c->vCCoeffsBank)); - if (!c->vYCoeffsBank || !c->vCCoeffsBank) + a->vYCoeffsBank = av_malloc_array(sws->dst_h, c->vLumFilterSize * sizeof(*a->vYCoeffsBank)); + a->vCCoeffsBank = av_malloc_array(c->chrDstH, c->vChrFilterSize * sizeof(*a->vCCoeffsBank)); + if (!a->vYCoeffsBank || !a->vCCoeffsBank) return AVERROR(ENOMEM); for (int i = 0; i < c->vLumFilterSize * sws->dst_h; ++i) { - short *p = (short *)&c->vYCoeffsBank[i]; + short *p = (short *)&a->vYCoeffsBank[i]; for (int j = 0; j < 8; ++j) p[j] = c->vLumFilter[i]; } for (int i = 0; i < c->vChrFilterSize * c->chrDstH; ++i) { - short *p = (short *)&c->vCCoeffsBank[i]; + short *p = (short *)&a->vCCoeffsBank[i]; for (int j = 0; j < 8; ++j) p[j] = c->vChrFilter[i]; } @@ -899,7 +934,8 @@ av_cold int ff_sws_init_altivec_bufs(SwsInternal *c) av_cold void ff_sws_free_altivec_bufs(SwsInternal *c) { - av_freep(&c->vYCoeffsBank); - av_freep(&c->vCCoeffsBank); + SwsInternalAltivec *const a = sws_internal_altivec(c); + av_freep(&a->vYCoeffsBank); + av_freep(&a->vCCoeffsBank); } #endif /* HAVE_ALTIVEC */ diff --git a/libswscale/ppc/yuv2yuv_altivec.c b/libswscale/ppc/yuv2yuv_altivec.c index 7884c38d69..3e3bbea23a 100644 --- a/libswscale/ppc/yuv2yuv_altivec.c +++ b/libswscale/ppc/yuv2yuv_altivec.c @@ -30,6 +30,7 @@ #include "libswscale/swscale_internal.h" #if HAVE_ALTIVEC +#include "libavutil/ppc/util_altivec.h" static int yv12toyuy2_unscaled_altivec(SwsInternal *c, const uint8_t *const src[], const int srcStride[], int srcSliceY, diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index d9fddb271b..f4007379ab 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -37,10 +37,14 @@ #include "libavutil/pixfmt.h" #include "libavutil/pixdesc.h" #include "libavutil/slicethread.h" +#include "libavutil/half2float.h" + #if HAVE_ALTIVEC -#include "libavutil/ppc/util_altivec.h" +#define SWSINTERNAL_ADDITIONAL_ASM_SIZE (7*16 + 2*8 + /* alignment */ 16) +#endif +#ifndef SWSINTERNAL_ADDITIONAL_ASM_SIZE +#define SWSINTERNAL_ADDITIONAL_ASM_SIZE 0 #endif -#include "libavutil/half2float.h" #define STR(s) AV_TOSTRING(s) // AV_STRINGIFY is too long @@ -544,17 +548,6 @@ struct SwsInternal { const uint8_t *chrDither8, *lumDither8; -#if HAVE_ALTIVEC - vector signed short CY; - vector signed short CRV; - vector signed short CBU; - vector signed short CGU; - vector signed short CGV; - vector signed short OY; - vector unsigned short CSHIFT; - vector signed short *vYCoeffsBank, *vCCoeffsBank; -#endif - int use_mmx_vfilter; /* pre defined color-spaces gamma */ diff --git a/libswscale/utils.c b/libswscale/utils.c index 4e6e503b75..90839817d8 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -1031,7 +1031,7 @@ int sws_getColorspaceDetails(SwsContext *sws, int **inv_table, SwsContext *sws_alloc_context(void) { - SwsInternal *c = (SwsInternal *) av_mallocz(sizeof(SwsInternal)); + SwsInternal *c = av_mallocz(sizeof(*c) + SWSINTERNAL_ADDITIONAL_ASM_SIZE); if (!c) return NULL;
participants (2)
-
Andreas Rheinhardt -
ffmpeg-git