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. 
************************************************************************ 
*/   
 
/* 
************************************************************************************* 
* File name: macroblock.c 
* Function: Decode a Macroblock 
* 
************************************************************************************* 
*/ 
#include  
#include  
#include  
#include  
 
#include "global.h" 
#include "elements.h" 
#include "macroblock.h" 
#include "vlc.h" 
#include "interprediction.h" 
#include "output.h" 
 
#include "defines.h" 
#include "block.h" 
 
#define ZERO_P8x8     (mbmode==5) 
#define MODE_IS_P8x8  (mbmode==4 || mbmode==5) 
#define MODE_IS_I4x4  (mbmode==6) 
 
extern void readLumaCoeff_8x8_UVLC(int b8); 
 
 
 
/* 
************************************************************************* 
* 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->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]); 
  } 
  */ 
} 
 
/* 
************************************************************************* 
* Function:initializes the current macroblock 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
void start_macroblock()     //qwang 2004-3-8 
{ 
  int i,j,k,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 = loop_filter_disable; 
   
  // 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          = pgImage->qp ; 
  pgcurrMB->mb_type     = 0; 
  pgcurrMB->delta_quant = 0; 
  pgcurrMB->cbp         = 0; 
  pgcurrMB->cbp_blk     = 0; 
//  pgcurrMB->c_ipred_mode= DC_PRED_8; //GB 
  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; jm7[i][j] = 0;		 
         
        for (j=0; jm8[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; 
            } 
          } 
           
          for (i=0;i<4;i++) // reset vectors and pred. modes                 
            for(j=0;j<4;j++) 
            { 
//              pgImage->ipredmode[pgImage->block4_x+i+1][pgImage->block4_y+j+1] = DC_PRED; 
                //pgImage->ipredmode[pgImage->block4_x+i+1][pgImage->block4_y+j+1] = -1 ; //JX 05-4-1 
              pgImage->ipredmode[pgImage->block4_x+i+1][pgImage->block4_y+j+1] = (pps->constrained_intra_pred_flag?-1:10) ; 
   
            } 
          //added by MZ   
 /*         if(pps->constrained_intra_pred_flag) 
            pgImage->c_ipredmode[pgImage->block4_x+1][pgImage->block4_y+1] = -1; 
          else 
            pgImage->c_ipredmode[pgImage->block4_x+1][pgImage->block4_y+1] =  0; 
 
*/ 
            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; 
                    } 
} 
 
/* 
************************************************************************* 
* Function:Get the syntax elements from the NAL 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
int read_one_macroblock()    //qwang 2004-3-9 
{ 
  int b8,b4; 
  int len, inf;//WJP FOR SUB_MB_TYPE 
  int i; 
#if TRACE 
  int mb_y,mb_x; 
  //	int mb_uv; 
#endif 
  //read macroblock type 
  read_mb_type(pgcurrMB); 
   
  //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)) 
    { 
      pgcurrMB->abt_block_size_flag=0; 
      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(); 
   
#if TRACE 
  if (IS_INTRA(pgcurrMB)) 
		{ 
    fprintf(p_trace,"@MB Luma Mode\n"); 
    for (b8=0;b8<4;b8++) 
      for (b4=0;b4<4;b4++) 
      { 
        fprintf(p_trace,"%3d",MB_ipredmode_Y[b8][b4]); 
        if(!((b4+1)%4)) 
          fprintf(p_trace,"\n"); 
      } 
  } 
  fprintf(p_trace,"@VLD output: \n"); 
		for(mb_y=0;mb_y<16;mb_y++) 
    { 
      for(mb_x=0;mb_x<16;mb_x++) 
      { 
        fprintf(p_trace,"%4d",pgImage->m7[mb_y][mb_x]); 
        if(mb_x%4==3) 
          fprintf(p_trace,"  "); 
        if(mb_x==15) 
          fprintf(p_trace,"\n"); 
      } 
      if(mb_y%4==3) 
        fprintf(p_trace,"\n"); 
    } 
     
     
    for(mb_y = 0; mb_y < 8;mb_y++) 
    { 
      for(mb_x=0;mb_x < 8;mb_x++) 
      { 
        fprintf(p_trace,"%4d",pgImage->m8[0][mb_y][mb_x]); 
        if(mb_x%4==3) 
          fprintf(p_trace,"  "); 
      } 
       
      for(mb_x=0;mb_x<8;mb_x++) 
      { 
        fprintf(p_trace,"%4d",pgImage->m8[1][mb_y][mb_x]); 
        if(mb_x%4==3) 
          fprintf(p_trace,"  "); 
        if(mb_x==7) 
          fprintf(p_trace,"\n"); 
      } 
      if(mb_y%4==3) 
        fprintf(p_trace,"\n"); 
    } 
     
#endif 
     
    return DECODE_MB; 
} 
/* 
************************************************************************* 
* Function:decode intra prediction mode  
* Input:   8x8 block 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
//added by MAZHAN 
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]); 
     
    //*/  dsk 2004.6.15 
    //mostProbableIntraPredMode  = (upIntraPredMode < 0 || leftIntraPredMode < 0) ? DC_PRED : upIntraPredMode < leftIntraPredMode ? upIntraPredMode : leftIntraPredMode; 
    mostProbableIntraPredMode  = (upIntraPredMode < 0 || leftIntraPredMode < 0) ? DC_PRED : mpm[leftIntraPredMode][upIntraPredMode]; 
     
    dec = (currSE.value1 == -1) ? mostProbableIntraPredMode : currSE.value1 + (currSE.value1 >= mostProbableIntraPredMode); 
//    dec = (currSE.value1 == -1) ? -1 : currSE.value1 + (currSE.value1 >= mostProbableIntraPredMode); 
    //add by MZ 
    pgImage->ipredmode[1+bi][1+bj]=dec; 
     
#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 
  } 
   
} 
/* 
************************************************************************* 
* Function:decode intra chroma prediction mode 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
void read_chroma_ipred_modes()    //qwang 2004-3-9 
{ 
  SyntaxElement currSE; 
  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, "Ipred Mode", TRACESTRING_SIZE); 
  //#endif 
   
		currSE.type = SE_INTRAPREDMODE; 
#if TRACE 
    strncpy(currSE.tracestring, "intra_Chroma_pred_mode", TRACESTRING_SIZE); 
#endif 
     
    currSE.mapping = mapping_ue; 
     
    read_UVLC(&currSE); 
//    pgImage->c_ipredmode[pgImage->mb_x+1][pgImage->mb_y+1] = currSE.value1;//MZ 
    pgcurrMB->c_ipred_mode = currSE.value1; 
     
    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); 
    } 
} 
 
/* 
************************************************************************* 
* Function:Set context for reference frames 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
int BType2CtxRef (int btype) 
{ 
  if (btype<4) 
    return 0; 
  else 
    return 1; 
} 
 
 
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
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!=0)//WJP FOR ZERO_REF 
      {			 
        if (!picture_reference_flag) 
        { 
#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; jblock4_y+j][pgImage->block4_x+i] = refframe; 
      } 
      else 
      { 
        for (j=j0; jblock4_y+j][pgImage->block4_x+i] = 0; 
      } 
    } 
} 
 
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
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; jblock4_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;iimv[i4+ii+BLOCK_SIZE][j4+jj][k]=vec;				 
               
              /* 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; 
          } 
        } 
    }		 
} 
 
/* 
************************************************************************* 
* Function:Get coded block pattern and coefficients (run/level) 
from the NAL 
* Input: 
* Output: 
* Return: 
* Attention: 
************************************************************************* 
*/ 
 
void read_luma_chroma_coeffs() 
{ 
  int mb_nr = pgImage->current_mb_nr; //GBimg->current_mb_nr; 
  int  b8, b4; 
   
  int qp_per    = (pgImage->qp-MIN_QP)/6; 
  int qp_rem    = (pgImage->qp-MIN_QP)%6; 
  int qp_per_uv = QP_SCALE_CR[pgImage->qp-MIN_QP]/6; 
  int qp_rem_uv = QP_SCALE_CR[pgImage->qp-MIN_QP]%6; 
   
  pgcurrMB->qp = pgImage->qp; 
   
  // luma coefficients 
  for(b8=0; b8<4; b8++) 
  { 
    if (pgcurrMB->cbp&(1<mb_type==4 && pgcurrMB->sub_mb_type[b8]==0 && (!ABT_RDO) && USE_ABT) 
        pgcurrMB->abt_block_size_flag=1; 
      //WJP END 
       
      // dongjie read cbp_4x4 from bitstream 
      //pgcurrMB->cbp_4x4 = u_v(4, "cbp_4x4");//WJP FOR CBP4X4 
      // end 
       
      if((pgcurrMB->mb_type == I4MB)||(pgcurrMB->abt_block_size_flag==0)) // qhg for abt. 
      { 
        for(b4=0; b4<4; b4++) 
        { 
          if (pgcurrMB->cbp_4x4[b8]&(1<mb_type==4 && pgcurrMB->sub_mb_type[b8]==0 && (!ABT_RDO) && USE_ABT) 
        pgcurrMB->abt_block_size_flag=0; 
      //WJP END 
       
    } 
  }         
   
  if ((pgcurrMB->cbp>>4)&1) 
  { 
    // 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[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<allrefzero = 0;//WJP FOR ZERO_REF 
// add by JX 
   if (pgImage->number == 2 && pgImage->current_mb_nr == 49) 
	   pgImage->current_mb_nr = 49; 
 
   if(pgImage->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(pps->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 
 //         if(pgcurrMB->mb_type>5) 
//         fprintf(stdout,"%d\n",pgcurrMB->mb_type); 
         tracebits("MB Type", len, inf, pgcurrMB->mb_type); 
#endif 
         pgcurrMB->mb_type++; 
         pgImage->cod_counter--; 
          
         if(pgcurrMB->mb_type<4 && USE_ABT)//WJP 040824N 
         { 
           if(ABT_RDO) 
             pgcurrMB->abt_block_size_flag=u_v(1,"abt block size flag");//qhg for abt 
           else 
             pgcurrMB->abt_block_size_flag=1; 
         } 
       }  
       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)) 
     { 
     /* WJP FOR SUB_MB_TYPE 
     //if(pgcurrMB->abt_block_size_flag==0)//qhg for abt 
     {    pgcurrMB->abt_block_size_flag=0; 
				 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 
         } 
         } 
       */ 
       //pgImage->allrefzero = (pgcurrMB->mb_type==5);//WJP FOR ZERO_REF 
       pgcurrMB->mb_type=4; 
     } 
/*     else if(pgcurrMB->mb_type>=6) 
     { 
       pgcurrMB->cbp=NCBP[pgcurrMB->mb_type-6][0]; // qhg 
       pgcurrMB->mb_type = I4MB; 
     } 
*/ 
     else if(pgcurrMB->mb_type>=5) 
     { 
       pgcurrMB->cbp=NCBP[pgcurrMB->mb_type-5][0]; 
       pgcurrMB->mb_type = I4MB; 
     }  //JX 05-4-1 
   } 
} 
/* 
************************************************************************* 
* Function:decode CBP and delta quant 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
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_picture_qp && pgcurrMB->cbp !=0) 
  { 
    len =  GetVLCSymbol (&inf); 
    mapping_se(len,inf,&pgcurrMB->delta_quant);	  
#if TRACE 
    tracebits("Delta quant", len, inf, pgcurrMB->delta_quant); 
#endif 
    pgImage->qp= (pgImage->qp-MIN_QP+pgcurrMB->delta_quant+(MAX_QP-MIN_QP+1))%(MAX_QP-MIN_QP+1)+MIN_QP; 
  } 
  else 
  { 
    pgcurrMB->delta_quant = 0; 
  } 
}