• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/vp3dsp.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 the ffmpeg project
00003  *
00004  * This file is part of FFmpeg.
00005  *
00006  * FFmpeg 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  * FFmpeg 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 FFmpeg; 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     const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
00228     int i, dc = block[0];
00229     dc = (46341*dc)>>16;
00230     dc = (46341*dc + (8<<16))>>20;
00231 
00232     for(i = 0; i < 8; i++){
00233         dest[0] = cm[dest[0]+dc];
00234         dest[1] = cm[dest[1]+dc];
00235         dest[2] = cm[dest[2]+dc];
00236         dest[3] = cm[dest[3]+dc];
00237         dest[4] = cm[dest[4]+dc];
00238         dest[5] = cm[dest[5]+dc];
00239         dest[6] = cm[dest[6]+dc];
00240         dest[7] = cm[dest[7]+dc];
00241         dest += line_size;
00242     }
00243 }
00244 
00245 void ff_vp3_v_loop_filter_c(uint8_t *first_pixel, int stride, int *bounding_values)
00246 {
00247     unsigned char *end;
00248     int filter_value;
00249     const int nstride= -stride;
00250 
00251     for (end= first_pixel + 8; first_pixel < end; first_pixel++) {
00252         filter_value =
00253             (first_pixel[2 * nstride] - first_pixel[ stride])
00254          +3*(first_pixel[0          ] - first_pixel[nstride]);
00255         filter_value = bounding_values[(filter_value + 4) >> 3];
00256         first_pixel[nstride] = av_clip_uint8(first_pixel[nstride] + filter_value);
00257         first_pixel[0] = av_clip_uint8(first_pixel[0] - filter_value);
00258     }
00259 }
00260 
00261 void ff_vp3_h_loop_filter_c(uint8_t *first_pixel, int stride, int *bounding_values)
00262 {
00263     unsigned char *end;
00264     int filter_value;
00265 
00266     for (end= first_pixel + 8*stride; first_pixel != end; first_pixel += stride) {
00267         filter_value =
00268             (first_pixel[-2] - first_pixel[ 1])
00269          +3*(first_pixel[ 0] - first_pixel[-1]);
00270         filter_value = bounding_values[(filter_value + 4) >> 3];
00271         first_pixel[-1] = av_clip_uint8(first_pixel[-1] + filter_value);
00272         first_pixel[ 0] = av_clip_uint8(first_pixel[ 0] - filter_value);
00273     }
00274 }

Generated on Fri Sep 16 2011 17:17:45 for FFmpeg by  doxygen 1.7.1