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; jimg_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; jmvb[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 (); 
}