www.pudn.com > avs-m3.rar > macroblock.c
/*! ************************************************************************************* * \file macorblock.c * * \brief * decoder one macroblock ************************************************************************************* */ #include#include #include #include #include "global.h" #include "header.h" #include "macroblock.h" #include "vlc.h" #include "defines.h" #include "block.h" /*! ************************************************************************************* * \brief * Checks the availability of neighboring macroblocks of * the current macroblock for prediction and context determination; * marks the unavailable MBs for intra prediction in the * ipredmode-array by -1. Only neighboring MBs in the causal * past of the current MB are checked. ************************************************************************************* */ void CheckAvailabilityOfNeighbors() { const int mb_width = pgImage->width/MB_BLOCK_SIZE; const int mb_nr = pgImage->current_mb_nr; // Check MB to the left if(pgImage->pix_x >= MB_BLOCK_SIZE) { int remove_prediction = pgcurrMB->slice_nr != mb_data[mb_nr-1].slice_nr; // upper blocks if (remove_prediction) { pgImage->ipredmode[pgImage->block4_x][pgImage->block4_y+1] = -1; pgImage->ipredmode[pgImage->block4_x][pgImage->block4_y+2] = -1; pgImage->ipredmode[pgImage->block4_x][pgImage->block4_y+3] = -1; pgImage->ipredmode[pgImage->block4_x][pgImage->block4_y+4] = -1; } } // Check MB above if(pgImage->pix_y >= MB_BLOCK_SIZE) { int remove_prediction = pgcurrMB->slice_nr != mb_data[mb_nr-mb_width].slice_nr; // upper blocks if (remove_prediction) { pgImage->ipredmode[pgImage->block4_x+1][pgImage->block4_y] = -1; pgImage->ipredmode[pgImage->block4_x+2][pgImage->block4_y] = -1; pgImage->ipredmode[pgImage->block4_x+3][pgImage->block4_y] = -1; pgImage->ipredmode[pgImage->block4_x+4][pgImage->block4_y] = -1; } } // Check MB left above if(pgImage->pix_y >= MB_BLOCK_SIZE && pgImage->pix_x >= MB_BLOCK_SIZE) { int remove_prediction = pgcurrMB->slice_nr != mb_data[mb_nr-mb_width-1].slice_nr; if (remove_prediction) { pgImage->ipredmode[pgImage->block4_x][pgImage->block4_y] = -1; } } /* // Check MB right above if(pgImage->pix_y >= MB_BLOCK_SIZE && pgImage->pix_x < (pgImage->width-MB_BLOCK_SIZE )) { //if(pgcurrMB->slice_nr == mb_data[mb_nr-mb_width+1].slice_nr) //pgcurrMB->mb_available[0][2]=&(mb_data[mb_nr-mb_width+1]); } */ } /*! ************************************************************************************* * \brief * initializes the current macroblock ************************************************************************************* */ void start_macroblock() //qwang 2004-3-8 { int i,j,k; //int iii, jjj; assert (pgImage->current_mb_nr >=0 && pgImage->current_mb_nr < pgImage->max_mb_nr); pgcurrMB = &mb_data[pgImage->current_mb_nr];//GB pgcurrMB->slice_nr = pgImage->current_slice_nr;//WJP FOR SLICE// pgcurrMB->I_MODE = 1/*0 dongjie(check) */;//WJP FOR I_DIRECT //pgcurrMB->lf_disable = pgImage->loop_filter_disable_flag; // Update coordinates of the current macroblock pgImage->mb_x = (pgImage->current_mb_nr)%(pgImage->width/MB_BLOCK_SIZE); pgImage->mb_y = (pgImage->current_mb_nr)/(pgImage->width/MB_BLOCK_SIZE); // Define vertical positions pgImage->block4_y = pgImage->mb_y * BLOCK_SIZE; // 4x4 luma block position pgImage->pix_y = pgImage->mb_y * MB_BLOCK_SIZE; // luma macroblock position pgImage->pix_c_y = pgImage->mb_y * MB_BLOCK_SIZE/2; // chroma macroblock position // Define horizontal positions pgImage->block_x = pgImage->mb_x * BLOCK_SIZE/2; // luma block position //zhangnan //qwang 2004-3-10 pgImage->block4_x = pgImage->mb_x * BLOCK_SIZE; // 4x4 luma block position pgImage->pix_x = pgImage->mb_x * MB_BLOCK_SIZE; // luma pixel position pgImage->pix_c_x = pgImage->mb_x * MB_BLOCK_SIZE/2; // chroma pixel position //need modification for intra-prediction qwang 2004-3-9 ???? // If MB is next to a slice boundary, mark neighboring blocks unavailable for prediction CheckAvailabilityOfNeighbors(); // Reset syntax element entries in MB struct pgcurrMB->qp = previous_qp; pgcurrMB->mb_type = -1; /* Do not use the mb type defined in FCD 0-5*/ pgcurrMB->delta_quant = 0; pgcurrMB->cbp = 0; pgcurrMB->cbp_blk = 0; pgcurrMB->c_ipred_mode= -1; //MZ //for (l=0; l < 2; l++) for (j=0; j < BLOCK_MULTIPLE; j++) for (i=0; i < BLOCK_MULTIPLE; i++) for (k=0; k < 2; k++) pgcurrMB->mvd[j][i][k] = 0; // initialize pgImage->m7 for ABT//Lou for (j=0; j m7[i][j] = 0; for (j=0; j m8[0][i][j] = 0; pgImage->m8[1][i][j] = 0; } for (i=0;i<4;i++) pgcurrMB->sub_mb_type[i] = 0; for (i=0;i<4;i++) // reset vectors and pred. modes for(j=0;j<4;j++) { pgImage->mv[pgImage->block4_x+i+4][pgImage->block4_y+j][0] = 0; pgImage->mv[pgImage->block4_x+i+4][pgImage->block4_y+j][1] = 0; pgImage->ipredmode[pgImage->block4_x+i+1][pgImage->block4_y+j+1] = (pgImage->constrained_intra_pred_flag?-1:10) ; } //for (j=0;j<6;j++) // reset all chroma coeffs before read // for (i=0;i<4;i++) // for (iii=0;iii<4;iii++) // for (jjj=0;jjj<4;jjj++) // pgImage->cof[i][j][iii][jjj]=0; for (j=0; j<4; j++) for (i=0; i<4; i++) refFrArr[pgImage->block4_y+j][pgImage->block4_x+i] = -1; } /*! ************************************************************************************* * \brief * Get the syntax elements from the NAL ************************************************************************************* */ int read_one_macroblock() //qwang 2004-3-9 { int b8; int len, inf;//WJP FOR SUB_MB_TYPE int i; //read macroblock type read_mb_type(); //read intra prediction mode currStream->frame_bitoffset if (IS_INTRA(pgcurrMB)) { for (b8=0;b8<4;b8++) //b8 { read_luma_ipred_modes(b8); } read_chroma_ipred_modes(); } if (IS_COPY (pgcurrMB)) //keep last macroblock { FindSkipMVandRef(pgcurrMB); } if (IS_INTERMV (pgcurrMB)) { readReferenceIndex(); //WJP FOR SUB_MB_TYPE //====== READ 8x8 SUB-PARTITION MODES (modes of 8x8 blocks) and Intra VBST block modes ====== if (IS_P8x8 (pgcurrMB)) { for (i=0; i<4; i++) { len = GetVLCSymbol (&inf); mapping_ue(len,inf,&pgcurrMB->sub_mb_type[i]); #if TRACE tracebits("Sub mb type", len, inf, pgcurrMB->sub_mb_type[i]); #endif } } //WJP END //read motion information readMotionVector (); } // read CBP if not new intra mode if (!IS_COPY (pgcurrMB)) { read_CBP_dquant(pgcurrMB); } // read CBP and Coeffs *************************************************************** read_luma_chroma_coeffs(); CheckMbOverHeadValid(pgcurrMB); /* MB parameter check*/ #if TRACE trace_mboverhead(pgcurrMB); #endif return DECODE_MB; } /*! ************************************************************************************* * \brief * decode intra prediction mode ************************************************************************************* */ const int mpm[9][9] = { {0, 0, 2, 0, 0, 0, 2, 0, 2}, {2, 1, 2, 2, 2, 2, 2, 2, 2}, {2, 2, 2, 2, 2, 2, 2, 2, 2}, {2, 1, 2, 3, 4, 5, 2, 7, 2}, {4, 4, 2, 4, 4, 4, 6, 4, 4}, {5, 5, 2, 5, 5, 5, 6, 5, 5}, {6, 6, 6, 6, 6, 6, 6, 6, 6}, {7, 7, 2, 7, 7, 7, 6, 7, 7}, {0, 1, 2, 3, 4, 5, 6, 7, 8} }; void read_luma_ipred_modes(int b8) //qwang 2004-3-9 { int bi,bj,dec; int b4; SyntaxElement currSE; int mostProbableIntraPredMode; int upIntraPredMode; int leftIntraPredMode; int IntraChromaPredModeFlag; //int MBRowSize = pgImage->width / MB_BLOCK_SIZE; pgcurrMB=mb_data+pgImage->current_mb_nr;//current_mb_nr; IntraChromaPredModeFlag = IS_INTRA(pgcurrMB); currSE.type = SE_INTRAPREDMODE; #if TRACE strncpy(currSE.tracestring, "Intra4x4_pred_Mode", TRACESTRING_SIZE); #endif IntraChromaPredModeFlag = 1; //? for(b4=0; b4<4; b4++) { //get from stream if(pgcurrMB->I_MODE)//I4x4 read_Intra4x4PredictionMode(&currSE); //get from array and decode bi = (pgImage->block4_x + ((b8 &1)<<1) + (b4 &1)); bj = (pgImage->block4_y + ((b8>>1)<<1) + (b4>>1)); upIntraPredMode = ((pgImage->ipredmode[bi+1][bj]==10)?-1:pgImage->ipredmode[bi+1][bj]); leftIntraPredMode = ((pgImage->ipredmode[bi][bj+1]==10)?-1:pgImage->ipredmode[bi][bj+1]); mostProbableIntraPredMode = (upIntraPredMode < 0 || leftIntraPredMode < 0) ? DC_PRED : mpm[leftIntraPredMode][upIntraPredMode]; dec = (currSE.value1 == -1) ? mostProbableIntraPredMode : currSE.value1 + (currSE.value1 >= mostProbableIntraPredMode); pgImage->ipredmode[1+bi][1+bj]=dec; /* bistream conformance check -- zhan ma*/ stat_parameter->intra_luma_pred_mode[dec] = 1; #if TRACE MB_ipredmode_Y[((b8>>1)<<1) + (b4>>1)][((b8 &1)<<1) + (b4 &1)]=dec; #endif if(!pgcurrMB->I_MODE) // added by dongjie(check) pgImage->ipredmode[1+bi][1+bj]=mostProbableIntraPredMode; #if TRACE MB_ipredmode_Y[((b8>>1)<<1) + (b4>>1)][((b8 &1)<<1) + (b4 &1)]=dec; #endif } } /*! ************************************************************************************* * \brief * decode intra chroma prediction mode ************************************************************************************* */ void read_chroma_ipred_modes() //qwang 2004-3-9 { SyntaxElement currSE; int IntraChromaPredModeFlag; pgcurrMB=mb_data+pgImage->current_mb_nr;//current_mb_nr; IntraChromaPredModeFlag = IS_INTRA(pgcurrMB); currSE.type = SE_INTRAPREDMODE; #if TRACE strncpy(currSE.tracestring, "intra_Chroma_pred_mode", TRACESTRING_SIZE); #endif currSE.mapping = mapping_ue; read_UVLC(&currSE); pgcurrMB->c_ipred_mode = currSE.value1; /* bistream conformance check -- zhan ma */ stat_parameter->intra_chroma_pred_mode[pgcurrMB->c_ipred_mode] = 1; if (currSE.value1 < DC_PRED_8 || currSE.value1 > VERT_PRED_8) { printf("%d\n", pgImage->current_mb_nr); error("illegal chroma intra pred mode!\n", 600); } } /*! ************************************************************************************* * \brief * readReferenceIndex ************************************************************************************* */ void readReferenceIndex() { int i,j,k; SyntaxElement currSE; int partmode = (IS_P8x8(pgcurrMB)?4:pgcurrMB->mb_type); int step_h0 = BLOCK_STEP [partmode][0]; int step_v0 = BLOCK_STEP [partmode][1]; int i0, j0, refframe; int flag_mode; // If multiple ref. frames, read reference frame for the MB ********************************* flag_mode = 0; currSE.type = SE_REFFRAME; currSE.mapping = mapping_ue; // !! shenyanfei for (j0=0; j0<4; j0+=step_v0) for (i0=0; i0<4; i0+=step_h0) { k=2*(j0/2)+(i0/2); if (pgcurrMB->mb_type!=SKIP_MB)//WJP FOR ZERO_REF { if ((pgImage->num_ref_frames == 2)&&(!pgImage->picture_reference_flag)&&(!pgImage->is_ref0_an_IDR)) /* added by zhan ma*/ { #if TRACE strncpy(currSE.tracestring, "Fwd ref frame no ", TRACESTRING_SIZE); #endif currSE.len = 1; read_FLC(&currSE); refframe = currSE.value1; } else { refframe = 0; } for (j=j0; j block4_y+j][pgImage->block4_x+i] = refframe; } else { for (j=j0; j block4_y+j][pgImage->block4_x+i] = 0; } } } /*! ************************************************************************************* * \brief * readMotionVector ************************************************************************************* */ void readMotionVector() { int i,j,k,l,m; int step_h,step_v; int curr_mvd; SyntaxElement currSE; int partmode = (IS_P8x8(pgcurrMB)?4:pgcurrMB->mb_type); int step_h0 = BLOCK_STEP [partmode][0]; int step_v0 = BLOCK_STEP [partmode][1]; int i0, j0, refframe; int pmv[2]; int j4, i4, ii,jj; int vec; //===== READ FORWARD MOTION VECTORS ===== currSE.type = SE_MVD; currSE.mapping = mapping_se; for (j0=0; j0<4; j0+=step_v0) for (i0=0; i0<4; i0+=step_h0) { k=2*(j0/2)+(i0/2); step_h = BLOCK_STEP [pgcurrMB->mb_type +pgcurrMB->sub_mb_type[k]][0]; step_v = BLOCK_STEP [pgcurrMB->mb_type +pgcurrMB->sub_mb_type[k]][1]; refframe = refFrArr [pgImage->block4_y+j0][pgImage->block4_x+i0]; for (j=j0; j block4_y+j; i4 = pgImage->block4_x+i; // first make mv-prediction SetMotionVectorPredictor (pmv, pmv+1, refframe, i, j, 4*step_h, 4*step_v, 0);//Lou 1016 for (k=0; k < 2; k++) { #if TRACE snprintf(currSE.tracestring, TRACESTRING_SIZE, "FMVD (pred %d)",pmv[k]); #endif currSE.value2 = k ; // identifies the component; only used for context determination read_UVLC(&currSE); if ( pgImage->half_pixel_mv_flag == 0 ) // 1/4 accuracy { curr_mvd = currSE.value1; } else { curr_mvd = (currSE.value1 << 1); } vec=(curr_mvd)+pmv[k]; /* find motion vector */ for(ii=0;ii mv[i4+ii+BLOCK_SIZE][j4+jj][k]=vec; /* bistream conformance check */ if (stat_parameter->min_mv[k] >= pgImage->mv[i4+ii+BLOCK_SIZE][j4+jj][k]) stat_parameter->min_mv[k] = pgImage->mv[i4+ii+BLOCK_SIZE][j4+jj][k]; if (stat_parameter->max_mv[k] <= pgImage->mv[i4+ii+BLOCK_SIZE][j4+jj][k]) stat_parameter->max_mv[k] = pgImage->mv[i4+ii+BLOCK_SIZE][j4+jj][k]; } /* store (oversampled) mvd */ for (l=0; l < step_v; l++) for (m=0; m < step_h; m++) pgcurrMB->mvd[j+l][i+m][k] = curr_mvd; } } } } /*! ************************************************************************************* * \brief * Get coded block pattern and coefficients (run/level) from the NAL ************************************************************************************* */ void read_luma_chroma_coeffs() { int mb_nr = pgImage->current_mb_nr; //GBimg->current_mb_nr; int b8, b4; // luma coefficients for(b8=0; b8<4; b8++) { if (pgcurrMB->cbp&(1< cbp_4x4[b8]&(1< cbp>>4)&1) { for(b4=0; b4<4; b4++) { if (pgcurrMB->cbp_4x4[4]&(1< cbp>>4)&2) { // dongjie read cbp_4x4 from bitstream //pgcurrMB->cbp_4x4 = u_v(4, "cbp_4x4");//WJP FOR CBP4X4 // end for(b4=0; b4<4; b4++) { if (pgcurrMB->cbp_4x4[5]&(1< type == I_IMG) { pgcurrMB->mb_type = I4MB; pgcurrMB->I_MODE = u_v(1,"Intra Mb mode");//WJP FOR I_DIRECT } else { //skip run coding if(pgImage->skip_mode_flag) { if(pgImage->cod_counter == -1) // { len = GetVLCSymbol (&inf); mapping_ue(len,inf,&pgImage->cod_counter); #if TRACE tracebits("mb_skip_run", len, inf, pgImage->cod_counter); #endif } if (pgImage->cod_counter == 0) { len = GetVLCSymbol (&inf); mapping_ue(len,inf,&pgcurrMB->mb_type); #if TRACE tracebits("MB Type", len, inf, pgcurrMB->mb_type); #endif pgcurrMB->mb_type++; pgImage->cod_counter--; } else { pgImage->cod_counter--; pgcurrMB->mb_type = 0; // !! skip mode shenyanfei } } else { len = GetVLCSymbol (&inf); mapping_ue(len,inf,&pgcurrMB->mb_type); #if TRACE tracebits("mb_type", len, inf, pgcurrMB->mb_type); #endif } //====== READ 8x8 SUB-PARTITION MODES (modes of 8x8 blocks) and Intra VBST block modes ====== if (IS_P8x8 (pgcurrMB)) { pgcurrMB->mb_type=P8x8; } else if(pgcurrMB->mb_type>=I4MB) /* I4MB = 5 */ { pgcurrMB->cbp=NCBP[pgcurrMB->mb_type-5][0]; pgcurrMB->mb_type = I4MB; } //JX 05-4-1 } /* bistream conformance check -- zhan ma */ stat_parameter->mb_type[pgcurrMB->mb_type] = 1; } /*! ************************************************************************************* * \brief * read_CBP_dquant ************************************************************************************* */ void read_CBP_dquant() { int len; int inf; int i; if(pgImage->type==I_IMG) // qhg { len = GetVLCSymbol (&inf); read_cbp_intra(len,inf,&pgcurrMB->cbp); #if TRACE tracebits("Coded_Block_Pattern", len, inf, pgcurrMB->cbp); #endif } else if(IS_INTER(pgcurrMB)) // qhg { len = GetVLCSymbol (&inf); read_cbp_inter(len,inf,&pgcurrMB->cbp); #if TRACE tracebits("Coded_Block_Pattern", len, inf, pgcurrMB->cbp); #endif } //WJP FOR CBP4X4 for(i=0;i<6;i++) { if(pgcurrMB->cbp & (1<cbp_4x4[i] = u_v(4, "cbp_4x4"); } //WJP END // Delta quant only if nonzero coeffs if ((!fixed_slice_qp_flag) && pgcurrMB->cbp !=0) { len = GetVLCSymbol (&inf); mapping_se(len,inf,&pgcurrMB->delta_quant); #if TRACE tracebits("Delta quant", len, inf, pgcurrMB->delta_quant); #endif pgcurrMB->qp= (previous_qp-MIN_QP+pgcurrMB->delta_quant+(MAX_QP-MIN_QP+1))% (MAX_QP-MIN_QP+1)+MIN_QP; // zhan ma 0714 } else pgcurrMB->delta_quant = 0; } /*! ************************************************************************************* * \brief : * macorblock decoding process including ************************************************************************************* */ int decode_one_macroblock() { int bx,by; int tmp_block[4][4]; int i=0,j=0,ii=0,jj=0,i1=0,j1=0,j4=0,i4=0; int js0=0,js1=0,js2=0,js3=0,jf=0; int uv; int vec1_x=0,vec1_y=0,vec2_x=0,vec2_y=0; int k; int ioff,joff; int tmp; int b8, b4; // needed for ABT int ii0,jj0,ii1,jj1,if1,jf1,if0,jf0; int mv_mul,f1,f2,f3,f4; int chroma_offset =0; const byte decode_block_scan[16] = {0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15}; /* block relative coordinate mapping */ int refframe; // = pgcurrMB->ref_frame; //int fw_ref_idx; int*** mv_array; //int b8_s=0,b8_e=4,incr_y=1,off_y=0,even_y=4,add_y=0; int mb_nr = pgImage->current_mb_nr; int mb_width = pgImage->width/MB_BLOCK_SIZE; int mb_available_up = (pgImage->mb_y == 0) ? 0 : (mb_data[mb_nr].slice_nr == mb_data[mb_nr-mb_width].slice_nr); int mb_available_left = (pgImage->mb_x == 0) ? 0 : (mb_data[mb_nr].slice_nr == mb_data[mb_nr-1].slice_nr); #ifdef _ISOLATED_REGION_ if (iREGenable) { if (pgImage->type == P_IMG) { if (mb_available_up != 0) { if (iREGmap[pgImage->mb_y - 1][pgImage->mb_x] != 2) mb_available_up = 0; } if (mb_available_left != 0) { if (iREGmap[pgImage->mb_y][pgImage->mb_x - 1] != 2) mb_available_left = 0; } } } #endif // _ISOLATED_REGION_ mv_mul=4; f1=8; f2=7; f3=f1*f1; f4=f3/2; //f4=f4; // luma decoding ************************************************** for (b8=0; b8 > 2) & 3); ioff=i*4; i4=pgImage->block4_x+i; joff=j*4; j4=pgImage->block4_y+j; /* locate the 4x4 block position of a macroblock */ /*Get Predictive Sample*/ if (pgcurrMB->mb_type != I4MB) {//===== FORWARD PREDICTION ===== refframe = refFrArr[j4][i4]; //fw_ref_idx = refframe; mv_array = pgImage->mv; vec1_x = i4*4*mv_mul + mv_array[i4+BLOCK_SIZE][j4][0]; /* obtain absolute MV coordinate */ vec1_y = j4*4*mv_mul + mv_array[i4+BLOCK_SIZE][j4][1]; //fprintf(p_trace,"@INTER_MV (x,y) (%d,%d)\n" , vec1_x,vec1_y); MAZHAN //--- INTER PREDICTION --- //Get the block from reference frame with MVP get_block(vec1_x, vec1_y, tmp_block,reference_frame[refframe][0]); for(ii=0;ii pred_sample[b8][b4][ii][jj] = tmp_block[ii][jj]; //vld } } else { //--- INTRA PREDICTION --- tmp = intrapred(b8, b4, ioff, joff, i4, j4); if ( tmp == SEARCH_SYNC) /* make 4x4 prediction block mpr from given prediction pgImage->mb_mode */ return SEARCH_SYNC; } Get_residual(b8,b4); /* inverse transform */ Dequant_B4(pgcurrMB->qp, b8, b4); //zhangnan Inv_Transform_B4 (b8,b4); Recon_B4(b8, b4); } //!< end of b4-loop } // chroma decoding ******************************************************* if(IS_INTRA(pgcurrMB)) { for (b4=0;b4<4;b4++) { intrapred_chroma_4x4(pgImage->mb_x,pgImage->mb_y,b4,pgcurrMB->c_ipred_mode); bx = (b4 &1)<<2; by = (b4>>1)<<2; for (uv=0; uv<2;uv++) { Get_residual(4+uv,b4); /* inverse transform */ Dequant_B4(pgcurrMB->qp, 4+uv, b4); Inv_Transform_B4 (4+uv,b4); Recon_B4(4+uv, b4); } } } else { //--- FORWARD PREDICTION --- for(uv =0;uv<2;uv++) { for (j=4;j<6;j++) { joff = (j-4)*4; j4 = pgImage->pix_c_y + joff; for (i=0;i<2;i++) { ioff = i*4; i4 = pgImage->pix_c_x + ioff; mv_array = pgImage->mv; for(jj=0;jj<4;jj++) { jf=(j4+jj)/2; for(ii=0;ii<4;ii++) { if1=(i4+ii)/2; refframe = refFrArr[jf][if1]; // fw_ref_idx = refFrArr[jf][if1]; chroma_offset = 0; i1=(pgImage->pix_c_x+ii+ioff)*f1+mv_array[if1+4][jf][0]; j1=(pgImage->pix_c_y+jj+joff)*f1+mv_array[if1+4][jf][1]; j1 += chroma_offset; ii0=max (0, min (i1/f1, pgImage->width_cr-1)); jj0=max (0, min (j1/f1, pgImage->height_cr-1)); ii1=max (0, min ((i1+f2)/f1, pgImage->width_cr-1)); jj1=max (0, min ((j1+f2)/f1, pgImage->height_cr-1)); if1=(i1 & f2); jf1=(j1 & f2); if0=f1-if1; jf0=f1-jf1; pgcurrMB->pred_sample[4+uv][(j-4)*2+i][ii][jj]= (if0*jf0*reference_frame[refframe][uv+1][jj0][ii0] +if1*jf0*reference_frame[refframe][uv+1][jj0][ii1] +if0*jf1*reference_frame[refframe][uv+1][jj1][ii0] +if1*jf1*reference_frame[refframe][uv+1][jj1][ii1]+f4)/f3; } //end for ii }// end for jj } // end for i }// end for j for(b4=0; b4<4; b4++) { Get_residual(4+uv,b4); /* inverse transform */ Dequant_B4(pgcurrMB->qp, 4+uv, b4); Inv_Transform_B4 (4+uv,b4); Recon_B4(4+uv, b4); } }// end for uv } // end for if(IS_INTRA(pgcurrMB)) #if TRACE trace_mb_data(pgcurrMB); #endif return 0; }