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
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include"vid_sim.h"
00045 #include"video_codec.h"
00046
00047 extern video_codec *VidSt;
00048
00049 static int roundtab[] = {0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2};
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 MB_Structure *Predict_P(PictImage *curr_image, PictImage *prev_image,
00068 unsigned char *prev_ipol, int x, int y,
00069 MotionVector *MV[6][MBR+1][MBC+2], int PB)
00070 {
00071 int m,n;
00072 int curr[16][16];
00073 int pred[16][16];
00074 MotionVector *fr0,*fr1,*fr2,*fr3,*fr4;
00075 int sum, dx, dy;
00076 int xmb, ymb;
00077
00078 MB_Structure *pred_error = (MB_Structure *)malloc(sizeof(MB_Structure));
00079
00080 xmb = x/MB_SIZE+1;
00081 ymb = y/MB_SIZE+1;
00082
00083 fr0 = MV[0][ymb][xmb];
00084 fr1 = MV[1][ymb][xmb];
00085 fr2 = MV[2][ymb][xmb];
00086 fr3 = MV[3][ymb][xmb];
00087 fr4 = MV[4][ymb][xmb];
00088
00089
00090 FindMB(x, y, curr_image->lum, curr);
00091
00092
00093 if ((VidSt->advanced)) {
00094 FindPredOBMC(x, y, MV, prev_ipol, &pred[0][0], 0, PB);
00095 FindPredOBMC(x, y, MV, prev_ipol, &pred[0][8], 1, PB);
00096 FindPredOBMC(x, y, MV, prev_ipol, &pred[8][0], 2, PB);
00097 FindPredOBMC(x, y, MV, prev_ipol, &pred[8][8], 3, PB);
00098 }
00099
00100 else
00101 FindPred(x, y, fr0, prev_ipol, &pred[0][0], 16, 0);
00102
00103
00104 if (fr0->Mode == MODE_INTER || fr0->Mode == MODE_INTER_Q) {
00105 for (n = 0; n < MB_SIZE; n++)
00106 for (m = 0; m < MB_SIZE; m++)
00107 pred_error->lum[n][m] = (int)(curr[n][m] - pred[n][m]);
00108
00109 dx = 2*fr0->x + fr0->x_half;
00110 dy = 2*fr0->y + fr0->y_half;
00111 dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );
00112 dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 );
00113
00114 DoPredChrom_P(x, y, dx, dy, curr_image, prev_image, pred_error);
00115 }
00116
00117 else if (fr0->Mode == MODE_INTER4V) {
00118 for (n = 0; n < MB_SIZE; n++)
00119 for (m = 0; m < MB_SIZE; m++)
00120 pred_error->lum[n][m] = (int)(curr[n][m] - pred[n][m]);
00121
00122 sum = 2*fr1->x + fr1->x_half + 2*fr2->x + fr2->x_half +
00123 2*fr3->x + fr3->x_half + 2*fr4->x + fr4->x_half ;
00124 dx = sign(sum)*(roundtab[abs(sum)%16] + (abs(sum)/16)*2);
00125
00126 sum = 2*fr1->y + fr1->y_half + 2*fr2->y + fr2->y_half +
00127 2*fr3->y + fr3->y_half + 2*fr4->y + fr4->y_half;
00128 dy = sign(sum)*(roundtab[abs(sum)%16] + (abs(sum)/16)*2);
00129
00130 DoPredChrom_P(x, y, dx, dy, curr_image, prev_image, pred_error);
00131 }
00132
00133 else
00134 fprintf(stderr,"Illegal Mode in Predict_P (vid_pred.c)\n");
00135
00136
00137 return pred_error;
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 MB_Structure *Predict_B(PictImage *curr_image, PictImage *prev_image,
00157 unsigned char *prev_ipol,int x, int y,
00158 MotionVector *MV[5][MBR+1][MBC+2],
00159 MB_Structure *recon_P, int TRD,int TRB)
00160 {
00161 int i,j,k;
00162 int dx, dy, sad, sad_min=INT_MAX, curr[16][16], bdx=0, bdy=0;
00163 MB_Structure *p_err = (MB_Structure *)malloc(sizeof(MB_Structure));
00164 MB_Structure *pred = (MB_Structure *)malloc(sizeof(MB_Structure));
00165 MotionVector *f[5];
00166 int xvec, yvec, mvx, mvy;
00167
00168 for (k = 0; k <= 4; k++)
00169 f[k] = MV[k][y/MB_SIZE+1][x/MB_SIZE+1];
00170
00171
00172 FindMB(x, y, curr_image->lum, curr);
00173
00174 if (f[0]->Mode == MODE_INTER4V) {
00175
00176
00177
00178 for (j = -DEF_PBDELTA_WIN; j <= DEF_PBDELTA_WIN; j++) {
00179 for (i = -DEF_PBDELTA_WIN; i <= DEF_PBDELTA_WIN; i++) {
00180
00181 FindForwLumPredPB(prev_ipol, x, y, f[1], &pred->lum[0][0],
00182 TRD, TRB, i, j, 8, 0);
00183 FindForwLumPredPB(prev_ipol, x, y, f[2], &pred->lum[0][8],
00184 TRD, TRB, i, j, 8, 1);
00185 FindForwLumPredPB(prev_ipol, x, y, f[3], &pred->lum[8][0],
00186 TRD, TRB, i, j, 8, 2);
00187 FindForwLumPredPB(prev_ipol, x, y, f[4], &pred->lum[8][8],
00188 TRD, TRB, i, j, 8, 3);
00189
00190 sad = SAD_MB_integer(&curr[0][0],&pred->lum[0][0], 16,INT_MAX);
00191 if (i == 0 && j == 0)
00192 sad -= PREF_PBDELTA_NULL_VEC;
00193 if (sad < sad_min) {
00194 sad_min = sad;
00195 bdx = i;
00196 bdy = j;
00197 }
00198 }
00199 }
00200
00201 FindForwLumPredPB(prev_ipol,x,y,f[1],&pred->lum[0][0],TRD,TRB,bdx,bdy,8,0);
00202 FindForwLumPredPB(prev_ipol,x,y,f[2],&pred->lum[0][8],TRD,TRB,bdx,bdy,8,1);
00203 FindForwLumPredPB(prev_ipol,x,y,f[3],&pred->lum[8][0],TRD,TRB,bdx,bdy,8,2);
00204 FindForwLumPredPB(prev_ipol,x,y,f[4],&pred->lum[8][8],TRD,TRB,bdx,bdy,8,3);
00205
00206
00207 xvec = yvec = 0;
00208 for (k = 1; k <= 4; k++) {
00209 xvec += TRB*(2*f[k]->x + f[k]->x_half)/TRD + bdx;
00210 yvec += TRB*(2*f[k]->y + f[k]->y_half)/TRD + bdy;
00211 }
00212
00213
00214 dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
00215 dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
00216
00217 FindChromBlock_P(x, y, dx, dy, prev_image, pred);
00218
00219
00220 FindBiDirLumPredPB(&recon_P->lum[0][0], f[1], &pred->lum[0][0],
00221 TRD, TRB, bdx, bdy, 0, 0);
00222 FindBiDirLumPredPB(&recon_P->lum[0][8], f[2], &pred->lum[0][8],
00223 TRD, TRB, bdx, bdy, 1, 0);
00224 FindBiDirLumPredPB(&recon_P->lum[8][0], f[3], &pred->lum[8][0],
00225 TRD, TRB, bdx, bdy, 0, 1);
00226 FindBiDirLumPredPB(&recon_P->lum[8][8], f[4], &pred->lum[8][8],
00227 TRD, TRB, bdx, bdy, 1, 1);
00228
00229
00230 xvec = yvec = 0;
00231 for (k = 1; k <= 4; k++) {
00232 mvx = 2*f[k]->x + f[k]->x_half;
00233 mvy = 2*f[k]->y + f[k]->y_half;
00234 xvec += bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx;
00235 yvec += bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy;
00236 }
00237
00238
00239 dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
00240 dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
00241
00242 FindBiDirChrPredPB(recon_P, dx, dy, pred);
00243 }
00244
00245 else {
00246
00247
00248 for (j = -DEF_PBDELTA_WIN; j <= DEF_PBDELTA_WIN; j++) {
00249 for (i = -DEF_PBDELTA_WIN; i <= DEF_PBDELTA_WIN; i++) {
00250
00251 dx = i; dy = j;
00252
00253 if (!(VidSt->mv_outside_frame)) {
00254 if (x == 0) dx = 0;
00255 if (x == (VidSt->pels) - MB_SIZE) dx = 0;
00256 if (y == 0) dy = 0;
00257 if (y == (VidSt->lines) - MB_SIZE) dy = 0;
00258 }
00259
00260 if (f[0]->Mode == MODE_INTRA || f[0]->Mode == MODE_INTRA_Q) {
00261 dx = dy = 0;
00262 }
00263
00264 if (f[0]->x == 0 && f[0]->y == 0 &&
00265 f[0]->x_half == 0 && f[0]->y_half == 0) {
00266 dx = dy = 0;
00267 }
00268
00269 FindForwLumPredPB(prev_ipol, x, y, f[0], &pred->lum[0][0],
00270 TRD, TRB, dx, dy, 16, 0);
00271
00272 sad = SAD_MB_integer(&curr[0][0],&pred->lum[0][0], 16, INT_MAX);
00273 if (i == 0 && j == 0)
00274 sad -= PREF_PBDELTA_NULL_VEC;
00275 if (sad < sad_min) {
00276 sad_min = sad;
00277 bdx = dx;
00278 bdy = dy;
00279 }
00280 }
00281 }
00282 FindForwLumPredPB(prev_ipol,x,y,f[0],&pred->lum[0][0],TRD,TRB,
00283 bdx,bdy,16,0);
00284
00285 xvec = 4 * (TRB*(2*f[0]->x + f[0]->x_half) / TRD + bdx);
00286 yvec = 4 * (TRB*(2*f[0]->y + f[0]->y_half) / TRD + bdy);
00287
00288 dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
00289 dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
00290
00291 FindChromBlock_P(x, y, dx, dy, prev_image, pred);
00292
00293
00294 FindBiDirLumPredPB(&recon_P->lum[0][0], f[0], &pred->lum[0][0],
00295 TRD, TRB, bdx, bdy, 0, 0);
00296 FindBiDirLumPredPB(&recon_P->lum[0][8], f[0], &pred->lum[0][8],
00297 TRD, TRB, bdx, bdy, 1, 0);
00298 FindBiDirLumPredPB(&recon_P->lum[8][0], f[0], &pred->lum[8][0],
00299 TRD, TRB, bdx, bdy, 0, 1);
00300 FindBiDirLumPredPB(&recon_P->lum[8][8], f[0], &pred->lum[8][8],
00301 TRD, TRB, bdx, bdy, 1, 1);
00302
00303
00304 mvx = 2*f[0]->x + f[0]->x_half;
00305 xvec = bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx;
00306 xvec *= 4;
00307
00308 mvy = 2*f[0]->y + f[0]->y_half;
00309 yvec = bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy;
00310 yvec *= 4;
00311
00312
00313 dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
00314 dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
00315
00316 FindBiDirChrPredPB(recon_P, dx, dy, pred);
00317 }
00318
00319
00320 MV[5][y/MB_SIZE+1][x/MB_SIZE+1]->x = bdx;
00321 MV[5][y/MB_SIZE+1][x/MB_SIZE+1]->y = bdy;
00322 MV[5][y/MB_SIZE+1][x/MB_SIZE+1]->x_half = 0;
00323 MV[5][y/MB_SIZE+1][x/MB_SIZE+1]->y_half = 0;
00324
00325
00326
00327 for (j = 0; j < MB_SIZE; j++)
00328 for (i = 0; i < MB_SIZE; i++)
00329 p_err->lum[j][i] =
00330 *(curr_image->lum+x+i + (y+j)*(VidSt->pels)) - pred->lum[j][i];
00331
00332 y >>= 1;
00333 x >>= 1;
00334 for (j = 0; j < MB_SIZE>>1; j++)
00335 for (i = 0; i < MB_SIZE>>1; i++) {
00336 p_err->Cr[j][i] = *(curr_image->Cr+x+i + (y+j)*(VidSt->cpels)) - pred->Cr[j][i];
00337 p_err->Cb[j][i] = *(curr_image->Cb+x+i + (y+j)*(VidSt->cpels)) - pred->Cb[j][i];
00338 }
00339
00340 free(pred);
00341 return p_err;
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 MB_Structure *MB_Recon_B(PictImage *prev_image, MB_Structure *diff,
00361 unsigned char *prev_ipol,int x, int y,
00362 MotionVector *MV[5][MBR+1][MBC+2],
00363 MB_Structure *recon_P,int TRD, int TRB)
00364 {
00365 int i,j,k;
00366 int dx, dy, bdx, bdy, mvx, mvy, xvec, yvec;
00367 MB_Structure *recon_B = (MB_Structure *)malloc(sizeof(MB_Structure));
00368 MB_Structure *pred = (MB_Structure *)malloc(sizeof(MB_Structure));
00369 MotionVector *f[5];
00370
00371 for (k = 0; k <= 4; k++)
00372 f[k] = MV[k][y/MB_SIZE+1][x/MB_SIZE+1];
00373
00374 bdx = MV[5][y/MB_SIZE+1][x/MB_SIZE+1]->x;
00375 bdy = MV[5][y/MB_SIZE+1][x/MB_SIZE+1]->y;
00376
00377 if (f[0]->Mode == MODE_INTER4V) {
00378
00379
00380
00381 FindForwLumPredPB(prev_ipol,x,y,f[1],&pred->lum[0][0],TRD,TRB,bdx,bdy,8,0);
00382 FindForwLumPredPB(prev_ipol,x,y,f[2],&pred->lum[0][8],TRD,TRB,bdx,bdy,8,1);
00383 FindForwLumPredPB(prev_ipol,x,y,f[3],&pred->lum[8][0],TRD,TRB,bdx,bdy,8,2);
00384 FindForwLumPredPB(prev_ipol,x,y,f[4],&pred->lum[8][8],TRD,TRB,bdx,bdy,8,3);
00385
00386
00387 xvec = yvec = 0;
00388 for (k = 1; k <= 4; k++) {
00389 xvec += TRB*(2*f[k]->x + f[k]->x_half)/TRD + bdx;
00390 yvec += TRB*(2*f[k]->y + f[k]->y_half)/TRD + bdy;
00391 }
00392
00393
00394 dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
00395 dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
00396
00397 FindChromBlock_P(x, y, dx, dy, prev_image, pred);
00398
00399
00400 FindBiDirLumPredPB(&recon_P->lum[0][0], f[1], &pred->lum[0][0],
00401 TRD, TRB, bdx, bdy, 0, 0);
00402 FindBiDirLumPredPB(&recon_P->lum[0][8], f[2], &pred->lum[0][8],
00403 TRD, TRB, bdx, bdy, 1, 0);
00404 FindBiDirLumPredPB(&recon_P->lum[8][0], f[3], &pred->lum[8][0],
00405 TRD, TRB, bdx, bdy, 0, 1);
00406 FindBiDirLumPredPB(&recon_P->lum[8][8], f[4], &pred->lum[8][8],
00407 TRD, TRB, bdx, bdy, 1, 1);
00408
00409
00410 xvec = yvec = 0;
00411 for (k = 1; k <= 4; k++) {
00412 mvx = 2*f[k]->x + f[k]->x_half;
00413 mvy = 2*f[k]->y + f[k]->y_half;
00414 xvec += bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx;
00415 yvec += bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy;
00416 }
00417
00418
00419 dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
00420 dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
00421
00422 FindBiDirChrPredPB(recon_P, dx, dy, pred);
00423
00424 }
00425 else {
00426
00427
00428 FindForwLumPredPB(prev_ipol,x,y,f[0],&pred->lum[0][0],TRD,TRB,
00429 bdx,bdy,16,0);
00430
00431 xvec = 4 * (TRB*(2*f[0]->x + f[0]->x_half) / TRD + bdx);
00432 yvec = 4 * (TRB*(2*f[0]->y + f[0]->y_half) / TRD + bdy);
00433
00434 dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
00435 dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
00436
00437 FindChromBlock_P(x, y, dx, dy, prev_image, pred);
00438
00439
00440 FindBiDirLumPredPB(&recon_P->lum[0][0], f[0], &pred->lum[0][0],
00441 TRD, TRB, bdx, bdy, 0, 0);
00442 FindBiDirLumPredPB(&recon_P->lum[0][8], f[0], &pred->lum[0][8],
00443 TRD, TRB, bdx, bdy, 1, 0);
00444 FindBiDirLumPredPB(&recon_P->lum[8][0], f[0], &pred->lum[8][0],
00445 TRD, TRB, bdx, bdy, 0, 1);
00446 FindBiDirLumPredPB(&recon_P->lum[8][8], f[0], &pred->lum[8][8],
00447 TRD, TRB, bdx, bdy, 1, 1);
00448
00449
00450 mvx = 2*f[0]->x + f[0]->x_half;
00451 xvec = bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx;
00452 xvec *= 4;
00453
00454 mvy = 2*f[0]->y + f[0]->y_half;
00455 yvec = bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy;
00456 yvec *= 4;
00457
00458
00459 dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
00460 dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
00461
00462 FindBiDirChrPredPB(recon_P, dx, dy, pred);
00463
00464 }
00465
00466
00467 for (j = 0; j < MB_SIZE; j++)
00468 for (i = 0; i < MB_SIZE; i++)
00469 recon_B->lum[j][i] = pred->lum[j][i] + diff->lum[j][i];
00470
00471 for (j = 0; j < MB_SIZE>>1; j++)
00472 for (i = 0; i < MB_SIZE>>1; i++) {
00473 recon_B->Cr[j][i] = pred->Cr[j][i] + diff->Cr[j][i];
00474 recon_B->Cb[j][i] = pred->Cb[j][i] + diff->Cb[j][i];
00475 }
00476
00477 free(pred);
00478 return recon_B;
00479 }
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494 void FindForwLumPredPB(unsigned char *prev_ipol, int x_curr, int y_curr,
00495 MotionVector *fr, int *pred, int TRD, int TRB,
00496 int bdx, int bdy, int bs, int comp)
00497 {
00498 int i,j;
00499 int xvec,yvec,lx;
00500
00501 lx = ((VidSt->mv_outside_frame) ? (VidSt->pels) + ((VidSt->long_vectors)?64:32) : (VidSt->pels));
00502
00503
00504 xvec = (TRB)*(2*fr->x + fr->x_half)/TRD + bdx;
00505 yvec = (TRB)*(2*fr->y + fr->y_half)/TRD + bdy;
00506
00507 x_curr += ((comp&1)<<3);
00508 y_curr += ((comp&2)<<2);
00509
00510 for (j = 0; j < bs; j++) {
00511 for (i = 0; i < bs; i++) {
00512 *(pred+i+j*16) = *(prev_ipol + (i+x_curr)*2 + xvec +
00513 ((j+y_curr)*2 + yvec)*lx*2);
00514 }
00515 }
00516
00517 return;
00518 }
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 void FindBiDirLumPredPB(int *recon_P, MotionVector *fr, int *pred, int TRD,
00535 int TRB, int bdx, int bdy, int nh, int nv)
00536 {
00537 int xstart,xstop,ystart,ystop;
00538 int xvec,yvec, mvx, mvy;
00539
00540 mvx = 2*fr->x + fr->x_half;
00541 mvy = 2*fr->y + fr->y_half;
00542
00543 xvec = (bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx);
00544 yvec = (bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy);
00545
00546
00547
00548 FindBiDirLimits(xvec,&xstart,&xstop,nh);
00549 FindBiDirLimits(yvec,&ystart,&ystop,nv);
00550
00551 BiDirPredBlock(xstart,xstop,ystart,ystop,xvec,yvec, recon_P,pred,16);
00552
00553 return;
00554 }
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569 void FindBiDirChrPredPB(MB_Structure *recon_P, int dx, int dy,
00570 MB_Structure *pred)
00571 {
00572 int xstart,xstop,ystart,ystop;
00573
00574 FindBiDirChromaLimits(dx,&xstart,&xstop);
00575 FindBiDirChromaLimits(dy,&ystart,&ystop);
00576
00577 BiDirPredBlock(xstart,xstop,ystart,ystop,dx,dy,
00578 &recon_P->Cb[0][0], &pred->Cb[0][0],8);
00579 BiDirPredBlock(xstart,xstop,ystart,ystop,dx,dy,
00580 &recon_P->Cr[0][0], &pred->Cr[0][0],8);
00581
00582 return;
00583 }
00584
00585 void FindBiDirLimits(int vec, int *start, int *stop, int nhv)
00586 {
00587
00588
00589 *start = mmax(0,(-vec+1)/2 - nhv*8);
00590 *stop = mmin(7,15-(vec+1)/2 - nhv*8);
00591
00592 return;
00593
00594 }
00595
00596 void FindBiDirChromaLimits(int vec, int *start, int *stop)
00597 {
00598
00599
00600 *start = mmax(0,(-vec+1)/2);
00601 *stop = mmin(7,7-(vec+1)/2);
00602
00603 return;
00604 }
00605
00606
00607 void BiDirPredBlock(int xstart, int xstop, int ystart, int ystop,
00608 int xvec, int yvec, int *recon, int *pred, int bl)
00609 {
00610 int i,j,pel;
00611 int xint, yint;
00612 int xh, yh;
00613
00614 xint = xvec>>1;
00615 xh = xvec - 2*xint;
00616 yint = yvec>>1;
00617 yh = yvec - 2*yint;
00618
00619 if (!xh && !yh) {
00620 for (j = ystart; j <= ystop; j++) {
00621 for (i = xstart; i <= xstop; i++) {
00622 pel = *(recon +(j+yint)*bl + i+xint);
00623 *(pred + j*bl + i) = (mmin(255,mmax(0,pel)) + *(pred + j*bl + i))>>1;
00624 }
00625 }
00626 }
00627 else if (!xh && yh) {
00628 for (j = ystart; j <= ystop; j++) {
00629 for (i = xstart; i <= xstop; i++) {
00630 pel = (*(recon +(j+yint)*bl + i+xint) +
00631 *(recon +(j+yint+yh)*bl + i+xint) + 1)>>1;
00632 *(pred + j*bl + i) = (pel + *(pred + j*bl + i))>>1;
00633 }
00634 }
00635 }
00636 else if (xh && !yh) {
00637 for (j = ystart; j <= ystop; j++) {
00638 for (i = xstart; i <= xstop; i++) {
00639 pel = (*(recon +(j+yint)*bl + i+xint) +
00640 *(recon +(j+yint)*bl + i+xint+xh) + 1)>>1;
00641 *(pred + j*bl + i) = (pel + *(pred + j*bl + i))>>1;
00642 }
00643 }
00644 }
00645 else {
00646 for (j = ystart; j <= ystop; j++) {
00647 for (i = xstart; i <= xstop; i++) {
00648 pel = (*(recon +(j+yint)*bl + i+xint) +
00649 *(recon +(j+yint+yh)*bl + i+xint) +
00650 *(recon +(j+yint)*bl + i+xint+xh) +
00651 *(recon +(j+yint+yh)*bl + i+xint+xh)+2)>>2;
00652 *(pred + j*bl + i) = (pel + *(pred + j*bl + i))>>1;
00653 }
00654 }
00655 }
00656 return;
00657 }
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676 void DoPredChrom_P(int x_curr, int y_curr, int dx, int dy,
00677 PictImage *curr, PictImage *prev,
00678 MB_Structure *pred_error)
00679 {
00680 int m,n;
00681
00682 int x, y, ofx, ofy, pel, lx;
00683 int xint, yint;
00684 int xh, yh;
00685
00686 lx = ((VidSt->mv_outside_frame) ? (VidSt->pels)/2 + ((VidSt->long_vectors)?32:16) : (VidSt->pels)/2);
00687
00688 x = x_curr>>1;
00689 y = y_curr>>1;
00690
00691 xint = dx>>1;
00692 xh = dx & 1;
00693 yint = dy>>1;
00694 yh = dy & 1;
00695
00696 if (!xh && !yh) {
00697 for (n = 0; n < 8; n++) {
00698 for (m = 0; m < 8; m++) {
00699
00700 ofx = x + xint + m;
00701 ofy = y + yint + n;
00702 pel=*(prev->Cr+ofx + (ofy )*lx);
00703 pred_error->Cr[n][m] = (int)(*(curr->Cr + x+m + (y+n)*(VidSt->cpels)) - pel);
00704
00705 pel=*(prev->Cb+ofx + (ofy )*lx);
00706 pred_error->Cb[n][m] = (int)(*(curr->Cb + x+m + (y+n)*(VidSt->cpels)) - pel);
00707 }
00708 }
00709 }
00710 else if (!xh && yh) {
00711 for (n = 0; n < 8; n++) {
00712 for (m = 0; m < 8; m++) {
00713
00714 ofx = x + xint + m;
00715 ofy = y + yint + n;
00716 pel=(*(prev->Cr+ofx + (ofy )*lx)+
00717 *(prev->Cr+ofx + (ofy+yh)*lx) + 1)>>1;
00718
00719 pred_error->Cr[n][m] =
00720 (int)(*(curr->Cr + x+m + (y+n)*(VidSt->cpels)) - pel);
00721
00722 pel=(*(prev->Cb+ofx + (ofy )*lx)+
00723 *(prev->Cb+ofx + (ofy+yh)*lx) + 1)>>1;
00724
00725 pred_error->Cb[n][m] =
00726 (int)(*(curr->Cb + x+m + (y+n)*(VidSt->cpels)) - pel);
00727
00728 }
00729 }
00730 }
00731 else if (xh && !yh) {
00732 for (n = 0; n < 8; n++) {
00733 for (m = 0; m < 8; m++) {
00734
00735 ofx = x + xint + m;
00736 ofy = y + yint + n;
00737 pel=(*(prev->Cr+ofx + (ofy )*lx)+
00738 *(prev->Cr+ofx+xh + (ofy )*lx) + 1)>>1;
00739
00740 pred_error->Cr[n][m] =
00741 (int)(*(curr->Cr + x+m + (y+n)*(VidSt->cpels)) - pel);
00742
00743 pel=(*(prev->Cb+ofx + (ofy )*lx)+
00744 *(prev->Cb+ofx+xh + (ofy )*lx) + 1)>>1;
00745
00746 pred_error->Cb[n][m] =
00747 (int)(*(curr->Cb + x+m + (y+n)*(VidSt->cpels)) - pel);
00748
00749 }
00750 }
00751 }
00752 else {
00753 for (n = 0; n < 8; n++) {
00754 for (m = 0; m < 8; m++) {
00755 ofx = x + xint + m;
00756 ofy = y + yint + n;
00757 pel=(*(prev->Cr+ofx + (ofy )*lx)+
00758 *(prev->Cr+ofx+xh + (ofy )*lx)+
00759 *(prev->Cr+ofx + (ofy+yh)*lx)+
00760 *(prev->Cr+ofx+xh + (ofy+yh)*lx)+
00761 2)>>2;
00762
00763 pred_error->Cr[n][m] =
00764 (int)(*(curr->Cr + x+m + (y+n)*(VidSt->cpels)) - pel);
00765
00766 pel=(*(prev->Cb+ofx + (ofy )*lx)+
00767 *(prev->Cb+ofx+xh + (ofy )*lx)+
00768 *(prev->Cb+ofx + (ofy+yh)*lx)+
00769 *(prev->Cb+ofx+xh + (ofy+yh)*lx)+
00770 2)>>2;
00771
00772 pred_error->Cb[n][m] =
00773 (int)(*(curr->Cb + x+m + (y+n)*(VidSt->cpels)) - pel);
00774
00775 }
00776 }
00777 }
00778 return;
00779 }
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 void FindHalfPel(int x, int y, MotionVector *fr, unsigned char *prev,
00798 int *curr, int bs, int comp)
00799 {
00800 int i, m, n;
00801 int half_pel;
00802 int start_x, start_y, stop_x, stop_y, new_x, new_y, lx;
00803 int min_pos;
00804 int AE, AE_min;
00805 Point search[9];
00806
00807 start_x = -1;
00808 stop_x = 1;
00809 start_y = -1;
00810 stop_y = 1;
00811
00812 new_x = x + fr->x;
00813 new_y = y + fr->y;
00814
00815 new_x += ((comp&1)<<3);
00816 new_y += ((comp&2)<<2);
00817
00818 lx = ((VidSt->mv_outside_frame) ? (VidSt->pels) + ((VidSt->long_vectors)?64:32) : (VidSt->pels));
00819
00820
00821 if (!(VidSt->mv_outside_frame)) {
00822 if ((new_x) <= 0)
00823 start_x = 0;
00824 if ((new_y) <= 0)
00825 start_y = 0;
00826 if ((new_x) >= ((VidSt->pels)-bs))
00827 stop_x = 0;
00828 if ((new_y) >= ((VidSt->lines)-bs))
00829 stop_y = 0;
00830 }
00831
00832 search[0].x = 0; search[0].y = 0;
00833 search[1].x = start_x; search[1].y = start_y;
00834 search[2].x = 0; search[2].y = start_y;
00835 search[3].x = stop_x; search[3].y = start_y;
00836 search[4].x = start_x; search[4].y = 0;
00837 search[5].x = stop_x; search[5].y = 0;
00838 search[6].x = start_x; search[6].y = stop_y;
00839 search[7].x = 0; search[7].y = stop_y;
00840 search[8].x = stop_x; search[8].y = stop_y;
00841
00842 AE_min = INT_MAX;
00843 min_pos = 0;
00844 for (i = 0; i < 9; i++) {
00845 AE = 0;
00846 for (n = 0; n < bs; n++) {
00847 for (m = 0; m < bs; m++) {
00848
00849 half_pel = *(prev + 2*new_x + 2*m + search[i].x +
00850 (2*new_y + 2*n + search[i].y)*lx*2);
00851 AE += abs(half_pel - *(curr + m + n*16));
00852 }
00853 }
00854
00855
00856
00857
00858 if (AE < AE_min) {
00859 AE_min = AE;
00860 min_pos = i;
00861 }
00862 }
00863
00864
00865 fr->min_error = AE_min;
00866 fr->x_half = search[min_pos].x;
00867 fr->y_half = search[min_pos].y;
00868
00869 return;
00870 }
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888 void FindPred(int x, int y, MotionVector *fr, unsigned char *prev,
00889 int *pred, int bs, int comp)
00890 {
00891 int m, n;
00892 int new_x, new_y;
00893 int lx;
00894
00895 lx = ((VidSt->mv_outside_frame) ? (VidSt->pels) + ((VidSt->long_vectors)?64:32) : (VidSt->pels));
00896
00897 new_x = x + fr->x;
00898 new_y = y + fr->y;
00899
00900 new_x += ((comp&1)<<3);
00901 new_y += ((comp&2)<<2);
00902
00903
00904
00905 for (n = 0; n < bs; n++) {
00906 for (m = 0; m < bs; m++) {
00907
00908 *(pred + m + n*16) = *(prev + (new_x + m)*2 + fr->x_half +
00909 ((new_y + n)*2 + fr->y_half)*lx*2);
00910 }
00911 }
00912 return;
00913 }
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931 void FindPredOBMC(int x, int y, MotionVector *MV[6][MBR+1][MBC+2],
00932 unsigned char *prev, int *pred, int comp, int PB)
00933 {
00934 int m, n;
00935 int pc,pt,pb,pr,pl;
00936 int nxc,nxt,nxb,nxr,nxl;
00937 int nyc,nyt,nyb,nyr,nyl;
00938 int xit,xib,xir,xil;
00939 int yit,yib,yir,yil;
00940 int vect,vecb,vecr,vecl;
00941 int c8,t8,l8,r8;
00942 int ti8,li8,ri8;
00943 int xmb, ymb, lx;
00944 MotionVector *fc,*ft,*fb,*fr,*fl;
00945
00946 int Mc[8][8] = {
00947 {4,5,5,5,5,5,5,4},
00948 {5,5,5,5,5,5,5,5},
00949 {5,5,6,6,6,6,5,5},
00950 {5,5,6,6,6,6,5,5},
00951 {5,5,6,6,6,6,5,5},
00952 {5,5,6,6,6,6,5,5},
00953 {5,5,5,5,5,5,5,5},
00954 {4,5,5,5,5,5,5,4},
00955 };
00956 int Mt[8][8] = {
00957 {2,2,2,2,2,2,2,2},
00958 {1,1,2,2,2,2,1,1},
00959 {1,1,1,1,1,1,1,1},
00960 {1,1,1,1,1,1,1,1},
00961 {0,0,0,0,0,0,0,0},
00962 {0,0,0,0,0,0,0,0},
00963 {0,0,0,0,0,0,0,0},
00964 {0,0,0,0,0,0,0,0},
00965 };
00966 int Mb[8][8] = {
00967 {0,0,0,0,0,0,0,0},
00968 {0,0,0,0,0,0,0,0},
00969 {0,0,0,0,0,0,0,0},
00970 {0,0,0,0,0,0,0,0},
00971 {1,1,1,1,1,1,1,1},
00972 {1,1,1,1,1,1,1,1},
00973 {1,1,2,2,2,2,1,1},
00974 {2,2,2,2,2,2,2,2},
00975 };
00976 int Mr[8][8] = {
00977 {0,0,0,0,1,1,1,2},
00978 {0,0,0,0,1,1,2,2},
00979 {0,0,0,0,1,1,2,2},
00980 {0,0,0,0,1,1,2,2},
00981 {0,0,0,0,1,1,2,2},
00982 {0,0,0,0,1,1,2,2},
00983 {0,0,0,0,1,1,2,2},
00984 {0,0,0,0,1,1,1,2},
00985 };
00986 int Ml[8][8] = {
00987 {2,1,1,1,0,0,0,0},
00988 {2,2,1,1,0,0,0,0},
00989 {2,2,1,1,0,0,0,0},
00990 {2,2,1,1,0,0,0,0},
00991 {2,2,1,1,0,0,0,0},
00992 {2,2,1,1,0,0,0,0},
00993 {2,2,1,1,0,0,0,0},
00994 {2,1,1,1,0,0,0,0},
00995 };
00996
00997 xmb = x/MB_SIZE+1;
00998 ymb = y/MB_SIZE+1;
00999
01000 lx = ((VidSt->mv_outside_frame) ? (VidSt->pels) + ((VidSt->long_vectors)?64:32) : (VidSt->pels));
01001
01002 c8 = (MV[0][ymb][xmb]->Mode == MODE_INTER4V ? 1 : 0);
01003
01004 t8 = (MV[0][ymb-1][xmb]->Mode == MODE_INTER4V ? 1 : 0);
01005 ti8 = (MV[0][ymb-1][xmb]->Mode == MODE_INTRA ? 1 : 0);
01006 ti8 = (MV[0][ymb-1][xmb]->Mode == MODE_INTRA_Q ? 1 : ti8);
01007
01008 l8 = (MV[0][ymb][xmb-1]->Mode == MODE_INTER4V ? 1 : 0);
01009 li8 = (MV[0][ymb][xmb-1]->Mode == MODE_INTRA ? 1 : 0);
01010 li8 = (MV[0][ymb][xmb-1]->Mode == MODE_INTRA_Q ? 1 : li8);
01011
01012 r8 = (MV[0][ymb][xmb+1]->Mode == MODE_INTER4V ? 1 : 0);
01013 ri8 = (MV[0][ymb][xmb+1]->Mode == MODE_INTRA ? 1 : 0);
01014 ri8 = (MV[0][ymb][xmb+1]->Mode == MODE_INTRA_Q ? 1 : ri8);
01015
01016 if (PB) {
01017 ti8 = li8 = ri8 = 0;
01018 }
01019
01020 switch (comp+1) {
01021
01022 case 1:
01023 vect = (ti8 ? (c8 ? 1 : 0) : (t8 ? 3 : 0));
01024 yit = (ti8 ? ymb : ymb - 1);
01025 xit = xmb;
01026
01027 vecb = (c8 ? 3 : 0) ; yib = ymb; xib = xmb;
01028
01029 vecl = (li8 ? (c8 ? 1 : 0) : (l8 ? 2 : 0));
01030 yil = ymb;
01031 xil = (li8 ? xmb : xmb-1);
01032
01033 vecr = (c8 ? 2 : 0) ; yir = ymb; xir = xmb;
01034
01035
01036 if (ymb == 1) {
01037 yit = ymb;
01038 vect = (c8 ? 1 : 0);
01039 }
01040 if (xmb == 1) {
01041 xil = xmb;
01042 vecl = (c8 ? 1 : 0);
01043 }
01044 break;
01045
01046 case 2:
01047 vect = (ti8 ? (c8 ? 2 : 0) : (t8 ? 4 : 0));
01048 yit = (ti8 ? ymb : ymb-1);
01049 xit = xmb;
01050
01051 vecb = (c8 ? 4 : 0) ; yib = ymb; xib = xmb;
01052 vecl = (c8 ? 1 : 0) ; yil = ymb; xil = xmb;
01053
01054 vecr = (ri8 ? (c8 ? 2 : 0) : (r8 ? 1 : 0));
01055 yir = ymb;
01056 xir = (ri8 ? xmb : xmb+1);
01057
01058
01059 if (ymb == 1) {
01060 yit = ymb;
01061 vect = (c8 ? 2 : 0);
01062 }
01063 if (xmb == (VidSt->pels)/16) {
01064 xir = xmb;
01065 vecr = (c8 ? 2 : 0);
01066 }
01067 break;
01068
01069 case 3:
01070 vect = (c8 ? 1 : 0) ; yit = ymb ; xit = xmb;
01071 vecb = (c8 ? 3 : 0) ; yib = ymb ; xib = xmb;
01072
01073 vecl = (li8 ? (c8 ? 3 : 0) : (l8 ? 4 : 0));
01074 yil = ymb;
01075 xil = (li8 ? xmb : xmb-1);
01076
01077 vecr = (c8 ? 4 : 0) ; yir = ymb ; xir = xmb;
01078
01079
01080 if (xmb == 1) {
01081 xil = xmb;
01082 vecl = (c8 ? 3 : 0);
01083 }
01084 break;
01085
01086 case 4:
01087 vect = (c8 ? 2 : 0) ; yit = ymb ; xit = xmb;
01088 vecb = (c8 ? 4 : 0) ; yib = ymb ; xib = xmb;
01089 vecl = (c8 ? 3 : 0) ; yil = ymb ; xil = xmb;
01090
01091 vecr = (ri8 ? (c8 ? 4 : 0) : (r8 ? 3 : 0));
01092 yir = ymb;
01093 xir = (ri8 ? xmb : xmb+1);
01094
01095
01096 if (xmb == (VidSt->pels)/16) {
01097 xir = xmb;
01098 vecr = (c8 ? 4 : 0);
01099 }
01100 break;
01101
01102 default:
01103 fprintf(stderr,"Illegal block number in FindPredOBMC (vid_pred.c)\n");
01104 exit(-1);
01105 break;
01106 }
01107
01108 fc = MV[c8 ? comp + 1: 0][ymb][xmb];
01109
01110 ft = MV[vect][yit][xit];
01111 fb = MV[vecb][yib][xib];
01112 fr = MV[vecr][yir][xir];
01113 fl = MV[vecl][yil][xil];
01114
01115 nxc = 2*x + ((comp&1)<<4); nyc = 2*y + ((comp&2)<<3);
01116 nxt = nxb = nxr = nxl = nxc;
01117 nyt = nyb = nyr = nyl = nyc;
01118
01119 nxc += 2*fc->x + fc->x_half; nyc += 2*fc->y + fc->y_half;
01120 nxt += 2*ft->x + ft->x_half; nyt += 2*ft->y + ft->y_half;
01121 nxb += 2*fb->x + fb->x_half; nyb += 2*fb->y + fb->y_half;
01122 nxr += 2*fr->x + fr->x_half; nyr += 2*fr->y + fr->y_half;
01123 nxl += 2*fl->x + fl->x_half; nyl += 2*fl->y + fl->y_half;
01124
01125
01126 for (n = 0; n < 8; n++) {
01127 for (m = 0; m < 8; m++) {
01128
01129
01130 pc = *(prev + nxc + 2*m + (nyc + 2*n)*lx*2) * Mc[n][m];
01131 pt = *(prev + nxt + 2*m + (nyt + 2*n)*lx*2) * Mt[n][m];
01132 pb = *(prev + nxb + 2*m + (nyb + 2*n)*lx*2) * Mb[n][m];
01133 pr = *(prev + nxr + 2*m + (nyr + 2*n)*lx*2) * Mr[n][m];
01134 pl = *(prev + nxl + 2*m + (nyl + 2*n)*lx*2) * Ml[n][m];
01135
01136
01137
01138
01139
01140
01141
01142 *(pred + m + n*16) = (pc+pt+pb+pr+pl+4)>>3;
01143 }
01144 }
01145 return;
01146 }
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164 MB_Structure *MB_Recon_P(PictImage *prev_image, unsigned char *prev_ipol,
01165 MB_Structure *diff, int x_curr, int y_curr,
01166 MotionVector *MV[6][MBR+1][MBC+2], int PB)
01167 {
01168 MB_Structure *recon_data = (MB_Structure *)malloc(sizeof(MB_Structure));
01169 MotionVector *fr0,*fr1,*fr2,*fr3,*fr4;
01170 int pred[16][16];
01171 int dx, dy, sum;
01172 int i,j;
01173
01174 fr0 = MV[0][y_curr/MB_SIZE+1][x_curr/MB_SIZE+1];
01175
01176 if ((VidSt->advanced)) {
01177 if (fr0->Mode == MODE_INTER || fr0->Mode == MODE_INTER_Q) {
01178 FindPredOBMC(x_curr, y_curr, MV, prev_ipol, &pred[0][0], 0, PB);
01179 FindPredOBMC(x_curr, y_curr, MV, prev_ipol, &pred[0][8], 1, PB);
01180 FindPredOBMC(x_curr, y_curr, MV, prev_ipol, &pred[8][0], 2, PB);
01181 FindPredOBMC(x_curr, y_curr, MV, prev_ipol, &pred[8][8], 3, PB);
01182 for (j = 0; j < MB_SIZE; j++)
01183 for (i = 0; i < MB_SIZE; i++)
01184 diff->lum[j][i] += pred[j][i];
01185
01186 dx = 2*fr0->x + fr0->x_half;
01187 dy = 2*fr0->y + fr0->y_half;
01188 dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );
01189 dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 );
01190 ReconChromBlock_P(x_curr, y_curr, dx, dy, prev_image, diff);
01191 }
01192 else if (fr0->Mode == MODE_INTER4V) {
01193
01194 FindPredOBMC(x_curr, y_curr, MV, prev_ipol, &pred[0][0], 0, PB);
01195 FindPredOBMC(x_curr, y_curr, MV, prev_ipol, &pred[0][8], 1, PB);
01196 FindPredOBMC(x_curr, y_curr, MV, prev_ipol, &pred[8][0], 2, PB);
01197 FindPredOBMC(x_curr, y_curr, MV, prev_ipol, &pred[8][8], 3, PB);
01198 for (j = 0; j < MB_SIZE; j++)
01199 for (i = 0; i < MB_SIZE; i++)
01200 diff->lum[j][i] += pred[j][i];
01201
01202 fr1 = MV[1][y_curr/MB_SIZE+1][x_curr/MB_SIZE+1];
01203 fr2 = MV[2][y_curr/MB_SIZE+1][x_curr/MB_SIZE+1];
01204 fr3 = MV[3][y_curr/MB_SIZE+1][x_curr/MB_SIZE+1];
01205 fr4 = MV[4][y_curr/MB_SIZE+1][x_curr/MB_SIZE+1];
01206
01207 sum = 2*fr1->x + fr1->x_half + 2*fr2->x + fr2->x_half +
01208 2*fr3->x + fr3->x_half + 2*fr4->x + fr4->x_half ;
01209 dx = sign(sum)*(roundtab[abs(sum)%16] + (abs(sum)/16)*2);
01210
01211 sum = 2*fr1->y + fr1->y_half + 2*fr2->y + fr2->y_half +
01212 2*fr3->y + fr3->y_half + 2*fr4->y + fr4->y_half;
01213 dy = sign(sum)*(roundtab[abs(sum)%16] + (abs(sum)/16)*2);
01214
01215 ReconChromBlock_P(x_curr, y_curr, dx, dy, prev_image, diff);
01216 }
01217 }
01218 else {
01219 if (fr0->Mode == MODE_INTER || fr0->Mode == MODE_INTER_Q) {
01220
01221 ReconLumBlock_P(x_curr,y_curr,fr0,prev_ipol,&diff->lum[0][0],16,0);
01222
01223 dx = 2*fr0->x + fr0->x_half;
01224 dy = 2*fr0->y + fr0->y_half;
01225 dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );
01226 dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 );
01227 ReconChromBlock_P(x_curr, y_curr, dx, dy, prev_image, diff);
01228 }
01229 }
01230
01231 memcpy(recon_data, diff, sizeof(MB_Structure));
01232
01233 return recon_data;
01234 }
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249 void ReconLumBlock_P(int x, int y, MotionVector *fr,
01250 unsigned char *prev, int *data, int bs, int comp)
01251 {
01252 int m, n;
01253 int x1, y1, lx;
01254
01255 lx = ((VidSt->mv_outside_frame) ? (VidSt->pels) + ((VidSt->long_vectors)?64:32) : (VidSt->pels));
01256
01257 x1 = 2*(x + fr->x) + fr->x_half;
01258 y1 = 2*(y + fr->y) + fr->y_half;
01259
01260 x1 += ((comp&1)<<4);
01261 y1 += ((comp&2)<<3);
01262
01263 for (n = 0; n < bs; n++) {
01264 for (m = 0; m < bs; m++) {
01265 *(data+m+n*16) += (int)(*(prev+x1+2*m + (y1+2*n)*2*lx));
01266 }
01267 }
01268
01269 return;
01270 }
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285 void ReconChromBlock_P(int x_curr, int y_curr, int dx, int dy,
01286 PictImage *prev, MB_Structure *data)
01287
01288 {
01289 int m,n;
01290
01291 int x, y, ofx, ofy, pel,lx;
01292 int xint, yint;
01293 int xh, yh;
01294
01295 lx = ((VidSt->mv_outside_frame) ? (VidSt->pels)/2 + ((VidSt->long_vectors)?32:16) : (VidSt->pels)/2);
01296
01297 x = x_curr>>1;
01298 y = y_curr>>1;
01299
01300 xint = dx>>1;
01301 xh = dx & 1;
01302 yint = dy>>1;
01303 yh = dy & 1;
01304
01305 if (!xh && !yh) {
01306 for (n = 0; n < 8; n++) {
01307 for (m = 0; m < 8; m++) {
01308
01309 ofx = x + xint + m;
01310 ofy = y + yint + n;
01311 pel=*(prev->Cr+ofx + (ofy )*lx);
01312 data->Cr[n][m] += pel;
01313
01314 pel=*(prev->Cb+ofx + (ofy )*lx);
01315 data->Cb[n][m] += pel;
01316 }
01317 }
01318 }
01319 else if (!xh && yh) {
01320 for (n = 0; n < 8; n++) {
01321 for (m = 0; m < 8; m++) {
01322
01323 ofx = x + xint + m;
01324 ofy = y + yint + n;
01325 pel=(*(prev->Cr+ofx + (ofy )*lx)+
01326 *(prev->Cr+ofx + (ofy+yh)*lx) + 1)>>1;
01327
01328 data->Cr[n][m] += pel;
01329
01330 pel=(*(prev->Cb+ofx + (ofy )*lx)+
01331 *(prev->Cb+ofx + (ofy+yh)*lx) + 1)>>1;
01332
01333 data->Cb[n][m] += pel;
01334
01335 }
01336 }
01337 }
01338 else if (xh && !yh) {
01339 for (n = 0; n < 8; n++) {
01340 for (m = 0; m < 8; m++) {
01341
01342 ofx = x + xint + m;
01343 ofy = y + yint + n;
01344 pel=(*(prev->Cr+ofx + (ofy )*lx)+
01345 *(prev->Cr+ofx+xh + (ofy )*lx) + 1)>>1;
01346
01347 data->Cr[n][m] += pel;
01348
01349 pel=(*(prev->Cb+ofx + (ofy )*lx)+
01350 *(prev->Cb+ofx+xh + (ofy )*lx) + 1)>>1;
01351
01352 data->Cb[n][m] += pel;
01353
01354 }
01355 }
01356 }
01357 else {
01358 for (n = 0; n < 8; n++) {
01359 for (m = 0; m < 8; m++) {
01360 ofx = x + xint + m;
01361 ofy = y + yint + n;
01362 pel=(*(prev->Cr+ofx + (ofy )*lx)+
01363 *(prev->Cr+ofx+xh + (ofy )*lx)+
01364 *(prev->Cr+ofx + (ofy+yh)*lx)+
01365 *(prev->Cr+ofx+xh + (ofy+yh)*lx)+
01366 2)>>2;
01367
01368 data->Cr[n][m] += pel;
01369
01370 pel=(*(prev->Cb+ofx + (ofy )*lx)+
01371 *(prev->Cb+ofx+xh + (ofy )*lx)+
01372 *(prev->Cb+ofx + (ofy+yh)*lx)+
01373 *(prev->Cb+ofx+xh + (ofy+yh)*lx)+
01374 2)>>2;
01375
01376 data->Cb[n][m] += pel;
01377
01378 }
01379 }
01380 }
01381 return;
01382 }
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395 void FindChromBlock_P(int x_curr, int y_curr, int dx, int dy,
01396 PictImage *prev, MB_Structure *data)
01397
01398 {
01399 int m,n;
01400
01401 int x, y, ofx, ofy, pel,lx;
01402 int xint, yint;
01403 int xh, yh;
01404
01405 lx = ((VidSt->mv_outside_frame) ? (VidSt->pels)/2 + ((VidSt->long_vectors)?32:16) : (VidSt->pels)/2);
01406
01407 x = x_curr>>1;
01408 y = y_curr>>1;
01409
01410 xint = dx>>1;
01411 xh = dx & 1;
01412 yint = dy>>1;
01413 yh = dy & 1;
01414
01415 if (!xh && !yh) {
01416 for (n = 0; n < 8; n++) {
01417 for (m = 0; m < 8; m++) {
01418
01419 ofx = x + xint + m;
01420 ofy = y + yint + n;
01421 pel=*(prev->Cr+ofx + (ofy )*lx);
01422 data->Cr[n][m] = pel;
01423
01424 pel=*(prev->Cb+ofx + (ofy )*lx);
01425 data->Cb[n][m] = pel;
01426 }
01427 }
01428 }
01429 else if (!xh && yh) {
01430 for (n = 0; n < 8; n++) {
01431 for (m = 0; m < 8; m++) {
01432
01433 ofx = x + xint + m;
01434 ofy = y + yint + n;
01435 pel=(*(prev->Cr+ofx + (ofy )*lx)+
01436 *(prev->Cr+ofx + (ofy+yh)*lx) + 1)>>1;
01437
01438 data->Cr[n][m] = pel;
01439
01440 pel=(*(prev->Cb+ofx + (ofy )*lx)+
01441 *(prev->Cb+ofx + (ofy+yh)*lx) + 1)>>1;
01442
01443 data->Cb[n][m] = pel;
01444
01445 }
01446 }
01447 }
01448 else if (xh && !yh) {
01449 for (n = 0; n < 8; n++) {
01450 for (m = 0; m < 8; m++) {
01451
01452 ofx = x + xint + m;
01453 ofy = y + yint + n;
01454 pel=(*(prev->Cr+ofx + (ofy )*lx)+
01455 *(prev->Cr+ofx+xh + (ofy )*lx) + 1)>>1;
01456
01457 data->Cr[n][m] = pel;
01458
01459 pel=(*(prev->Cb+ofx + (ofy )*lx)+
01460 *(prev->Cb+ofx+xh + (ofy )*lx) + 1)>>1;
01461
01462 data->Cb[n][m] = pel;
01463
01464 }
01465 }
01466 }
01467 else {
01468 for (n = 0; n < 8; n++) {
01469 for (m = 0; m < 8; m++) {
01470 ofx = x + xint + m;
01471 ofy = y + yint + n;
01472 pel=(*(prev->Cr+ofx + (ofy )*lx)+
01473 *(prev->Cr+ofx+xh + (ofy )*lx)+
01474 *(prev->Cr+ofx + (ofy+yh)*lx)+
01475 *(prev->Cr+ofx+xh + (ofy+yh)*lx)+
01476 2)>>2;
01477
01478 data->Cr[n][m] = pel;
01479
01480 pel=(*(prev->Cb+ofx + (ofy )*lx)+
01481 *(prev->Cb+ofx+xh + (ofy )*lx)+
01482 *(prev->Cb+ofx + (ofy+yh)*lx)+
01483 *(prev->Cb+ofx+xh + (ofy+yh)*lx)+
01484 2)>>2;
01485
01486 data->Cb[n][m] = pel;
01487
01488 }
01489 }
01490 }
01491 return;
01492 }
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509 int ChooseMode(unsigned char *curr, int x_pos, int y_pos, int min_SAD)
01510 {
01511 int i,j;
01512 int MB_mean = 0, A = 0;
01513 int y_off;
01514
01515 for (j = 0; j < MB_SIZE; j++) {
01516 y_off = (y_pos + j) * (VidSt->pels);
01517 for (i = 0; i < MB_SIZE; i++) {
01518 MB_mean += *(curr + x_pos + i + y_off);
01519 }
01520 }
01521 MB_mean /= (MB_SIZE*MB_SIZE);
01522 for (j = 0; j < MB_SIZE; j++) {
01523 y_off = (y_pos + j) * (VidSt->pels);
01524 for (i = 0; i < MB_SIZE; i++) {
01525 A += abs( *(curr + x_pos + i + y_off) - MB_mean );
01526 }
01527 }
01528
01529 if (A < (min_SAD - 500))
01530 return MODE_INTRA;
01531 else
01532 return MODE_INTER;
01533 }
01534
01535 int ModifyMode(int Mode, int dquant)
01536 {
01537
01538 if (Mode == MODE_INTRA) {
01539 if(dquant!=0)
01540 return MODE_INTRA_Q;
01541 else
01542 return MODE_INTRA;
01543 }
01544 else{
01545 if(dquant!=0)
01546 return MODE_INTER_Q;
01547 else
01548 return Mode;
01549 }
01550 }