www.pudn.com > wm2.5.zip > macroblock.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2004, Advanced Audio Video Coding Standard, Part II * * DISCLAIMER OF WARRANTY * * These software programs are available to the users without any * license fee or royalty on an "as is" basis. The AVS disclaims * any and all warranties, whether express, implied, or statutory, * including any implied warranties of merchantability or of fitness * for a particular purpose. In no event shall the contributors or * the AVS be liable for any incidental, punitive, or consequential * damages of any kind whatsoever arising from the use of this program. * * This disclaimer of warranty extends to the user of this program * and user's customers, employees, agents, transferees, successors, * and assigns. * * The AVS does not represent or warrant that the program furnished * hereunder are free of infringement of any third-party patents. * Commercial implementations of AVS, including shareware, may be * subject to royalty fees to patent holders. Information regarding * the AVS patent policy is available from the AVS Web site at * http://www.avs.org.cn * * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. ************************************************************************ */ #include#include "global.h" #include "types.h" #include "define.h" #include "interpred.h" #include "block.h" #include "macroblock.h" #include "block_const.h" #include "vlc.h" #include "parset.h" extern const int csiInter_Block_Size[4][2]; extern const int csiInter_Subblk_Size[4][2]; extern int writeLumaCoeffAVS_B8(int b8); extern int counter_chroma_ipred_mode[4]; //for test //WJP FOR SLICE /* ************************************************************************* * Function: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. * Input: * Output: * Return: * Attention: ************************************************************************* */ void CheckAvailabilityOfNeighbors() { const int mb_width = pgImage->img_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 = pgMbData->slice_nr != pgImage->mb_data_forlf[mb_nr-1].slice_nr; // upper blocks if (remove_prediction) { ipredmode[pgImage->block_x][pgImage->block_y+1] = -1; ipredmode[pgImage->block_x][pgImage->block_y+2] = -1; ipredmode[pgImage->block_x][pgImage->block_y+3] = -1; ipredmode[pgImage->block_x][pgImage->block_y+4] = -1; } } // Check MB above if(pgImage->pix_y >= MB_BLOCK_SIZE) { int remove_prediction = pgMbData->slice_nr != pgImage->mb_data_forlf[mb_nr-mb_width].slice_nr; // upper blocks if (remove_prediction) { ipredmode[pgImage->block_x+1][pgImage->block_y] = -1; ipredmode[pgImage->block_x+2][pgImage->block_y] = -1; ipredmode[pgImage->block_x+3][pgImage->block_y] = -1; ipredmode[pgImage->block_x+4][pgImage->block_y] = -1; } } // Check MB left above if(pgImage->pix_y >= MB_BLOCK_SIZE && pgImage->pix_x >= MB_BLOCK_SIZE) { int remove_prediction = pgMbData->slice_nr != pgImage->mb_data_forlf[mb_nr-mb_width-1].slice_nr; if (remove_prediction) { ipredmode[pgImage->block_x][pgImage->block_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]); } */ } //WJP END /******************************************************************** Created: 12:2:2004 Author : Siwei Ma Input : img_x,img_y: absolute position in non-padding frame Output : Function: *********************************************************************/ void Init_Macroblock(int img_x, int img_y) { int i, j; int img_chroma_x = img_x/2; int img_chroma_y = img_y/2; for(j=0; j<16; j++) for(i=0; i<16; i++) { pgMbData->org_luma[j][i] = original_frame[0][img_y + j][img_x + i]; } for(j=0; j<8; j++) for(i=0; i<8; i++) { pgMbData->org_chroma[0][j][i] = original_frame[1][img_chroma_y + j][img_chroma_x + i]; pgMbData->org_chroma[1][j][i] = original_frame[2][img_chroma_y + j][img_chroma_x + i]; } pgMbData->slice_nr = pgImage->current_slice_nr;//WJP FOR SLICE pgMbHeader->cbp = 0;//jiahz added 2004-02-18 // dongjie for(i=0;i<6;i++) pgMbHeader->cbp_4x4[i] = 0; // end // Define vertical positions //zhangnan 2004-04-16 pgImage->block_y = pgImage->mb_y * BLOCK_SIZE; // vertical luma block position pgImage->pix_y = pgImage->mb_y * MB_BLOCK_SIZE; // vertical luma macroblock position pgImage->block_c_y = pgImage->mb_y * BLOCK_SIZE/2; // chroma block pgImage->pix_c_y = pgImage->mb_y * MB_BLOCK_SIZE/2; // vertical chroma macroblock position // Define horizontal positions pgImage->block_x = pgImage->mb_x * BLOCK_SIZE; // luma block pgImage->pix_x = pgImage->mb_x * MB_BLOCK_SIZE; // luma pixel pgImage->block_c_x = pgImage->mb_x * BLOCK_SIZE/2; // chroma block pgImage->pix_c_x = pgImage->mb_x * MB_BLOCK_SIZE/2; // chroma pixel*/} CheckAvailabilityOfNeighbors();//WJP FOR SLICE pgMbHeader->cbp_blk=0; //for loopfilter test cbzhu pgMbHeader->lf_alpha_c0_offset=-2; pgMbHeader->lf_beta_offset=-1; //pgMbHeader->all_zero_ref = 0;WJP FOR ZERO_REF } /******************************************************************** Created: 12:2:2004 Author : Siwei Ma Input : img_x, img_y: absolute position in non-padding non-interpolated image Output : Function: *********************************************************************/ void Load_Integer_Pel_Ref(int ref, int img_x, int img_y) { int i, j; int ii, jj; img_x += PAD_SIZE; img_y += PAD_SIZE; for(j=0; j img_height + (PAD_SIZE<<1) - 1); ii = min(max(img_x + i, 0), pgImage->img_width + (PAD_SIZE<<1) - 1); pgMbData->Integer_pixel_buffer[ref][j][i] = reference_frame[ref][0][jj][ii]; } } } /******************************************************************** Created: 14:2:2004 Author : Siwei Ma Input : absolute mb position in 1 pixel unit Output : Function: *********************************************************************/ void Load_Ref_Luma(void) //zhangnan //qwang 2004-3-22 { int b8, b4, blk_x, blk_y; int i, j; int ii, jj; int x_pos, y_pos; int width4, height4; int refframe; width4 = (pgImage->img_width + (PAD_SIZE<<1) - 1)<<2; height4 = (pgImage->img_height + (PAD_SIZE<<1) - 1)<<2; for(b8=0; b8<4; b8++) { for(b4=0; b4<4; b4++) { refframe = refFrArr [pgImage->block_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)]; blk_x = ((b8 &1)<<3) + ((b4 &1)<<2); blk_y = ((b8>>1)<<3) + ((b4>>1)<<2); x_pos = (((pgMbData->mb_x<<4) + blk_x) << 2) + (PAD_SIZE<<2); y_pos = (((pgMbData->mb_y<<4) + blk_y) << 2) + (PAD_SIZE<<2); for(j=0; j<4; j++) for(i=0; i<4; i++) { ii = x_pos + (i<<2) + pgMbData->mvb[b8][b4][0] ; jj = y_pos + (j<<2) + pgMbData->mvb[b8][b4][1] ; // module operation when out of range by jhzheng [14:30 2004/02/18] ii = (ii < 0) ? (ii & 3) : (ii > width4 ) ? (width4 + (ii & 3)) : ii; jj = (jj < 0) ? (jj & 3) : (jj > height4) ? (height4 + (jj & 3)) : jj; pgMbData->pred_sample[b8][b4][j][i] = reference_quater_pel_frame[refframe][jj][ii]; pgMbHeader->pred_residual[b8][b4][j][i] =pgMbData->org_luma[blk_y+j][blk_x+i] - pgMbData->pred_sample[b8][b4][j][i] ; } } } } /******************************************************************** Created: 14:2:2004 Author : Siwei Ma Input : absolute mb position in 1 pixel unit Output : Function: *********************************************************************/ void Load_8x8_Residual(int b8) { int b4, blk_x, blk_y; int i, j; int ii, jj; int x_pos, y_pos; int width4, height4; int refframe; width4 = (pgImage->img_width + (PAD_SIZE<<1) - 1)<<2; height4 = (pgImage->img_height + (PAD_SIZE<<1) - 1)<<2; for(b4=0; b4<4; b4++) { refframe = refFrArr [pgImage->block_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)]; blk_x = ((b8 &1)<<3) + ((b4 &1)<<2); blk_y = ((b8>>1)<<3) + ((b4>>1)<<2); x_pos = (((pgMbData->mb_x<<4) + blk_x) << 2) + (PAD_SIZE<<2); y_pos = (((pgMbData->mb_y<<4) + blk_y) << 2) + (PAD_SIZE<<2); for(j=0; j<4; j++) for(i=0; i<4; i++) { ii = x_pos + (i<<2) + pgMbData->mvb[b8][b4][0] ; jj = y_pos + (j<<2) + pgMbData->mvb[b8][b4][1] ; // module operation when out of range by jhzheng [14:30 2004/02/18] ii = (ii < 0) ? (ii & 3) : (ii > width4 ) ? (width4 + (ii & 3)) : ii; jj = (jj < 0) ? (jj & 3) : (jj > height4) ? (height4 + (jj & 3)) : jj; pgMbData->pred_sample[b8][b4][j][i] = reference_quater_pel_frame[refframe][jj][ii]; pgMbHeader->pred_residual[b8][b4][j][i] =pgMbData->org_luma[blk_y+j][blk_x+i] - pgMbData->pred_sample[b8][b4][j][i] ; } } } /******************************************************************** Created: 14:2:2004 Author : Siwei Ma Input : Output : Function: *********************************************************************/ void Load_Ref_Chroma(void) //zhangnan //qwang 2004-3-22 { int b8, b4; int i, j; short dx, dy, rx, ry; int ii, jj; int ii0, jj0, ii1, jj1; int img_chroma_x =(pgMbData->mb_x<<3); int img_chroma_y =(pgMbData->mb_y<<3); int refframe; for(b8=0; b8<4; b8++) for(b4=0; b4<4; b4++) { refframe = refFrArr [pgImage->block_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x+((b8 &1)<<1) + (b4 &1)]; for (j=img_chroma_y + (b8/2)*4 + (b4/2)*2; j mvb[b8][b4][0]; jj = (j<<3) + pgMbData->mvb[b8][b4][1]; ii0 = max (0, min (pgImage->img_width/2 -1, ii>>3 )); jj0 = max (0, min (pgImage->img_height/2-1, jj>>3 )); ii1 = max (0, min (pgImage->img_width/2 -1, (ii+7)>>3)); jj1 = max (0, min (pgImage->img_height/2-1, (jj+7)>>3)); dx = (ii&7); rx = 8-dx; dy = (jj&7); ry = 8-dy; pgMbData->pred_sample_c[4][j-img_chroma_y][i-img_chroma_x] = (rx * ry * reference_frame[refframe][1][jj0][ii0] + dx * ry * reference_frame[refframe][1][jj0][ii1] + rx * dy * reference_frame[refframe][1][jj1][ii0] + dx * dy * reference_frame[refframe][1][jj1][ii1] + 32) / 64; //zhangnan pgMbData->pred_sample_c[5][j-img_chroma_y][i-img_chroma_x] = (rx * ry * reference_frame[refframe][2][jj0][ii0] + dx * ry * reference_frame[refframe][2][jj0][ii1] + rx * dy * reference_frame[refframe][2][jj1][ii0] + dx * dy * reference_frame[refframe][2][jj1][ii1] + 32) / 64; //zhangnan } } } } /* ************************************************************************* * Function: write differential motion vector * Input: * Output: * Return: * Attention: ************************************************************************* */ int writeMVD (void) { int k, j0, i0; int step_h0; int step_v0; int b8, b4; if(pgMbHeader->mb_type != P8x8) //qwang 2004-3-22 { step_h0 = (csiInter_Block_Size[IS_P8x8(pgMbHeader) ? 3 : pgMbHeader->mb_type-1][0] >> 3); step_v0 = (csiInter_Block_Size[IS_P8x8(pgMbHeader) ? 3 : pgMbHeader->mb_type-1][1] >> 3); for (j0=0; j0<2; ) { for (i0=0; i0<2; ) { k=j0*2+i0; if ( pgImage->half_pixel_mv_flag == 0) // 1/4-PIXEL mv { se_linfo(pgMbHeader->mvd[k][0][0]); //qwang 2004-3-21 pgMbHeader->mvd[k][0] se_linfo(pgMbHeader->mvd[k][0][1]);//zhangnan //qwang 2004-3-21 pgMbHeader->mvd[k][1] } else { se_linfo(pgMbHeader->mvd[k][0][0] >> 1); se_linfo(pgMbHeader->mvd[k][0][1] >> 1); } i0+=max(1,step_h0); } j0+=max(1,step_v0); } } else { for(b8=0; b8<4; b8++) { step_h0 = (csiInter_Subblk_Size[pgMbHeader->subblk_type[b8]-1][0]>>2); step_v0 = (csiInter_Subblk_Size[pgMbHeader->subblk_type[b8]-1][1]>>2); for(j0 = 0 ; j0 < 2 ; j0 += step_v0) for( i0 = 0 ; i0 < 2 ; i0 += step_h0) { b4 = j0 * 2 + i0; if ( pgImage->half_pixel_mv_flag == 0 ) // 1/4-pixel mv { se_linfo(pgMbHeader->mvd[b8][b4][0]); se_linfo(pgMbHeader->mvd[b8][b4][1]); } else { se_linfo(pgMbHeader->mvd[b8][b4][0] >> 1); se_linfo(pgMbHeader->mvd[b8][b4][1] >> 1); } } } } return 0; } /* ************************************************************************* * Function: write reference index * Input: * Output: * Return: * Attention: ************************************************************************* */ void writeFrameRef (int ref) { int num_ref = pgImage->picture_code_type== INTER_IMG ? 2:1; if( num_ref == 1 ) { return ; } // Add the new bits to the bitstream. // Write out a byte if it is full pgcurrBitStream->byte_buf <<= 1; if (ref & 1) pgcurrBitStream->byte_buf |= 1; pgcurrBitStream->bits_to_go--; if (pgcurrBitStream->bits_to_go==0) { pgcurrBitStream->bits_to_go = 8; pgcurrBitStream->streamBuffer[pgcurrBitStream->byte_pos++]=pgcurrBitStream->byte_buf; pgcurrBitStream->byte_buf = 0; } } /* ************************************************************************* * Function:Converts macroblock type to coding value * Input: * Output: * Return: * Attention: ************************************************************************* */ int MBType2Value (MacroblockHeader* currMB) { if (currMB->mb_type==I4MB) // return (pgImage->picture_code_type==INTRA_IMG ? 0 : 6)+NCBP[currMB->cbp][0];// qhg; return (pgImage->picture_code_type==INTRA_IMG ? 0 : 5)+NCBP[currMB->cbp][0]; //JX 05-4-1 //return (pgImage->picture_code_type==INTRA_IMG ? 0 : 6);// qhg; else { /*WJP FOR ZERO_REF if(pgMbHeader->all_zero_ref) return P8x8_Zero_Ref; else */ return currMB->mb_type; } } /* ************************************************************************* * Function: Codes macroblock header * Input: * Output: * Return: * Attention: ************************************************************************* */ void writeMBHeader (void) // GB CHROMA !!!!!!!! //qwang 2004-3-8 { int i,j,value1; //zhangnan //WJP FOR SLICE int Width_in_MB = input.img_width/MB_BLOCK_SIZE; int Slice_nr=pgImage->current_slice_nr; int Slice_P=input.slice_parameter; //WJP END static int MbCounter = 0; //===== BITS FOR MACROBLOCK MODE ===== MbCounter++; if(pgImage->picture_code_type != INTRA_IMG)//GB { if(active_pps->skip_mode_flag) { // Run Length Coding if (pgMbHeader->mb_type != 0) { //===== Run Length Coding: Non-Skipped macorblock ===== ue_linfo(pgImage->cod_counter); pgImage->cod_counter = 0;// Reset cod counter // Put out mb mode value1 = MBType2Value (pgMbHeader); value1--; ue_linfo(value1); if(value1<3&&input.ABT&&input.ABT_RDO)//WJP 040824N u_v(1, "abt block size flag", pgMbHeader->abt_block_size_flag); //qhg for abt } else { //Run Length Coding: Skipped macroblock pgImage->cod_counter++; //indicates the SKIP MB number /*WJP FOR SLICE_HEADER 050320 if(pgImage->current_mb_nr == (pgImage->total_mb_number-1)|| pgImage->current_mb_nr == Width_in_MB*(input.slice ? Slice_nr+1 : 0)*Slice_P-1) */ if(pgImage->current_mb_nr == (pgImage->total_mb_number-1)|| !((pgImage->current_mb_nr+1)%Slice_P)) //WJP END { ue_linfo(pgImage->cod_counter); // Put out run pgImage->cod_counter = 0;// Reset cod counter MbCounter = 0; } } } else { value1 = MBType2Value (pgMbHeader); ue_linfo(value1); } } if(IS_INTRA(pgMbHeader)) { //WJP FOR I_DIRECT if (pgImage->picture_code_type == INTRA_IMG) u_v(1, "Intra Mb mode", pgMbHeader->I_MODE); if(/*! dongjie(check) */pgMbHeader->I_MODE)//not I_direct mode { for (i=0; i<4; i++) { for(j=0; j<4; j++) { write_Intra4x4PredictionMode(pgMbHeader->luma_ipred_mode[i][j]); } } } //WJP END ue_linfo( pgMbHeader->chroma_ipred_mode); } } /* ************************************************************************* * Function: Codes CBP and delta quant * Input: * Output: * Return: * Attention: ************************************************************************* */ int writeCBPandDqp () { int i; //===== C B P ===== //--------------------- if(pgImage->picture_code_type==INTRA_IMG||IS_INTER(pgMbHeader)) { if (IS_INTRA (pgMbHeader)) { ue_linfo(NCBP[pgMbHeader->cbp][0]); } else { ue_linfo(NCBP[pgMbHeader->cbp][1]); } } //WJP FOR CBP4X4 for(i=0;i<6;i++) { if(pgMbHeader->cbp & (1<cbp_4x4[i]); } //WJP END //===== DQUANT ===== //---------------------- if (pgMbHeader->cbp&&!pgImage->fixed_picture_qp) { se_linfo(pgMbHeader->dquant); } return 0; } /* ************************************************************************* * Function: * Input: * Output: * Return: * Attention: ************************************************************************* */ int writeReferenceIndex (void) //zhangnan 2004-04 { int k, j0, i0; int step_h0 = (csiInter_Block_Size[IS_P8x8(pgMbHeader) ? 4 : pgMbHeader->mb_type-1][0] >> 2); int step_v0 = (csiInter_Block_Size[IS_P8x8(pgMbHeader) ? 4 : pgMbHeader->mb_type-1][1] >> 2); for (j0=0; j0<4; j0+=step_v0) { for (i0=0; i0<4; i0+=step_h0) { k=j0+(i0/2); if ( pgImage->nb_references>1) //WJP FOR ZERO_REF u_v(1,"piture reference index",pgMbHeader->refIndex[k]); } } return 0; } /* ************************************************************************* * Function:Passes the chosen syntax elements to the NAL * Input: * Output: * Return: * Attention: ************************************************************************* */ void write_one_macroblock (void) //qwang 2004-3-8 { int i, j,value1;//WJP FOR SUB_MB_TYPE //--- write header --- writeMBHeader (); // Do nothing more if copy and inter mode if (IS_INTERMV (pgMbHeader)) { writeReferenceIndex(); //WJP FOR SUB_MB_TYPE if(pgMbHeader->mb_type == 4) { for(i=0; i<4; i++) { value1 = pgMbHeader->subblk_type[i]; value1--; ue_linfo(value1); } } //WJP END writeMVD(); } if (IS_INTERMV (pgMbHeader) || IS_INTRA (pgMbHeader)) { writeCBPandDqp(); for (i=0; i < 4; i++) //writeBlockCoeff (i); { if (pgMbHeader->cbp & (1<mb_type==4 && pgMbHeader->subblk_type[i]==1 && (!input.ABT_RDO) && input.ABT) { pgMbHeader->abt_block_size_flag=1; } //WJP END if((pgMbHeader->mb_type==I4MB)||(pgMbHeader->abt_block_size_flag==0)||(!input.ABT)) //qhg for abt { // dongjie write the cbp_4x4 //u_v(4,"cbp_4x4", pgMbHeader->cbp_4x4[i]);//WJP FOR CBP4X4 // end for(j=0; j<4; j++) { if(pgMbHeader->cbp_4x4[i] & (1< mb_type==I4MB)); //qwang 2004-3-15 } } else { writeLumaCoeffAVS_B8(i); } //WJP 040903 if(pgMbHeader->mb_type==4 && pgMbHeader->subblk_type[i]==1 && (!input.ABT_RDO) && input.ABT) { pgMbHeader->abt_block_size_flag=0; } //WJP END } } for (i=4; i < 6; i++) { if (pgMbHeader->cbp & (1<cbp_4x4[i]);//WJP FOR CBP4X4 // end for(j=0; j<4; j++) { if(pgMbHeader->cbp_4x4[i] & (1< pred_sample[b8][b4][j][i]; } for(b8=0; b8<4; b8++) for(b4=0; b4<4; b4++) for(j=0; j<4; j++) for(i=0; i<4; i++) { imgY[img_y + (b8/2)*8+(b4/2)*4+j][img_x+ (b8%2)*8+(b4%2)*4+i] = (Byte) pgMbData->pred_sample[b8][b4][j][i]; } for(b4=0; b4<4; b4++) for(j=0; j<4; j++) for(i=0; i<4; i++) { current_frame[1][img_chroma_y + (b4/2)*4+j][img_chroma_x + (b4%2)*4+i] = (Byte) pgMbData->pred_sample[4][b4][j][i]; current_frame[2][img_chroma_y + (b4/2)*4+j][img_chroma_x + (b4%2)*4+i] = (Byte) pgMbData->pred_sample[5][b4][j][i]; } for(b4=0; b4<4; b4++) for(j=0; j<4; j++) for(i=0; i<4; i++) { imgUV[0][img_chroma_y + (b4/2)*4+j][img_chroma_x +(b4%2)*4+ i] = (Byte) pgMbData->pred_sample[4][b4][j][i]; } for(b4=0; b4<4; b4++) for(j=0; j<4; j++) for(i=0; i<4; i++) { imgUV[1][img_chroma_y + (b4/2)*4+j][img_chroma_x +(b4%2)*4+ i] = (Byte) pgMbData->pred_sample[5][b4][j][i]; } } /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function name : Inter_ReLoad_Residual + parameters : void + return : void + descriptions : created by jhzheng : 2004/02/15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ void Inter_ReLoad_Residual(void) //zhangnan { int i,j,blk;//,blk_x,blk_y; Load_Ref_Luma(); Load_Ref_Chroma(); for(blk = 4 ; blk < 6 ; blk ++) { for (j=0; j<8; j++) { for (i=0; i<8; i++) { pgMbHeader->pred_residual[blk][i/4+(j/4)*2][j%4][i%4] = pgMbData->org_chroma[blk-4][j][i] - pgMbData->pred_sample_c[blk][j][i]; pgMbData->pred_sample[blk][i/4+(j/4)*2][j%4][i%4] = pgMbData->pred_sample_c[blk][j][i]; } } } } /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function name : Inter_ReLoad_Residual + parameters : void + return : void + descriptions : created by jhzheng : 2004/02/15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ void Code_Inter_Macroblock(void) //zhangnan { int b8, b4; int pic_block_x, pic_block_y; int k, i, j; int img_x = pgMbData->mb_x<<4; int img_y = pgMbData->mb_y<<4; int step_h0, step_v0; int coeff_cost; pgMbHeader->mb_type = pgMbData->best_mode; if(pgMbHeader->mb_type == 4) //qwang 2004-3-22 { for(i=0; i<4; i++) pgMbHeader->subblk_type[i] = pgMbData->best_mode_subblk[i]; } //--- Set the numbers of MV --- pgMbHeader->mv_num = (pgMbData->best_mode == 3) ? 2 : pgMbData->best_mode; //--- Update left ref --- pgMbData->left_ref = 0; //--- Update Intra line buffer --- for (b8=0;b8<4;b8++) for (b4=0;b4<4;b4++) { pic_block_x=(img_x/4 + 2*(b8%2)+(b4%2)); pic_block_y=(img_y/4 + 2*(b8/2)+(b4/2)); // ipredmode[pic_block_x+1][pic_block_y+1] = DC_PRED;//zhangnan // ipredmode[pic_block_x+1][pic_block_y+1] = -1; //JX ipredmode[pic_block_x+1][pic_block_y+1] = (active_pps->constrained_intra_pred_flag ? -1 : 10); /* if(active_pps->constrained_intra_pred_flag) c_ipredmode[img_x/16+1][img_y/16 +1] = -1; //JX else c_ipredmode[img_x/16+1][img_y/16 +1] = 0; //MZ 04-03-05 */ } //--- Get RefIndex info --- //zhangnan step_h0 = (csiInter_Block_Size[pgMbHeader->mb_type-1][0] >> 2); step_v0 = (csiInter_Block_Size[pgMbHeader->mb_type-1][1] >> 2); //??? zhangnan for (j=0; j<4; j+=step_v0) for (i=0; i<4; i+=step_h0) { k=j+(i/2); pgMbHeader->refIndex[k] = refFrArr[pgMbData->mb_y*4+j][pgMbData->mb_x*4+i ]; } //--- Get MVD info --- for(b8=0; b8<4; b8++) for(b4=0; b4<4; b4++) { pgMbHeader->mvd[b8][b4][0] = pgMbData->mvb[b8][b4][0] - pgMbData->pred_mv[b8][b4][0]; pgMbHeader->mvd[b8][b4][1] = pgMbData->mvb[b8][b4][1] - pgMbData->pred_mv[b8][b4][1]; } for(b8=0; b8<4; b8++) for(b4=0; b4<4; b4++) { tmp_mv[0][pgImage->block_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)+4] = pgMbData->mvb[b8][b4][0]; tmp_mv[1][pgImage->block_y +((b8>>1)<<1) + (b4>>1)][pgImage->block_x +((b8 &1)<<1) + (b4 &1)+4] = pgMbData->mvb[b8][b4][1]; } //--- Reset cbp --- pgMbHeader->cbp = 0; // dongjie for(b8=0;b8<6;b8++) pgMbHeader->cbp_4x4[b8]=0; // end Inter_ReLoad_Residual(); for (b8=0; b8<4; b8++) //zhangnan { coeff_cost = 0; coeff_cost_4x4[0]=coeff_cost_4x4[1]=coeff_cost_4x4[2]=coeff_cost_4x4[3] = 0; // dongjie //WJP 040903 if(pgMbHeader->mb_type==4 && pgMbHeader->subblk_type[b8]==1 && (!input.ABT_RDO) && input.ABT) { pgMbHeader->abt_block_size_flag=1; } //WJP END if(pgMbHeader->abt_block_size_flag==0||!input.ABT) //qhg for abt { for (b4=0; b4<4; b4++) { Transform_B4(b8, b4); Quant_B4(pgMbData->qp_mb, b8, b4, &coeff_cost); } // dongjie if(pgMbHeader->cbp_4x4[b8]==0) pgMbHeader->cbp &= (~(1< cbp |= (1< qp_mb, b8, &coeff_cost); } if(coeff_cost <= (b8<4 ? LUMACOEFFCOST:CHROMACOEFFCOST)) { pgMbHeader->cbp &= (63 - (1< pred_residual[b8][b4][j][i] = 0; } // dongjie else { for(b4=0;b4<4;b4++) { if(coeff_cost_4x4[b4] <= LUMACOEFFCOST4x4) { pgMbHeader->cbp_4x4[b8] &= (15 - (1< pred_residual[b8][b4][j][i] = 0; } } } // end //WJP 040903 if(pgMbHeader->mb_type==4 && pgMbHeader->subblk_type[b8]==1 && (!input.ABT_RDO) && input.ABT) { pgMbHeader->abt_block_size_flag=0; } //WJP END } for (b8=4; b8<6; b8++) //qhg for abt { coeff_cost = 0; for (b4=0; b4<4; b4++) Transform_B4(b8, b4); //TranformChromaDC(b8); for(b4=0; b4<4; b4++) Quant_B4(pgMbData->qp_mb, b8, b4, &coeff_cost); // dongjie if(pgMbHeader->cbp_4x4[b8]==0) pgMbHeader->cbp &= (~(1< cbp |= (1< cbp &= (63 - (1< pred_residual[b8][b4][j][i] = 0; } // dongjie else { for(b4=0;b4<4;b4++) { if(coeff_cost_4x4[b4] <= CHROMACOEFFCOST4x4) { pgMbHeader->cbp_4x4[b8] &= (15 - (1< pred_residual[b8][b4][j][i] = 0; } } } // end } for (b8=0; b8<4; b8++) { //WJP 040903 if(pgMbHeader->mb_type==4 && pgMbHeader->subblk_type[b8]==1 && (!input.ABT_RDO) && input.ABT) { pgMbHeader->abt_block_size_flag=1; } //WJP END if(pgMbHeader->abt_block_size_flag==0||!input.ABT) //qhg for abt { for (b4=0; b4<4; b4++) { Dequant_B4(pgMbData->qp_mb, b8, b4); Inv_Transform_B4(b8, b4); } } else { abt_dequant_B8(pgMbData->qp_mb,b8); abt_Itransform_B8(b8); } //WJP 040903 if(pgMbHeader->mb_type==4 && pgMbHeader->subblk_type[b8]==1 && (!input.ABT_RDO) && input.ABT) { pgMbHeader->abt_block_size_flag=0; } //WJP END } for (b8=4; b8<6; b8++) { for(b4=0; b4<4; b4++) Dequant_B4(pgMbData->qp_mb, b8, b4); //InvTransformChromaDC(b8); for (b4=0; b4<4; b4++) Inv_Transform_B4(b8, b4); } for (b8=0; b8<6; b8++) for (b4=0; b4<4; b4++) Recon_B4(b8, b4, 1); //--- DECISION FOR SKIP MODE --- if (pgMbHeader->mb_type == 1 && pgMbHeader->cbp == 0 && pgMbData->mvb[0][0][0] == sSkip_MV[0] && pgMbData->mvb[0][0][1] == sSkip_MV[1] && refFrArr[pgImage->block_y][pgImage->block_x] ==0 ) //zhangnan { pgMbHeader->mb_type = 0; } /*WJP FOR ZERO_REF if(pgMbHeader->mb_type==4 && pgImage->nb_references>1) { pgMbHeader->all_zero_ref = 1; for(i=0; i<4; i++) { if(pgMbHeader->refIndex[i]==1) { pgMbHeader->all_zero_ref = 0; break; } } } */ //write one macroblock to bitstream write_one_macroblock (); }