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

📄 macroblock.cpp

📁 264的播放器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
          }
    }
    return;
  }
  if(currMB->mb_type!=IPCM)
  {    
    // intra prediction modes for a macroblock 4x4 **********************************************
    read_ipred_modes(img);    
    // read inter frame vector data *********************************************************
    readMotionInfoFromNAL (img);
    // read CBP and Coeffs  ***************************************************************
    readCBPandCoeffsFromNAL (img);
	return;
  }
  else
  {
    //read pcm_alignment_zero_bit and pcm_byte[i] 
    
    // here dP is assigned with the same dP as SE_MBTYPE, because IPCM syntax is in the 
    // same category as MBTYPE
    dP = &(currSlice->partArr[partMap[SE_MBTYPE]]);
    readIPCMcoeffsFromNAL(img,dP);
  }
}

/*!
 ************************************************************************
 * \brief
 *    Read IPCM pcm_alignment_zero_bit and pcm_byte[i] from stream to img->cof
 *    (for IPCM CABAC and IPCM CAVLC  28/11/2003)
 *
 * \author
 *    Dong Wang <Dong.Wang@bristol.ac.uk>
 ************************************************************************
 */

void readIPCMcoeffsFromNAL(struct img_par *img, struct datapartition *dP)
{
  SyntaxElement currSE;
  unsigned int i,j;
  
  //read bits to let stream byte aligned
  i=(dP->bitstream->frame_bitoffset)&0x0111;
  if(i!=0)
  {
    currSE.len=8-i;
    readSyntaxElement_FLC(&currSE, dP->bitstream);
  }

  //read luma and chroma IPCM coefficients
  currSE.len=8;

  for(i=0;i<16;i++)
    for(j=0;j<16;j++)
    {
      readSyntaxElement_FLC(&currSE, dP->bitstream);
      img->cof[i>>2][j>>2][i&0x0003][j&0x0003]=currSE.value1;
    }

  for(i=0;i<8;i++)
    for(j=0;j<8;j++)
    {
      readSyntaxElement_FLC(&currSE, dP->bitstream);
      img->cof[i>>2][j>>2+4][i&0x0003][j&0x0003]=currSE.value1;
    }

  for(i=0;i<8;i++)
    for(j=0;j<8;j++)
    {
      readSyntaxElement_FLC(&currSE, dP->bitstream);
      img->cof[i>>2+2][j>>2+4][i&0x0003][j&0x0003]=currSE.value1;
    }
}



void read_ipred_modes(struct img_par *img)
{
  int b8,i,j,bi,bj,bx,by,dec;
  SyntaxElement currSE;
  Slice *currSlice;
  DataPartition *dP;
  int *partMap;
  Macroblock *currMB;
  int mostProbableIntraPredMode;
  int upIntraPredMode;
  int leftIntraPredMode;
  int IntraChromaPredModeFlag;

  PixelPos left_block;
  PixelPos top_block;
  
  currMB = &img->mb_data[img->current_mb_nr];

  IntraChromaPredModeFlag = IS_INTRA(currMB);

  currSlice = img->currentSlice;
  partMap = assignSE2partition[currSlice->dp_mode];

  currSE.type = SE_INTRAPREDMODE;

  //intra4x4_pred_mode
  dP = &(currSlice->partArr[partMap[currSE.type]]);

  if(currMB->mb_type == I4MB)
  {
    for(b8=0;b8<4;b8++)  //loop 8x8 blocks
	{
//   IntraChromaPredModeFlag = 1;

      for(j=0;j<2;j++)  //loop subblocks
        for(i=0;i<2;i++)
        {
          //get from stream
          readSyntaxElement_Intra4x4PredictionMode(&currSE,dP);

          bx = ((b8&1)<<1) + i;
          by = (b8&2)      + j;

          getLuma4x4Neighbour(img->current_mb_nr, bx, by, -1,  0, &left_block);
          getLuma4x4Neighbour(img->current_mb_nr, bx, by,  0, -1, &top_block);
          
          //get from array and decode
          bi = img->block_x + bx;
          bj = img->block_y + by;

          if (img->constrained_intra_pred_flag)
          {
            left_block.available = left_block.available ? img->intra_block[left_block.mb_addr] : 0;
            top_block.available  = top_block.available  ? img->intra_block[top_block.mb_addr]  : 0;
          }

          upIntraPredMode            = (top_block.available) ? img->ipredmode[top_block.pos_x ][top_block.pos_y ] : -1;
          leftIntraPredMode          = (left_block.available) ? img->ipredmode[left_block.pos_x][left_block.pos_y] : -1;

          mostProbableIntraPredMode  = (upIntraPredMode < 0 || leftIntraPredMode < 0) ? DC_PRED : upIntraPredMode < leftIntraPredMode ? upIntraPredMode : leftIntraPredMode;

          dec = (currSE.value1 == -1) ? mostProbableIntraPredMode : currSE.value1 + (currSE.value1 >= mostProbableIntraPredMode);

          //set
          img->ipredmode[bi][bj]=dec;
        }
    }
  }

  if (IntraChromaPredModeFlag)
  {
    currSE.type = SE_INTRAPREDMODE;
    //intra_chroma_pred_mode
    dP = &(currSlice->partArr[partMap[currSE.type]]);

    currSE.mapping = linfo_ue;

    dP->readSyntaxElement(&currSE,dP);
    currMB->c_ipred_mode = currSE.value1;

    if (currMB->c_ipred_mode < DC_PRED_8 || currMB->c_ipred_mode > PLANE_8)
    {
      error("illegal chroma intra pred mode!\n", 600);
    }
  }
}



/*!
 ************************************************************************
 * \brief
 *    Set motion vector predictor
 ************************************************************************
 */
static void SetMotionVectorPredictor (struct img_par  *img,
                                      int             *pmv_x,
                                      int             *pmv_y,
                                      int             ref_frame,
                                      int             list,
                                      int             ***refPic,
                                      int             ****tmp_mv,
                                      int             block_x,
                                      int             block_y,
                                      int             blockshape_x,
                                      int             blockshape_y)
{
  int mb_x                 = 4*block_x;
  int mb_y                 = 4*block_y;
  int mb_nr                = img->current_mb_nr;

  int mv_a, mv_b, mv_c, pred_vec=0;
  int mvPredType, rFrameL, rFrameU, rFrameUR;
  int hv;


  PixelPos block_a, block_b, block_c, block_d;

  getLuma4x4Neighbour(mb_nr, block_x, block_y,           -1,  0, &block_a);
  getLuma4x4Neighbour(mb_nr, block_x, block_y,            0, -1, &block_b);
  getLuma4x4Neighbour(mb_nr, block_x, block_y, blockshape_x, -1, &block_c);
  getLuma4x4Neighbour(mb_nr, block_x, block_y,           -1, -1, &block_d);

  if (mb_y > 0)
  {
    if (mb_x < 8)  // first column of 8x8 blocks
    {
      if (mb_y==8)
      {
        if (blockshape_x == 16)      block_c.available  = 0;
        else                         block_c.available &= 1;
      }
      else
      {
        if (mb_x+blockshape_x != 8)  block_c.available &= 1;
        else                         block_c.available  = 0;
      }
    }
    else
    {
      if (mb_x+blockshape_x != 16)   block_c.available &= 1;
      else                           block_c.available  = 0;
    }
  }

  if (!block_c.available)
  {
    block_c=block_d;
  }

  mvPredType = MVPRED_MEDIAN;

  rFrameL    = block_a.available    ? refPic[list][block_a.pos_x][block_a.pos_y] : -1;
  rFrameU    = block_b.available    ? refPic[list][block_b.pos_x][block_b.pos_y] : -1;
  rFrameUR   = block_c.available    ? refPic[list][block_c.pos_x][block_c.pos_y] : -1;

  /* Prediction if only one of the neighbors uses the reference frame
   * we are checking
   */
  if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame)       mvPredType = MVPRED_L;
  else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame)  mvPredType = MVPRED_U;
  else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame)  mvPredType = MVPRED_UR;
  // Directional predictions 
  if(blockshape_x == 8 && blockshape_y == 16)
  {
	  if((mb_x == 0) && (rFrameL == ref_frame))
		  mvPredType = MVPRED_L;
	  else if((mb_x != 0) && (rFrameUR == ref_frame))
		  mvPredType = MVPRED_UR;
  }
  else if(blockshape_x == 16 && blockshape_y == 8)
  {
    if((mb_y == 0)&& (rFrameU == ref_frame))
        mvPredType = MVPRED_U;
    else if((mb_y != 0)&& (rFrameL == ref_frame))
        mvPredType = MVPRED_L;
  }

  for (hv=0; hv < 2; hv++)
  {
    mv_a = block_a.available  ? tmp_mv[list][block_a.pos_x][block_a.pos_y][hv] : 0;
    mv_b = block_b.available  ? tmp_mv[list][block_b.pos_x][block_b.pos_y][hv] : 0;
    mv_c = block_c.available  ? tmp_mv[list][block_c.pos_x][block_c.pos_y][hv] : 0;
    
    switch (mvPredType)
    {
    case MVPRED_MEDIAN:
      if(!(block_b.available || block_c.available))
        pred_vec = mv_a;
      else
        pred_vec = mv_a+mv_b+mv_c-min(mv_a,min(mv_b,mv_c))-max(mv_a,max(mv_b,mv_c));
      break;
    case MVPRED_L:
      pred_vec = mv_a;
      break;
    case MVPRED_U:
      pred_vec = mv_b;
      break;
    case MVPRED_UR:
      pred_vec = mv_c;
      break;
    default:
      break;
    }

    if (hv==0)  *pmv_x = pred_vec;
    else        *pmv_y = pred_vec;

  }
}

/*!
 ************************************************************************
 * \brief
 *    Read motion info
 ************************************************************************
 */
void readMotionInfoFromNAL (struct img_par *img)
{
  int i,j,k;
  int step_h,step_v;
  int curr_mvd;
  Macroblock *currMB  = &img->mb_data[img->current_mb_nr];
  SyntaxElement currSE;
  Slice *currSlice    = img->currentSlice;
  DataPartition *dP;
  int *partMap        = assignSE2partition[currSlice->dp_mode];
  int partmode        = (IS_P8x8(currMB)?4:currMB->mb_type);
  int step_h0         = BLOCK_STEP [partmode][0];
  int step_v0         = BLOCK_STEP [partmode][1];

  int mv_mode, i0, j0, refframe;
  int pmv[2];
  int j4, i4, ii,jj;
  int vec;

  int flag_mode;

  //  If multiple ref. frames, read reference frame for the MB *********************************
  if(img->num_ref_idx_l0_active>1) 
  {
    flag_mode = ( img->num_ref_idx_l0_active == 2 ? 1 : 0);

    currSE.type = SE_REFFRAME;
    dP = &(currSlice->partArr[partMap[SE_REFFRAME]]);

    currSE.mapping = linfo_ue;
    
    for (j0=0; j0<4; j0+=step_v0)
    {
      for (i0=0; i0<4; i0+=step_h0)
      {
        k=2*(j0/2)+(i0/2);
        if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
        {
          //ref_idx_l0

          if (!IS_P8x8 (currMB) || (!img->allrefzero))
          {
            if( (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) && flag_mode )
            {
              currSE.len = 1;
              readSyntaxElement_FLC(&currSE, dP->bitstream);
              currSE.value1 = 1 - currSE.value1;
            }
            else
            {
              currSE.value2 = LIST_0;
              dP->readSyntaxElement (&currSE,dP);
            }
            refframe = currSE.value1;
            
          }
          else
          {
            refframe = 0;
          }
          
          for (j=j0; j<j0+step_v0;j++)
            for (i=i0; i<i0+step_h0;i++)
            {
              dec_picture->ref_idx[LIST_0][img->block_x + i][img->block_y + j] = refframe;
            }
          
        }
      }
    }
  }
  else
  {
    for (j0=0; j0<4; j0+=step_v0)
    {
      for (i0=0; i0<4; i0+=step_h0)
      {
        k=2*(j0/2)+(i0/2);
        if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
        {
          for (i=i0; i<i0+step_h0;i++)
            for (j=j0; j<j0+step_v0;j++)
              dec_picture->ref_idx[LIST_0][img->block_x + i][img->block_y + j] = 0;
        }
      }
    }
  }

  //=====  READ FORWARD MOTION VECTORS =====
  currSE.type = SE_MVD;
  dP = &(currSlice->partArr[partMap[SE_MVD]]);

  currSE.mapping = linfo_se;

  for (j0=0; j0<4; j0+=step_v0)
    for (i0=0; i0<4; i0+=step_h0)
    {
      k=2*(j0/2)+(i0/2);

      if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && (currMB->b8mode[k] !=0))//has forward vector
      {
        mv_mode  = currMB->b8mode[k];
        step_h   = BLOCK_STEP [mv_mode][0];
        step_v   = BLOCK_STEP [mv_mode][1];
        
        refframe = dec_picture->ref_idx[LIST_0][img->block_x+i0][img->block_y+j0];
        
        for (j=j0; j<j0+step_v0; j+=step_v)
        {
          for (i=i0; i<i0+step_h0; i+=step_h)
          {
            j4 = img->block_y+j;
            i4 = img->block_x+i;
            
            // first make mv-prediction
            SetMotionVectorPredictor (img, pmv, pmv+1, refframe, LIST_0, dec_picture->ref_idx, dec_picture->mv, i, j, 4*step_h, 4*step_v);

            for (k=0; k < 2; k++) 
            {
              //mvd_l0
              currSE.value2 = k<<1; // identifies the component; only used for context determination
              dP->readSyntaxElement(&currSE,dP);
              curr_mvd = currSE.value1; 
              
              vec=curr_mvd+pmv[k];           /* find motion vector */
              
              for(ii=0;ii<step_h;ii++)
              {
                for(jj=0;jj<step_v;jj++)
                {
                  dec_picture->mv  [LIST_0][i4+ii][j4+jj][k] = vec;
                  currMB->mvd      [LIST_0][j+jj] [i+ii] [k] = curr_mvd;
                }
              }
            }
          }
        }
      }
  }

  // record reference picture Ids for deblocking decisions
 
  for(i4=img->block_x;i4<(img->block_x+4);i4++)
	 for(j4=img->block_y;j4<(img->block_y+4);j4++)
	 {
	   if(dec_picture->ref_idx[LIST_0][i4][j4]>=0)
	      dec_picture->ref_pic_id[LIST_0][i4][j4] = dec_picture->ref_pic_num[LIST_0][dec_picture->ref_idx[LIST_0][i4][j4]];
	  else
	     dec_picture->ref_pic_id[LIST_0][i4][j4] = INT64_MIN;
  }
}



/*!
 ************************************************************************
 * \brief
 *    Get the Prediction from the Neighboring Blocks for Number of Nonzero Coefficients 

⌨️ 快捷键说明

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