📄 coder.cpp
字号:
cr_now += Global::cpels; cr_prev += Global::cpels;#endif } return;}/********************************************************************** * * Name: InterpolateImage * Description: Interpolates a complete image for easier half * pel prediction *
* Input: pointer to image structure
* Returns: pointer to interpolated image
* Side effects: allocates memory to interpolated image
* * Date: 950207 Author: Karl.Lillevold@nta.no * 960207 Author: Roalt aalmoes ***********************************************************************/void InterpolateImage(unsigned int *image, unsigned int *ipol_image, int width, int height){ /* If anyone has better ideas to optimize this code, be my guest! note: assembly or some advanced bitshifts routine might do the trick...*/ register unsigned int *ii, *oo, *ii_new, *ii_new_line2, *oo_prev, *oo_prev_line2; register int i,j; register unsigned int pix1,pix2,pix3,pix4; ii = ipol_image; oo = image; oo_prev = image; oo_prev_line2 = image + width; ii_new = ipol_image; ii_new_line2 = ipol_image + (width<<1); /* main image */ for (j = 0; j < height-1; j++) { /* get Pix1 and Pix3, because they are not known the first time */ pix1 = *oo_prev; pix3 = *oo_prev_line2; for (i = 0; i < width-1; i++) { /* Pix1 Pix2 Pix3 Pix4 */ /* Pix2 and Pix4 are used here for first time */ pix2 = *(oo_prev + 1); pix4 = *(oo_prev_line2 + 1); *(ii_new) = pix1; /* X. ..*/ *(ii_new + 1) = (pix1 + pix2 + 1)>>1; /* *X .. */ *ii_new_line2 = (pix1 + pix3 + 1)>>1; /* *. X. */ *(ii_new_line2 + 1) = (pix1 + pix2 + pix3 + pix4 + 2)>>2; oo_prev++; oo_prev_line2++; ii_new += 2; ii_new_line2 += 2; pix1 = pix2; pix3 = pix4; /* Pix1 Pix2=Pix1' Pix2' */ /* Pix3 Pix4=Pix3' Pix4' */ } /* One but last column */ *(ii_new++) = pix1; *(ii_new++) = pix3; /* Last column -On the Edge - */ *(ii_new_line2++) = (pix1 + pix3 + 1 ) >>1; *(ii_new_line2++) = (pix1 + pix3 + 1 ) >>1; ii_new += (width<<1); /* ii_new now on old position ii_new_line2,so one interpolated screen line must be added*/ ii_new_line2 += (width<<1); /* In fact, ii_new_line here has same value as ii_new */ oo_prev += 1; /* Remember, loop is done one time less! */ oo_prev_line2 += 1; } /* last lines */ pix1 = *oo_prev; for (i = 0; i < width-1; i++) { pix2 = *(oo_prev + 1); *ii_new = *ii_new_line2 = pix1; *(ii_new + 1) = *(ii_new_line2 + 1) = (pix1 + pix2 + 1)>>1; ii_new += 2; ii_new_line2 += 2; oo_prev += 1; pix1 = pix2; /* Pix1 Pix2=Pix1' Pix2' */ } /* bottom right corner Global::pels */ *(ii_new) = pix1; *(ii_new + 1) = pix1; *(ii_new_line2) = pix1; *(ii_new_line2+1) = pix1; return;}/********************************************************************** * * Name: FullMotionEstimatePicture * Description: Finds integer and half pel motion estimation * * Input: current image, previous image, interpolated * reconstructed previous image, seek_dist, * motion vector array * Returns: * Side effects: allocates memory for MV structure * * Date: 960418 Author: Roatlt * ***********************************************************************/void FullMotionEstimatePicture(unsigned int *curr, unsigned int *prev, unsigned int *prev_ipol, int seek_dist, MotionVector *MV_ptr, int advanced_method, int *EncodeThisBlock){ int i,j; MotionVector *current_MV; for(j = 0; j < Global::mbr; j++) { for(i = 0; i < Global::mbc; i++) { current_MV = MV_ptr + j*Global::mbc + i; if(advanced_method && !*(EncodeThisBlock + j*Global::mbc + i) ) { current_MV->x = current_MV->y = current_MV->x_half = current_MV->y_half = 0; current_MV->Mode = MODE_SKIP; } else { /* EncodeThisBlock */ FullMotionEstimation(curr, prev_ipol, seek_dist, current_MV, i*MB_SIZE, j*MB_SIZE); current_MV->Mode = ChooseMode(curr,i*MB_SIZE,j*MB_SIZE, current_MV->min_error); if(current_MV->Mode == MODE_INTRA) ZeroVec(current_MV); } } }}void CodeInterH263(CParam *params, Bits *bits){ MotionVector *MV; MotionVector ZERO = {0,0,0,0,0}; MB_Structure *recon_data_P; MB_Structure *diff; int *qcoeff_P; unsigned int *new_recon=NULL; unsigned int *prev_recon; int Mode; int CBP, CBPB=0; int newgob; int i,j; Global::search_p_frames = params->search_method; MV =(struct motionvector*) malloc(sizeof(MotionVector)*Global::mbc*Global::mbr); new_recon =(unsigned int*) malloc(Global::sizeof_frame); prev_recon = params->recon; /* buffer control vars */ ZeroBits(bits); /* Interpolate luminance from reconstr. picture */ InterpolateImage(prev_recon,params->interpolated_lum,Global::pels,Global::lines); FullMotionEstimatePicture( params->data, prev_recon, params->interpolated_lum, params->half_pixel_searchwindow,MV, params->advanced_method, params->EncodeThisBlock); /* Calculate MV for each MB */ /* ENCODE TO H.263 STREAM */ for ( j = 0; j < Global::mbr; j++) { newgob = 0; if (j == 0) { Global::pic->QUANT = params->Q_inter; Global::pic->picture_coding_type = PCT_INTER; bits->header += CountBitsPicture(Global::pic); } else if (Global::pic->use_gobsync && j%Global::pic->use_gobsync == 0) { bits->header += CountBitsSlice(j,params->Q_inter); /* insert gob sync */ newgob = 1; } for ( i = 0; i < Global::mbc; i++) { /* This means: For every macroblock (i,j) do ... */ /* We have 4 different situations:
1) !EncodeThisBlock: this means that the
macroblock in not encoded
2) EncodeThisBlock: This means that the MB is encoded by using the predicted motion vector. 3) EncodeThisBlock: However, the approx of the motion vector was so bad, that INTRA coding is more appropiate here ... 4) EncodeThisBlock: The approx is so good that the coefficients are all zero (after quant.) and are not send. */ /* This means: For every macroblock (i,j) do ... */ Global::pic->DQUANT = 0; Mode = MV[j*Global::mbc + i].Mode; /* Determine position of MB */ Global::pic->MB = i + j * Global::mbc; if(Mode == MODE_SKIP) { /* SITUATION 1 */ Mode = MODE_INTRA; /* This might be done "better" in the future*/ MV[j*Global::mbc + i].Mode = Mode; ZeroVec(&(MV[j*Global::mbc + i])); CBP = CBPB = 0; /* Now send code for "skip this MB" */ CountBitsMB(Mode,1,CBP,CBPB,Global::pic,bits); ReconCopyImage(i,j,new_recon,prev_recon); } else { /* Encode this block */ if (Mode == MODE_INTER) { /* SITUATION 2 */ /* Predict P-MB */ diff = Predict_P(params->data,
prev_recon,
params->interpolated_lum,i*MB_SIZE,
j*MB_SIZE,MV); } else { /* SITUATION 3 */ /* Create MB_Structure diff that contains coefficients that must be sent to the other end */ diff = (MB_Structure *)malloc(sizeof(MB_Structure)); FillLumBlock(i*MB_SIZE, j*MB_SIZE, params->data, diff); /* Copy curr->lum to diff for macroblock (i,j) */ FillChromBlock(i*MB_SIZE, j*MB_SIZE, params->data, diff); /* Equiv. for curr->Cb and curr->Cr */ } /* P or INTRA Macroblock */ /* diff -> DCT -> QUANTIZED -> qcoeff_P */ qcoeff_P = MB_EncodeAndFindCBP(diff, params->Q_inter, Mode,&CBP); /* CBP = FindCBP(qcoeff_P, Mode, 64); -> Not required anymore */ /* All encoded, now calculate decoded image for comparison in next frame */ /* Do DECODING */ if (CBP == 0 && (Mode == MODE_INTER) ) { /* SITUATION 4 */ ZeroMBlock(diff); } else { /* qcoeff_P -> Dequantized -> IDCT -> diff */ MB_Decode(qcoeff_P, diff, params->Q_inter, Mode); } recon_data_P = MB_Recon_P(prev_recon, params->interpolated_lum,diff, i*MB_SIZE,j*MB_SIZE,MV); Clip(recon_data_P); free(diff); /* Do bitstream encoding */ if((CBP==0) && (EqualVec(&(MV[j*Global::mbc+i]),&ZERO)) && (Mode == MODE_INTER) ) { /* Skipped MB : both CBP and CBPB are zero, 16x16 vector is zero, PB delta vector is zero and Mode = MODE_INTER */ /* Now send code for "skip this MB" */ CountBitsMB(Mode,1,CBP,CBPB,Global::pic,bits); } else { /* Normal MB */ /* VLC */ CountBitsMB(Mode,0,CBP,CBPB,Global::pic,bits); if (Mode == MODE_INTER) { bits->no_inter++; CountBitsVectors(MV, bits, i, j, Mode, newgob, Global::pic);
} else {
/* MODE_INTRA */ bits->no_intra++; } /* Only encode coefficient if they are nonzero or Mode is INTRA*/
if (CBP || Mode == MODE_INTRA)
CountBitsCoeff(qcoeff_P, Mode, CBP, bits, 64); } /* End skip/not skip macroblock encoding */ ReconImage(i,j,recon_data_P,new_recon); free(recon_data_P); free(qcoeff_P); } /* End advanced */ } /* End for i */ } /* End for j */ Global::pic->QP_mean = params->Q_inter; free(prev_recon); params->recon = new_recon; AddBitsPicture(bits); free(MV); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -