⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macroblock.c

📁 davinci avs.......................................................
💻 C
📖 第 1 页 / 共 2 页
字号:
/*!
 *************************************************************************************
 * \file macorblock.c
 *
 * \brief
 *    decoder one macroblock
 *************************************************************************************
 */
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

#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<MB_BLOCK_SIZE; j++)
    for (i=0; i<MB_BLOCK_SIZE; i++)
      pgImage->m7[i][j] = 0;		
        
  for (j=0; j<B8_SIZE; j++)
    for (i=0; i<B8_SIZE; i++)
    {
      pgImage->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<j0+step_v0;j++)
          for (i=i0; i<i0+step_h0;i++)
            refFrArr[pgImage->block4_y+j][pgImage->block4_x+i] = refframe;
      }
      else
      {
        for (j=j0; j<j0+step_v0;j++)
          for (i=i0; i<i0+step_h0;i++)
            refFrArr[pgImage->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];
      

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -