00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include "dsputil.h"
00025 #include "intrax8dsp.h"
00026 #include "libavutil/common.h"
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #define area1 (0)
00045 #define area2 (8)
00046 #define area3 (8+8)
00047 #define area4 (8+8+1)
00048 #define area5 (8+8+1+8)
00049 #define area6 (8+8+1+16)
00050
00066 static void x8_setup_spatial_compensation(uint8_t *src, uint8_t *dst, int linesize,
00067 int * range, int * psum, int edges){
00068 uint8_t * ptr;
00069 int sum;
00070 int i;
00071 int min_pix,max_pix;
00072 uint8_t c;
00073
00074 if((edges&3)==3){
00075 *psum=0x80*(8+1+8+2);
00076 *range=0;
00077 memset(dst,0x80,16+1+16+8);
00078
00079
00080 return;
00081 }
00082
00083 min_pix=256;
00084 max_pix=-1;
00085
00086 sum=0;
00087
00088 if(!(edges&1)){
00089 ptr=src-1;
00090 for(i=7;i>=0;i--){
00091 c=*(ptr-1);
00092 dst[area1+i]=c;
00093 c=*(ptr);
00094
00095 sum+=c;
00096 min_pix=FFMIN(min_pix,c);
00097 max_pix=FFMAX(max_pix,c);
00098 dst[area2+i]=c;
00099
00100 ptr+=linesize;
00101 }
00102 }
00103
00104 if(!(edges&2)){
00105 ptr=src-linesize;
00106 for(i=0;i<8;i++){
00107 c=*(ptr+i);
00108 sum+=c;
00109 min_pix=FFMIN(min_pix, c);
00110 max_pix=FFMAX(max_pix, c);
00111 }
00112 if(edges&4){
00113 memset(dst+area5,c,8);
00114 memcpy(dst+area4, ptr, 8);
00115 }else{
00116 memcpy(dst+area4, ptr, 16);
00117 }
00118 memcpy(dst+area6, ptr-linesize, 8);
00119 }
00120
00121 if(edges&3){
00122 int avg=(sum+4)>>3;
00123 if(edges&1){
00124 memset(dst+area1,avg,8+8+1);
00125 }else{
00126 memset(dst+area3,avg, 1+16+8);
00127 }
00128 sum+=avg*9;
00129 }else{
00130 uint8_t c=*(src-1-linesize);
00131 dst[area3]=c;
00132 sum+=c;
00133
00134 }
00135 (*range) = max_pix - min_pix;
00136 sum += *(dst+area5) + *(dst+area5+1);
00137 *psum = sum;
00138 }
00139
00140
00141 static const uint16_t zero_prediction_weights[64*2] = {
00142 640, 640, 669, 480, 708, 354, 748, 257, 792, 198, 760, 143, 808, 101, 772, 72,
00143 480, 669, 537, 537, 598, 416, 661, 316, 719, 250, 707, 185, 768, 134, 745, 97,
00144 354, 708, 416, 598, 488, 488, 564, 388, 634, 317, 642, 241, 716, 179, 706, 132,
00145 257, 748, 316, 661, 388, 564, 469, 469, 543, 395, 571, 311, 655, 238, 660, 180,
00146 198, 792, 250, 719, 317, 634, 395, 543, 469, 469, 507, 380, 597, 299, 616, 231,
00147 161, 855, 206, 788, 266, 710, 340, 623, 411, 548, 455, 455, 548, 366, 576, 288,
00148 122, 972, 159, 914, 211, 842, 276, 758, 341, 682, 389, 584, 483, 483, 520, 390,
00149 110, 1172, 144, 1107, 193, 1028, 254, 932, 317, 846, 366, 731, 458, 611, 499, 499
00150 };
00151
00152 static void spatial_compensation_0(uint8_t *src , uint8_t *dst, int linesize){
00153 int i,j;
00154 int x,y;
00155 unsigned int p;
00156 int a;
00157 uint16_t left_sum[2][8] = { { 0 } };
00158 uint16_t top_sum[2][8] = { { 0 } };
00159
00160 for(i=0;i<8;i++){
00161 a=src[area2+7-i]<<4;
00162 for(j=0;j<8;j++){
00163 p=abs(i-j);
00164 left_sum[p&1][j]+= a>>(p>>1);
00165 }
00166 }
00167
00168 for(i=0;i<8;i++){
00169 a=src[area4+i]<<4;
00170 for(j=0;j<8;j++){
00171 p=abs(i-j);
00172 top_sum[p&1][j]+= a>>(p>>1);
00173 }
00174 }
00175 for(;i<10;i++){
00176 a=src[area4+i]<<4;
00177 for(j=5;j<8;j++){
00178 p=abs(i-j);
00179 top_sum[p&1][j]+= a>>(p>>1);
00180 }
00181 }
00182 for(;i<12;i++){
00183 a=src[area4+i]<<4;
00184 for(j=7;j<8;j++){
00185 p=abs(i-j);
00186 top_sum[p&1][j]+= a>>(p>>1);
00187 }
00188 }
00189
00190 for(i=0;i<8;i++){
00191 top_sum [0][i]+=(top_sum [1][i]*181 + 128 )>>8;
00192 left_sum[0][i]+=(left_sum[1][i]*181 + 128 )>>8;
00193 }
00194 for(y=0;y<8;y++){
00195 for(x=0;x<8;x++){
00196 dst[x] = (
00197 (uint32_t)top_sum [0][x]*zero_prediction_weights[y*16+x*2+0] +
00198 (uint32_t)left_sum[0][y]*zero_prediction_weights[y*16+x*2+1] +
00199 0x8000
00200 )>>16;
00201 }
00202 dst+=linesize;
00203 }
00204 }
00205 static void spatial_compensation_1(uint8_t *src , uint8_t *dst, int linesize){
00206 int x,y;
00207
00208 for(y=0;y<8;y++){
00209 for(x=0;x<8;x++){
00210 dst[x]=src[area4 + FFMIN(2*y+x+2, 15) ];
00211 }
00212 dst+=linesize;
00213 }
00214 }
00215 static void spatial_compensation_2(uint8_t *src , uint8_t *dst, int linesize){
00216 int x,y;
00217
00218 for(y=0;y<8;y++){
00219 for(x=0;x<8;x++){
00220 dst[x]=src[area4 +1+y+x];
00221 }
00222 dst+=linesize;
00223 }
00224 }
00225 static void spatial_compensation_3(uint8_t *src , uint8_t *dst, int linesize){
00226 int x,y;
00227
00228 for(y=0;y<8;y++){
00229 for(x=0;x<8;x++){
00230 dst[x]=src[area4 +((y+1)>>1)+x];
00231 }
00232 dst+=linesize;
00233 }
00234 }
00235 static void spatial_compensation_4(uint8_t *src , uint8_t *dst, int linesize){
00236 int x,y;
00237
00238 for(y=0;y<8;y++){
00239 for(x=0;x<8;x++){
00240 dst[x]=( src[area4+x] + src[area6+x] + 1 )>>1;
00241 }
00242 dst+=linesize;
00243 }
00244 }
00245 static void spatial_compensation_5(uint8_t *src , uint8_t *dst, int linesize){
00246 int x,y;
00247
00248 for(y=0;y<8;y++){
00249 for(x=0;x<8;x++){
00250 if(2*x-y<0){
00251 dst[x]=src[area2+9+2*x-y];
00252 }else{
00253 dst[x]=src[area4 +x-((y+1)>>1)];
00254 }
00255 }
00256 dst+=linesize;
00257 }
00258 }
00259 static void spatial_compensation_6(uint8_t *src , uint8_t *dst, int linesize){
00260 int x,y;
00261
00262 for(y=0;y<8;y++){
00263 for(x=0;x<8;x++){
00264 dst[x]=src[area3+x-y];
00265 }
00266 dst+=linesize;
00267 }
00268 }
00269 static void spatial_compensation_7(uint8_t *src , uint8_t *dst, int linesize){
00270 int x,y;
00271
00272 for(y=0;y<8;y++){
00273 for(x=0;x<8;x++){
00274 if(x-2*y>0){
00275 dst[x]=( src[area3-1+x-2*y] + src[area3+x-2*y] + 1)>>1;
00276 }else{
00277 dst[x]=src[area2+8-y +(x>>1)];
00278 }
00279 }
00280 dst+=linesize;
00281 }
00282 }
00283 static void spatial_compensation_8(uint8_t *src , uint8_t *dst, int linesize){
00284 int x,y;
00285
00286 for(y=0;y<8;y++){
00287 for(x=0;x<8;x++){
00288 dst[x]=( src[area1+7-y] + src[area2+7-y] + 1 )>>1;
00289 }
00290 dst+=linesize;
00291 }
00292 }
00293 static void spatial_compensation_9(uint8_t *src , uint8_t *dst, int linesize){
00294 int x,y;
00295
00296 for(y=0;y<8;y++){
00297 for(x=0;x<8;x++){
00298 dst[x]=src[area2+6-FFMIN(x+y,6)];
00299 }
00300 dst+=linesize;
00301 }
00302 }
00303 static void spatial_compensation_10(uint8_t *src , uint8_t *dst, int linesize){
00304 int x,y;
00305
00306 for(y=0;y<8;y++){
00307 for(x=0;x<8;x++){
00308 dst[x]=(src[area2+7-y]*(8-x)+src[area4+x]*x+4)>>3;
00309 }
00310 dst+=linesize;
00311 }
00312 }
00313 static void spatial_compensation_11(uint8_t *src , uint8_t *dst, int linesize){
00314 int x,y;
00315
00316 for(y=0;y<8;y++){
00317 for(x=0;x<8;x++){
00318 dst[x]=(src[area2+7-y]*y+src[area4+x]*(8-y)+4)>>3;
00319 }
00320 dst+=linesize;
00321 }
00322 }
00323
00324 static void x8_loop_filter(uint8_t * ptr, const int a_stride, const int b_stride, int quant){
00325 int i,t;
00326 int p0,p1,p2,p3,p4,p5,p6,p7,p8,p9;
00327 int ql=(quant+10)>>3;
00328
00329 for(i=0; i<8; i++,ptr+=b_stride){
00330 p0=ptr[-5*a_stride];
00331 p1=ptr[-4*a_stride];
00332 p2=ptr[-3*a_stride];
00333 p3=ptr[-2*a_stride];
00334 p4=ptr[-1*a_stride];
00335 p5=ptr[ 0 ];
00336 p6=ptr[ 1*a_stride];
00337 p7=ptr[ 2*a_stride];
00338 p8=ptr[ 3*a_stride];
00339 p9=ptr[ 4*a_stride];
00340
00341 t=
00342 (FFABS(p1-p2) <= ql) +
00343 (FFABS(p2-p3) <= ql) +
00344 (FFABS(p3-p4) <= ql) +
00345 (FFABS(p4-p5) <= ql);
00346 if(t>0){
00347 t+=
00348 (FFABS(p5-p6) <= ql) +
00349 (FFABS(p6-p7) <= ql) +
00350 (FFABS(p7-p8) <= ql) +
00351 (FFABS(p8-p9) <= ql) +
00352 (FFABS(p0-p1) <= ql);
00353 if(t>=6){
00354 int min,max;
00355
00356 min=max=p1;
00357 min=FFMIN(min,p3); max=FFMAX(max,p3);
00358 min=FFMIN(min,p5); max=FFMAX(max,p5);
00359 min=FFMIN(min,p8); max=FFMAX(max,p8);
00360 if(max-min<2*quant){
00361 min=FFMIN(min,p2); max=FFMAX(max,p2);
00362 min=FFMIN(min,p4); max=FFMAX(max,p4);
00363 min=FFMIN(min,p6); max=FFMAX(max,p6);
00364 min=FFMIN(min,p7); max=FFMAX(max,p7);
00365 if(max-min<2*quant){
00366 ptr[-2*a_stride]=(4*p2 + 3*p3 + 1*p7 + 4)>>3;
00367 ptr[-1*a_stride]=(3*p2 + 3*p4 + 2*p7 + 4)>>3;
00368 ptr[ 0 ]=(2*p2 + 3*p5 + 3*p7 + 4)>>3;
00369 ptr[ 1*a_stride]=(1*p2 + 3*p6 + 4*p7 + 4)>>3;
00370 continue;
00371 };
00372 }
00373 }
00374 }
00375 {
00376 int x,x0,x1,x2;
00377 int m;
00378
00379 x0 = (2*p3 - 5*p4 + 5*p5 - 2*p6 + 4)>>3;
00380 if(FFABS(x0) < quant){
00381 x1=(2*p1 - 5*p2 + 5*p3 - 2*p4 + 4)>>3;
00382 x2=(2*p5 - 5*p6 + 5*p7 - 2*p8 + 4)>>3;
00383
00384 x=FFABS(x0) - FFMIN( FFABS(x1), FFABS(x2) );
00385 m=p4-p5;
00386
00387 if( x > 0 && (m^x0) <0){
00388 int32_t sign;
00389
00390 sign=m>>31;
00391 m=(m^sign)-sign;
00392 m>>=1;
00393
00394 x=(5*x)>>3;
00395
00396 if(x>m) x=m;
00397
00398 x=(x^sign)-sign;
00399
00400 ptr[-1*a_stride] -= x;
00401 ptr[ 0] += x;
00402 }
00403 }
00404 }
00405 }
00406 }
00407
00408 static void x8_h_loop_filter(uint8_t *src, int stride, int qscale){
00409 x8_loop_filter(src, stride, 1, qscale);
00410 }
00411
00412 static void x8_v_loop_filter(uint8_t *src, int stride, int qscale){
00413 x8_loop_filter(src, 1, stride, qscale);
00414 }
00415
00416 av_cold void ff_intrax8dsp_init(IntraX8DSPContext *dsp)
00417 {
00418 dsp->h_loop_filter=x8_h_loop_filter;
00419 dsp->v_loop_filter=x8_v_loop_filter;
00420 dsp->setup_spatial_compensation=x8_setup_spatial_compensation;
00421 dsp->spatial_compensation[0]=spatial_compensation_0;
00422 dsp->spatial_compensation[1]=spatial_compensation_1;
00423 dsp->spatial_compensation[2]=spatial_compensation_2;
00424 dsp->spatial_compensation[3]=spatial_compensation_3;
00425 dsp->spatial_compensation[4]=spatial_compensation_4;
00426 dsp->spatial_compensation[5]=spatial_compensation_5;
00427 dsp->spatial_compensation[6]=spatial_compensation_6;
00428 dsp->spatial_compensation[7]=spatial_compensation_7;
00429 dsp->spatial_compensation[8]=spatial_compensation_8;
00430 dsp->spatial_compensation[9]=spatial_compensation_9;
00431 dsp->spatial_compensation[10]=spatial_compensation_10;
00432 dsp->spatial_compensation[11]=spatial_compensation_11;
00433 }