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
00045
00046
00047
00048
00049
00050
00051
00052 #include"vid_sim.h"
00053 #include"video_codec.h"
00054
00055 extern video_codec *VidSt;
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 void CodeOneOrTwo(PictImage *curr, PictImage *B_image, PictImage *prev,
00074 PictImage *pr, int QP, int frameskip, Bits *bits,
00075 Pict *pic, PictImage *B_recon, PictImage *recon)
00076 {
00077 unsigned char *prev_ipol,*pi_edge=NULL,*pi,*orig_lum;
00078 PictImage *prev_recon=NULL, *pr_edge=NULL;
00079 MotionVector *MV[6][MBR+1][MBC+2];
00080 MotionVector ZERO = {0,0,0,0,0};
00081 MB_Structure *recon_data_P;
00082 MB_Structure *recon_data_B=NULL;
00083 MB_Structure *diff;
00084 int *qcoeff_P;
00085 int *qcoeff_B=NULL;
00086
00087 int Mode,B;
00088 int CBP, CBPB=0;
00089 int bquant[] = {5,6,7,8};
00090 int QP_B;
00091 int newgob;
00092
00093 int i,j,k;
00094
00095
00096 float QP_cumulative = (float)0.0;
00097 int abs_mb_num = 0, QuantChangePostponed = 0;
00098 int QP_new, QP_prev, dquant, QP_xmitted=QP;
00099
00100 ZeroBits(bits);
00101
00102
00103 if ((VidSt->mv_outside_frame)) {
00104 if ((VidSt->long_vectors)) {
00105
00106
00107
00108 B = 16;
00109 }
00110 else {
00111
00112 B = 8;
00113 }
00114 pi_edge = (unsigned char *)malloc(sizeof(char)*((VidSt->pels)+4*B)*((VidSt->lines)+4*B));
00115 if (pi_edge == NULL) {
00116 fprintf(stderr,"Couldn't allocate memory for pi_edge\n");
00117 exit(-1);
00118 }
00119 MakeEdgeImage(pr->lum,pi_edge + ((VidSt->pels) + 4*B)*2*B+2*B,(VidSt->pels),(VidSt->lines),2*B);
00120 pi = InterpolateImage(pi_edge, (VidSt->pels)+4*B, (VidSt->lines)+4*B);
00121 free(pi_edge);
00122 prev_ipol = pi + (2*(VidSt->pels) + 8*B) * 4*B + 4*B;
00123
00124
00125 pr_edge = InitImage(((VidSt->pels)+4*B)*((VidSt->lines)+4*B));
00126 MakeEdgeImage(prev->lum, pr_edge->lum + ((VidSt->pels) + 4*B)*2*B+2*B,
00127 (VidSt->pels),(VidSt->lines),2*B);
00128 orig_lum = pr_edge->lum + ((VidSt->pels) + 4*B)*2*B+2*B;
00129
00130
00131 MakeEdgeImage(pr->lum,pr_edge->lum + ((VidSt->pels)+4*B)*2*B + 2*B,(VidSt->pels),(VidSt->lines),2*B);
00132 MakeEdgeImage(pr->Cr,pr_edge->Cr + ((VidSt->pels)/2 + 2*B)*B + B,(VidSt->pels)/2,(VidSt->lines)/2,B);
00133 MakeEdgeImage(pr->Cb,pr_edge->Cb + ((VidSt->pels)/2 + 2*B)*B + B,(VidSt->pels)/2,(VidSt->lines)/2,B);
00134
00135 prev_recon = (PictImage *)malloc(sizeof(PictImage));
00136 prev_recon->lum = pr_edge->lum + ((VidSt->pels) + 4*B)*2*B + 2*B;
00137 prev_recon->Cr = pr_edge->Cr + ((VidSt->pels)/2 + 2*B)*B + B;
00138 prev_recon->Cb = pr_edge->Cb + ((VidSt->pels)/2 + 2*B)*B + B;
00139 }
00140 else {
00141 pi = InterpolateImage(pr->lum,(VidSt->pels),(VidSt->lines));
00142 prev_ipol = pi;
00143 prev_recon = pr;
00144 orig_lum = prev->lum;
00145 }
00146
00147
00148 for (i = 1; i < ((VidSt->pels)>>4)+1; i++) {
00149 for (k = 0; k < 6; k++) {
00150 MV[k][0][i] = (MotionVector *)malloc(sizeof(MotionVector));
00151 MarkVec(MV[k][0][i]);
00152 }
00153 MV[0][0][i]->Mode = MODE_INTRA;
00154 }
00155
00156 for (i = 0; i < ((VidSt->lines)>>4)+1; i++) {
00157 for (k = 0; k < 6; k++) {
00158 MV[k][i][0] = (MotionVector *)malloc(sizeof(MotionVector));
00159 ZeroVec(MV[k][i][0]);
00160 MV[k][i][((VidSt->pels)>>4)+1] = (MotionVector *)malloc(sizeof(MotionVector));
00161 ZeroVec(MV[k][i][((VidSt->pels)>>4)+1]);
00162 }
00163 MV[0][i][0]->Mode = MODE_INTRA;
00164 MV[0][i][((VidSt->pels)>>4)+1]->Mode = MODE_INTRA;
00165 }
00166
00167
00168 MotionEstimatePicture(curr->lum,prev_recon->lum,prev_ipol,
00169 pic->seek_dist,MV, pic->use_gobsync);
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 if (pic->bit_rate != 0) {
00181
00182 QP_new = InitializeQuantizer(PCT_INTER, (float)pic->bit_rate,
00183 (pic->PB ? pic->target_frame_rate/2 : pic->target_frame_rate),
00184 pic->QP_mean);
00185 QP_xmitted = QP_prev = QP_new;
00186 }
00187 else {
00188 QP_new = QP_xmitted = QP_prev = QP;
00189 }
00190
00191 dquant = 0;
00192
00193 for ( j = 0; j < (VidSt->lines)/MB_SIZE; j++) {
00194
00195
00196 if (pic->bit_rate != 0) {
00197
00198 AddBitsPicture(bits);
00199
00200 QP_new = UpdateQuantizer(abs_mb_num, pic->QP_mean, PCT_INTER,
00201 (float)pic->bit_rate, (VidSt->pels)/MB_SIZE,
00202 (VidSt->lines)/MB_SIZE, bits->total);
00203 }
00204
00205 newgob = 0;
00206
00207 if (j == 0) {
00208 pic->QUANT = QP_new;
00209 bits->header += CountBitsPicture(pic);
00210 QP_xmitted = QP_prev = QP_new;
00211 }
00212 else if (pic->use_gobsync && j%pic->use_gobsync == 0) {
00213 bits->header += CountBitsSlice(j,QP_new);
00214 QP_xmitted = QP_prev = QP_new;
00215 newgob = 1;
00216 }
00217
00218 for ( i = 0; i < (VidSt->pels)/MB_SIZE; i++) {
00219
00220
00221 dquant = QP_new - QP_prev;
00222 if (dquant != 0 && i != 0 && MV[0][j+1][i+1]->Mode == MODE_INTER4V) {
00223
00224
00225
00226
00227
00228
00229 dquant = 0;
00230 QP_xmitted = QP_prev;
00231 QuantChangePostponed = 1;
00232 }
00233 else {
00234 QP_xmitted = QP_new;
00235 QuantChangePostponed = 0;
00236 }
00237 if (dquant > 2) { dquant = 2; QP_xmitted = QP_prev + dquant;}
00238 if (dquant < -2) { dquant = -2; QP_xmitted = QP_prev + dquant;}
00239
00240 pic->DQUANT = dquant;
00241
00242 Mode = ModifyMode(MV[0][j+1][i+1]->Mode,pic->DQUANT);
00243 MV[0][j+1][i+1]->Mode = Mode;
00244
00245 pic->MB = i + j * ((VidSt->pels)/MB_SIZE);
00246
00247 if (Mode == MODE_INTER || Mode == MODE_INTER_Q || Mode==MODE_INTER4V) {
00248
00249 diff = Predict_P(curr,prev_recon,prev_ipol,
00250 i*MB_SIZE,j*MB_SIZE,MV,pic->PB);
00251
00252 }
00253 else {
00254 diff = (MB_Structure *)malloc(sizeof(MB_Structure));
00255 FillLumBlock(i*MB_SIZE, j*MB_SIZE, curr, diff);
00256 FillChromBlock(i*MB_SIZE, j*MB_SIZE, curr, diff);
00257 }
00258
00259
00260 qcoeff_P = MB_Encode(diff, QP_xmitted, Mode);
00261 CBP = FindCBP(qcoeff_P, Mode, 64);
00262 if (CBP == 0 && (Mode == MODE_INTER || Mode == MODE_INTER_Q))
00263 ZeroMBlock(diff);
00264 else
00265 MB_Decode(qcoeff_P, diff, QP_xmitted, Mode);
00266 recon_data_P = MB_Recon_P(prev_recon, prev_ipol,diff,
00267 i*MB_SIZE,j*MB_SIZE,MV,pic->PB);
00268 Clip(recon_data_P);
00269 free(diff);
00270
00271
00272
00273 if (pic->PB) {
00274 diff = Predict_B(B_image, prev_recon, prev_ipol,i*MB_SIZE, j*MB_SIZE,
00275 MV, recon_data_P, frameskip, pic->TRB);
00276 if (QP_xmitted == 0)
00277 QP_B = 0;
00278 else
00279 QP_B = mmax(1,mmin(31,bquant[pic->BQUANT]*QP_xmitted/4));
00280 qcoeff_B = MB_Encode(diff, QP_B, MODE_INTER);
00281 CBPB = FindCBP(qcoeff_B, MODE_INTER, 64);
00282 if (CBPB)
00283 MB_Decode(qcoeff_B, diff, QP_B, MODE_INTER);
00284 else
00285 ZeroMBlock(diff);
00286 recon_data_B = MB_Recon_B(prev_recon, diff,prev_ipol,i*MB_SIZE,
00287 j*MB_SIZE,MV,recon_data_P,frameskip,
00288 pic->TRB);
00289 Clip(recon_data_B);
00290
00291
00292
00293 if (CBPB) {
00294 pic->MODB = PBMODE_CBPB_MVDB;
00295 }
00296 else {
00297 if (MV[5][j+1][i+1]->x == 0 && MV[5][j+1][i+1]->y == 0)
00298 pic->MODB = PBMODE_NORMAL;
00299 else
00300 pic->MODB = PBMODE_MVDB;
00301 }
00302
00303 free(diff);
00304
00305 }
00306 else
00307 ZeroVec(MV[5][j+1][i+1]);
00308
00309 if ((CBP==0) && (CBPB==0) && (EqualVec(MV[0][j+1][i+1],&ZERO)) &&
00310 (EqualVec(MV[5][j+1][i+1],&ZERO)) &&
00311 (Mode == MODE_INTER || Mode == MODE_INTER_Q)) {
00312
00313
00314 if (Mode == MODE_INTER_Q) {
00315
00316 QP_xmitted = QP_prev;
00317 pic->DQUANT = 0;
00318 Mode = MODE_INTER;
00319 }
00320 if (!(VidSt->syntax_arith_coding))
00321 CountBitsMB(Mode,1,CBP,CBPB,pic,bits);
00322 else
00323 Count_sac_BitsMB(Mode,1,CBP,CBPB,pic,bits);
00324 }
00325 else {
00326
00327 if (!(VidSt->syntax_arith_coding)) {
00328 CountBitsMB(Mode,0,CBP,CBPB,pic,bits);
00329
00330 if (Mode == MODE_INTER || Mode == MODE_INTER_Q) {
00331 bits->no_inter++;
00332 CountBitsVectors(MV, bits, i, j, Mode, newgob, pic);
00333 }
00334 else if (Mode == MODE_INTER4V) {
00335 bits->no_inter4v++;
00336 CountBitsVectors(MV, bits, i, j, Mode, newgob, pic);
00337 }
00338 else {
00339
00340 bits->no_intra++;
00341 if (pic->PB)
00342 CountBitsVectors(MV, bits, i, j, Mode, newgob, pic);
00343 }
00344
00345 if (CBP || Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
00346 CountBitsCoeff(qcoeff_P, Mode, CBP, bits, 64);
00347 if (CBPB)
00348 CountBitsCoeff(qcoeff_B, MODE_INTER, CBPB, bits, 64);
00349 }
00350
00351 else {
00352 Count_sac_BitsMB(Mode,0,CBP,CBPB,pic,bits);
00353
00354 if (Mode == MODE_INTER || Mode == MODE_INTER_Q) {
00355 bits->no_inter++;
00356 Count_sac_BitsVectors(MV, bits, i, j, Mode, newgob, pic);
00357 }
00358 else if (Mode == MODE_INTER4V) {
00359 bits->no_inter4v++;
00360 Count_sac_BitsVectors(MV, bits, i, j, Mode, newgob, pic);
00361 }
00362 else {
00363
00364 bits->no_intra++;
00365 if (pic->PB)
00366 Count_sac_BitsVectors(MV, bits, i, j, Mode, newgob, pic);
00367 }
00368
00369 if (CBP || Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
00370 Count_sac_BitsCoeff(qcoeff_P, Mode, CBP, bits, 64);
00371 if (CBPB)
00372 Count_sac_BitsCoeff(qcoeff_B, MODE_INTER, CBPB, bits, 64);
00373 }
00374
00375 QP_prev = QP_xmitted;
00376 }
00377
00378 abs_mb_num++;
00379 QP_cumulative += QP_xmitted;
00380 #ifdef PRINTQ
00381
00382 if (QuantChangePostponed)
00383 fprintf(stdout,"@%2d",QP_xmitted);
00384 else
00385 fprintf(stdout," %2d",QP_xmitted);
00386 #endif
00387
00388 if (pic->PB)
00389 ReconImage(i,j,recon_data_B,B_recon);
00390
00391 ReconImage(i,j,recon_data_P,recon);
00392 free(recon_data_P);
00393 free(qcoeff_P);
00394 if (pic->PB) {
00395 free(qcoeff_B);
00396 free(recon_data_B);
00397 }
00398 }
00399 #ifdef PRINTQ
00400 fprintf(stdout,"\n");
00401 #endif
00402 }
00403
00404 pic->QP_mean = QP_cumulative/(float)abs_mb_num;
00405
00406
00407 free(pi);
00408 if ((VidSt->mv_outside_frame)) {
00409 free(prev_recon);
00410 FreeImage(pr_edge);
00411 }
00412 for (j = 0; j < ((VidSt->lines)>>4)+1; j++)
00413 for (i = 0; i < ((VidSt->pels)>>4)+2; i++)
00414 for (k = 0; k < 6; k++)
00415 free(MV[k][j][i]);
00416 return;
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 PictImage *CodeOneIntra(PictImage *curr, int QP, Bits *bits, Pict *pic)
00436 {
00437 PictImage *recon;
00438 MB_Structure *data = (MB_Structure *)malloc(sizeof(MB_Structure));
00439 int *qcoeff;
00440 int Mode = MODE_INTRA;
00441 int CBP,COD;
00442 int i,j;
00443
00444 recon = InitImage((VidSt->pels)*(VidSt->lines));
00445 ZeroBits(bits);
00446
00447 pic->QUANT = QP;
00448 bits->header += CountBitsPicture(pic);
00449
00450 COD = 0;
00451 for ( j = 0; j < (VidSt->lines)/MB_SIZE; j++) {
00452
00453
00454 if (pic->use_gobsync && j != 0)
00455 bits->header += CountBitsSlice(j,QP);
00456 for ( i = 0; i < (VidSt->pels)/MB_SIZE; i++) {
00457
00458 pic->MB = i + j * ((VidSt->pels)/MB_SIZE);
00459 bits->no_intra++;
00460 FillLumBlock(i*MB_SIZE, j*MB_SIZE, curr, data);
00461 FillChromBlock(i*MB_SIZE, j*MB_SIZE, curr, data);
00462 qcoeff = MB_Encode(data, QP, Mode);
00463 CBP = FindCBP(qcoeff,Mode,64);
00464
00465 if (!(VidSt->syntax_arith_coding)) {
00466 CountBitsMB(Mode,COD,CBP,0,pic,bits);
00467 CountBitsCoeff(qcoeff, Mode, CBP,bits,64);
00468 } else {
00469 Count_sac_BitsMB(Mode,COD,CBP,0,pic,bits);
00470 Count_sac_BitsCoeff(qcoeff, Mode, CBP,bits,64);
00471 }
00472
00473 MB_Decode(qcoeff, data, QP, Mode);
00474 Clip(data);
00475 ReconImage(i,j,data,recon);
00476 free(qcoeff);
00477 }
00478 }
00479 pic->QP_mean = (float)QP;
00480
00481
00482 free(data);
00483 return recon;
00484 }
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 int *MB_Encode(MB_Structure *mb_orig, int QP, int I)
00502 {
00503 int i, j, k, l, row, col;
00504 int fblock[64];
00505 int coeff[384];
00506 int *coeff_ind;
00507 int *qcoeff;
00508 int *qcoeff_ind;
00509
00510 if ((qcoeff=(int *)malloc(sizeof(int)*384)) == 0) {
00511 fprintf(stderr,"mb_encode(): Couldn't allocate qcoeff.\n");
00512 exit(-1);
00513 }
00514
00515 coeff_ind = coeff;
00516 qcoeff_ind = qcoeff;
00517 for (k=0;k<16;k+=8) {
00518 for (l=0;l<16;l+=8) {
00519 for (i=k,row=0;row<64;i++,row+=8) {
00520 for (j=l,col=0;col<8;j++,col++) {
00521 *(fblock+row+col) = mb_orig->lum[i][j];
00522 }
00523 }
00524 Dct(fblock,coeff_ind);
00525 Quant(coeff_ind,qcoeff_ind,QP,I);
00526 coeff_ind += 64;
00527 qcoeff_ind += 64;
00528 }
00529 }
00530 for (i=0;i<8;i++) {
00531 for (j=0;j<8;j++) {
00532 *(fblock+i*8+j) = mb_orig->Cb[i][j];
00533 }
00534 }
00535 Dct(fblock,coeff_ind);
00536 Quant(coeff_ind,qcoeff_ind,QP,I);
00537 coeff_ind += 64;
00538 qcoeff_ind += 64;
00539
00540 for (i=0;i<8;i++) {
00541 for (j=0;j<8;j++) {
00542 *(fblock+i*8+j) = mb_orig->Cr[i][j];
00543 }
00544 }
00545 Dct(fblock,coeff_ind);
00546 Quant(coeff_ind,qcoeff_ind,QP,I);
00547
00548 return qcoeff;
00549 }
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566 int MB_Decode(int *qcoeff, MB_Structure *mb_recon, int QP, int I)
00567 {
00568 int i, j, k, l, row, col;
00569 int *iblock;
00570 int *qcoeff_ind;
00571 int *rcoeff, *rcoeff_ind;
00572
00573 if ((iblock = (int *)malloc(sizeof(int)*64)) == NULL) {
00574 fprintf(stderr,"MB_Coder: Could not allocate space for iblock\n");
00575 exit(-1);
00576 }
00577 if ((rcoeff = (int *)malloc(sizeof(int)*384)) == NULL) {
00578 fprintf(stderr,"MB_Coder: Could not allocate space for rcoeff\n");
00579 exit(-1);
00580 }
00581
00582
00583
00584 for (i = 0; i < 16; i++)
00585 for (j = 0; j < 16; j++)
00586 mb_recon->lum[j][i] = 0;
00587 for (i = 0; i < 8; i++)
00588 for (j = 0; j < 8; j++) {
00589 mb_recon->Cb[j][i] = 0;
00590 mb_recon->Cr[j][i] = 0;
00591 }
00592
00593 qcoeff_ind = qcoeff;
00594 rcoeff_ind = rcoeff;
00595
00596 for (k=0;k<16;k+=8) {
00597 for (l=0;l<16;l+=8) {
00598 Dequant(qcoeff_ind,rcoeff_ind,QP,I);
00599 #ifndef FASTIDCT
00600 idctref(rcoeff_ind,iblock);
00601 #else
00602 idct(rcoeff_ind,iblock);
00603 #endif
00604 qcoeff_ind += 64;
00605 rcoeff_ind += 64;
00606 for (i=k,row=0;row<64;i++,row+=8) {
00607 for (j=l,col=0;col<8;j++,col++) {
00608 mb_recon->lum[i][j] = *(iblock+row+col);
00609 }
00610 }
00611 }
00612 }
00613 Dequant(qcoeff_ind,rcoeff_ind,QP,I);
00614 #ifndef FASTIDCT
00615 idctref(rcoeff_ind,iblock);
00616 #else
00617 idct(rcoeff_ind,iblock);
00618 #endif
00619 qcoeff_ind += 64;
00620 rcoeff_ind += 64;
00621 for (i=0;i<8;i++) {
00622 for (j=0;j<8;j++) {
00623 mb_recon->Cb[i][j] = *(iblock+i*8+j);
00624 }
00625 }
00626 Dequant(qcoeff_ind,rcoeff_ind,QP,I);
00627 #ifndef FASTIDCT
00628 idctref(rcoeff_ind,iblock);
00629 #else
00630 idct(rcoeff_ind,iblock);
00631 #endif
00632 for (i=0;i<8;i++) {
00633 for (j=0;j<8;j++) {
00634 mb_recon->Cr[i][j] = *(iblock+i*8+j);
00635 }
00636 }
00637 free(iblock);
00638 free(rcoeff);
00639 return 0;
00640 }
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 void FillLumBlock( int x, int y, PictImage *image, MB_Structure *data)
00657 {
00658 int n;
00659 register int m;
00660
00661 for (n = 0; n < MB_SIZE; n++)
00662 for (m = 0; m < MB_SIZE; m++)
00663 data->lum[n][m] =
00664 (int)(*(image->lum + x+m + (y+n)*(VidSt->pels)));
00665 return;
00666 }
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 void FillChromBlock(int x_curr, int y_curr, PictImage *image,
00683 MB_Structure *data)
00684 {
00685 int n;
00686 register int m;
00687
00688 int x, y;
00689
00690 x = x_curr>>1;
00691 y = y_curr>>1;
00692
00693 for (n = 0; n < (MB_SIZE>>1); n++)
00694 for (m = 0; m < (MB_SIZE>>1); m++) {
00695 data->Cr[n][m] =
00696 (int)(*(image->Cr +x+m + (y+n)*(VidSt->cpels)));
00697 data->Cb[n][m] =
00698 (int)(*(image->Cb +x+m + (y+n)*(VidSt->cpels)));
00699 }
00700 return;
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717 void ZeroMBlock(MB_Structure *data)
00718 {
00719 int n;
00720 register int m;
00721
00722 for (n = 0; n < MB_SIZE; n++)
00723 for (m = 0; m < MB_SIZE; m++)
00724 data->lum[n][m] = 0;
00725 for (n = 0; n < (MB_SIZE>>1); n++)
00726 for (m = 0; m < (MB_SIZE>>1); m++) {
00727 data->Cr[n][m] = 0;
00728 data->Cb[n][m] = 0;
00729 }
00730 return;
00731 }
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747 void ReconImage (int i, int j, MB_Structure *data, PictImage *recon)
00748 {
00749 int n;
00750 register int m;
00751
00752 int x_curr, y_curr;
00753
00754 x_curr = i * MB_SIZE;
00755 y_curr = j * MB_SIZE;
00756
00757
00758 for (n = 0; n < MB_SIZE; n++)
00759 for (m= 0; m < MB_SIZE; m++) {
00760 *(recon->lum + x_curr+m + (y_curr+n)*(VidSt->pels)) = data->lum[n][m];
00761 }
00762
00763
00764 for (n = 0; n < MB_SIZE>>1; n++)
00765 for (m = 0; m < MB_SIZE>>1; m++) {
00766 *(recon->Cr + (x_curr>>1)+m + ((y_curr>>1)+n)*(VidSt->cpels)) = data->Cr[n][m];
00767 *(recon->Cb + (x_curr>>1)+m + ((y_curr>>1)+n)*(VidSt->cpels)) = data->Cb[n][m];
00768 }
00769 return;
00770 }
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788 unsigned char *InterpolateImage(unsigned char *image, int width, int height)
00789 {
00790 unsigned char *ipol_image, *ii, *oo;
00791 int i,j;
00792
00793 ipol_image = (unsigned char *)malloc(sizeof(char)*width*height*4);
00794 ii = ipol_image;
00795 oo = image;
00796
00797
00798 for (j = 0; j < height-1; j++) {
00799 for (i = 0; i < width-1; i++) {
00800 *(ii + (i<<1)) = *(oo + i);
00801 *(ii + (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1)>>1;
00802 *(ii + (i<<1)+(width<<1)) = (*(oo + i) + *(oo + i + width) + 1)>>1;
00803 *(ii + (i<<1)+1+(width<<1)) = (*(oo+i) + *(oo+i+1) +
00804 *(oo+i+width) + *(oo+i+1+width) + 2)>>2;
00805 }
00806
00807 *(ii+ (width<<1) - 2) = *(oo + width - 1);
00808 *(ii+ (width<<1) - 1) = *(oo + width - 1);
00809 *(ii+ (width<<1)+ (width<<1)-2) = (*(oo+width-1)+*(oo+width+width-1)+1)>>1;
00810 *(ii+ (width<<1)+ (width<<1)-1) = (*(oo+width-1)+*(oo+width+width-1)+1)>>1;
00811 ii += (width<<2);
00812 oo += width;
00813 }
00814
00815
00816 for (i = 0; i < width-1; i++) {
00817 *(ii+ (i<<1)) = *(oo + i);
00818 *(ii+ (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1)>>1;
00819 *(ii+ (width<<1)+ (i<<1)) = *(oo + i);
00820 *(ii+ (width<<1)+ (i<<1)+1) = (*(oo + i) + *(oo + i + 1) + 1)>>1;
00821
00822 }
00823
00824
00825 *(ii + (width<<1) - 2) = *(oo + width -1);
00826 *(ii + (width<<1) - 1) = *(oo + width -1);
00827 *(ii + (width<<2) - 2) = *(oo + width -1);
00828 *(ii + (width<<2) - 1) = *(oo + width -1);
00829
00830 return ipol_image;
00831 }
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851 void MotionEstimatePicture(unsigned char *curr, unsigned char *prev,
00852 unsigned char *prev_ipol, int seek_dist,
00853 MotionVector *MV[6][MBR+1][MBC+2], int gobsync)
00854
00855 {
00856 int i,j,k;
00857 int pmv0,pmv1,xoff,yoff;
00858 int curr_mb[16][16];
00859 int sad8 = INT_MAX, sad16, sad0;
00860 int newgob;
00861 MotionVector *f0,*f1,*f2,*f3,*f4;
00862
00863
00864 for ( j = 0; j < (VidSt->lines)/MB_SIZE; j++) {
00865
00866 newgob = 0;
00867 if (gobsync && j%gobsync == 0) {
00868 newgob = 1;
00869 }
00870
00871 for ( i = 0; i < (VidSt->pels)/MB_SIZE; i++) {
00872 for (k = 0; k < 6; k++)
00873 MV[k][j+1][i+1] = (MotionVector *)malloc(sizeof(MotionVector));
00874
00875
00876 f0 = MV[0][j+1][i+1];
00877 f1 = MV[1][j+1][i+1];
00878 f2 = MV[2][j+1][i+1];
00879 f3 = MV[3][j+1][i+1];
00880 f4 = MV[4][j+1][i+1];
00881
00882
00883
00884
00885 FindPMV(MV,i+1,j+1,&pmv0,&pmv1,0,newgob,0);
00886
00887 if ((VidSt->long_vectors)) {
00888 xoff = pmv0/2;
00889 yoff = pmv1/2;
00890 }
00891 else {
00892 xoff = yoff = 0;
00893 }
00894
00895 MotionEstimation(curr, prev, i*MB_SIZE, j*MB_SIZE,
00896 xoff, yoff, seek_dist, MV, &sad0);
00897
00898 sad16 = f0->min_error;
00899 if ((VidSt->advanced))
00900 sad8 = f1->min_error + f2->min_error + f3->min_error + f4->min_error;
00901
00902 f0->Mode = ChooseMode(curr,i*MB_SIZE,j*MB_SIZE, mmin(sad8,sad16));
00903
00904
00905 if (f0->Mode != MODE_INTRA) {
00906 FindMB(i*MB_SIZE,j*MB_SIZE ,curr, curr_mb);
00907 FindHalfPel(i*MB_SIZE,j*MB_SIZE,f0, prev_ipol, &curr_mb[0][0],16,0);
00908 sad16 = f0->min_error;
00909
00910 if ((VidSt->advanced)) {
00911 FindHalfPel(i*MB_SIZE,j*MB_SIZE,f1, prev_ipol, &curr_mb[0][0],8,0);
00912 FindHalfPel(i*MB_SIZE,j*MB_SIZE,f2, prev_ipol, &curr_mb[0][8],8,1);
00913 FindHalfPel(i*MB_SIZE,j*MB_SIZE,f3, prev_ipol, &curr_mb[8][0],8,2);
00914 FindHalfPel(i*MB_SIZE,j*MB_SIZE,f4, prev_ipol, &curr_mb[8][8],8,3);
00915
00916 sad8 = f1->min_error +f2->min_error +f3->min_error +f4->min_error;
00917 sad8 += PREF_16_VEC;
00918
00919
00920 if (sad0 < sad8 && sad0 < sad16) {
00921 f0->x = f0->y = 0;
00922 f0->x_half = f0->y_half = 0;
00923 }
00924 else {
00925 if (sad8 < sad16)
00926 f0->Mode = MODE_INTER4V;
00927 }
00928 }
00929 else {
00930
00931 if (sad0 < sad16) {
00932 f0->x = f0->y = 0;
00933 f0->x_half = f0->y_half = 0;
00934 }
00935 }
00936
00937 }
00938 else
00939 for (k = 0; k < 5; k++)
00940 ZeroVec(MV[k][j+1][i+1]);
00941
00942 }
00943 }
00944
00945 #ifdef PRINTMV
00946 fprintf(stdout,"Motion estimation\n");
00947 fprintf(stdout,"16x16 vectors:\n");
00948
00949 for ( j = 0; j < (VidSt->lines)/MB_SIZE; j++) {
00950 for ( i = 0; i < (VidSt->pels)/MB_SIZE; i++) {
00951 if (MV[0][j+1][i+1]->Mode != MODE_INTRA)
00952 fprintf(stdout," %3d%3d",
00953 2*MV[0][j+1][i+1]->x + MV[0][j+1][i+1]->x_half,
00954 2*MV[0][j+1][i+1]->y + MV[0][j+1][i+1]->y_half);
00955 else
00956 fprintf(stdout," . . ");
00957 }
00958 fprintf(stdout,"\n");
00959 }
00960 if ((VidSt->advanced)) {
00961 fprintf(stdout,"8x8 vectors:\n");
00962 for (k = 1; k < 5; k++) {
00963 fprintf(stdout,"Block: %d\n", k-1);
00964 for ( j = 0; j < (VidSt->lines)/MB_SIZE; j++) {
00965 for ( i = 0; i < (VidSt->pels)/MB_SIZE; i++) {
00966 if (MV[0][j+1][i+1]->Mode != MODE_INTRA)
00967 fprintf(stdout," %3d%3d",
00968 2*MV[k][j+1][i+1]->x + MV[k][j+1][i+1]->x_half,
00969 2*MV[k][j+1][i+1]->y + MV[k][j+1][i+1]->y_half);
00970 else
00971 fprintf(stdout," . . ");
00972 }
00973 fprintf(stdout,"\n");
00974 }
00975 }
00976 }
00977 #endif
00978 return;
00979 }
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997 void MakeEdgeImage(unsigned char *src, unsigned char *dst, int width,
00998 int height, int edge)
00999 {
01000 int i,j;
01001 unsigned char *p1,*p2,*p3,*p4;
01002 unsigned char *o1,*o2,*o3,*o4;
01003
01004
01005 p1 = dst;
01006 o1 = src;
01007 for (j = 0; j < height;j++) {
01008 memcpy(p1,o1,width);
01009 p1 += width + (edge<<1);
01010 o1 += width;
01011 }
01012
01013
01014 p1 = dst-1;
01015 o1 = src;
01016 for (j = 0; j < height;j++) {
01017 for (i = 0; i < edge; i++) {
01018 *(p1 - i) = *o1;
01019 *(p1 + width + i + 1) = *(o1 + width - 1);
01020 }
01021 p1 += width + (edge<<1);
01022 o1 += width;
01023 }
01024
01025
01026 p1 = dst;
01027 p2 = dst + (width + (edge<<1))*(height-1);
01028 o1 = src;
01029 o2 = src + width*(height-1);
01030 for (j = 0; j < edge;j++) {
01031 p1 = p1 - (width + (edge<<1));
01032 p2 = p2 + (width + (edge<<1));
01033 for (i = 0; i < width; i++) {
01034 *(p1 + i) = *(o1 + i);
01035 *(p2 + i) = *(o2 + i);
01036 }
01037 }
01038
01039
01040 p1 = dst - (width+(edge<<1)) - 1;
01041 p2 = p1 + width + 1;
01042 p3 = dst + (width+(edge<<1))*(height)-1;
01043 p4 = p3 + width + 1;
01044
01045 o1 = src;
01046 o2 = o1 + width - 1;
01047 o3 = src + width*(height-1);
01048 o4 = o3 + width - 1;
01049 for (j = 0; j < edge; j++) {
01050 for (i = 0; i < edge; i++) {
01051 *(p1 - i) = *o1;
01052 *(p2 + i) = *o2;
01053 *(p3 - i) = *o3;
01054 *(p4 + i) = *o4;
01055 }
01056 p1 = p1 - (width + (edge<<1));
01057 p2 = p2 - (width + (edge<<1));
01058 p3 = p3 + width + (edge<<1);
01059 p4 = p4 + width + (edge<<1);
01060 }
01061 }
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076 void Clip(MB_Structure *data)
01077 {
01078 int m,n;
01079
01080 for (n = 0; n < 16; n++) {
01081 for (m = 0; m < 16; m++) {
01082 data->lum[n][m] = mmin(255,mmax(0,data->lum[n][m]));
01083 }
01084 }
01085 for (n = 0; n < 8; n++) {
01086 for (m = 0; m < 8; m++) {
01087 data->Cr[n][m] = mmin(255,mmax(0,data->Cr[n][m]));
01088 data->Cb[n][m] = mmin(255,mmax(0,data->Cb[n][m]));
01089 }
01090 }
01091 }