avcodec/ppc/h264dsp: POWER LE support for h264_idct8_add_altivec() h264_idct_dc_add_internal() h264_loop_filter_luma_altivec() write16x4() VEC_1D_DCT() weight_h264_W_altivec() biweight_h264_W_altivec() VEC_LOAD_U8_ADD_S16_STORE_U8() ALTIVEC_STORE_SUM_CLIP()

add marcos GET_2PERM() dstv_load() vdst_load() dest_unligned_store()

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
pull/100/head
Rong Yan 10 years ago committed by Michael Niedermayer
parent f001a2bd34
commit 57c89c50bd
  1. 89
      libavcodec/ppc/h264dsp.c

@ -62,10 +62,17 @@
b2 = vec_mergeh( a1, a3 ); \ b2 = vec_mergeh( a1, a3 ); \
b3 = vec_mergel( a1, a3 ) b3 = vec_mergel( a1, a3 )
#if HAVE_BIGENDIAN
#define vdst_load(d) \
vdst_orig = vec_ld(0, dst); \
vdst = vec_perm(vdst_orig, zero_u8v, vdst_mask);
#else
#define vdst_load(d) vdst = vec_vsx_ld(0, dst)
#endif
#define VEC_LOAD_U8_ADD_S16_STORE_U8(va) \ #define VEC_LOAD_U8_ADD_S16_STORE_U8(va) \
vdst_orig = vec_ld(0, dst); \ vdst_load(); \
vdst = vec_perm(vdst_orig, zero_u8v, vdst_mask); \ vdst_ss = (vec_s16) VEC_MERGEH(zero_u8v, vdst); \
vdst_ss = (vec_s16) vec_mergeh(zero_u8v, vdst); \
va = vec_add(va, vdst_ss); \ va = vec_add(va, vdst_ss); \
va_u8 = vec_packsu(va, zero_s16v); \ va_u8 = vec_packsu(va, zero_s16v); \
va_u32 = vec_splat((vec_u32)va_u8, 0); \ va_u32 = vec_splat((vec_u32)va_u8, 0); \
@ -165,26 +172,43 @@ static void h264_idct_add_altivec(uint8_t *dst, int16_t *block, int stride)
d7 = vec_sub(b0v, b7v); \ d7 = vec_sub(b0v, b7v); \
} }
#if HAVE_BIGENDIAN
#define GET_2PERM(ldv, stv, d) \
ldv = vec_lvsl(0, d); \
stv = vec_lvsr(8, d);
#define dstv_load(d) \
vec_u8 hv = vec_ld( 0, d ); \
vec_u8 lv = vec_ld( 7, d); \
vec_u8 dstv = vec_perm( hv, lv, (vec_u8)perm_ldv );
#define dest_unligned_store(d) \
vec_u8 edgehv; \
vec_u8 bodyv = vec_perm( idstsum8, idstsum8, perm_stv ); \
vec_u8 edgelv = vec_perm( sel, zero_u8v, perm_stv ); \
lv = vec_sel( lv, bodyv, edgelv ); \
vec_st( lv, 7, d ); \
hv = vec_ld( 0, d ); \
edgehv = vec_perm( zero_u8v, sel, perm_stv ); \
hv = vec_sel( hv, bodyv, edgehv ); \
vec_st( hv, 0, d );
#else
#define GET_2PERM(ldv, stv, d) {}
#define dstv_load(d) vec_u8 dstv = vec_vsx_ld(0, d)
#define dest_unligned_store(d)\
vec_u8 dst8 = vec_perm((vec_u8)idstsum8, dstv, vcprm(2,3,s2,s3));\
vec_vsx_st(dst8, 0, d)
#endif /* HAVE_BIGENDIAN */
#define ALTIVEC_STORE_SUM_CLIP(dest, idctv, perm_ldv, perm_stv, sel) { \ #define ALTIVEC_STORE_SUM_CLIP(dest, idctv, perm_ldv, perm_stv, sel) { \
/* unaligned load */ \ /* unaligned load */ \
vec_u8 hv = vec_ld( 0, dest ); \ dstv_load(dest); \
vec_u8 lv = vec_ld( 7, dest ); \
vec_u8 dstv = vec_perm( hv, lv, (vec_u8)perm_ldv ); \
vec_s16 idct_sh6 = vec_sra(idctv, sixv); \ vec_s16 idct_sh6 = vec_sra(idctv, sixv); \
vec_u16 dst16 = (vec_u16)vec_mergeh(zero_u8v, dstv); \ vec_u16 dst16 = (vec_u16)VEC_MERGEH(zero_u8v, dstv); \
vec_s16 idstsum = vec_adds(idct_sh6, (vec_s16)dst16); \ vec_s16 idstsum = vec_adds(idct_sh6, (vec_s16)dst16); \
vec_u8 idstsum8 = vec_packsu(zero_s16v, idstsum); \ vec_u8 idstsum8 = vec_packsu(zero_s16v, idstsum); \
vec_u8 edgehv; \
/* unaligned store */ \ /* unaligned store */ \
vec_u8 bodyv = vec_perm( idstsum8, idstsum8, perm_stv );\ dest_unligned_store(dest);\
vec_u8 edgelv = vec_perm( sel, zero_u8v, perm_stv ); \ }
lv = vec_sel( lv, bodyv, edgelv ); \
vec_st( lv, 7, dest ); \
hv = vec_ld( 0, dest ); \
edgehv = vec_perm( zero_u8v, sel, perm_stv ); \
hv = vec_sel( hv, bodyv, edgehv ); \
vec_st( hv, 0, dest ); \
}
static void h264_idct8_add_altivec(uint8_t *dst, int16_t *dct, int stride) static void h264_idct8_add_altivec(uint8_t *dst, int16_t *dct, int stride)
{ {
@ -192,8 +216,8 @@ static void h264_idct8_add_altivec(uint8_t *dst, int16_t *dct, int stride)
vec_s16 d0, d1, d2, d3, d4, d5, d6, d7; vec_s16 d0, d1, d2, d3, d4, d5, d6, d7;
vec_s16 idct0, idct1, idct2, idct3, idct4, idct5, idct6, idct7; vec_s16 idct0, idct1, idct2, idct3, idct4, idct5, idct6, idct7;
vec_u8 perm_ldv = vec_lvsl(0, dst); vec_u8 perm_ldv, perm_stv;
vec_u8 perm_stv = vec_lvsr(8, dst); GET_2PERM(perm_ldv, perm_stv, dst);
const vec_u16 onev = vec_splat_u16(1); const vec_u16 onev = vec_splat_u16(1);
const vec_u16 twov = vec_splat_u16(2); const vec_u16 twov = vec_splat_u16(2);
@ -236,20 +260,25 @@ static av_always_inline void h264_idct_dc_add_internal(uint8_t *dst, int16_t *bl
{ {
vec_s16 dc16; vec_s16 dc16;
vec_u8 dcplus, dcminus, v0, v1, v2, v3, aligner; vec_u8 dcplus, dcminus, v0, v1, v2, v3, aligner;
vec_s32 v_dc32;
LOAD_ZERO; LOAD_ZERO;
DECLARE_ALIGNED(16, int, dc); DECLARE_ALIGNED(16, int, dc);
int i; int i;
dc = (block[0] + 32) >> 6; dc = (block[0] + 32) >> 6;
block[0] = 0; block[0] = 0;
dc16 = vec_splat((vec_s16) vec_lde(0, &dc), 1); v_dc32 = vec_lde(0, &dc);
dc16 = VEC_SPLAT16((vec_s16)v_dc32, 1);
if (size == 4) if (size == 4)
dc16 = vec_sld(dc16, zero_s16v, 8); dc16 = VEC_SLD16(dc16, zero_s16v, 8);
dcplus = vec_packsu(dc16, zero_s16v); dcplus = vec_packsu(dc16, zero_s16v);
dcminus = vec_packsu(vec_sub(zero_s16v, dc16), zero_s16v); dcminus = vec_packsu(vec_sub(zero_s16v, dc16), zero_s16v);
aligner = vec_lvsr(0, dst); aligner = vec_lvsr(0, dst);
#if !HAVE_BIGENDIAN
aligner = vec_perm(aligner, zero_u8v, vcswapc());
#endif
dcplus = vec_perm(dcplus, dcplus, aligner); dcplus = vec_perm(dcplus, dcplus, aligner);
dcminus = vec_perm(dcminus, dcminus, aligner); dcminus = vec_perm(dcminus, dcminus, aligner);
@ -633,6 +662,9 @@ void weight_h264_W_altivec(uint8_t *block, int stride, int height,
temp[2] = offset; temp[2] = offset;
vtemp = (vec_s16)vec_ld(0, temp); vtemp = (vec_s16)vec_ld(0, temp);
#if !HAVE_BIGENDIAN
vtemp =(vec_s16)vec_perm(vtemp, vtemp, vcswapi2s(0,1,2,3));
#endif
vlog2_denom = (vec_u16)vec_splat(vtemp, 1); vlog2_denom = (vec_u16)vec_splat(vtemp, 1);
vweight = vec_splat(vtemp, 3); vweight = vec_splat(vtemp, 3);
voffset = vec_splat(vtemp, 5); voffset = vec_splat(vtemp, 5);
@ -641,8 +673,8 @@ void weight_h264_W_altivec(uint8_t *block, int stride, int height,
for (y = 0; y < height; y++) { for (y = 0; y < height; y++) {
vblock = vec_ld(0, block); vblock = vec_ld(0, block);
v0 = (vec_s16)vec_mergeh(zero_u8v, vblock); v0 = (vec_s16)VEC_MERGEH(zero_u8v, vblock);
v1 = (vec_s16)vec_mergel(zero_u8v, vblock); v1 = (vec_s16)VEC_MERGEL(zero_u8v, vblock);
if (w == 16 || aligned) { if (w == 16 || aligned) {
v0 = vec_mladd(v0, vweight, zero_s16v); v0 = vec_mladd(v0, vweight, zero_s16v);
@ -679,6 +711,9 @@ void biweight_h264_W_altivec(uint8_t *dst, uint8_t *src, int stride, int height,
temp[3] = offset; temp[3] = offset;
vtemp = (vec_s16)vec_ld(0, temp); vtemp = (vec_s16)vec_ld(0, temp);
#if !HAVE_BIGENDIAN
vtemp =(vec_s16)vec_perm(vtemp, vtemp, vcswapi2s(0,1,2,3));
#endif
vlog2_denom = (vec_u16)vec_splat(vtemp, 1); vlog2_denom = (vec_u16)vec_splat(vtemp, 1);
vweights = vec_splat(vtemp, 3); vweights = vec_splat(vtemp, 3);
vweightd = vec_splat(vtemp, 5); vweightd = vec_splat(vtemp, 5);
@ -690,10 +725,10 @@ void biweight_h264_W_altivec(uint8_t *dst, uint8_t *src, int stride, int height,
vdst = vec_ld(0, dst); vdst = vec_ld(0, dst);
vsrc = vec_ld(0, src); vsrc = vec_ld(0, src);
v0 = (vec_s16)vec_mergeh(zero_u8v, vdst); v0 = (vec_s16)VEC_MERGEH(zero_u8v, vdst);
v1 = (vec_s16)vec_mergel(zero_u8v, vdst); v1 = (vec_s16)VEC_MERGEL(zero_u8v, vdst);
v2 = (vec_s16)vec_mergeh(zero_u8v, vsrc); v2 = (vec_s16)VEC_MERGEH(zero_u8v, vsrc);
v3 = (vec_s16)vec_mergel(zero_u8v, vsrc); v3 = (vec_s16)VEC_MERGEL(zero_u8v, vsrc);
if (w == 8) { if (w == 8) {
if (src_aligned) if (src_aligned)

Loading…
Cancel
Save