Libav 0.7.1
|
00001 /* 00002 * Copyright (C) 2004 the ffmpeg project 00003 * 00004 * This file is part of Libav. 00005 * 00006 * Libav is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * Libav is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with Libav; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 /* Inverse DCT on the rows now */ 00052 for (i = 0; i < 8; i++) { 00053 /* Check for non-zero values */ 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 /* Final sequence of operations over-write original inputs. */ 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; /* next row */ 00096 } 00097 00098 ip = input; 00099 00100 for ( i = 0; i < 8; i++) { 00101 /* Check for non-zero values (bitwise or faster than ||) */ 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){ //HACK 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 /* Final sequence of operations over-write original inputs. */ 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++; /* next column */ 00210 dst++; 00211 } 00212 } 00213 00214 void ff_vp3_idct_c(DCTELEM *block/* align 16*/){ 00215 idct(NULL, 0, block, 0); 00216 } 00217 00218 void ff_vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/){ 00219 idct(dest, line_size, block, 1); 00220 } 00221 00222 void ff_vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/){ 00223 idct(dest, line_size, block, 2); 00224 } 00225 00226 void ff_vp3_idct_dc_add_c(uint8_t *dest/*align 8*/, int line_size, const DCTELEM *block/*align 16*/){ 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 }