00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavcodec/dsputil.h"
00023 #include "libavcodec/vc1dsp.h"
00024
00025 #include "util_altivec.h"
00026 #include "dsputil_altivec.h"
00027
00028
00029 #define STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_rnd) \
00030 do { \
00031 t0 = vec_sl(vec_add(s0, s4), vec_2); \
00032 t0 = vec_add(vec_sl(t0, vec_1), t0); \
00033 t0 = vec_add(t0, vec_rnd); \
00034 t1 = vec_sl(vec_sub(s0, s4), vec_2); \
00035 t1 = vec_add(vec_sl(t1, vec_1), t1); \
00036 t1 = vec_add(t1, vec_rnd); \
00037 t2 = vec_add(vec_sl(s6, vec_2), vec_sl(s6, vec_1)); \
00038 t2 = vec_add(t2, vec_sl(s2, vec_4)); \
00039 t3 = vec_add(vec_sl(s2, vec_2), vec_sl(s2, vec_1)); \
00040 t3 = vec_sub(t3, vec_sl(s6, vec_4)); \
00041 t4 = vec_add(t0, t2); \
00042 t5 = vec_add(t1, t3); \
00043 t6 = vec_sub(t1, t3); \
00044 t7 = vec_sub(t0, t2); \
00045 \
00046 t0 = vec_sl(vec_add(s1, s3), vec_4); \
00047 t0 = vec_add(t0, vec_sl(s5, vec_3)); \
00048 t0 = vec_add(t0, vec_sl(s7, vec_2)); \
00049 t0 = vec_add(t0, vec_sub(s5, s3)); \
00050 \
00051 t1 = vec_sl(vec_sub(s1, s5), vec_4); \
00052 t1 = vec_sub(t1, vec_sl(s7, vec_3)); \
00053 t1 = vec_sub(t1, vec_sl(s3, vec_2)); \
00054 t1 = vec_sub(t1, vec_add(s1, s7)); \
00055 \
00056 t2 = vec_sl(vec_sub(s7, s3), vec_4); \
00057 t2 = vec_add(t2, vec_sl(s1, vec_3)); \
00058 t2 = vec_add(t2, vec_sl(s5, vec_2)); \
00059 t2 = vec_add(t2, vec_sub(s1, s7)); \
00060 \
00061 t3 = vec_sl(vec_sub(s5, s7), vec_4); \
00062 t3 = vec_sub(t3, vec_sl(s3, vec_3)); \
00063 t3 = vec_add(t3, vec_sl(s1, vec_2)); \
00064 t3 = vec_sub(t3, vec_add(s3, s5)); \
00065 \
00066 s0 = vec_add(t4, t0); \
00067 s1 = vec_add(t5, t1); \
00068 s2 = vec_add(t6, t2); \
00069 s3 = vec_add(t7, t3); \
00070 s4 = vec_sub(t7, t3); \
00071 s5 = vec_sub(t6, t2); \
00072 s6 = vec_sub(t5, t1); \
00073 s7 = vec_sub(t4, t0); \
00074 }while(0)
00075
00076 #define SHIFT_HOR8(s0, s1, s2, s3, s4, s5, s6, s7) \
00077 do { \
00078 s0 = vec_sra(s0, vec_3); \
00079 s1 = vec_sra(s1, vec_3); \
00080 s2 = vec_sra(s2, vec_3); \
00081 s3 = vec_sra(s3, vec_3); \
00082 s4 = vec_sra(s4, vec_3); \
00083 s5 = vec_sra(s5, vec_3); \
00084 s6 = vec_sra(s6, vec_3); \
00085 s7 = vec_sra(s7, vec_3); \
00086 }while(0)
00087
00088 #define SHIFT_VERT8(s0, s1, s2, s3, s4, s5, s6, s7) \
00089 do { \
00090 s0 = vec_sra(s0, vec_7); \
00091 s1 = vec_sra(s1, vec_7); \
00092 s2 = vec_sra(s2, vec_7); \
00093 s3 = vec_sra(s3, vec_7); \
00094 s4 = vec_sra(vec_add(s4, vec_1s), vec_7); \
00095 s5 = vec_sra(vec_add(s5, vec_1s), vec_7); \
00096 s6 = vec_sra(vec_add(s6, vec_1s), vec_7); \
00097 s7 = vec_sra(vec_add(s7, vec_1s), vec_7); \
00098 }while(0)
00099
00100
00101 #define STEP4(s0, s1, s2, s3, vec_rnd) \
00102 do { \
00103 t1 = vec_add(vec_sl(s0, vec_4), s0); \
00104 t1 = vec_add(t1, vec_rnd); \
00105 t2 = vec_add(vec_sl(s2, vec_4), s2); \
00106 t0 = vec_add(t1, t2); \
00107 t1 = vec_sub(t1, t2); \
00108 t3 = vec_sl(vec_sub(s3, s1), vec_1); \
00109 t3 = vec_add(t3, vec_sl(t3, vec_2)); \
00110 t2 = vec_add(t3, vec_sl(s1, vec_5)); \
00111 t3 = vec_add(t3, vec_sl(s3, vec_3)); \
00112 t3 = vec_add(t3, vec_sl(s3, vec_2)); \
00113 s0 = vec_add(t0, t2); \
00114 s1 = vec_sub(t1, t3); \
00115 s2 = vec_add(t1, t3); \
00116 s3 = vec_sub(t0, t2); \
00117 }while (0)
00118
00119 #define SHIFT_HOR4(s0, s1, s2, s3) \
00120 s0 = vec_sra(s0, vec_3); \
00121 s1 = vec_sra(s1, vec_3); \
00122 s2 = vec_sra(s2, vec_3); \
00123 s3 = vec_sra(s3, vec_3);
00124
00125 #define SHIFT_VERT4(s0, s1, s2, s3) \
00126 s0 = vec_sra(s0, vec_7); \
00127 s1 = vec_sra(s1, vec_7); \
00128 s2 = vec_sra(s2, vec_7); \
00129 s3 = vec_sra(s3, vec_7);
00130
00133 static void vc1_inv_trans_8x8_altivec(DCTELEM block[64],
00134 int sign, int rangered)
00135 {
00136 vector signed short src0, src1, src2, src3, src4, src5, src6, src7;
00137 vector signed int s0, s1, s2, s3, s4, s5, s6, s7;
00138 vector signed int s8, s9, sA, sB, sC, sD, sE, sF;
00139 vector signed int t0, t1, t2, t3, t4, t5, t6, t7;
00140 const vector signed int vec_64 = vec_sl(vec_splat_s32(4), vec_splat_u32(4));
00141 const vector unsigned int vec_7 = vec_splat_u32(7);
00142 const vector unsigned int vec_4 = vec_splat_u32(4);
00143 const vector signed int vec_4s = vec_splat_s32(4);
00144 const vector unsigned int vec_3 = vec_splat_u32(3);
00145 const vector unsigned int vec_2 = vec_splat_u32(2);
00146 const vector signed int vec_1s = vec_splat_s32(1);
00147 const vector unsigned int vec_1 = vec_splat_u32(1);
00148 const vector unsigned short rangered_shift = vec_splat_u16(1);
00149 const vector signed short signed_bias = vec_sl(vec_splat_s16(4),
00150 vec_splat_u16(4));
00151
00152 src0 = vec_ld( 0, block);
00153 src1 = vec_ld( 16, block);
00154 src2 = vec_ld( 32, block);
00155 src3 = vec_ld( 48, block);
00156 src4 = vec_ld( 64, block);
00157 src5 = vec_ld( 80, block);
00158 src6 = vec_ld( 96, block);
00159 src7 = vec_ld(112, block);
00160
00161 s0 = vec_unpackl(src0);
00162 s1 = vec_unpackl(src1);
00163 s2 = vec_unpackl(src2);
00164 s3 = vec_unpackl(src3);
00165 s4 = vec_unpackl(src4);
00166 s5 = vec_unpackl(src5);
00167 s6 = vec_unpackl(src6);
00168 s7 = vec_unpackl(src7);
00169 s8 = vec_unpackh(src0);
00170 s9 = vec_unpackh(src1);
00171 sA = vec_unpackh(src2);
00172 sB = vec_unpackh(src3);
00173 sC = vec_unpackh(src4);
00174 sD = vec_unpackh(src5);
00175 sE = vec_unpackh(src6);
00176 sF = vec_unpackh(src7);
00177 STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_4s);
00178 SHIFT_HOR8(s0, s1, s2, s3, s4, s5, s6, s7);
00179 STEP8(s8, s9, sA, sB, sC, sD, sE, sF, vec_4s);
00180 SHIFT_HOR8(s8, s9, sA, sB, sC, sD, sE, sF);
00181 src0 = vec_pack(s8, s0);
00182 src1 = vec_pack(s9, s1);
00183 src2 = vec_pack(sA, s2);
00184 src3 = vec_pack(sB, s3);
00185 src4 = vec_pack(sC, s4);
00186 src5 = vec_pack(sD, s5);
00187 src6 = vec_pack(sE, s6);
00188 src7 = vec_pack(sF, s7);
00189 TRANSPOSE8(src0, src1, src2, src3, src4, src5, src6, src7);
00190
00191 s0 = vec_unpackl(src0);
00192 s1 = vec_unpackl(src1);
00193 s2 = vec_unpackl(src2);
00194 s3 = vec_unpackl(src3);
00195 s4 = vec_unpackl(src4);
00196 s5 = vec_unpackl(src5);
00197 s6 = vec_unpackl(src6);
00198 s7 = vec_unpackl(src7);
00199 s8 = vec_unpackh(src0);
00200 s9 = vec_unpackh(src1);
00201 sA = vec_unpackh(src2);
00202 sB = vec_unpackh(src3);
00203 sC = vec_unpackh(src4);
00204 sD = vec_unpackh(src5);
00205 sE = vec_unpackh(src6);
00206 sF = vec_unpackh(src7);
00207 STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_64);
00208 SHIFT_VERT8(s0, s1, s2, s3, s4, s5, s6, s7);
00209 STEP8(s8, s9, sA, sB, sC, sD, sE, sF, vec_64);
00210 SHIFT_VERT8(s8, s9, sA, sB, sC, sD, sE, sF);
00211 src0 = vec_pack(s8, s0);
00212 src1 = vec_pack(s9, s1);
00213 src2 = vec_pack(sA, s2);
00214 src3 = vec_pack(sB, s3);
00215 src4 = vec_pack(sC, s4);
00216 src5 = vec_pack(sD, s5);
00217 src6 = vec_pack(sE, s6);
00218 src7 = vec_pack(sF, s7);
00219
00220 if (rangered) {
00221 if (!sign) {
00222 src0 = vec_sub(src0, signed_bias);
00223 src1 = vec_sub(src1, signed_bias);
00224 src2 = vec_sub(src2, signed_bias);
00225 src3 = vec_sub(src3, signed_bias);
00226 src4 = vec_sub(src4, signed_bias);
00227 src5 = vec_sub(src5, signed_bias);
00228 src6 = vec_sub(src6, signed_bias);
00229 src7 = vec_sub(src7, signed_bias);
00230 }
00231 src0 = vec_sl(src0, rangered_shift);
00232 src1 = vec_sl(src1, rangered_shift);
00233 src2 = vec_sl(src2, rangered_shift);
00234 src3 = vec_sl(src3, rangered_shift);
00235 src4 = vec_sl(src4, rangered_shift);
00236 src5 = vec_sl(src5, rangered_shift);
00237 src6 = vec_sl(src6, rangered_shift);
00238 src7 = vec_sl(src7, rangered_shift);
00239 }
00240
00241 vec_st(src0, 0, block);
00242 vec_st(src1, 16, block);
00243 vec_st(src2, 32, block);
00244 vec_st(src3, 48, block);
00245 vec_st(src4, 64, block);
00246 vec_st(src5, 80, block);
00247 vec_st(src6, 96, block);
00248 vec_st(src7,112, block);
00249 }
00250
00251 static void vc1_inv_trans_8x8_add_altivec(uint8_t *dest, int stride, DCTELEM *b)
00252 {
00253 vc1_inv_trans_8x8_altivec(b, 0, 0);
00254 ff_add_pixels_clamped_c(b, dest, stride);
00255 }
00256
00257 static void vc1_inv_trans_8x8_put_signed_altivec(uint8_t *dest, int stride, DCTELEM *b)
00258 {
00259 vc1_inv_trans_8x8_altivec(b, 1, 0);
00260 ff_put_signed_pixels_clamped_c(b, dest, stride);
00261 }
00262
00263 static void vc1_inv_trans_8x8_put_signed_rangered_altivec(uint8_t *dest, int stride, DCTELEM *b)
00264 {
00265 vc1_inv_trans_8x8_altivec(b, 1, 1);
00266 ff_put_signed_pixels_clamped_c(b, dest, stride);
00267 }
00268
00269 static void vc1_inv_trans_8x8_put_altivec(uint8_t *dest, int stride, DCTELEM *b)
00270 {
00271 vc1_inv_trans_8x8_altivec(b, 0, 0);
00272 ff_put_pixels_clamped_c(b, dest, stride);
00273 }
00274
00275 static void vc1_inv_trans_8x8_put_rangered_altivec(uint8_t *dest, int stride, DCTELEM *b)
00276 {
00277 vc1_inv_trans_8x8_altivec(b, 0, 1);
00278 ff_put_pixels_clamped_c(b, dest, stride);
00279 }
00280
00283 static void vc1_inv_trans_8x4_altivec(uint8_t *dest, int stride, DCTELEM *block)
00284 {
00285 vector signed short src0, src1, src2, src3, src4, src5, src6, src7;
00286 vector signed int s0, s1, s2, s3, s4, s5, s6, s7;
00287 vector signed int s8, s9, sA, sB, sC, sD, sE, sF;
00288 vector signed int t0, t1, t2, t3, t4, t5, t6, t7;
00289 const vector signed int vec_64 = vec_sl(vec_splat_s32(4), vec_splat_u32(4));
00290 const vector unsigned int vec_7 = vec_splat_u32(7);
00291 const vector unsigned int vec_5 = vec_splat_u32(5);
00292 const vector unsigned int vec_4 = vec_splat_u32(4);
00293 const vector signed int vec_4s = vec_splat_s32(4);
00294 const vector unsigned int vec_3 = vec_splat_u32(3);
00295 const vector unsigned int vec_2 = vec_splat_u32(2);
00296 const vector unsigned int vec_1 = vec_splat_u32(1);
00297 vector unsigned char tmp;
00298 vector signed short tmp2, tmp3;
00299 vector unsigned char perm0, perm1, p0, p1, p;
00300
00301 src0 = vec_ld( 0, block);
00302 src1 = vec_ld( 16, block);
00303 src2 = vec_ld( 32, block);
00304 src3 = vec_ld( 48, block);
00305 src4 = vec_ld( 64, block);
00306 src5 = vec_ld( 80, block);
00307 src6 = vec_ld( 96, block);
00308 src7 = vec_ld(112, block);
00309
00310 TRANSPOSE8(src0, src1, src2, src3, src4, src5, src6, src7);
00311 s0 = vec_unpackl(src0);
00312 s1 = vec_unpackl(src1);
00313 s2 = vec_unpackl(src2);
00314 s3 = vec_unpackl(src3);
00315 s4 = vec_unpackl(src4);
00316 s5 = vec_unpackl(src5);
00317 s6 = vec_unpackl(src6);
00318 s7 = vec_unpackl(src7);
00319 s8 = vec_unpackh(src0);
00320 s9 = vec_unpackh(src1);
00321 sA = vec_unpackh(src2);
00322 sB = vec_unpackh(src3);
00323 sC = vec_unpackh(src4);
00324 sD = vec_unpackh(src5);
00325 sE = vec_unpackh(src6);
00326 sF = vec_unpackh(src7);
00327 STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_4s);
00328 SHIFT_HOR8(s0, s1, s2, s3, s4, s5, s6, s7);
00329 STEP8(s8, s9, sA, sB, sC, sD, sE, sF, vec_4s);
00330 SHIFT_HOR8(s8, s9, sA, sB, sC, sD, sE, sF);
00331 src0 = vec_pack(s8, s0);
00332 src1 = vec_pack(s9, s1);
00333 src2 = vec_pack(sA, s2);
00334 src3 = vec_pack(sB, s3);
00335 src4 = vec_pack(sC, s4);
00336 src5 = vec_pack(sD, s5);
00337 src6 = vec_pack(sE, s6);
00338 src7 = vec_pack(sF, s7);
00339 TRANSPOSE8(src0, src1, src2, src3, src4, src5, src6, src7);
00340
00341 s0 = vec_unpackh(src0);
00342 s1 = vec_unpackh(src1);
00343 s2 = vec_unpackh(src2);
00344 s3 = vec_unpackh(src3);
00345 s8 = vec_unpackl(src0);
00346 s9 = vec_unpackl(src1);
00347 sA = vec_unpackl(src2);
00348 sB = vec_unpackl(src3);
00349 STEP4(s0, s1, s2, s3, vec_64);
00350 SHIFT_VERT4(s0, s1, s2, s3);
00351 STEP4(s8, s9, sA, sB, vec_64);
00352 SHIFT_VERT4(s8, s9, sA, sB);
00353 src0 = vec_pack(s0, s8);
00354 src1 = vec_pack(s1, s9);
00355 src2 = vec_pack(s2, sA);
00356 src3 = vec_pack(s3, sB);
00357
00358 p0 = vec_lvsl (0, dest);
00359 p1 = vec_lvsl (stride, dest);
00360 p = vec_splat_u8 (-1);
00361 perm0 = vec_mergeh (p, p0);
00362 perm1 = vec_mergeh (p, p1);
00363
00364 #define ADD(dest,src,perm) \
00365 \
00366 tmp = vec_ld (0, dest); \
00367 tmp2 = (vector signed short)vec_perm (tmp, vec_splat_u8(0), perm); \
00368 tmp3 = vec_adds (tmp2, src); \
00369 tmp = vec_packsu (tmp3, tmp3); \
00370 vec_ste ((vector unsigned int)tmp, 0, (unsigned int *)dest); \
00371 vec_ste ((vector unsigned int)tmp, 4, (unsigned int *)dest);
00372
00373 ADD (dest, src0, perm0) dest += stride;
00374 ADD (dest, src1, perm1) dest += stride;
00375 ADD (dest, src2, perm0) dest += stride;
00376 ADD (dest, src3, perm1)
00377 }
00378
00379 #define PUT_OP_U8_ALTIVEC(d, s, dst) d = s
00380 #define AVG_OP_U8_ALTIVEC(d, s, dst) d = vec_avg(dst, s)
00381
00382 #define OP_U8_ALTIVEC PUT_OP_U8_ALTIVEC
00383 #define PREFIX_no_rnd_vc1_chroma_mc8_altivec put_no_rnd_vc1_chroma_mc8_altivec
00384 #include "h264_template_altivec.c"
00385 #undef OP_U8_ALTIVEC
00386 #undef PREFIX_no_rnd_vc1_chroma_mc8_altivec
00387
00388 #define OP_U8_ALTIVEC AVG_OP_U8_ALTIVEC
00389 #define PREFIX_no_rnd_vc1_chroma_mc8_altivec avg_no_rnd_vc1_chroma_mc8_altivec
00390 #include "h264_template_altivec.c"
00391 #undef OP_U8_ALTIVEC
00392 #undef PREFIX_no_rnd_vc1_chroma_mc8_altivec
00393
00394 void ff_vc1dsp_init_altivec(VC1DSPContext* dsp)
00395 {
00396 if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
00397 return;
00398
00399 dsp->vc1_inv_trans_8x8_add = vc1_inv_trans_8x8_add_altivec;
00400 dsp->vc1_inv_trans_8x8_put_signed[0] = vc1_inv_trans_8x8_put_signed_altivec;
00401 dsp->vc1_inv_trans_8x8_put_signed[1] = vc1_inv_trans_8x8_put_signed_rangered_altivec;
00402 dsp->vc1_inv_trans_8x8_put[0] = vc1_inv_trans_8x8_put_altivec;
00403 dsp->vc1_inv_trans_8x8_put[1] = vc1_inv_trans_8x8_put_rangered_altivec;
00404 dsp->vc1_inv_trans_8x4 = vc1_inv_trans_8x4_altivec;
00405 dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = put_no_rnd_vc1_chroma_mc8_altivec;
00406 dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = avg_no_rnd_vc1_chroma_mc8_altivec;
00407 }