📄 b_picture.c
字号:
/************************************************************************ * * coder.c, main coding engine of tmn (TMN encoder) * * Copyright (C) 1997 University of BC, Canada * * Contacts: * Michael Gallant <mikeg@ee.ubc.ca> * Guy Cote <guyc@ee.ubc.ca> * Berna Erol <bernae@ee.ubc.ca> * * UBC Image Processing Laboratory http://www.ee.ubc.ca/image * 2356 Main Mall tel.: +1 604 822 4051 * Vancouver BC Canada V6T1Z4 fax.: +1 604 822 5949 * ************************************************************************//* * Disclaimer of Warranty * * These software programs are available to the user without any * license fee or royalty on an "as is" basis. The University of * British Columbia disclaims any and all warranties, whether * express, implied, or statuary, including any implied warranties * or merchantability or of fitness for a particular purpose. In no * event shall the copyright-holder be liable for any incidental, * punitive, or consequential damages of any kind whatsoever arising * from the use of these programs. * * This disclaimer of warranty extends to the user of these programs * and user's customers, employees, agents, transferees, successors, * and assigns. * * The University of British Columbia does not represent or warrant * that the programs furnished hereunder are free of infringement of * any third-party patents. * * Commercial implementations of H.263, including shareware, are * subject to royalty fees to patent holders. Many of these patents * are general enough such that they are unavoidable regardless of * implementation design. **/#include"sim.h"/********************************************************************** * * Name: CodeOneTrueB * Description: code one true B image * * Input: pointer to image, prev_image, prev_recon, Q * * Returns: pointer to reconstructed image * Side effects: memory is allocated to recon image * * Date: 950930 Author: Michael Gallant <mikeg@ee.ubc.ca> * ***********************************************************************/void CodeOneTrueB(PictImage *curr, PictImage *B_image, PictImage *prev, PictImage *pr, int QP, int frameskip, Bits *bits, Pict *pic, PictImage *B_recon, PictImage *recon){ unsigned char *prev_ipol, *next_ipol, *pi, *ni; PictImage *prev_recon=NULL, *next_recon=NULL, *pr_edge = NULL, *nr_edge = NULL; MotionVector *MV[7][MBR+1][MBC+2]; MotionVector ZERO = {0,0,0,0,0}; MB_Structure *recon_data_true_B = NULL; MB_Structure *diff; int *rcoeff, *coeff; int *qcoeff_true_B = NULL; int Mode; int CBP; int newgob, advanced_temporarily_off = DEF_AIC_MODE; int i,j,k; int true_B_prediction_type; /* buffer control vars */ float QP_cumulative = (float)0.0; int abs_mb_num = 0, QuantChangePostponed = 0; int QP_new, QP_prev, QP_xmitted=QP; MB_Structure *pred = (MB_Structure *)malloc(sizeof(MB_Structure)); /* advanced intra coding variables */ int *store_rcoeff, *store_coeff, *pcoeff; ZeroBits(bits); /* Currently, the MV info is stored in 7 MV structs per MB. MV[0] * stores the 16x16 MV. MV[1] through MV[4] store the 8x8 MVs. MV[6] * stores the PB delta MV or the forward predicted B MV. MV[5] * stores the backward predicted MV for true-B pictures. */ InitializeMV(MV); /* Mark PMV's outside the frame. */ for (i = 1; i < (pels>>4)+1; i++) { for (j = 0; j < 7; j++) { MarkVec(MV[j][0][i]); } MV[0][0][i]->Mode = MODE_INTRA; } /* Zero out PMV's outside the frame */ for (i = 0; i < (lines>>4)+1; i++) { for (j = 0; j < 7; j++) { ZeroVec(MV[j][i][0]); ZeroVec(MV[j][i][(pels>>4)+1]); } MV[0][i][0]->Mode = MODE_INTRA; MV[0][i][(pels>>4)+1]->Mode = MODE_INTRA; } GenerateFrameAndInterpolatedImages(pr, pic, &prev_ipol, &prev_recon, &pi, &pr_edge); GenerateFrameAndInterpolatedImages(recon, pic, &next_ipol, &next_recon, &ni, &nr_edge); if (adv_pred) { /* Turn off advanced coding since there can be only 1 * motion vector for B frames of IPB. */ advanced_temporarily_off = YES; overlapping_MC = OFF; adv_pred = OFF; use_4mv = OFF; } /* If coding a B-picture, need to pass pictures for forward AND * backward prediction, as well as interpolated forward and backward * pictures for half-pel prediction. */ MotionEstimatePicture( B_image->lum,prev_recon->lum, next_recon->lum, prev_ipol, next_ipol, pic->seek_dist, MV, pic->use_gobsync, B_PICTURE_ESTIMATION); QP_new = QP_xmitted = QP_prev = QP; /* Copy the passed value of QP */ for ( j = 0; j < lines/MB_SIZE; j++) { newgob = 0; if (j == 0) { if (advanced_intra_coding) { /* store the coeff for the frame */ if ((store_coeff=(int *)calloc(384*(pels/MB_SIZE)*(lines/MB_SIZE), sizeof(int))) == 0) { fprintf(stderr,"coder(): Couldn't allocate store_coeff.\n"); exit(-1); } if ((store_rcoeff=(int *)calloc(384*(pels/MB_SIZE)*(lines/MB_SIZE), sizeof(int))) == 0) { fprintf(stderr,"coder(): Couldn't allocate store_rcoeff.\n"); exit(-1); } } pic->QUANT = QP_new; bits->header += CountBitsPicture(pic); QP_xmitted = QP_prev = QP_new; } else if (pic->use_gobsync && j%pic->use_gobsync == 0) { bits->header += CountBitsGOB(j,QP_new,pic); /* insert gob sync */ QP_xmitted = QP_prev = QP_new; newgob = 1; } for ( i = 0; i < pels/MB_SIZE; i++) { pic->MB = i + j * (pels/MB_SIZE); /* store the QP for every macroblock */ quant_map[j+1][i+1] = QP_xmitted; if ((rcoeff = (int *)malloc(sizeof(int)*384)) == NULL) { fprintf(stderr,"MB_Coder: Could not allocate space for rcoeff\n"); exit(-1); } /* Predict true B-MB */ diff = Predict_True_B( B_image, prev_recon, prev_ipol,next_recon, next_ipol, pred,i*MB_SIZE, j*MB_SIZE, MV, True_B_Direct_Mode_MV, pic->TRB, &true_B_prediction_type, &Mode, pic->RTYPE); if (B_INTRA_PREDICTION == true_B_prediction_type) { FillLumBlock(i*MB_SIZE, j*MB_SIZE, B_image, diff); FillChromBlock(i*MB_SIZE, j*MB_SIZE, B_image, diff); } if ((qcoeff_true_B=(int *)malloc(sizeof(int)*384)) == 0) { fprintf(stderr,"coder(): Couldn't allocate qcoeff_true_B.\n"); exit(-1); } coeff = MB_Encode(diff); if (advanced_intra_coding) { if (!(Mode == MODE_INTRA || Mode == MODE_INTRA_Q)) { for (k=0;k<6;k++) { /* store default coeff if non-intra macroblock */ store_coeff[(i + j * pels/MB_SIZE) * 384 + k * 64] = 1024; store_rcoeff[(i + j * pels/MB_SIZE) * 384 + k * 64] = 1024; } for (k=0;k<6;k++) Quant_blk(coeff,qcoeff_true_B,QP_xmitted, Mode,k); CBP = FindCBP(qcoeff_true_B, Mode, 64); if (CBP == 0 && (Mode == MODE_INTER || Mode == MODE_INTER_Q)) ZeroMBlock(diff); else { for (k=0;k<6;k++) { Quant_blk(coeff,qcoeff_true_B,QP_xmitted, Mode,k); Dequant(qcoeff_true_B, rcoeff, QP_xmitted, Mode,k); } MB_Decode(rcoeff, diff); } } else { if ((pcoeff=(int *)malloc(sizeof(int)*384)) == 0) { fprintf(stderr,"coder(): Couldn't allocate pcoeff.\n"); exit(-1); } /* store the quantized DCT coefficients */ memcpy( (void *) (store_coeff + (i + j*pels/MB_SIZE)*384), (void *) coeff, sizeof(int) * 384); /* Do Intra mode prediction */ pic->Intra_Mode = Choose_Intra_Mode(pcoeff, store_coeff, i, j, newgob); for (k=0;k<6;k++) { Intra_AC_DC_Encode(coeff, store_rcoeff, pic->Intra_Mode, i, j, newgob,k); Quant_blk(coeff,pcoeff,QP_xmitted,Mode,k); Dequant(pcoeff, rcoeff, QP_xmitted, Mode,k); Intra_AC_DC_Decode(rcoeff, store_rcoeff, pic->Intra_Mode, i, j, newgob,k); } MB_Decode(rcoeff, diff); CBP = FindCBP(pcoeff,Mode,64); } } else { for (k=0;k<6;k++) Quant_blk(coeff,qcoeff_true_B,QP_xmitted, Mode,k); CBP = FindCBP(qcoeff_true_B, Mode, 64); if (CBP == 0 && (Mode == MODE_INTER || Mode == MODE_INTER_Q)) ZeroMBlock(diff); else { for (k=0;k<6;k++) Dequant(qcoeff_true_B, rcoeff, QP_xmitted, Mode,k); MB_Decode(rcoeff, diff); } } recon_data_true_B = MB_Recon_True_B( prev_recon, prev_ipol, diff, next_recon, next_ipol, i*MB_SIZE,j*MB_SIZE,MV, True_B_Direct_Mode_MV, pic->TRB, true_B_prediction_type, pic->RTYPE); Clip(recon_data_true_B); free(diff); free(coeff); if ((CBP==0) && (B_DIRECT_PREDICTION == true_B_prediction_type) && (Mode == MODE_INTER) && (0 == pic->DQUANT) ) { coded_map[j+1][i+1] = 0; quant_map[j+1][i+1] = 0; CountBitsScalMB(Mode, 1, CBP, 0, pic, bits, true_B_prediction_type, 0); } else { CountBitsScalMB(Mode,0,CBP,0,pic,bits,true_B_prediction_type, 0); if (!CBP) intra_refresh[j+1][i+1] += 1; if (MODE_INTER == Mode || MODE_INTER_Q == Mode) { coded_map[j+1][i+1] = 1; quant_map[j+1][i+1] = QP_xmitted; bits->no_inter++; CountBitsVectors( MV, bits, i, j, Mode, newgob, pic, true_B_prediction_type); } else { /* MODE_INTRA or MODE_INTRA_Q */ coded_map[j+1][i+1] = 2; quant_map[j+1][i+1] = QP_xmitted; intra_refresh[j+1][i+1] = 0; bits->no_intra++; } if ( (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) && advanced_intra_coding ) { Scan(pcoeff,pic->Intra_Mode); CountBitsCoeff(pcoeff, Mode, CBP, bits, 64); } else if (CBP || Mode == MODE_INTRA || Mode == MODE_INTRA_Q) { Scan(qcoeff_true_B,0); CountBitsCoeff(qcoeff_true_B, Mode, CBP, bits, 64); } } QP_prev = QP_xmitted; abs_mb_num++; QP_cumulative += QP_xmitted; #ifdef PRINTQ /* most useful when quantizer changes within a picture */ if (QuantChangePostponed) fprintf(stdout,"@%2d",QP_xmitted); else fprintf(stdout," %2d",QP_xmitted);#endif ReconImage(i,j,recon_data_true_B,B_recon); free(qcoeff_true_B); free(recon_data_true_B); if (advanced_intra_coding && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)) free(pcoeff); }#ifdef PRINTQ fprintf(stdout,"\n");#endif } pic->QP_mean = QP_cumulative/(float)abs_mb_num; /* Free memory */ free(pred); free(prev_recon); free(next_recon); FreeImage(pr_edge); FreeImage(nr_edge); free(pi); free(ni); for (j = 0; j < (lines>>4)+1; j++) for (i = 0; i < (pels>>4)+2; i++) for (k = 0; k < 7; k++) free(MV[k][j][i]); if (advanced_intra_coding)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -