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

📄 macroblock.c

📁 H.264基于baseline解码器的C++实现源码
💻 C
📖 第 1 页 / 共 5 页
字号:

          // !! KS: not sure if the following is still correct...
          ts = ls = 0;   // Check to see if the neighboring block is SI
          if (currMB->mb_type == I4MB && img->type == SI_SLICE)           // need support for MBINTLC1
          {
            if (left_block.available)
              if (img->siblock [left_block.pos_y][left_block.pos_x])
                ls=1;

            if (top_block.available)
              if (img->siblock [top_block.pos_y][top_block.pos_x])
                ts=1;
          }

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

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

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

          //set
          for(jj = 0; jj < (bs_y >> 2); jj++)   //loop 4x4s in the subblock for 8x8 prediction setting
          {
            memset(&(img->ipredmode[bj + jj][bi]), dec, (bs_x>>2) * sizeof(char));
          }
        }
      }
    }
  }

  if (IntraChromaPredModeFlag && (dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444))
  {
    currSE.type = SE_INTRAPREDMODE;
    TRACE_STRING("intra_chroma_pred_mode");
    dP = &(currSlice->partArr[partMap[currSE.type]]);

    if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) 
      currSE.mapping = linfo_ue;
    else
      currSE.reading = readCIPredMode_CABAC;

    dP->readSyntaxElement(&currSE,img,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
 *    Get current block spatial neighbors
 ************************************************************************
 */
void get_neighbors(Macroblock *currMB,     // <--  current Macroblock
                   PixelPos *block_a,      // <--> left block
                   PixelPos *block_b,      // <--> top  block
                   PixelPos *block_c,      // <--> top-right block | top-left block
                   PixelPos *block_d,      // <--> top-left block. Can be removed.
                   int       mb_x,         // <--  block x position
                   int       mb_y,         // <--  block y position
                   int       blockshape_x  // <--  block width
                   )
{
  int *mb_size = img->mb_size[IS_LUMA];

  get4x4Neighbour(currMB, mb_x - 1,            mb_y    , mb_size, block_a);
  get4x4Neighbour(currMB, mb_x,                mb_y - 1, mb_size, block_b);
  get4x4Neighbour(currMB, mb_x + blockshape_x, mb_y - 1, mb_size, block_c);
  get4x4Neighbour(currMB, mb_x - 1,            mb_y - 1, mb_size, block_d);

  if (mb_y > 0)
  {
    if (mb_x < 8)  // first column of 8x8 blocks
    {
      if (mb_y == 8 )
      {
        if (blockshape_x == MB_BLOCK_SIZE)      
          block_c->available  = 0;
      }
      else if (mb_x+blockshape_x == 8)
      {
        block_c->available = 0;
      }
    }
    else if (mb_x + blockshape_x == MB_BLOCK_SIZE)
    {
      block_c->available = 0;
    }
  }

  if (!block_c->available)
  {
    *block_c = *block_d;
  }
}


/*!
 ************************************************************************
 * \brief
 *    Get motion vector predictor
 ************************************************************************
 */
void GetMotionVectorPredictor (Macroblock *currMB, 
                               PixelPos *block_a,      // <--> left block
                               PixelPos *block_b,      // <--> top  block
                               PixelPos *block_c,      // <--> top-right block
                               short  pmv[2],
                               char  ref_frame,
                               char   **refPic,
                               short  ***tmp_mv,                               
                               int    mb_x,
                               int    mb_y,
                               int    blockshape_x,
                               int    blockshape_y)
{
  int mv_a, mv_b, mv_c, pred_vec=0;
  int mvPredType, rFrameL, rFrameU, rFrameUR;
  int hv;

  mvPredType = MVPRED_MEDIAN;

  if (!img->MbaffFrameFlag)
  {
    rFrameL  = block_a->available ? refPic[block_a->pos_y][block_a->pos_x] : -1;
    rFrameU  = block_b->available ? refPic[block_b->pos_y][block_b->pos_x] : -1;
    rFrameUR = block_c->available ? refPic[block_c->pos_y][block_c->pos_x] : -1;
  }
  else
  {
    if (currMB->mb_field)
    {
      rFrameL  = block_a->available
        ? (img->mb_data[block_a->mb_addr].mb_field
        ? refPic[block_a->pos_y][block_a->pos_x]
        : refPic[block_a->pos_y][block_a->pos_x] * 2) : -1;
        rFrameU  = block_b->available
          ? (img->mb_data[block_b->mb_addr].mb_field
          ? refPic[block_b->pos_y][block_b->pos_x]
          : refPic[block_b->pos_y][block_b->pos_x] * 2) : -1;
          rFrameUR = block_c->available
            ? (img->mb_data[block_c->mb_addr].mb_field
            ? refPic[block_c->pos_y][block_c->pos_x]
            : refPic[block_c->pos_y][block_c->pos_x] * 2) : -1;
    }
    else
    {
      rFrameL = block_a->available
        ? (img->mb_data[block_a->mb_addr].mb_field
        ? refPic[block_a->pos_y][block_a->pos_x] >>1
        : refPic[block_a->pos_y][block_a->pos_x]) : -1;
      rFrameU  = block_b->available
        ? (img->mb_data[block_b->mb_addr].mb_field
        ? refPic[block_b->pos_y][block_b->pos_x] >>1
        : refPic[block_b->pos_y][block_b->pos_x]) : -1;
      rFrameUR = block_c->available
        ? (img->mb_data[block_c->mb_addr].mb_field
        ? refPic[block_c->pos_y][block_c->pos_x] >>1
        : refPic[block_c->pos_y][block_c->pos_x]) : -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)
    {
      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++)
  {
    if (!img->MbaffFrameFlag || hv == 0)
    {
      mv_a = block_a->available ? tmp_mv[block_a->pos_y][block_a->pos_x][hv] : 0;
      mv_b = block_b->available ? tmp_mv[block_b->pos_y][block_b->pos_x][hv] : 0;
      mv_c = block_c->available ? tmp_mv[block_c->pos_y][block_c->pos_x][hv] : 0;
    }
    else
    {
      if (currMB->mb_field)
      {
        mv_a = block_a->available  ? img->mb_data[block_a->mb_addr].mb_field
          ? tmp_mv[block_a->pos_y][block_a->pos_x][hv]
          : tmp_mv[block_a->pos_y][block_a->pos_x][hv] / 2
            : 0;
          mv_b = block_b->available  ? img->mb_data[block_b->mb_addr].mb_field
            ? tmp_mv[block_b->pos_y][block_b->pos_x][hv]
            : tmp_mv[block_b->pos_y][block_b->pos_x][hv] / 2
              : 0;
            mv_c = block_c->available  ? img->mb_data[block_c->mb_addr].mb_field
              ? tmp_mv[block_c->pos_y][block_c->pos_x][hv]
              : tmp_mv[block_c->pos_y][block_c->pos_x][hv] / 2
                : 0;
      }
      else
      {
        mv_a = block_a->available  ? img->mb_data[block_a->mb_addr].mb_field
          ? tmp_mv[block_a->pos_y][block_a->pos_x][hv] * 2
          : tmp_mv[block_a->pos_y][block_a->pos_x][hv]
          : 0;
          mv_b = block_b->available  ? img->mb_data[block_b->mb_addr].mb_field
            ? tmp_mv[block_b->pos_y][block_b->pos_x][hv] * 2
            : tmp_mv[block_b->pos_y][block_b->pos_x][hv]
            : 0;
            mv_c = block_c->available  ? img->mb_data[block_c->mb_addr].mb_field
              ? tmp_mv[block_c->pos_y][block_c->pos_x][hv] * 2
              : tmp_mv[block_c->pos_y][block_c->pos_x][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 - imin(mv_a, imin(mv_b, mv_c)) - imax(mv_a, imax(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;
    }

    pmv[hv] = (short) pred_vec;
  }
}


/*!
 ************************************************************************
 * \brief
 *    Read motion info
 ************************************************************************
 */
static void readMotionInfoFromNAL (ImageParameters *img, Slice *currSlice, Macroblock *currMB)
{
  int i,j,k;
  int mb_nr = img->current_mb_nr;
  SyntaxElement currSE;
  DataPartition *dP = NULL;
  byte *partMap       = assignSE2partition[currSlice->dp_mode];
  int bslice          = (img->type==B_SLICE);
  int partmode        = ((currMB->mb_type == P8x8) ? 4 : currMB->mb_type);
  int step_h0         = BLOCK_STEP [partmode][0];
  int step_v0         = BLOCK_STEP [partmode][1];

  int i0, j0, j6;

  int j4, i4, ii;
  PicMotionParams *motion = &dec_picture->motion;
  MotionParams *colocated;

  int mv_scale = 0;

  int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (mb_nr&0x01) ? 4 : 2 : 0;


  if (bslice)
  {
    if ((img->MbaffFrameFlag) && (currMB->mb_field))
    {
      if(mb_nr&0x01)
      {
        colocated = &Co_located->bottom;
      }
      else
      {
        colocated = &Co_located->top;
      }
    }
    else
    {
      colocated = &Co_located->frame;
    }

    if (currMB->mb_type == P8x8)
    {
      if (img->direct_spatial_mv_pred_flag)
      {
        char  l0_rFrame, l1_rFrame;
        short pmvl0[2]={0,0}, pmvl1[2]={0,0};

        prepare_direct_params(currMB, dec_picture, img, pmvl0, pmvl1, &l0_rFrame, &l1_rFrame);

        for (k = 0; k < 4; k++)
        {        
          if (currMB->b8mode[k] == 0)
          {
            i = img->block_x + 2 * (k & 0x01);
            for(j = 2 * (k >> 1); j < 2 * (k >> 1)+2;j++)
            {
              j6 = img->block_y_aff + j;
              j4 = img->block_y     + j;
              for(i4 = i; i4 < i + 2; i4++)
              {
                if (l0_rFrame >= 0)
                {
                  if  (!l0_rFrame  && ((!colocated->moving_block[j6][i4]) && (!listX[LIST_1 + list_offset][0]->is_long_term)))
                  {
                    motion->mv  [LIST_0][j4][i4][0] = 0;
                    motion->mv  [LIST_0][j4][i4][1] = 0;
                    motion->ref_idx[LIST_0][j4][i4] = 0;
                  }
                  else
                  {
                    motion->mv  [LIST_0][j4][i4][0] = pmvl0[0];
                    motion->mv  [LIST_0][j4][i4][1] = pmvl0[1];
                    motion->ref_idx[LIST_0][j4][i4] = l0_rFrame;
                  }
                }
                else
                {
                  motion->mv  [LIST_0][j4][i4][0] = 0;
                  motion->mv  [LIST_0][j4][i4][1] = 0;
                  motion->ref_idx[LIST_0][j4][i4] = -1;
                }

                if (l1_rFrame >= 0)
                {
                  if  (l1_rFrame==0 && ((!colocated->moving_block[j6][i4])&& (!listX[LIST_1 + list_offset][0]->is_long_term)))
                  {
                    motion->mv  [LIST_1][j4][i4][0] = 0;
                    motion->mv  [LIST_1][j4][i4][1] = 0;
                    motion->ref_idx[LIST_1][j4][i4] = 0;
                  }
                  else
                  {
                    motion->mv  [LIST_1][j4][i4][0] = pmvl1[0];
                    motion->mv  [LIST_1][j4][i4][1] = pmvl1[1];
                    motion->ref_idx[LIST_1][j4][i4] = l1_rFrame;
                  }
                }
                else
                {
                  motion->mv  [LIST_1][j4][i4][0] = 0;
                  motion->mv  [LIST_1][j4][i4][1] = 0;
                  motion->ref_idx[LIST_1][j4][i4] = -1;
                }

                if (l0_rFrame <0 && l1_rFrame <0)
                {
                  motion->ref_idx[LIST_0][j4][i4] = 0;
                  motion->ref_idx[LIST_1][j4][i4] = 0;
                }
              }
            }
          }
        }
      }
      else
      {
        for (k = 0; k < 4; k++) // Scan all blocks
        {
          if (currMB->b8mode[k] == 0)
          {
            for(j0 = 2 * (k >> 1); j0 < 2 * (k >> 1) + 2; j0 += step_v0)
            {
              for(i0 = img->block_x + 2*(k & 0x01); i0 < img->block_x + 2 * (k & 0x01)+2; i0 += step_h0)
              {
                int refList = colocated->ref_idx[LIST_0 ][img->block_y_aff + j0][i0]== -1 ? LIST_1 : LIST_0;
                int ref_idx = colocated->ref_idx[refList][img->block_y_aff + j0][i0];
                int mapped_idx = -1, iref;

                if (ref_idx == -1)
                {
                  for (j4 = img->block_y + j0; j4 < img->block_y + j0 + step_v0; j4++)
                  {
                    memset(&motion->ref_idx [LIST_0][j4]

⌨️ 快捷键说明

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