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

📄 macroblock.c

📁 包含了从MPEG4的视频解码到H.264的视频编码部分的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
static void SetMotionVectorPredictor (struct img_par  *img,
                                      int             *pmv_x,
                                      int             *pmv_y,
                                      int             ref_frame,
                                      int             **refFrArr,
                                      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 pic_block_x          = img->block_x + block_x;
  int pic_block_y          = img->block_y + block_y;
  int mb_width             = img->width/16;
  int mb_nr = img->map_mb_nr;
  int mb_available_up   = (img->mb_y == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width  ].slice_nr);
  int mb_available_left = (img->mb_x == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-1         ].slice_nr);
  int mb_available_upleft  = (img->mb_x == 0) ? 0 : ((img->mb_y == 0) ? 0 : 
                                                     (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width-1].slice_nr));
  int mb_available_upright = (img->mb_y == 0) ? 0 : ((img->mb_x >= (mb_width-1)) ? 0 :
                                                     (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width+1].slice_nr));

  int block_available_up, block_available_left, block_available_upright, block_available_upleft;
  int mv_a, mv_b, mv_c, mv_d, pred_vec=0;
  int mvPredType, rFrameL, rFrameU, rFrameUR;
  int hv;


  if (img->structure==FRAME && img->mb_field)
  {
    if (img->current_mb_nr%2==0)    // top field
    {
      if (!(img->type==B_SLICE))
        tmp_mv             = img->mv_top;
      pic_block_x          = img->block_x + (mb_x>>2);
      pic_block_y          = img->block_y/2 + (mb_y>>2);
    }
    else
    {
      if (!(img->type==B_SLICE))
        tmp_mv             = img->mv_bot;
      pic_block_x          = img->block_x + (mb_x>>2);
      pic_block_y          = (img->block_y-4)/2 + (mb_y>>2);

      mb_available_up   = (img->mb_y == 1 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width  ].slice_nr);
      mb_available_upleft  = (img->mb_x == 0) ? 0 : ((img->mb_y == 1) ? 0 : 
                                                     (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width-1].slice_nr));
      mb_available_upright = 0;
    }
  }
  else
  {
    if(img->mb_frame_field_flag)
      mb_available_upright = (img->mb_y%2) ? 0:mb_available_upright;  // Not sure if this is right
  }

  /* D B C */
  /* A X   */

  /* 1 A, B, D are set to 0 if unavailable       */
  /* 2 If C is not available it is replaced by D */
  block_available_up   = mb_available_up   || (mb_y > 0);
  block_available_left = mb_available_left || (mb_x > 0);

  if (mb_y > 0)
  {
    if (mb_x < 8)  // first column of 8x8 blocks
    {
      if (mb_y==8)
      {
        if (blockshape_x == 16)      block_available_upright = 0;
        else                         block_available_upright = 1;
      }
      else
      {
        if (mb_x+blockshape_x != 8)  block_available_upright = 1;
        else                         block_available_upright = 0;
      }
    }
    else
    {
      if (mb_x+blockshape_x != 16)   block_available_upright = 1;
      else                           block_available_upright = 0;
    }
  }
  else if (mb_x+blockshape_x != MB_BLOCK_SIZE)
  {
    block_available_upright = block_available_up;
  }
  else
  {
    block_available_upright = mb_available_upright;
  }

  if (mb_x > 0)
  {
    block_available_upleft = (mb_y > 0 ? 1 : mb_available_up);
  }
  else if (mb_y > 0)
  {
    block_available_upleft = mb_available_left;
  }
  else
  {
    block_available_upleft = mb_available_upleft;
  }


  mvPredType = MVPRED_MEDIAN;
  rFrameL    = block_available_left    ? refFrArr[pic_block_y]  [pic_block_x-1             ] : -1;
  rFrameU    = block_available_up      ? refFrArr[pic_block_y-1][pic_block_x               ]   : -1;
  rFrameUR   = block_available_upright ? refFrArr[pic_block_y-1][pic_block_x+blockshape_x/4] :
               block_available_upleft  ? refFrArr[pic_block_y-1][pic_block_x-1             ] : -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 
  else if(blockshape_x == 8 && blockshape_y == 16)
  {
    if(mb_x == 0)
    {
      if(rFrameL == ref_frame)
        mvPredType = MVPRED_L;
    }
    else
    {
      if( rFrameUR == ref_frame)
        mvPredType = MVPRED_UR;
    }
  }
  else if(blockshape_x == 16 && blockshape_y == 8)
  {
    if(mb_y == 0)
    {
      if(rFrameU == ref_frame)
        mvPredType = MVPRED_U;
    }
    else
    {
      if(rFrameL == ref_frame)
        mvPredType = MVPRED_L;
    }
  }

  for (hv=0; hv < 2; hv++)
  {
    mv_a = block_available_left    ? tmp_mv[4+pic_block_x-1             ][pic_block_y  ][hv] : 0;
    mv_b = block_available_up      ? tmp_mv[4+pic_block_x               ][pic_block_y-1][hv] : 0;
    mv_d = block_available_upleft  ? tmp_mv[4+pic_block_x-1             ][pic_block_y-1][hv] : 0;
    mv_c = block_available_upright ? tmp_mv[4+pic_block_x+blockshape_x/4][pic_block_y-1][hv] : mv_d;


    switch (mvPredType)
    {
    case MVPRED_MEDIAN:
      if(!(block_available_upleft || block_available_up || block_available_upright))
        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;

  }
  if (img->structure==FRAME && img->mb_field)
    tmp_mv = img->mv_frm;
}


/*!
 ************************************************************************
 * \brief
 *    Set context for reference frames
 ************************************************************************
 */
int
BType2CtxRef (int btype)
{
  if (btype<4)  return 0;
  else          return 1;
}

/*!
 ************************************************************************
 * \brief
 *    Read motion info
 ************************************************************************
 */
void readMotionInfoFromNAL (struct img_par *img, struct inp_par *inp)
{
  int i,j,k,l,m;
  int step_h,step_v;
  int curr_mvd;
 // int mb_nr           = img->current_mb_nr; //GB Falsch
  Macroblock *currMB  = &img->mb_data[img->map_mb_nr];
  SyntaxElement currSE;
  Slice *currSlice    = img->currentSlice;
  DataPartition *dP;
  int *partMap        = assignSE2partition[currSlice->dp_mode];
  int bframe          = (img->type==B_SLICE);
  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 iTRb,iTRp;
  int mv_scale;
  int frame_no_next_P, frame_no_B, delta_P;
  int ref;
  int img_block_y;
  int use_scaled_mv;
  int fw_refframe,current_tr;

  int **fwRefFrArr = img->fw_refFrArr;
  int **bwRefFrArr = img->bw_refFrArr;
  int  ***fw_mv = img->fw_mv;
  int  ***bw_mv = img->bw_mv;
  int  **moving_block_dir = moving_block; 
  int  ***fw_mv_array, ***bw_mv_array;
  int j6;  
  int flag_mode;

  if (bframe && IS_P8x8 (currMB))
  {
    if (img->direct_type && img->mb_frame_field_flag )
    {
      if (!img->mb_field)
      {
        fwRefFrArr= img->fw_refFrArr_frm;
        bwRefFrArr= img->bw_refFrArr_frm;
        fw_mv=img->fw_mv_frm;
        bw_mv=img->bw_mv_frm;
        fw_mv_array = img->dfMV;
        bw_mv_array = img->dbMV;
      }
      else if (img->current_mb_nr%2 )
      {
        fwRefFrArr= img->fw_refFrArr_bot;
        bwRefFrArr= img->bw_refFrArr_bot;
        fw_mv=img->fw_mv_bot;
        bw_mv=img->bw_mv_bot;
        moving_block_dir = moving_block_bot; 
        fw_mv_array = img->dfMV_bot;
        bw_mv_array = img->dbMV_bot;
      }
      else
      {
        fwRefFrArr=img->fw_refFrArr_top ;
        bwRefFrArr=img->bw_refFrArr_top ;
        fw_mv=img->fw_mv_top;
        bw_mv=img->bw_mv_top;
        moving_block_dir = moving_block_top; 
        fw_mv_array = img->dfMV_top;
        bw_mv_array = img->dbMV_top;
      }
    }
    if (img->direct_type)
    {
      int pic_blockx          = img->block_x;
      int pic_blocky          = (img->mb_frame_field_flag && img->mb_field)? ((img->current_mb_nr%2)?img->block_y/2-BLOCK_SIZE / 2:img->block_y/2):img->block_y;
      int mb_nr                = img->map_mb_nr; //GB current_mb_nr; //HIER
      int mb_width             = img->width/16;
      int mb_available_up =      (img->mb_y == 0 || pic_blocky == 0  ) ? 0 : (img->mb_frame_field_flag? 1 :(currMB->slice_nr == img->mb_data[mb_nr-mb_width].slice_nr));
      int mb_available_left =    (img->mb_x == 0                      ) ? 0 : (currMB->slice_nr == img->mb_data[mb_nr-1].slice_nr);
      int mb_available_upleft  = (img->mb_x == 0 || img->mb_y == 0 || pic_blocky == 0) ? 0 : (img->mb_frame_field_flag)? 1 :(currMB->slice_nr == img->mb_data[mb_nr-mb_width-1].slice_nr);
      int mb_available_upright = (img->mb_frame_field_flag && img->current_mb_nr%2)?0:(img->mb_x >= mb_width-1 ||
        img->mb_y == 0 || pic_blocky == 0 ) ? 0 : (img->mb_frame_field_flag)? 1 :(currMB->slice_nr == img->mb_data[mb_nr-mb_width+1].slice_nr);
      
      
      int fw_rFrameL              = mb_available_left    ? fwRefFrArr[pic_blocky]  [pic_blockx-1]   : -1;
      int fw_rFrameU              = mb_available_up      ? fwRefFrArr[pic_blocky-1][pic_blockx]     : -1;
      int fw_rFrameUL             = mb_available_upleft  ? fwRefFrArr[pic_blocky-1][pic_blockx-1]   : -1;
      int fw_rFrameUR             = mb_available_upright ? fwRefFrArr[pic_blocky-1][pic_blockx+4]   : fw_rFrameUL;  
      
      int bw_rFrameL              = mb_available_left    ? bwRefFrArr[pic_blocky]  [pic_blockx-1]   : -1;
      int bw_rFrameU              = mb_available_up      ? bwRefFrArr[pic_blocky-1][pic_blockx]     : -1;
      int bw_rFrameUL             = mb_available_upleft  ? bwRefFrArr[pic_blocky-1][pic_blockx-1]   : -1;
      int bw_rFrameUR             = mb_available_upright ? bwRefFrArr[pic_blocky-1][pic_blockx+4]   : bw_rFrameUL;
      
      
      int fw_rFrame,bw_rFrame;
      int pmvfw[2]={0,0},pmvbw[2]={0,0};
      int j5=0;
      
      if (!fw_rFrameL || !fw_rFrameU || !fw_rFrameUR)
        fw_rFrame=0;
      else
        fw_rFrame=min(fw_rFrameL&15,min(fw_rFrameU&15,fw_rFrameUR&15));
      
      if(img->num_ref_pic_active_bwd>1 && (bw_rFrameL==1 || bw_rFrameU==1 || bw_rFrameUR==1))
        bw_rFrame=1;
      else if (!bw_rFrameL || !bw_rFrameU || !bw_rFrameUR)
        bw_rFrame=0;
      else
        bw_rFrame=min(bw_rFrameL&15,min(bw_rFrameU&15,bw_rFrameUR&15));
      
      if (fw_rFrame !=15)
        SetMotionVectorPredictor (img, pmvfw, pmvfw+1, fw_rFrame, fwRefFrArr, fw_mv, 0, 0, 16, 16);  
      if (bw_rFrame !=15)
        SetMotionVectorPredictor (img, pmvbw, pmvbw+1, bw_rFrame, bwRefFrArr, bw_mv, 0, 0, 16, 16);  
      
      for (i=0;i<4;i++)
      {
        if (currMB->b8mode[i] == 0)
          for(j=2*(i/2);j<2*(i/2)+2;j++)
            for(k=2*(i%2);k<2*(i%2)+2;k++)
            {
              j4 = img->block_y+j;
              j6 = pic_blocky+j;
              i4 = img->block_x+k;
              if (img->mb_frame_field_flag) 
              {
                j5 = img->block_y / 2 + j;
                if (img->current_mb_nr%2)
                  j5 -= BLOCK_SIZE / 2;
              }
              if (!(img->mb_frame_field_flag && img->mb_field))
              {
                if (fw_rFrame !=15)
                {
                  if  (!fw_rFrame  && !moving_block_dir[j6][i4])       
                  {                    
                    img->fw_mv[i4+BLOCK_SIZE][j4][0]=img->dfMV[i4+BLOCK_SIZE][j4][0] = 0;
                    img->fw_mv[i4+BLOCK_SIZE][j4][1]=img->dfMV[i4+BLOCK_SIZE][j4][1] = 0;
                    if (img->mb_frame_field_flag)
                    {
                      if (img->current_mb_nr%2 == 0)
                      {
                        img->dfMV_top[i4+BLOCK_SIZE][j5][0]=img->fw_mv_top[i4+BLOCK_SIZE][j5][0]=0;
                        img->dfMV_top[i4+BLOCK_SIZE][j5][1]=img->fw_mv_top[i4+BLOCK_SIZE][j5][1]=0;
                        img->fw_refFrArr_top[j5][i4]=0;                        
                      }
                      else
                      {
                        img->dfMV_bot[i4+BLOCK_SIZE][j5][0]=img->fw_mv_bot[i4+BLOCK_SIZE][j5][0]=0;
                        img->dfMV_bot[i4+BLOCK_SIZE][j5][1]=img->fw_mv_bot[i4+BLOCK_SIZE][j5][1]=0;
                        img->fw_refFrArr_bot[j5][i4]=0;
                      }
                    }                    
                    if (img->structure == TOP_FIELD)  //! Note that this seems to be unecessary for different img->structure.
                      fwRefFrArr[j4][i4] = 0;         //! copied to be consistent with temporal direct, just in case there is 
    

⌨️ 快捷键说明

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