Main Page | Class List | File List | Class Members | File Members

vid_coder.c File Reference

#include "vid_sim.h"
#include "video_codec.h"

Go to the source code of this file.

Functions

void CodeOneOrTwo (PictImage *curr, PictImage *B_image, PictImage *prev, PictImage *pr, int QP, int frameskip, Bits *bits, Pict *pic, PictImage *B_recon, PictImage *recon)
PictImageCodeOneIntra (PictImage *curr, int QP, Bits *bits, Pict *pic)
int * MB_Encode (MB_Structure *mb_orig, int QP, int I)
int MB_Decode (int *qcoeff, MB_Structure *mb_recon, int QP, int I)
void FillLumBlock (int x, int y, PictImage *image, MB_Structure *data)
void FillChromBlock (int x_curr, int y_curr, PictImage *image, MB_Structure *data)
void ZeroMBlock (MB_Structure *data)
void ReconImage (int i, int j, MB_Structure *data, PictImage *recon)
unsigned char * InterpolateImage (unsigned char *image, int width, int height)
void MotionEstimatePicture (unsigned char *curr, unsigned char *prev, unsigned char *prev_ipol, int seek_dist, MotionVector *MV[6][MBR+1][MBC+2], int gobsync)
void MakeEdgeImage (unsigned char *src, unsigned char *dst, int width, int height, int edge)
void Clip (MB_Structure *data)

Variables

video_codecVidSt


Function Documentation

void Clip MB_Structure data  ) 
 

Definition at line 1076 of file vid_coder.c.

References mb_structure::Cb, mb_structure::Cr, data, mb_structure::lum, MB_Structure, mmax, and mmin.

Referenced by CodeOneIntra(), and CodeOneOrTwo().

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 }

PictImage* CodeOneIntra PictImage curr,
int  QP,
Bits bits,
Pict pic
 

Definition at line 435 of file vid_coder.c.

References Bits, Clip(), Count_sac_BitsCoeff(), Count_sac_BitsMB(), CountBitsCoeff(), CountBitsMB(), CountBitsPicture(), CountBitsSlice(), data, FillChromBlock(), FillLumBlock(), FindCBP(), bits_counted::header, InitImage(), video_codec::lines, pict::MB, MB_Decode(), MB_Encode(), MB_SIZE, MB_Structure, bits_counted::no_intra, video_codec::pels, Pict, PictImage, pict::QP_mean, pict::QUANT, ReconImage(), video_codec::syntax_arith_coding, pict::use_gobsync, VidSt, and ZeroBits().

Referenced by code_video().

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; /* Every block is coded in Intra frame */
00451   for ( j = 0; j < (VidSt->lines)/MB_SIZE; j++) {
00452 
00453     /* insert sync in *every* slice if use_gobsync is chosen */
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 }

void CodeOneOrTwo PictImage curr,
PictImage B_image,
PictImage prev,
PictImage pr,
int  QP,
int  frameskip,
Bits bits,
Pict pic,
PictImage B_recon,
PictImage recon
 

Definition at line 73 of file vid_coder.c.

References AddBitsPicture(), pict::bit_rate, Bits, pict::BQUANT, pict_image::Cb, Clip(), Count_sac_BitsCoeff(), Count_sac_BitsMB(), Count_sac_BitsVectors(), CountBitsCoeff(), CountBitsMB(), CountBitsPicture(), CountBitsSlice(), CountBitsVectors(), pict_image::Cr, pict::DQUANT, EqualVec(), FillChromBlock(), FillLumBlock(), FindCBP(), FreeImage(), bits_counted::header, InitializeQuantizer(), InitImage(), InterpolateImage(), video_codec::lines, video_codec::long_vectors, pict_image::lum, MakeEdgeImage(), MarkVec(), pict::MB, MB_Decode(), MB_Encode(), MB_Recon_B(), MB_Recon_P(), MB_SIZE, MB_Structure, MBC, MBR, mmax, mmin, pict::MODB, motionvector::Mode, MODE_INTER, MODE_INTER_Q, MODE_INTRA, ModifyMode(), MotionEstimatePicture(), MotionVector, video_codec::mv_outside_frame, bits_counted::no_inter, bits_counted::no_inter4v, bits_counted::no_intra, pict::PB, PCT_INTER, video_codec::pels, Pict, PictImage, Predict_B(), Predict_P(), pict::QP_mean, pict::QUANT, ReconImage(), pict::seek_dist, video_codec::syntax_arith_coding, pict::target_frame_rate, bits_counted::total, pict::TRB, UpdateQuantizer(), pict::use_gobsync, VidSt, motionvector::x, motionvector::y, ZeroBits(), ZeroMBlock(), and ZeroVec().

Referenced by code_video().

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   /* buffer control vars */
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   /* interpolate image */
00103   if ((VidSt->mv_outside_frame)) {
00104     if ((VidSt->long_vectors)) {
00105       /* If the Extended Motion Vector range is used, motion vectors
00106          may point further out of the picture than in the normal range,
00107          and the edge images will have to be made larger */
00108       B = 16;
00109     }
00110     else {
00111       /* normal range */
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     /* luma of non_interpolated image */
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     /* non-interpolated image */
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   /* mark PMV's outside the frame */
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   /* zero out PMV's outside the frame */
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   /* Integer and half pel motion estimation */
00168   MotionEstimatePicture(curr->lum,prev_recon->lum,prev_ipol,
00169         pic->seek_dist,MV, pic->use_gobsync);
00170   /* note: integer pel motion estimation is now based on previous
00171      reconstructed image, not the previous original image. We have
00172      found that this works better for some sequences and not worse for
00173      others.  Note that it can not easily be changed back by
00174      substituting prev_recon->lum with orig_lum in the line above,
00175      because SAD for zero vector is not re-calculated in the half
00176      pel search. The half pel search has always been based on the
00177      previous reconstructed image */
00178 
00179 
00180   if (pic->bit_rate != 0) {
00181     /* Initialization routine for Rate Control */
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; /* Copy the passed value of 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       /* QP updated at the beginning of each row */
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); /* insert gob sync */
00214       QP_xmitted = QP_prev = QP_new;
00215       newgob = 1;
00216     }
00217 
00218     for ( i = 0; i < (VidSt->pels)/MB_SIZE; i++) {
00219 
00220       /* Update of dquant, check and correct its limit */
00221       dquant = QP_new - QP_prev;
00222       if (dquant != 0 && i != 0 && MV[0][j+1][i+1]->Mode == MODE_INTER4V) {
00223         /* It is not possible to change the quantizer and at the same
00224            time use 8x8 vectors. Turning off 8x8 vectors is not
00225            possible at this stage because the previous macroblock
00226            encoded assumed this one should use 8x8 vectors. Therefore
00227            the change of quantizer is postponed until the first MB
00228            without 8x8 vectors */
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       /* modify mode if dquant != 0 (e.g. MODE_INTER -> MODE_INTER_Q) */
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         /* Predict P-MB */
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       /* P or INTRA Macroblock */
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       /* Predict B-MB using reconstructed P-MB and prev. recon. image */
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;  /* (QP = 0 means no quantization) */
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         /* decide MODB */ 
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]); /* Zero out PB deltas */
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         /* Skipped MB : both CBP and CBPB are zero, 16x16 vector is zero,
00313            PB delta vector is zero and Mode = MODE_INTER */
00314         if (Mode == MODE_INTER_Q) {
00315           /* DQUANT != 0 but not coded anyway */
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         /* Normal MB */
00327         if (!(VidSt->syntax_arith_coding)) { /* VLC */
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             /* MODE_INTRA or MODE_INTRA_Q */
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         } /* end VLC */
00350 
00351         else { /* SAC */
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             /* MODE_INTRA or MODE_INTRA_Q */
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         } /* end SAC */
00374 
00375         QP_prev = QP_xmitted;
00376       }
00377 
00378       abs_mb_num++;
00379       QP_cumulative += QP_xmitted;     
00380 #ifdef PRINTQ 
00381       /* most useful when quantizer changes within a picture */
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   /* Free memory */
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 }

void FillChromBlock int  x_curr,
int  y_curr,
PictImage image,
MB_Structure data
 

Definition at line 682 of file vid_coder.c.

References mb_structure::Cb, pict_image::Cb, video_codec::cpels, mb_structure::Cr, pict_image::Cr, data, MB_Structure, PictImage, and VidSt.

Referenced by CodeOneIntra(), and CodeOneOrTwo().

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 }

void FillLumBlock int  x,
int  y,
PictImage image,
MB_Structure data
 

Definition at line 656 of file vid_coder.c.

References data, mb_structure::lum, pict_image::lum, MB_Structure, video_codec::pels, PictImage, and VidSt.

Referenced by CodeOneIntra(), and CodeOneOrTwo().

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 }

unsigned char* InterpolateImage unsigned char *  image,
int  width,
int  height
 

Definition at line 788 of file vid_coder.c.

Referenced by CodeOneOrTwo().

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   /* main image */
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     /* last pels on each line */
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   /* last lines */
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   /* bottom right corner pels */
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 }

void MakeEdgeImage unsigned char *  src,
unsigned char *  dst,
int  width,
int  height,
int  edge
 

Definition at line 997 of file vid_coder.c.

Referenced by CodeOneOrTwo().

00999 {
01000   int i,j;
01001   unsigned char *p1,*p2,*p3,*p4;
01002   unsigned char *o1,*o2,*o3,*o4;
01003 
01004   /* center image */
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   /* left and right edges */
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   /* top and bottom edges */
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   /* corners */
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 }

int MB_Decode int *  qcoeff,
MB_Structure mb_recon,
int  QP,
int  I
 

Definition at line 566 of file vid_coder.c.

References mb_structure::Cb, mb_structure::Cr, Dequant(), idct(), idctref(), mb_structure::lum, and MB_Structure.

Referenced by CodeOneIntra(), and CodeOneOrTwo().

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   /* For control purposes */
00583   /* Zero data */
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 }

int* MB_Encode MB_Structure mb_orig,
int  QP,
int  I
 

Definition at line 501 of file vid_coder.c.

References mb_structure::Cb, mb_structure::Cr, Dct(), mb_structure::lum, MB_Structure, and Quant().

Referenced by CodeOneIntra(), and CodeOneOrTwo().

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 }

void MotionEstimatePicture unsigned char *  curr,
unsigned char *  prev,
unsigned char *  prev_ipol,
int  seek_dist,
MotionVector MV[6][MBR+1][MBC+2],
int  gobsync
 

Definition at line 851 of file vid_coder.c.

References video_codec::advanced, ChooseMode(), FindHalfPel(), FindMB(), FindPMV(), video_codec::lines, video_codec::long_vectors, MB_SIZE, motionvector::min_error, mmin, motionvector::Mode, MotionEstimation(), MotionVector, video_codec::pels, VidSt, motionvector::x, motionvector::x_half, motionvector::y, motionvector::y_half, and ZeroVec().

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   /* Do motion estimation and store result in array */
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       /* Integer pel search */
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       /* Here the PMV's are found using integer motion vectors */
00884       /* (NB should add explanation for this )*/
00885       FindPMV(MV,i+1,j+1,&pmv0,&pmv1,0,newgob,0);
00886 
00887       if ((VidSt->long_vectors)) {
00888         xoff = pmv0/2; /* always divisable by two */
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       /* Half pel search */
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           /* Choose Zero Vector, 8x8 or 16x16 vectors */
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           /* Choose Zero Vector or 16x16 vectors */
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 }

void ReconImage int  i,
int  j,
MB_Structure data,
PictImage recon
 

Definition at line 747 of file vid_coder.c.

References pict_image::Cb, mb_structure::Cb, video_codec::cpels, pict_image::Cr, mb_structure::Cr, data, pict_image::lum, mb_structure::lum, MB_Structure, video_codec::pels, PictImage, and VidSt.

Referenced by CodeOneIntra(), and CodeOneOrTwo().

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   /* Fill in luminance data */
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   /* Fill in chrominance data */
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 }

void ZeroMBlock MB_Structure data  ) 
 

Definition at line 717 of file vid_coder.c.

References mb_structure::Cb, mb_structure::Cr, data, mb_structure::lum, and MB_Structure.

Referenced by CodeOneOrTwo().

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 }


Variable Documentation

video_codec* VidSt
 

Definition at line 16 of file vid_wrapper.c.

Referenced by alignbits(), bit_in_psc_layer(), bitcount(), ChooseMode(), close_video_codec(), Code_sac_Coeff(), code_video(), CodeCoeff(), CodeOneIntra(), CodeOneOrTwo(), ComputeSNR(), Count_sac_BitsCoeff(), Count_sac_BitsMB(), Count_sac_BitsVectors(), CountBitsMB(), CountBitsPicture(), CountBitsSlice(), CountBitsVectors(), DoPredChrom_P(), encoder_flush(), FillChromBlock(), FillImage(), FillLumBlock(), FindChromBlock_P(), FindForwLumPredPB(), FindFrameSkip(), FindHalfPel(), FindMB(), FindPred(), FindPredOBMC(), initbits(), InitializeQuantizer(), InitializeRateControl(), MB_Recon_P(), MotionEstimatePicture(), MotionEstimation(), new_video_codec(), NextTwoPB(), Predict_B(), Predict_P(), putbits(), ReadImage(), ReconChromBlock_P(), ReconImage(), ReconLumBlock_P(), UpdateQuantizer(), UpdateRateControl(), and WriteImage().


Generated on Sun Jul 16 16:27:47 2006 by  doxygen 1.3.9.1