00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdlib.h>
00025 #include <stdio.h>
00026
00027 #include "libavutil/cpu.h"
00028 #include "libavutil/ppc/types_altivec.h"
00029 #include "libavutil/ppc/util_altivec.h"
00030 #include "libavcodec/dsputil.h"
00031 #include "libavcodec/mpegvideo.h"
00032
00033 #include "dsputil_altivec.h"
00034
00035
00036
00037 static void dct_unquantize_h263_altivec(MpegEncContext *s,
00038 DCTELEM *block, int n, int qscale)
00039 {
00040 int i, level, qmul, qadd;
00041 int nCoeffs;
00042
00043 assert(s->block_last_index[n]>=0);
00044
00045 qadd = (qscale - 1) | 1;
00046 qmul = qscale << 1;
00047
00048 if (s->mb_intra) {
00049 if (!s->h263_aic) {
00050 if (n < 4)
00051 block[0] = block[0] * s->y_dc_scale;
00052 else
00053 block[0] = block[0] * s->c_dc_scale;
00054 }else
00055 qadd = 0;
00056 i = 1;
00057 nCoeffs= 63;
00058 } else {
00059 i = 0;
00060 nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ];
00061 }
00062
00063 {
00064 register const vector signed short vczero = (const vector signed short)vec_splat_s16(0);
00065 DECLARE_ALIGNED(16, short, qmul8) = qmul;
00066 DECLARE_ALIGNED(16, short, qadd8) = qadd;
00067 register vector signed short blockv, qmulv, qaddv, nqaddv, temp1;
00068 register vector bool short blockv_null, blockv_neg;
00069 register short backup_0 = block[0];
00070 register int j = 0;
00071
00072 qmulv = vec_splat((vec_s16)vec_lde(0, &qmul8), 0);
00073 qaddv = vec_splat((vec_s16)vec_lde(0, &qadd8), 0);
00074 nqaddv = vec_sub(vczero, qaddv);
00075
00076
00077
00078 for(; (j + 7) <= nCoeffs ; j+=8) {
00079 blockv = vec_ld(j << 1, block);
00080 blockv_neg = vec_cmplt(blockv, vczero);
00081 blockv_null = vec_cmpeq(blockv, vczero);
00082
00083 temp1 = vec_sel(qaddv, nqaddv, blockv_neg);
00084
00085 temp1 = vec_mladd(blockv, qmulv, temp1);
00086
00087 blockv = vec_sel(temp1, blockv, blockv_null);
00088 vec_st(blockv, j << 1, block);
00089 }
00090
00091
00092
00093
00094
00095 for(; j <= nCoeffs ; j++) {
00096 level = block[j];
00097 if (level) {
00098 if (level < 0) {
00099 level = level * qmul - qadd;
00100 } else {
00101 level = level * qmul + qadd;
00102 }
00103 block[j] = level;
00104 }
00105 }
00106
00107 if (i == 1) {
00108
00109 block[0] = backup_0;
00110 }
00111 }
00112 }
00113
00114
00115 void ff_MPV_common_init_altivec(MpegEncContext *s)
00116 {
00117 if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) return;
00118
00119 if ((s->avctx->dct_algo == FF_DCT_AUTO) ||
00120 (s->avctx->dct_algo == FF_DCT_ALTIVEC)) {
00121 s->dct_unquantize_h263_intra = dct_unquantize_h263_altivec;
00122 s->dct_unquantize_h263_inter = dct_unquantize_h263_altivec;
00123 }
00124 }