00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "libavcodec/avcodec.h"
00022 #include "libavcodec/dsputil.h"
00023 #include "libavcodec/mpegvideo.h"
00024 #include "mpegvideo_arm.h"
00025
00026 static void dct_unquantize_h263_intra_iwmmxt(MpegEncContext *s,
00027 DCTELEM *block, int n, int qscale)
00028 {
00029 int level, qmul, qadd;
00030 int nCoeffs;
00031 DCTELEM *block_orig = block;
00032
00033 assert(s->block_last_index[n]>=0);
00034
00035 qmul = qscale << 1;
00036
00037 if (!s->h263_aic) {
00038 if (n < 4)
00039 level = block[0] * s->y_dc_scale;
00040 else
00041 level = block[0] * s->c_dc_scale;
00042 qadd = (qscale - 1) | 1;
00043 }else{
00044 qadd = 0;
00045 level = block[0];
00046 }
00047 if(s->ac_pred)
00048 nCoeffs=63;
00049 else
00050 nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
00051
00052 __asm__ volatile (
00053
00054
00055
00056 "tbcsth wr6, %[qmul] \n\t"
00057
00058
00059
00060 "tbcsth wr5, %[qadd] \n\t"
00061 "wzero wr7 \n\t"
00062 "wzero wr4 \n\t"
00063 "wsubh wr7, wr5, wr7 \n\t"
00064 "1: \n\t"
00065 "wldrd wr2, [%[block]] \n\t"
00066 "wldrd wr3, [%[block], #8] \n\t"
00067 "wmulsl wr0, wr6, wr2 \n\t"
00068 "wmulsl wr1, wr6, wr3 \n\t"
00069
00070
00071 "wcmpgtsh wr2, wr4, wr2 \n\t"
00072 "wcmpgtsh wr3, wr4, wr2 \n\t"
00073 "wxor wr0, wr2, wr0 \n\t"
00074 "wxor wr1, wr3, wr1 \n\t"
00075 "waddh wr0, wr7, wr0 \n\t"
00076 "waddh wr1, wr7, wr1 \n\t"
00077 "wxor wr2, wr0, wr2 \n\t"
00078 "wxor wr3, wr1, wr3 \n\t"
00079 "wcmpeqh wr0, wr7, wr0 \n\t"
00080 "wcmpeqh wr1, wr7, wr1 \n\t"
00081 "wandn wr0, wr2, wr0 \n\t"
00082 "wandn wr1, wr3, wr1 \n\t"
00083 "wstrd wr0, [%[block]] \n\t"
00084 "wstrd wr1, [%[block], #8] \n\t"
00085 "add %[block], %[block], #16 \n\t"
00086 "subs %[i], %[i], #1 \n\t"
00087 "bne 1b \n\t"
00088 :[block]"+r"(block)
00089 :[i]"r"((nCoeffs + 8) / 8), [qmul]"r"(qmul), [qadd]"r"(qadd)
00090 :"memory");
00091
00092 block_orig[0] = level;
00093 }
00094
00095 #if 0
00096 static void dct_unquantize_h263_inter_iwmmxt(MpegEncContext *s,
00097 DCTELEM *block, int n, int qscale)
00098 {
00099 int nCoeffs;
00100
00101 assert(s->block_last_index[n]>=0);
00102
00103 if(s->ac_pred)
00104 nCoeffs=63;
00105 else
00106 nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
00107
00108 ippiQuantInvInter_Compact_H263_16s_I(block, nCoeffs+1, qscale);
00109 }
00110 #endif
00111
00112 void MPV_common_init_iwmmxt(MpegEncContext *s)
00113 {
00114 if (!(mm_flags & FF_MM_IWMMXT)) return;
00115
00116 s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_iwmmxt;
00117 #if 0
00118 s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_iwmmxt;
00119 #endif
00120 }