From f043d91d958fde7eac0665c9e00f817d0a11ddef Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Fri, 24 Jul 2026 04:10:12 +0000 Subject: [PATCH 07/38] avcodec/ppc: add AltiVec ff_put/avg_pixels8_altivec for hpeldsp Adds exported 8-wide plain copy/average pixel helpers, matching the existing ff_put/avg_pixels16_altivec pattern (rightside-alignment vec_perm blend, since block is only guaranteed 8-byte aligned). Wired into ff_hpeldsp_init_ppc's put_pixels_tab[1][0] / avg_pixels_tab[1][0] (previously unset for put, previously pointed at an unexported near-identical static avg_pixels8_altivec, now removed as a duplicate). VALIDATED: checkasm hpeldsp passes under the cross-PPC/qemu harness (qemu-ppc-static -cpu 7400), real ALTIVEC dispatch confirmed. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_0194bzLUrg6cVCQ7u4NNDpaB --- libavcodec/ppc/hpeldsp_altivec.c | 62 ++++++++++++++++++++++---------- libavcodec/ppc/hpeldsp_altivec.h | 4 +++ 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/libavcodec/ppc/hpeldsp_altivec.c b/libavcodec/ppc/hpeldsp_altivec.c index d8cf751..def7972 100644 --- a/libavcodec/ppc/hpeldsp_altivec.c +++ b/libavcodec/ppc/hpeldsp_altivec.c @@ -82,32 +82,57 @@ void ff_avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t li } /* next one assumes that ((line_size % 8) == 0) */ -static void avg_pixels8_altivec(uint8_t * block, const uint8_t * pixels, ptrdiff_t line_size, int h) +void ff_put_pixels8_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) { register vector unsigned char pixelsv, blockv; int i; - for (i = 0; i < h; i++) { - /* block is 8 bytes-aligned, so we're either in the - left block (16 bytes-aligned) or in the right block (not) */ - int rightside = ((unsigned long)block & 0x0000000F); + for (i = 0; i < h; i++) { + int rightside = ((unsigned long)block & 0x0000000F); + + blockv = vec_ld(0, block); + pixelsv = VEC_LD(0, pixels); - blockv = vec_ld(0, block); - pixelsv = VEC_LD( 0, pixels); + if (rightside) { + pixelsv = vec_perm(blockv, pixelsv, vcprm(0,1,s0,s1)); + } else { + pixelsv = vec_perm(blockv, pixelsv, vcprm(s0,s1,2,3)); + } - if (rightside) { - pixelsv = vec_perm(blockv, pixelsv, vcprm(0,1,s0,s1)); - } else { - pixelsv = vec_perm(blockv, pixelsv, vcprm(s0,s1,2,3)); - } + vec_st(pixelsv, 0, block); - blockv = vec_avg(blockv, pixelsv); + pixels += line_size; + block += line_size; + } +} - vec_st(blockv, 0, block); +/* next one assumes that ((line_size % 8) == 0) */ +void ff_avg_pixels8_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + register vector unsigned char pixelsv, blockv; + int i; - pixels += line_size; - block += line_size; - } + for (i = 0; i < h; i++) { + /* block is 8 bytes-aligned, so we're either in the + left block (16 bytes-aligned) or in the right block (not) */ + int rightside = ((unsigned long)block & 0x0000000F); + + blockv = vec_ld(0, block); + pixelsv = VEC_LD( 0, pixels); + + if (rightside) { + pixelsv = vec_perm(blockv, pixelsv, vcprm(0,1,s0,s1)); + } else { + pixelsv = vec_perm(blockv, pixelsv, vcprm(s0,s1,2,3)); + } + + blockv = vec_avg(blockv, pixelsv); + + vec_st(blockv, 0, block); + + pixels += line_size; + block += line_size; + } } /* next one assumes that ((line_size % 8) == 0) */ @@ -372,10 +397,11 @@ av_cold void ff_hpeldsp_init_ppc(HpelDSPContext *c, int flags) return; c->avg_pixels_tab[0][0] = ff_avg_pixels16_altivec; - c->avg_pixels_tab[1][0] = avg_pixels8_altivec; + c->avg_pixels_tab[1][0] = ff_avg_pixels8_altivec; c->avg_pixels_tab[1][3] = avg_pixels8_xy2_altivec; c->put_pixels_tab[0][0] = ff_put_pixels16_altivec; + c->put_pixels_tab[1][0] = ff_put_pixels8_altivec; c->put_pixels_tab[1][3] = put_pixels8_xy2_altivec; c->put_pixels_tab[0][3] = put_pixels16_xy2_altivec; diff --git a/libavcodec/ppc/hpeldsp_altivec.h b/libavcodec/ppc/hpeldsp_altivec.h index 590809f..ff377ac 100644 --- a/libavcodec/ppc/hpeldsp_altivec.h +++ b/libavcodec/ppc/hpeldsp_altivec.h @@ -30,5 +30,9 @@ void ff_avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h); void ff_put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h); +void ff_avg_pixels8_altivec(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_altivec(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); #endif /* AVCODEC_PPC_HPELDSP_ALTIVEC_H */ -- 2.43.0