00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "config.h"
00031 #include <stdio.h>
00032 #include "global.h"
00033 #include "cpu_accel.h"
00034 #include "simd.h"
00035
00036
00037
00038 static void predict_mb (
00039 pict_data_s *picture,
00040 uint8_t *oldref[], uint8_t *newref[], uint8_t *cur[],
00041 int lx, int bx, int by, mbinfo_s *mbi, int secondfield);
00042
00043 static void pred (
00044 pict_data_s *picture,
00045 uint8_t *src[], int sfield,
00046 uint8_t *dst[], int dfield,
00047 int lx, int w, int h, int x, int y, int dx, int dy, int addflag);
00048
00049 static void pred_comp (
00050 pict_data_s *picture,
00051 uint8_t *src, uint8_t *dst,
00052 int lx, int w, int h, int x, int y, int dx, int dy, int addflag);
00053 #ifdef X86_CPU
00054 static void pred_comp_mmxe(
00055 pict_data_s *picture,
00056 uint8_t *src, uint8_t *dst,
00057 int lx, int w, int h, int x, int y, int dx, int dy, int addflag);
00058 static void pred_comp_mmx(
00059 pict_data_s *picture,
00060 uint8_t *src, uint8_t *dst,
00061 int lx, int w, int h, int x, int y, int dx, int dy, int addflag);
00062 #endif
00063 static void calc_DMV
00064 ( pict_data_s *picture,int DMV[][2],
00065 int *dmvector, int mvx, int mvy);
00066
00067 static void clearblock (pict_data_s *picture,
00068 uint8_t *cur[], int i0, int j0);
00069
00070
00071
00072
00073
00074
00075
00076 static void (*ppred_comp)(
00077 pict_data_s *picture,
00078 uint8_t *src, uint8_t *dst,
00079 int lx, int w, int h, int x, int y, int dx, int dy, int addflag);
00080
00081 void init_predict_hv()
00082 {
00083 int cpucap = cpu_accel();
00084
00085 if( cpucap == 0 )
00086 {
00087 ppred_comp = pred_comp;
00088 }
00089
00090 #ifdef X86_CPU
00091 else if(cpucap & ACCEL_X86_MMXEXT )
00092 {
00093 if(verbose) fprintf( stderr, "SETTING EXTENDED MMX for PREDICTION!\n");
00094 ppred_comp = pred_comp_mmxe;
00095 }
00096 else if(cpucap & ACCEL_X86_MMX )
00097 {
00098 if(verbose) fprintf( stderr, "SETTING MMX for PREDICTION!\n");
00099 ppred_comp = pred_comp_mmx;
00100 }
00101 #endif
00102 else
00103 {
00104 ppred_comp = pred_comp;
00105 }
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 void predict(pict_data_s *picture,
00121 uint8_t *reff[],
00122 uint8_t *refb[],
00123 uint8_t *cur[3],
00124 int secondfield)
00125 {
00126 int i, j, k;
00127 mbinfo_s *mbi = picture->mbinfo;
00128 k = 0;
00129
00130
00131 for (j=0; j<height2; j+=16)
00132 for (i=0; i<width; i+=16)
00133 {
00134 predict_mb(picture,reff,refb,cur,width,i,j,
00135 &mbi[k], secondfield );
00136 k++;
00137 }
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 static void predict_mb (
00170 pict_data_s *picture,
00171 uint8_t *oldref[], uint8_t *newref[], uint8_t *cur[],
00172 int lx, int bx, int by, mbinfo_s *mbi, int secondfield
00173 )
00174 {
00175 int addflag, currentfield;
00176 uint8_t **predframe;
00177 int DMV[2][2];
00178
00179 if (mbi->mb_type&MB_INTRA)
00180 {
00181 clearblock(picture,cur,bx,by);
00182 return;
00183 }
00184
00185 addflag = 0;
00186
00187 if ((mbi->mb_type & MB_FORWARD) || (picture->pict_type==P_TYPE))
00188 {
00189
00190
00191 if (picture->pict_struct==FRAME_PICTURE)
00192 {
00193
00194
00195 if ((mbi->motion_type==MC_FRAME) || !(mbi->mb_type & MB_FORWARD))
00196 {
00197
00198 pred(picture,
00199 oldref,0,cur,0,
00200 lx,16,16,bx,by,mbi->MV[0][0][0],mbi->MV[0][0][1],0);
00201 }
00202 else if (mbi->motion_type==MC_FIELD)
00203 {
00204
00205
00206
00207
00208
00209
00210
00211 pred(picture,oldref,mbi->mv_field_sel[0][0],cur,0,
00212 lx<<1,16,8,bx,by>>1,mbi->MV[0][0][0],mbi->MV[0][0][1]>>1,0);
00213
00214
00215 pred(picture,oldref,mbi->mv_field_sel[1][0],cur,1,
00216 lx<<1,16,8,bx,by>>1,mbi->MV[1][0][0],mbi->MV[1][0][1]>>1,0);
00217 }
00218 else if (mbi->motion_type==MC_DMV)
00219 {
00220
00221
00222
00223 calc_DMV(picture,DMV,mbi->dmvector,mbi->MV[0][0][0],mbi->MV[0][0][1]>>1);
00224
00225
00226 pred(picture,oldref,0,cur,0,
00227 lx<<1,16,8,bx,by>>1,mbi->MV[0][0][0],mbi->MV[0][0][1]>>1,0);
00228
00229
00230 pred(picture,oldref,1,cur,1,
00231 lx<<1,16,8,bx,by>>1,mbi->MV[0][0][0],mbi->MV[0][0][1]>>1,0);
00232
00233
00234 pred(picture,oldref,1,cur,0,
00235 lx<<1,16,8,bx,by>>1,DMV[0][0],DMV[0][1],1);
00236
00237
00238 pred(picture,oldref,0,cur,1,
00239 lx<<1,16,8,bx,by>>1,DMV[1][0],DMV[1][1],1);
00240 }
00241 else
00242 {
00243
00244 fprintf(stderr,"invalid motion_type\n");
00245 }
00246 }
00247 else
00248 {
00249
00250
00251 currentfield = (picture->pict_struct==BOTTOM_FIELD);
00252
00253
00254 if ((picture->pict_type==P_TYPE) && secondfield
00255 && (currentfield!=mbi->mv_field_sel[0][0]))
00256 predframe = newref;
00257 else
00258 predframe = oldref;
00259
00260 if ((mbi->motion_type==MC_FIELD) || !(mbi->mb_type & MB_FORWARD))
00261 {
00262
00263 pred(picture,predframe,mbi->mv_field_sel[0][0],cur,currentfield,
00264 lx<<1,16,16,bx,by,mbi->MV[0][0][0],mbi->MV[0][0][1],0);
00265 }
00266 else if (mbi->motion_type==MC_16X8)
00267 {
00268
00269
00270
00271 pred(picture,predframe,mbi->mv_field_sel[0][0],cur,currentfield,
00272 lx<<1,16,8,bx,by,mbi->MV[0][0][0],mbi->MV[0][0][1],0);
00273
00274
00275 if ((picture->pict_type==P_TYPE) && secondfield
00276 && (currentfield!=mbi->mv_field_sel[1][0]))
00277 predframe = newref;
00278 else
00279 predframe = oldref;
00280
00281
00282 pred(picture,predframe,mbi->mv_field_sel[1][0],cur,currentfield,
00283 lx<<1,16,8,bx,by+8,mbi->MV[1][0][0],mbi->MV[1][0][1],0);
00284 }
00285 else if (mbi->motion_type==MC_DMV)
00286 {
00287
00288
00289
00290 if (secondfield)
00291 predframe = newref;
00292 else
00293 predframe = oldref;
00294
00295
00296 calc_DMV(picture,DMV,mbi->dmvector,mbi->MV[0][0][0],mbi->MV[0][0][1]);
00297
00298
00299 pred(picture,oldref,currentfield,cur,currentfield,
00300 lx<<1,16,16,bx,by,mbi->MV[0][0][0],mbi->MV[0][0][1],0);
00301
00302
00303 pred(picture,predframe,!currentfield,cur,currentfield,
00304 lx<<1,16,16,bx,by,DMV[0][0],DMV[0][1],1);
00305 }
00306 else
00307 {
00308
00309 fprintf(stderr,"invalid motion_type\n");
00310 }
00311 }
00312 addflag = 1;
00313 }
00314
00315 if (mbi->mb_type & MB_BACKWARD)
00316 {
00317
00318
00319 if (picture->pict_struct==FRAME_PICTURE)
00320 {
00321
00322
00323 if (mbi->motion_type==MC_FRAME)
00324 {
00325
00326 pred(picture,newref,0,cur,0,
00327 lx,16,16,bx,by,mbi->MV[0][1][0],mbi->MV[0][1][1],addflag);
00328 }
00329 else
00330 {
00331
00332
00333
00334
00335
00336
00337
00338 pred(picture,newref,mbi->mv_field_sel[0][1],cur,0,
00339 lx<<1,16,8,bx,by>>1,mbi->MV[0][1][0],mbi->MV[0][1][1]>>1,addflag);
00340
00341
00342 pred(picture,newref,mbi->mv_field_sel[1][1],cur,1,
00343 lx<<1,16,8,bx,by>>1,mbi->MV[1][1][0],mbi->MV[1][1][1]>>1,addflag);
00344 }
00345 }
00346 else
00347 {
00348
00349
00350 currentfield = (picture->pict_struct==BOTTOM_FIELD);
00351
00352 if (mbi->motion_type==MC_FIELD)
00353 {
00354
00355 pred(picture,newref,mbi->mv_field_sel[0][1],cur,currentfield,
00356 lx<<1,16,16,bx,by,mbi->MV[0][1][0],mbi->MV[0][1][1],addflag);
00357 }
00358 else if (mbi->motion_type==MC_16X8)
00359 {
00360
00361
00362
00363 pred(picture,newref,mbi->mv_field_sel[0][1],cur,currentfield,
00364 lx<<1,16,8,bx,by,mbi->MV[0][1][0],mbi->MV[0][1][1],addflag);
00365
00366
00367 pred(picture,newref,mbi->mv_field_sel[1][1],cur,currentfield,
00368 lx<<1,16,8,bx,by+8,mbi->MV[1][1][0],mbi->MV[1][1][1],addflag);
00369 }
00370 else
00371 {
00372
00373 fprintf(stderr,"invalid motion_type\n");
00374 }
00375 }
00376 }
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 static void pred (
00395 pict_data_s *picture,
00396 uint8_t *src[], int sfield,
00397 uint8_t *dst[], int dfield,
00398 int lx, int w, int h, int x, int y, int dx, int dy, int addflag
00399 )
00400 {
00401 int cc;
00402
00403 for (cc=0; cc<3; cc++)
00404 {
00405 if (cc==1)
00406 {
00407
00408 if (chroma_format==CHROMA420)
00409 {
00410
00411 h >>= 1; y >>= 1; dy /= 2;
00412 }
00413 if (chroma_format!=CHROMA444)
00414 {
00415
00416 w >>= 1; x >>= 1; dx /= 2;
00417 lx >>= 1;
00418 }
00419 }
00420 (*ppred_comp)( picture,
00421 src[cc]+(sfield?lx>>1:0),dst[cc]+(dfield?lx>>1:0),
00422 lx,w,h,x,y,dx,dy,addflag);
00423 }
00424 }
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 static void pred_comp(
00440 pict_data_s *picture,
00441 uint8_t *src,
00442 uint8_t *dst,
00443 int lx,
00444 int w, int h,
00445 int x, int y,
00446 int dx, int dy,
00447 int addflag)
00448 {
00449 int xint, xh, yint, yh;
00450 int i, j;
00451 uint8_t *s, *d;
00452
00453
00454 xint = dx>>1;
00455 xh = dx & 1;
00456 yint = dy>>1;
00457 yh = dy & 1;
00458
00459
00460 s = src + lx*(y+yint) + (x+xint);
00461 d = dst + lx*y + x;
00462
00463 if (!xh && !yh)
00464 if (addflag)
00465 for (j=0; j<h; j++)
00466 {
00467 for (i=0; i<w; i++)
00468 d[i] = (unsigned int)(d[i]+s[i]+1)>>1;
00469 s+= lx;
00470 d+= lx;
00471 }
00472 else
00473 for (j=0; j<h; j++)
00474 {
00475 for (i=0; i<w; i++)
00476 d[i] = s[i];
00477 s+= lx;
00478 d+= lx;
00479 }
00480 else if (!xh && yh)
00481 if (addflag)
00482 for (j=0; j<h; j++)
00483 {
00484 for (i=0; i<w; i++)
00485 d[i] = (d[i] + ((unsigned int)(s[i]+s[i+lx]+1)>>1)+1)>>1;
00486 s+= lx;
00487 d+= lx;
00488 }
00489 else
00490 for (j=0; j<h; j++)
00491 {
00492 for (i=0; i<w; i++)
00493 d[i] = (unsigned int)(s[i]+s[i+lx]+1)>>1;
00494 s+= lx;
00495 d+= lx;
00496 }
00497 else if (xh && !yh)
00498 if (addflag)
00499 for (j=0; j<h; j++)
00500 {
00501 for (i=0; i<w; i++)
00502 d[i] = (d[i] + ((unsigned int)(s[i]+s[i+1]+1)>>1)+1)>>1;
00503 s+= lx;
00504 d+= lx;
00505 }
00506 else
00507 for (j=0; j<h; j++)
00508 {
00509 for (i=0; i<w; i++)
00510 d[i] = (unsigned int)(s[i]+s[i+1]+1)>>1;
00511 s+= lx;
00512 d+= lx;
00513 }
00514 else
00515 if (addflag)
00516 for (j=0; j<h; j++)
00517 {
00518 for (i=0; i<w; i++)
00519 d[i] = (d[i] + ((unsigned int)(s[i]+s[i+1]+s[i+lx]+s[i+lx+1]+2)>>2)+1)>>1;
00520 s+= lx;
00521 d+= lx;
00522 }
00523 else
00524 for (j=0; j<h; j++)
00525 {
00526 for (i=0; i<w; i++)
00527 d[i] = (unsigned int)(s[i]+s[i+1]+s[i+lx]+s[i+lx+1]+2)>>2;
00528 s+= lx;
00529 d+= lx;
00530 }
00531 }
00532
00533 #ifdef X86_CPU
00534 static void pred_comp_mmxe(
00535 pict_data_s *picture,
00536 uint8_t *src,
00537 uint8_t *dst,
00538 int lx,
00539 int w, int h,
00540 int x, int y,
00541 int dx, int dy,
00542 int addflag)
00543 {
00544 int xint, xh, yint, yh;
00545 uint8_t *s, *d;
00546
00547
00548 xint = dx>>1;
00549 xh = dx & 1;
00550 yint = dy>>1;
00551 yh = dy & 1;
00552
00553
00554 s = src + lx*(y+yint) + (x+xint);
00555 d = dst + lx*y + x;
00556
00557 if( xh )
00558 {
00559 if( yh )
00560 predcomp_11_mmxe(s,d,lx,w,h,addflag);
00561 else
00562 predcomp_10_mmxe(s,d,lx,w,h,addflag);
00563 }
00564 else
00565 {
00566 if( yh )
00567 predcomp_01_mmxe(s,d,lx,w,h,addflag);
00568 else
00569 predcomp_00_mmxe(s,d,lx,w,h,addflag);
00570 }
00571
00572 }
00573
00574 static void pred_comp_mmx(
00575 pict_data_s *picture,
00576 uint8_t *src,
00577 uint8_t *dst,
00578 int lx,
00579 int w, int h,
00580 int x, int y,
00581 int dx, int dy,
00582 int addflag)
00583 {
00584 int xint, xh, yint, yh;
00585 uint8_t *s, *d;
00586
00587
00588 xint = dx>>1;
00589 xh = dx & 1;
00590 yint = dy>>1;
00591 yh = dy & 1;
00592
00593
00594 s = src + lx*(y+yint) + (x+xint);
00595 d = dst + lx*y + x;
00596
00597 if( xh )
00598 {
00599 if( yh )
00600 predcomp_11_mmx(s,d,lx,w,h,addflag);
00601 else
00602 predcomp_10_mmx(s,d,lx,w,h,addflag);
00603 }
00604 else
00605 {
00606 if( yh )
00607 predcomp_01_mmx(s,d,lx,w,h,addflag);
00608 else
00609 predcomp_00_mmx(s,d,lx,w,h,addflag);
00610 }
00611
00612 }
00613 #endif
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 static void calc_DMV(
00628 pict_data_s *picture,int DMV[][2],
00629 int *dmvector, int mvx, int mvy
00630 )
00631 {
00632 if (picture->pict_struct==FRAME_PICTURE)
00633 {
00634 if (picture->topfirst)
00635 {
00636
00637 DMV[0][0] = ((mvx +(mvx>0))>>1) + dmvector[0];
00638 DMV[0][1] = ((mvy +(mvy>0))>>1) + dmvector[1] - 1;
00639
00640
00641 DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
00642 DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1;
00643 }
00644 else
00645 {
00646
00647 DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
00648 DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1;
00649
00650
00651 DMV[1][0] = ((mvx +(mvx>0))>>1) + dmvector[0];
00652 DMV[1][1] = ((mvy +(mvy>0))>>1) + dmvector[1] + 1;
00653 }
00654 }
00655 else
00656 {
00657
00658 DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0];
00659 DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1];
00660
00661
00662 if (picture->pict_struct==TOP_FIELD)
00663 DMV[0][1]--;
00664 else
00665 DMV[0][1]++;
00666 }
00667 }
00668
00669 static void clearblock(
00670 pict_data_s *picture,
00671 uint8_t *cur[], int i0, int j0
00672 )
00673 {
00674 int i, j, w, h;
00675 uint8_t *p;
00676
00677 p = cur[0] + ((picture->pict_struct==BOTTOM_FIELD) ? width : 0) + i0 + width2*j0;
00678
00679 for (j=0; j<16; j++)
00680 {
00681 for (i=0; i<16; i++)
00682 p[i] = 128;
00683 p+= width2;
00684 }
00685
00686 w = h = 16;
00687
00688 if (chroma_format!=CHROMA444)
00689 {
00690 i0>>=1; w>>=1;
00691 }
00692
00693 if (chroma_format==CHROMA420)
00694 {
00695 j0>>=1; h>>=1;
00696 }
00697
00698 p = cur[1] + ((picture->pict_struct==BOTTOM_FIELD) ? chrom_width : 0) + i0
00699 + chrom_width2*j0;
00700
00701 for (j=0; j<h; j++)
00702 {
00703 for (i=0; i<w; i++)
00704 p[i] = 128;
00705 p+= chrom_width2;
00706 }
00707
00708 p = cur[2] + ((picture->pict_struct==BOTTOM_FIELD) ? chrom_width : 0) + i0
00709 + chrom_width2*j0;
00710
00711 for (j=0; j<h; j++)
00712 {
00713 for (i=0; i<w; i++)
00714 p[i] = 128;
00715 p+= chrom_width2;
00716 }
00717 }