00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "dsputil.h"
00023 #include "mpegvideo.h"
00024 #include "avcodec.h"
00025
00026
00027 #ifdef ENABLE_ARM_TESTS
00028
00033 static inline void dct_unquantize_h263_helper_c(DCTELEM *block, int qmul, int qadd, int count)
00034 {
00035 int i, level;
00036 for (i = 0; i < count; i++) {
00037 level = block[i];
00038 if (level) {
00039 if (level < 0) {
00040 level = level * qmul - qadd;
00041 } else {
00042 level = level * qmul + qadd;
00043 }
00044 block[i] = level;
00045 }
00046 }
00047 }
00048 #endif
00049
00050
00051 #if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))
00052
00064 #define dct_unquantize_h263_special_helper_armv5te(xxblock, xxqmul, xxqadd, xxcount) \
00065 ({ DCTELEM *xblock = xxblock; \
00066 int xqmul = xxqmul, xqadd = xxqadd, xcount = xxcount, xtmp; \
00067 int xdata1, xdata2; \
00068 __asm__ __volatile__( \
00069 "subs %[count], %[count], #2 \n\t" \
00070 "ble 2f \n\t" \
00071 "ldrd r4, [%[block], #0] \n\t" \
00072 "1: \n\t" \
00073 "ldrd r6, [%[block], #8] \n\t" \
00074 \
00075 "rsbs %[data1], %[zero], r4, asr #16 \n\t" \
00076 "addgt %[data1], %[qadd], #0 \n\t" \
00077 "rsblt %[data1], %[qadd], #0 \n\t" \
00078 "smlatbne %[data1], r4, %[qmul], %[data1] \n\t" \
00079 \
00080 "rsbs %[data2], %[zero], r5, asr #16 \n\t" \
00081 "addgt %[data2], %[qadd], #0 \n\t" \
00082 "rsblt %[data2], %[qadd], #0 \n\t" \
00083 "smlatbne %[data2], r5, %[qmul], %[data2] \n\t" \
00084 \
00085 "rsbs %[tmp], %[zero], r4, asl #16 \n\t" \
00086 "addgt %[tmp], %[qadd], #0 \n\t" \
00087 "rsblt %[tmp], %[qadd], #0 \n\t" \
00088 "smlabbne r4, r4, %[qmul], %[tmp] \n\t" \
00089 \
00090 "rsbs %[tmp], %[zero], r5, asl #16 \n\t" \
00091 "addgt %[tmp], %[qadd], #0 \n\t" \
00092 "rsblt %[tmp], %[qadd], #0 \n\t" \
00093 "smlabbne r5, r5, %[qmul], %[tmp] \n\t" \
00094 \
00095 "strh r4, [%[block]], #2 \n\t" \
00096 "strh %[data1], [%[block]], #2 \n\t" \
00097 "strh r5, [%[block]], #2 \n\t" \
00098 "strh %[data2], [%[block]], #2 \n\t" \
00099 \
00100 "rsbs %[data1], %[zero], r6, asr #16 \n\t" \
00101 "addgt %[data1], %[qadd], #0 \n\t" \
00102 "rsblt %[data1], %[qadd], #0 \n\t" \
00103 "smlatbne %[data1], r6, %[qmul], %[data1] \n\t" \
00104 \
00105 "rsbs %[data2], %[zero], r7, asr #16 \n\t" \
00106 "addgt %[data2], %[qadd], #0 \n\t" \
00107 "rsblt %[data2], %[qadd], #0 \n\t" \
00108 "smlatbne %[data2], r7, %[qmul], %[data2] \n\t" \
00109 \
00110 "rsbs %[tmp], %[zero], r6, asl #16 \n\t" \
00111 "addgt %[tmp], %[qadd], #0 \n\t" \
00112 "rsblt %[tmp], %[qadd], #0 \n\t" \
00113 "smlabbne r6, r6, %[qmul], %[tmp] \n\t" \
00114 \
00115 "rsbs %[tmp], %[zero], r7, asl #16 \n\t" \
00116 "addgt %[tmp], %[qadd], #0 \n\t" \
00117 "rsblt %[tmp], %[qadd], #0 \n\t" \
00118 "smlabbne r7, r7, %[qmul], %[tmp] \n\t" \
00119 \
00120 "strh r6, [%[block]], #2 \n\t" \
00121 "strh %[data1], [%[block]], #2 \n\t" \
00122 "strh r7, [%[block]], #2 \n\t" \
00123 "strh %[data2], [%[block]], #2 \n\t" \
00124 \
00125 "subs %[count], %[count], #8 \n\t" \
00126 "ldrgtd r4, [%[block], #0] \n\t" \
00127 "bgt 1b \n\t" \
00128 \
00129 "adds %[count], %[count], #2 \n\t" \
00130 "ble 3f \n\t" \
00131 "2: \n\t" \
00132 "ldrsh %[data1], [%[block], #0] \n\t" \
00133 "ldrsh %[data2], [%[block], #2] \n\t" \
00134 "mov %[tmp], %[qadd] \n\t" \
00135 "cmp %[data1], #0 \n\t" \
00136 "rsblt %[tmp], %[qadd], #0 \n\t" \
00137 "smlabbne %[data1], %[data1], %[qmul], %[tmp] \n\t" \
00138 "mov %[tmp], %[qadd] \n\t" \
00139 "cmp %[data2], #0 \n\t" \
00140 "rsblt %[tmp], %[qadd], #0 \n\t" \
00141 "smlabbne %[data2], %[data2], %[qmul], %[tmp] \n\t" \
00142 "strh %[data1], [%[block]], #2 \n\t" \
00143 "strh %[data2], [%[block]], #2 \n\t" \
00144 "3: \n\t" \
00145 : [block] "+&r" (xblock), [count] "+&r" (xcount), [tmp] "=&r" (xtmp), \
00146 [data1] "=&r" (xdata1), [data2] "=&r" (xdata2) \
00147 : [qmul] "r" (xqmul), [qadd] "r" (xqadd), [zero] "r" (0) \
00148 : "r4", "r5", "r6", "r7", "cc", "memory" \
00149 ); \
00150 })
00151
00152 static void dct_unquantize_h263_intra_armv5te(MpegEncContext *s,
00153 DCTELEM *block, int n, int qscale)
00154 {
00155 int level, qmul, qadd;
00156 int nCoeffs;
00157
00158 assert(s->block_last_index[n]>=0);
00159
00160 qmul = qscale << 1;
00161
00162 if (!s->h263_aic) {
00163 if (n < 4)
00164 level = block[0] * s->y_dc_scale;
00165 else
00166 level = block[0] * s->c_dc_scale;
00167 qadd = (qscale - 1) | 1;
00168 }else{
00169 qadd = 0;
00170 level = block[0];
00171 }
00172 if(s->ac_pred)
00173 nCoeffs=63;
00174 else
00175 nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
00176
00177 dct_unquantize_h263_special_helper_armv5te(block, qmul, qadd, nCoeffs + 1);
00178 block[0] = level;
00179 }
00180
00181 static void dct_unquantize_h263_inter_armv5te(MpegEncContext *s,
00182 DCTELEM *block, int n, int qscale)
00183 {
00184 int qmul, qadd;
00185 int nCoeffs;
00186
00187 assert(s->block_last_index[n]>=0);
00188
00189 qadd = (qscale - 1) | 1;
00190 qmul = qscale << 1;
00191
00192 nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ];
00193
00194 dct_unquantize_h263_special_helper_armv5te(block, qmul, qadd, nCoeffs + 1);
00195 }
00196
00197 #define HAVE_DCT_UNQUANTIZE_H263_ARMV5TE_OPTIMIZED
00198
00199 #endif
00200
00201 void MPV_common_init_armv5te(MpegEncContext *s)
00202 {
00203 #ifdef HAVE_DCT_UNQUANTIZE_H263_ARMV5TE_OPTIMIZED
00204 s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_armv5te;
00205 s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_armv5te;
00206 #endif
00207 }