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