00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00027 #include "avcodec.h"
00028 #include "dsputil.h"
00029
00030 #define IdctAdjustBeforeShift 8
00031 #define xC1S7 64277
00032 #define xC2S6 60547
00033 #define xC3S5 54491
00034 #define xC4S4 46341
00035 #define xC5S3 36410
00036 #define xC6S2 25080
00037 #define xC7S1 12785
00038
00039 #define M(a,b) (((a) * (b))>>16)
00040
00041 static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int type)
00042 {
00043 int16_t *ip = input;
00044 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
00045
00046 int A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H;
00047 int Ed, Gd, Add, Bdd, Fd, Hd;
00048
00049 int i;
00050
00051
00052 for (i = 0; i < 8; i++) {
00053
00054 if ( ip[0] | ip[1] | ip[2] | ip[3] | ip[4] | ip[5] | ip[6] | ip[7] ) {
00055 A = M(xC1S7, ip[1]) + M(xC7S1, ip[7]);
00056 B = M(xC7S1, ip[1]) - M(xC1S7, ip[7]);
00057 C = M(xC3S5, ip[3]) + M(xC5S3, ip[5]);
00058 D = M(xC3S5, ip[5]) - M(xC5S3, ip[3]);
00059
00060 Ad = M(xC4S4, (A - C));
00061 Bd = M(xC4S4, (B - D));
00062
00063 Cd = A + C;
00064 Dd = B + D;
00065
00066 E = M(xC4S4, (ip[0] + ip[4]));
00067 F = M(xC4S4, (ip[0] - ip[4]));
00068
00069 G = M(xC2S6, ip[2]) + M(xC6S2, ip[6]);
00070 H = M(xC6S2, ip[2]) - M(xC2S6, ip[6]);
00071
00072 Ed = E - G;
00073 Gd = E + G;
00074
00075 Add = F + Ad;
00076 Bdd = Bd - H;
00077
00078 Fd = F - Ad;
00079 Hd = Bd + H;
00080
00081
00082 ip[0] = Gd + Cd ;
00083 ip[7] = Gd - Cd ;
00084
00085 ip[1] = Add + Hd;
00086 ip[2] = Add - Hd;
00087
00088 ip[3] = Ed + Dd ;
00089 ip[4] = Ed - Dd ;
00090
00091 ip[5] = Fd + Bdd;
00092 ip[6] = Fd - Bdd;
00093 }
00094
00095 ip += 8;
00096 }
00097
00098 ip = input;
00099
00100 for ( i = 0; i < 8; i++) {
00101
00102 if ( ip[1 * 8] | ip[2 * 8] | ip[3 * 8] |
00103 ip[4 * 8] | ip[5 * 8] | ip[6 * 8] | ip[7 * 8] ) {
00104
00105 A = M(xC1S7, ip[1*8]) + M(xC7S1, ip[7*8]);
00106 B = M(xC7S1, ip[1*8]) - M(xC1S7, ip[7*8]);
00107 C = M(xC3S5, ip[3*8]) + M(xC5S3, ip[5*8]);
00108 D = M(xC3S5, ip[5*8]) - M(xC5S3, ip[3*8]);
00109
00110 Ad = M(xC4S4, (A - C));
00111 Bd = M(xC4S4, (B - D));
00112
00113 Cd = A + C;
00114 Dd = B + D;
00115
00116 E = M(xC4S4, (ip[0*8] + ip[4*8])) + 8;
00117 F = M(xC4S4, (ip[0*8] - ip[4*8])) + 8;
00118
00119 if(type==1){
00120 E += 16*128;
00121 F += 16*128;
00122 }
00123
00124 G = M(xC2S6, ip[2*8]) + M(xC6S2, ip[6*8]);
00125 H = M(xC6S2, ip[2*8]) - M(xC2S6, ip[6*8]);
00126
00127 Ed = E - G;
00128 Gd = E + G;
00129
00130 Add = F + Ad;
00131 Bdd = Bd - H;
00132
00133 Fd = F - Ad;
00134 Hd = Bd + H;
00135
00136
00137 if(type==0){
00138 ip[0*8] = (Gd + Cd ) >> 4;
00139 ip[7*8] = (Gd - Cd ) >> 4;
00140
00141 ip[1*8] = (Add + Hd ) >> 4;
00142 ip[2*8] = (Add - Hd ) >> 4;
00143
00144 ip[3*8] = (Ed + Dd ) >> 4;
00145 ip[4*8] = (Ed - Dd ) >> 4;
00146
00147 ip[5*8] = (Fd + Bdd ) >> 4;
00148 ip[6*8] = (Fd - Bdd ) >> 4;
00149 }else if(type==1){
00150 dst[0*stride] = cm[(Gd + Cd ) >> 4];
00151 dst[7*stride] = cm[(Gd - Cd ) >> 4];
00152
00153 dst[1*stride] = cm[(Add + Hd ) >> 4];
00154 dst[2*stride] = cm[(Add - Hd ) >> 4];
00155
00156 dst[3*stride] = cm[(Ed + Dd ) >> 4];
00157 dst[4*stride] = cm[(Ed - Dd ) >> 4];
00158
00159 dst[5*stride] = cm[(Fd + Bdd ) >> 4];
00160 dst[6*stride] = cm[(Fd - Bdd ) >> 4];
00161 }else{
00162 dst[0*stride] = cm[dst[0*stride] + ((Gd + Cd ) >> 4)];
00163 dst[7*stride] = cm[dst[7*stride] + ((Gd - Cd ) >> 4)];
00164
00165 dst[1*stride] = cm[dst[1*stride] + ((Add + Hd ) >> 4)];
00166 dst[2*stride] = cm[dst[2*stride] + ((Add - Hd ) >> 4)];
00167
00168 dst[3*stride] = cm[dst[3*stride] + ((Ed + Dd ) >> 4)];
00169 dst[4*stride] = cm[dst[4*stride] + ((Ed - Dd ) >> 4)];
00170
00171 dst[5*stride] = cm[dst[5*stride] + ((Fd + Bdd ) >> 4)];
00172 dst[6*stride] = cm[dst[6*stride] + ((Fd - Bdd ) >> 4)];
00173 }
00174
00175 } else {
00176 if(type==0){
00177 ip[0*8] =
00178 ip[1*8] =
00179 ip[2*8] =
00180 ip[3*8] =
00181 ip[4*8] =
00182 ip[5*8] =
00183 ip[6*8] =
00184 ip[7*8] = ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20);
00185 }else if(type==1){
00186 dst[0*stride]=
00187 dst[1*stride]=
00188 dst[2*stride]=
00189 dst[3*stride]=
00190 dst[4*stride]=
00191 dst[5*stride]=
00192 dst[6*stride]=
00193 dst[7*stride]= cm[128 + ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20)];
00194 }else{
00195 if(ip[0*8]){
00196 int v= ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20);
00197 dst[0*stride] = cm[dst[0*stride] + v];
00198 dst[1*stride] = cm[dst[1*stride] + v];
00199 dst[2*stride] = cm[dst[2*stride] + v];
00200 dst[3*stride] = cm[dst[3*stride] + v];
00201 dst[4*stride] = cm[dst[4*stride] + v];
00202 dst[5*stride] = cm[dst[5*stride] + v];
00203 dst[6*stride] = cm[dst[6*stride] + v];
00204 dst[7*stride] = cm[dst[7*stride] + v];
00205 }
00206 }
00207 }
00208
00209 ip++;
00210 dst++;
00211 }
00212 }
00213
00214 void ff_vp3_idct_c(DCTELEM *block){
00215 idct(NULL, 0, block, 0);
00216 }
00217
00218 void ff_vp3_idct_put_c(uint8_t *dest, int line_size, DCTELEM *block){
00219 idct(dest, line_size, block, 1);
00220 }
00221
00222 void ff_vp3_idct_add_c(uint8_t *dest, int line_size, DCTELEM *block){
00223 idct(dest, line_size, block, 2);
00224 }
00225
00226 void ff_vp3_idct_dc_add_c(uint8_t *dest, int line_size, const DCTELEM *block){
00227 int i, dc = (block[0] + 15) >> 5;
00228 const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP + dc;
00229
00230 for(i = 0; i < 8; i++){
00231 dest[0] = cm[dest[0]];
00232 dest[1] = cm[dest[1]];
00233 dest[2] = cm[dest[2]];
00234 dest[3] = cm[dest[3]];
00235 dest[4] = cm[dest[4]];
00236 dest[5] = cm[dest[5]];
00237 dest[6] = cm[dest[6]];
00238 dest[7] = cm[dest[7]];
00239 dest += line_size;
00240 }
00241 }
00242
00243 void ff_vp3_v_loop_filter_c(uint8_t *first_pixel, int stride, int *bounding_values)
00244 {
00245 unsigned char *end;
00246 int filter_value;
00247 const int nstride= -stride;
00248
00249 for (end= first_pixel + 8; first_pixel < end; first_pixel++) {
00250 filter_value =
00251 (first_pixel[2 * nstride] - first_pixel[ stride])
00252 +3*(first_pixel[0 ] - first_pixel[nstride]);
00253 filter_value = bounding_values[(filter_value + 4) >> 3];
00254 first_pixel[nstride] = av_clip_uint8(first_pixel[nstride] + filter_value);
00255 first_pixel[0] = av_clip_uint8(first_pixel[0] - filter_value);
00256 }
00257 }
00258
00259 void ff_vp3_h_loop_filter_c(uint8_t *first_pixel, int stride, int *bounding_values)
00260 {
00261 unsigned char *end;
00262 int filter_value;
00263
00264 for (end= first_pixel + 8*stride; first_pixel != end; first_pixel += stride) {
00265 filter_value =
00266 (first_pixel[-2] - first_pixel[ 1])
00267 +3*(first_pixel[ 0] - first_pixel[-1]);
00268 filter_value = bounding_values[(filter_value + 4) >> 3];
00269 first_pixel[-1] = av_clip_uint8(first_pixel[-1] + filter_value);
00270 first_pixel[ 0] = av_clip_uint8(first_pixel[ 0] - filter_value);
00271 }
00272 }