Libav
|
00001 /* 00002 * RV30 decoder motion compensation functions 00003 * Copyright (c) 2007 Konstantin Shishkov 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00027 #include "avcodec.h" 00028 #include "dsputil.h" 00029 00030 #define RV30_LOWPASS(OPNAME, OP) \ 00031 static av_unused void OPNAME ## rv30_tpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\ 00032 const int h=8;\ 00033 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ 00034 int i;\ 00035 for(i=0; i<h; i++)\ 00036 {\ 00037 OP(dst[0], (-(src[-1]+src[2]) + src[0]*C1 + src[1]*C2 + 8)>>4);\ 00038 OP(dst[1], (-(src[ 0]+src[3]) + src[1]*C1 + src[2]*C2 + 8)>>4);\ 00039 OP(dst[2], (-(src[ 1]+src[4]) + src[2]*C1 + src[3]*C2 + 8)>>4);\ 00040 OP(dst[3], (-(src[ 2]+src[5]) + src[3]*C1 + src[4]*C2 + 8)>>4);\ 00041 OP(dst[4], (-(src[ 3]+src[6]) + src[4]*C1 + src[5]*C2 + 8)>>4);\ 00042 OP(dst[5], (-(src[ 4]+src[7]) + src[5]*C1 + src[6]*C2 + 8)>>4);\ 00043 OP(dst[6], (-(src[ 5]+src[8]) + src[6]*C1 + src[7]*C2 + 8)>>4);\ 00044 OP(dst[7], (-(src[ 6]+src[9]) + src[7]*C1 + src[8]*C2 + 8)>>4);\ 00045 dst+=dstStride;\ 00046 src+=srcStride;\ 00047 }\ 00048 }\ 00049 \ 00050 static void OPNAME ## rv30_tpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\ 00051 const int w=8;\ 00052 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ 00053 int i;\ 00054 for(i=0; i<w; i++)\ 00055 {\ 00056 const int srcA= src[-1*srcStride];\ 00057 const int src0= src[0 *srcStride];\ 00058 const int src1= src[1 *srcStride];\ 00059 const int src2= src[2 *srcStride];\ 00060 const int src3= src[3 *srcStride];\ 00061 const int src4= src[4 *srcStride];\ 00062 const int src5= src[5 *srcStride];\ 00063 const int src6= src[6 *srcStride];\ 00064 const int src7= src[7 *srcStride];\ 00065 const int src8= src[8 *srcStride];\ 00066 const int src9= src[9 *srcStride];\ 00067 OP(dst[0*dstStride], (-(srcA+src2) + src0*C1 + src1*C2 + 8)>>4);\ 00068 OP(dst[1*dstStride], (-(src0+src3) + src1*C1 + src2*C2 + 8)>>4);\ 00069 OP(dst[2*dstStride], (-(src1+src4) + src2*C1 + src3*C2 + 8)>>4);\ 00070 OP(dst[3*dstStride], (-(src2+src5) + src3*C1 + src4*C2 + 8)>>4);\ 00071 OP(dst[4*dstStride], (-(src3+src6) + src4*C1 + src5*C2 + 8)>>4);\ 00072 OP(dst[5*dstStride], (-(src4+src7) + src5*C1 + src6*C2 + 8)>>4);\ 00073 OP(dst[6*dstStride], (-(src5+src8) + src6*C1 + src7*C2 + 8)>>4);\ 00074 OP(dst[7*dstStride], (-(src6+src9) + src7*C1 + src8*C2 + 8)>>4);\ 00075 dst++;\ 00076 src++;\ 00077 }\ 00078 }\ 00079 \ 00080 static void OPNAME ## rv30_tpel8_hv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ 00081 const int w = 8;\ 00082 const int h = 8;\ 00083 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ 00084 int i, j;\ 00085 for(j = 0; j < h; j++){\ 00086 for(i = 0; i < w; i++){\ 00087 OP(dst[i], (\ 00088 src[srcStride*-1+i-1] -12*src[srcStride*-1+i] -6*src[srcStride*-1+i+1] +src[srcStride*-1+i+2]+\ 00089 -12*src[srcStride* 0+i-1] +144*src[srcStride* 0+i] +72*src[srcStride* 0+i+1] -12*src[srcStride* 0+i+2] +\ 00090 -6*src[srcStride* 1+i-1] +72*src[srcStride* 1+i] +36*src[srcStride* 1+i+1] -6*src[srcStride* 1+i+2] +\ 00091 src[srcStride* 2+i-1] -12*src[srcStride* 2+i] -6*src[srcStride* 2+i+1] +src[srcStride* 2+i+2] +\ 00092 128)>>8);\ 00093 }\ 00094 src += srcStride;\ 00095 dst += dstStride;\ 00096 }\ 00097 }\ 00098 \ 00099 static void OPNAME ## rv30_tpel8_hhv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ 00100 const int w = 8;\ 00101 const int h = 8;\ 00102 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ 00103 int i, j;\ 00104 for(j = 0; j < h; j++){\ 00105 for(i = 0; i < w; i++){\ 00106 OP(dst[i], (\ 00107 src[srcStride*-1+i-1] -12*src[srcStride*-1+i+1] -6*src[srcStride*-1+i] +src[srcStride*-1+i+2]+\ 00108 -12*src[srcStride* 0+i-1] +144*src[srcStride* 0+i+1] +72*src[srcStride* 0+i] -12*src[srcStride* 0+i+2]+\ 00109 -6*src[srcStride* 1+i-1] +72*src[srcStride* 1+i+1] +36*src[srcStride* 1+i] -6*src[srcStride* 1+i+2]+\ 00110 src[srcStride* 2+i-1] -12*src[srcStride* 2+i+1] -6*src[srcStride* 2+i] +src[srcStride* 2+i+2]+\ 00111 128)>>8);\ 00112 }\ 00113 src += srcStride;\ 00114 dst += dstStride;\ 00115 }\ 00116 }\ 00117 \ 00118 static void OPNAME ## rv30_tpel8_hvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ 00119 const int w = 8;\ 00120 const int h = 8;\ 00121 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ 00122 int i, j;\ 00123 for(j = 0; j < h; j++){\ 00124 for(i = 0; i < w; i++){\ 00125 OP(dst[i], (\ 00126 src[srcStride*-1+i-1] -12*src[srcStride*-1+i] -6*src[srcStride*-1+i+1] +src[srcStride*-1+i+2]+\ 00127 -6*src[srcStride* 0+i-1] +72*src[srcStride* 0+i] +36*src[srcStride* 0+i+1] -6*src[srcStride* 0+i+2]+\ 00128 -12*src[srcStride* 1+i-1] +144*src[srcStride* 1+i] +72*src[srcStride* 1+i+1] -12*src[srcStride* 1+i+2]+\ 00129 src[srcStride* 2+i-1] -12*src[srcStride* 2+i] -6*src[srcStride* 2+i+1] +src[srcStride* 2+i+2]+\ 00130 128)>>8);\ 00131 }\ 00132 src += srcStride;\ 00133 dst += dstStride;\ 00134 }\ 00135 }\ 00136 \ 00137 static void OPNAME ## rv30_tpel8_hhvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ 00138 const int w = 8;\ 00139 const int h = 8;\ 00140 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ 00141 int i, j;\ 00142 for(j = 0; j < h; j++){\ 00143 for(i = 0; i < w; i++){\ 00144 OP(dst[i], (\ 00145 36*src[i+srcStride*0] +54*src[i+1+srcStride*0] +6*src[i+2+srcStride*0]+\ 00146 54*src[i+srcStride*1] +81*src[i+1+srcStride*1] +9*src[i+2+srcStride*1]+\ 00147 6*src[i+srcStride*2] + 9*src[i+1+srcStride*2] + src[i+2+srcStride*2]+\ 00148 128)>>8);\ 00149 }\ 00150 src += srcStride;\ 00151 dst += dstStride;\ 00152 }\ 00153 }\ 00154 \ 00155 static void OPNAME ## rv30_tpel16_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\ 00156 OPNAME ## rv30_tpel8_v_lowpass(dst , src , dstStride, srcStride, C1, C2);\ 00157 OPNAME ## rv30_tpel8_v_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\ 00158 src += 8*srcStride;\ 00159 dst += 8*dstStride;\ 00160 OPNAME ## rv30_tpel8_v_lowpass(dst , src , dstStride, srcStride, C1, C2);\ 00161 OPNAME ## rv30_tpel8_v_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\ 00162 }\ 00163 \ 00164 static void OPNAME ## rv30_tpel16_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\ 00165 OPNAME ## rv30_tpel8_h_lowpass(dst , src , dstStride, srcStride, C1, C2);\ 00166 OPNAME ## rv30_tpel8_h_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\ 00167 src += 8*srcStride;\ 00168 dst += 8*dstStride;\ 00169 OPNAME ## rv30_tpel8_h_lowpass(dst , src , dstStride, srcStride, C1, C2);\ 00170 OPNAME ## rv30_tpel8_h_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\ 00171 }\ 00172 \ 00173 static void OPNAME ## rv30_tpel16_hv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ 00174 OPNAME ## rv30_tpel8_hv_lowpass(dst , src , dstStride, srcStride);\ 00175 OPNAME ## rv30_tpel8_hv_lowpass(dst+8, src+8, dstStride, srcStride);\ 00176 src += 8*srcStride;\ 00177 dst += 8*dstStride;\ 00178 OPNAME ## rv30_tpel8_hv_lowpass(dst , src , dstStride, srcStride);\ 00179 OPNAME ## rv30_tpel8_hv_lowpass(dst+8, src+8, dstStride, srcStride);\ 00180 }\ 00181 \ 00182 static void OPNAME ## rv30_tpel16_hhv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ 00183 OPNAME ## rv30_tpel8_hhv_lowpass(dst , src , dstStride, srcStride);\ 00184 OPNAME ## rv30_tpel8_hhv_lowpass(dst+8, src+8, dstStride, srcStride);\ 00185 src += 8*srcStride;\ 00186 dst += 8*dstStride;\ 00187 OPNAME ## rv30_tpel8_hhv_lowpass(dst , src , dstStride, srcStride);\ 00188 OPNAME ## rv30_tpel8_hhv_lowpass(dst+8, src+8, dstStride, srcStride);\ 00189 }\ 00190 \ 00191 static void OPNAME ## rv30_tpel16_hvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ 00192 OPNAME ## rv30_tpel8_hvv_lowpass(dst , src , dstStride, srcStride);\ 00193 OPNAME ## rv30_tpel8_hvv_lowpass(dst+8, src+8, dstStride, srcStride);\ 00194 src += 8*srcStride;\ 00195 dst += 8*dstStride;\ 00196 OPNAME ## rv30_tpel8_hvv_lowpass(dst , src , dstStride, srcStride);\ 00197 OPNAME ## rv30_tpel8_hvv_lowpass(dst+8, src+8, dstStride, srcStride);\ 00198 }\ 00199 \ 00200 static void OPNAME ## rv30_tpel16_hhvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ 00201 OPNAME ## rv30_tpel8_hhvv_lowpass(dst , src , dstStride, srcStride);\ 00202 OPNAME ## rv30_tpel8_hhvv_lowpass(dst+8, src+8, dstStride, srcStride);\ 00203 src += 8*srcStride;\ 00204 dst += 8*dstStride;\ 00205 OPNAME ## rv30_tpel8_hhvv_lowpass(dst , src , dstStride, srcStride);\ 00206 OPNAME ## rv30_tpel8_hhvv_lowpass(dst+8, src+8, dstStride, srcStride);\ 00207 }\ 00208 \ 00209 00210 #define RV30_MC(OPNAME, SIZE) \ 00211 static void OPNAME ## rv30_tpel ## SIZE ## _mc10_c(uint8_t *dst, uint8_t *src, int stride){\ 00212 OPNAME ## rv30_tpel ## SIZE ## _h_lowpass(dst, src, stride, stride, 12, 6);\ 00213 }\ 00214 \ 00215 static void OPNAME ## rv30_tpel ## SIZE ## _mc20_c(uint8_t *dst, uint8_t *src, int stride){\ 00216 OPNAME ## rv30_tpel ## SIZE ## _h_lowpass(dst, src, stride, stride, 6, 12);\ 00217 }\ 00218 \ 00219 static void OPNAME ## rv30_tpel ## SIZE ## _mc01_c(uint8_t *dst, uint8_t *src, int stride){\ 00220 OPNAME ## rv30_tpel ## SIZE ## _v_lowpass(dst, src, stride, stride, 12, 6);\ 00221 }\ 00222 \ 00223 static void OPNAME ## rv30_tpel ## SIZE ## _mc02_c(uint8_t *dst, uint8_t *src, int stride){\ 00224 OPNAME ## rv30_tpel ## SIZE ## _v_lowpass(dst, src, stride, stride, 6, 12);\ 00225 }\ 00226 \ 00227 static void OPNAME ## rv30_tpel ## SIZE ## _mc11_c(uint8_t *dst, uint8_t *src, int stride){\ 00228 OPNAME ## rv30_tpel ## SIZE ## _hv_lowpass(dst, src, stride, stride);\ 00229 }\ 00230 \ 00231 static void OPNAME ## rv30_tpel ## SIZE ## _mc12_c(uint8_t *dst, uint8_t *src, int stride){\ 00232 OPNAME ## rv30_tpel ## SIZE ## _hvv_lowpass(dst, src, stride, stride);\ 00233 }\ 00234 \ 00235 static void OPNAME ## rv30_tpel ## SIZE ## _mc21_c(uint8_t *dst, uint8_t *src, int stride){\ 00236 OPNAME ## rv30_tpel ## SIZE ## _hhv_lowpass(dst, src, stride, stride);\ 00237 }\ 00238 \ 00239 static void OPNAME ## rv30_tpel ## SIZE ## _mc22_c(uint8_t *dst, uint8_t *src, int stride){\ 00240 OPNAME ## rv30_tpel ## SIZE ## _hhvv_lowpass(dst, src, stride, stride);\ 00241 }\ 00242 \ 00243 00244 #define op_avg(a, b) a = (((a)+cm[b]+1)>>1) 00245 #define op_put(a, b) a = cm[b] 00246 00247 RV30_LOWPASS(put_ , op_put) 00248 RV30_LOWPASS(avg_ , op_avg) 00249 RV30_MC(put_, 8) 00250 RV30_MC(put_, 16) 00251 RV30_MC(avg_, 8) 00252 RV30_MC(avg_, 16) 00253 00254 av_cold void ff_rv30dsp_init(DSPContext* c, AVCodecContext *avctx) { 00255 c->put_rv30_tpel_pixels_tab[0][ 0] = c->put_h264_qpel_pixels_tab[0][0]; 00256 c->put_rv30_tpel_pixels_tab[0][ 1] = put_rv30_tpel16_mc10_c; 00257 c->put_rv30_tpel_pixels_tab[0][ 2] = put_rv30_tpel16_mc20_c; 00258 c->put_rv30_tpel_pixels_tab[0][ 4] = put_rv30_tpel16_mc01_c; 00259 c->put_rv30_tpel_pixels_tab[0][ 5] = put_rv30_tpel16_mc11_c; 00260 c->put_rv30_tpel_pixels_tab[0][ 6] = put_rv30_tpel16_mc21_c; 00261 c->put_rv30_tpel_pixels_tab[0][ 8] = put_rv30_tpel16_mc02_c; 00262 c->put_rv30_tpel_pixels_tab[0][ 9] = put_rv30_tpel16_mc12_c; 00263 c->put_rv30_tpel_pixels_tab[0][10] = put_rv30_tpel16_mc22_c; 00264 c->avg_rv30_tpel_pixels_tab[0][ 0] = c->avg_h264_qpel_pixels_tab[0][0]; 00265 c->avg_rv30_tpel_pixels_tab[0][ 1] = avg_rv30_tpel16_mc10_c; 00266 c->avg_rv30_tpel_pixels_tab[0][ 2] = avg_rv30_tpel16_mc20_c; 00267 c->avg_rv30_tpel_pixels_tab[0][ 4] = avg_rv30_tpel16_mc01_c; 00268 c->avg_rv30_tpel_pixels_tab[0][ 5] = avg_rv30_tpel16_mc11_c; 00269 c->avg_rv30_tpel_pixels_tab[0][ 6] = avg_rv30_tpel16_mc21_c; 00270 c->avg_rv30_tpel_pixels_tab[0][ 8] = avg_rv30_tpel16_mc02_c; 00271 c->avg_rv30_tpel_pixels_tab[0][ 9] = avg_rv30_tpel16_mc12_c; 00272 c->avg_rv30_tpel_pixels_tab[0][10] = avg_rv30_tpel16_mc22_c; 00273 c->put_rv30_tpel_pixels_tab[1][ 0] = c->put_h264_qpel_pixels_tab[1][0]; 00274 c->put_rv30_tpel_pixels_tab[1][ 1] = put_rv30_tpel8_mc10_c; 00275 c->put_rv30_tpel_pixels_tab[1][ 2] = put_rv30_tpel8_mc20_c; 00276 c->put_rv30_tpel_pixels_tab[1][ 4] = put_rv30_tpel8_mc01_c; 00277 c->put_rv30_tpel_pixels_tab[1][ 5] = put_rv30_tpel8_mc11_c; 00278 c->put_rv30_tpel_pixels_tab[1][ 6] = put_rv30_tpel8_mc21_c; 00279 c->put_rv30_tpel_pixels_tab[1][ 8] = put_rv30_tpel8_mc02_c; 00280 c->put_rv30_tpel_pixels_tab[1][ 9] = put_rv30_tpel8_mc12_c; 00281 c->put_rv30_tpel_pixels_tab[1][10] = put_rv30_tpel8_mc22_c; 00282 c->avg_rv30_tpel_pixels_tab[1][ 0] = c->avg_h264_qpel_pixels_tab[1][0]; 00283 c->avg_rv30_tpel_pixels_tab[1][ 1] = avg_rv30_tpel8_mc10_c; 00284 c->avg_rv30_tpel_pixels_tab[1][ 2] = avg_rv30_tpel8_mc20_c; 00285 c->avg_rv30_tpel_pixels_tab[1][ 4] = avg_rv30_tpel8_mc01_c; 00286 c->avg_rv30_tpel_pixels_tab[1][ 5] = avg_rv30_tpel8_mc11_c; 00287 c->avg_rv30_tpel_pixels_tab[1][ 6] = avg_rv30_tpel8_mc21_c; 00288 c->avg_rv30_tpel_pixels_tab[1][ 8] = avg_rv30_tpel8_mc02_c; 00289 c->avg_rv30_tpel_pixels_tab[1][ 9] = avg_rv30_tpel8_mc12_c; 00290 c->avg_rv30_tpel_pixels_tab[1][10] = avg_rv30_tpel8_mc22_c; 00291 }