#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) |
PictImage * | CodeOneIntra (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_codec * | VidSt |
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|