📄 ei_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: CodeOneEI * Description: codes one image intra * * Input: pointer to image, QP * * Returns: pointer to reconstructed image * Side effects: memory is allocated to recon image * * Date: 940110 Author: Michael Gallant mikeg@ee.ubc.ca * ***********************************************************************/void CodeOneEI(PictImage *curr_image, PictImage *pr, int QP, Bits *bits, Pict *pic, PictImage *recon){ MB_Structure *diff = (MB_Structure *)malloc(sizeof(MB_Structure)); MB_Structure *recon_data_ei = (MB_Structure *)malloc(sizeof(MB_Structure)); PictImage *base_recon=NULL, *base_recon_edge=NULL; int *qcoeff, *pcoeff, *rcoeff, *coeff; int Mode = MODE_INTER; int CBP; int i,j,k; int *store_coeff, *store_rcoeff; /* used to do prediction in advanced intra coding */ int newgob = 0; int ei_prediction_type; unsigned char *base_ipol, *bi; int advanced_temporarily_off = DEF_AIC_MODE; /* buffer control vars */ float QP_cumulative = (float)0.0; int abs_mb_num = 0, QuantChangePostponed = 0; int QP_new, QP_prev, QP_xmitted=QP; ZeroBits(bits); GenerateFrameAndInterpolatedImages(pr, pic, &base_ipol, &base_recon, &bi, &base_recon_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; } 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_EI( curr_image, base_recon, base_ipol, i*MB_SIZE, j*MB_SIZE, &ei_prediction_type, &Mode, pic->RTYPE); if (EI_INTRA_PREDICTION == ei_prediction_type) { FillLumBlock(i*MB_SIZE, j*MB_SIZE, curr_image, diff); FillChromBlock(i*MB_SIZE, j*MB_SIZE, curr_image, diff); } if ((qcoeff=(int *)malloc(sizeof(int)*384)) == 0) { fprintf(stderr,"coder(): Couldn't allocate qcoeff.\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,QP_xmitted, Mode,k); CBP = FindCBP(qcoeff, 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,QP_xmitted, Mode,k); Dequant(qcoeff, 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,QP_xmitted, Mode,k); CBP = FindCBP(qcoeff, Mode, 64); if (CBP == 0 && (Mode == MODE_INTER || Mode == MODE_INTER_Q)) ZeroMBlock(diff); else { for (k=0;k<6;k++) Dequant(qcoeff, rcoeff, QP_xmitted, Mode,k); MB_Decode(rcoeff, diff); } } recon_data_ei = MB_Recon_EI( base_recon, base_ipol, diff, i*MB_SIZE,j*MB_SIZE, ei_prediction_type, pic->RTYPE); Clip(recon_data_ei); free(diff); free(coeff); if (!CBP) intra_refresh[j+1][i+1] += 1; if ((CBP==0) && (EI_UPWARD_PREDICTION == ei_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, ei_prediction_type, 0); } else { CountBitsScalMB(Mode,0,CBP,0,pic,bits,ei_prediction_type, 0); 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++; } 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,0); CountBitsCoeff(qcoeff, 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_ei,recon); free(qcoeff); free(recon_data_ei); 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(base_recon); FreeImage(base_recon_edge); free(bi); if (advanced_intra_coding) { free(store_coeff); free(store_rcoeff); } if (advanced_temporarily_off) { overlapping_MC = ON; adv_pred = ON; use_4mv = ON; advanced_temporarily_off = NO; } return;}/*********************************************************************** * * Name: Predict_EI * Description: Predicts macroblock in EI picture * * Input: pointers to current frame, base recon. base * interpolated, pos. in image, MV data, * and MB prediction type. * Returns: pointer to differential MB data after prediction * Side effects: * * Date: 970831 Author: Michael Gallant ---mikeg@ee.ubc.ca * ***********************************************************************/MB_Structure *Predict_EI( PictImage *curr_image, PictImage *base_recon, unsigned char *base_ipol, int x, int y, int *prediction_type , int *mode, int RTYPE){ int curr[16][16]; MB_Structure *upward_pred = (MB_Structure *)malloc(sizeof(MB_Structure)); MB_Structure *pred_error = (MB_Structure *) malloc (sizeof (MB_Structure)); MotionVector ZERO = {0,0,0,0,0}; int i,j; int SADup; /* Find MB in current image */ FindMB (x, y, curr_image->lum, curr); /* Find predicted MB for current MB (upward prediction so MV=0 */ FindPred (x, y, &ZERO, base_ipol, &upward_pred->lum[0][0], 16, 0); SADup = SAD_MB_integer (&curr[0][0], &upward_pred->lum[0][0], 16, INT_MAX); SADup -= 150; *(mode) = ChooseMode( curr_image->lum, x, y, SADup); if (MODE_INTRA == *(mode) || MODE_INTRA_Q == *(mode)) { *(prediction_type) = EI_INTRA_PREDICTION; } else { *(prediction_type) = EI_UPWARD_PREDICTION; } switch (*(prediction_type)) { case EI_UPWARD_PREDICTION: DoPredChrom_P (x, y, 0, 0, curr_image, base_recon, upward_pred, pred_error, RTYPE); for (j = 0; j < MB_SIZE; j++) { for (i = 0; i < MB_SIZE; i++) { pred_error->lum[j][i] = *(curr_image->lum + x + i + (y + j) * pels) - upward_pred->lum[j][i]; } } break; case EI_INTRA_PREDICTION: break; default: break; } free (upward_pred); return pred_error;}/*********************************************************************** * * Name: MB_Recon_EI * Description: Reconstructs EI macroblocks * * Input: * Returns: pointer to differential MB data after prediction * Side effects: * * Date: 970831 Author: Michael Gallant ---mikeg@ee.ubc.ca * ***********************************************************************/MB_Structure *MB_Recon_EI( PictImage *base_recon, unsigned char *base_ipol, MB_Structure *diff, int x, int y, int prediction_type, int RTYPE){ MB_Structure *upward = (MB_Structure *) malloc (sizeof (MB_Structure)); MB_Structure *recon_data = (MB_Structure *) malloc (sizeof (MB_Structure)); MotionVector ZERO = {0,0,0,0,0}; switch (prediction_type) { case EI_UPWARD_PREDICTION: /* Inter 16x16 */ ReconLumBlock_P (x, y, &ZERO, base_ipol, &diff->lum[0][0], 16, 0); ReconChromBlock_P (x, y, 0, 0, base_recon, diff, RTYPE); break; case EI_INTRA_PREDICTION: break; default: fprintf (stderr, "Illegal scalable prediction type in MB_Recon_EP (pred.c)\n"); exit (-1); break; } memcpy (recon_data, diff, sizeof (MB_Structure)); free (upward); return recon_data;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -