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 }