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

📄 macroblock.c

📁 比较老的264解码器baseline实现
💻 C
📖 第 1 页 / 共 5 页
字号:
      offset = -7;
  }

  for (*cr_cbp=0, uv=0; uv<2; uv++)
  {
    //===== prediction of chrominance blocks ===d==
    block8 = 0;
    for (block_y=0; block_y<8; block_y+=4)
    for (block_x=0; block_x<8; block_x+=4, block8++)
    {
      SetModesAndRefframe (block8, &fw_mode, &bw_mode, &refframe, &bw_ref);

      ChromaPrediction4x4 (uv, block_x, block_y, fw_mode, bw_mode, refframe, bw_ref);
    }

        // ==== set chroma residue to zero for skip Mode in SP frames 
    if (img->NoResidueDirect)
      for (j=0; j<8; j++)
        for (i=0; i<8; i++)
        {
          enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x+i] = img->mpr[i][j];
        }
        else
    if (skipped && img->type==SP_SLICE)
      for (j=0; j<8; j++)
        for (i=0; i<8; i++)
        {
          img->m7[i][j] = 0;
        }
    else
    if (skipped)
    {
      for (j=0; j<8; j++)
        for (i=0; i<8; i++)
        {
          enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x+i] = img->mpr[i][j];
        }
    }
    else
      for (j=0; j<8; j++)
        for (i=0; i<8; i++)
        {
          img->m7[i][j] = imgUV_org[uv][img->pix_c_y+(j*incr)+offset][img->pix_c_x+i] - img->mpr[i][j];
        }

    //===== DCT, Quantization, inverse Quantization, IDCT, and Reconstruction =====
    //===== Call function for skip mode in SP frames to properly process frame ====
    
    if (skipped && img->type==SP_SLICE)
    {
        *cr_cbp=dct_chroma_sp(uv,*cr_cbp);
    }
    else
    if (!img->NoResidueDirect && !skipped)
    {
      if (img->type!=SP_SLICE || IS_INTRA (&img->mb_data[img->current_mb_nr]))
        *cr_cbp=dct_chroma   (uv,*cr_cbp);
      else
        *cr_cbp=dct_chroma_sp(uv,*cr_cbp);
    }
  }

  //===== update currMB->cbp =====
  img->mb_data[img->current_mb_nr].cbp += ((*cr_cbp)<<4);  
}


/*!
 ************************************************************************
 * \brief
 *    Predict an intra chroma 8x8 block
 ************************************************************************
 */
void IntraChromaPrediction8x8 (int *mb_up, int *mb_left, int*mb_up_left)
{
  Macroblock *currMB = &img->mb_data[img->current_mb_nr];
  int     s, s0, s1, s2, s3, i, j, k;
  pel_t** image;
  int     block_x, block_y, b4;
  int     img_cx            = img->pix_c_x;
  int     img_cy            = img->pix_c_y;
  int     img_cx_1          = img->pix_c_x-1;
  int     img_cx_4          = img->pix_c_x+4;
  int     img_cy_1          = img->pix_c_y-1;
  int     img_cy_4          = img->pix_c_y+4;
  int     mb_nr             = img->current_mb_nr;
  int     mb_width          = img->width/16;
  int     mb_available_up   = (img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width].slice_nr);
  int     mb_available_left = (img_cx/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-1]       .slice_nr);
  int     mb_available_up_left = (img_cx/BLOCK_SIZE == 0 || img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width-1].slice_nr);
  int     ih,iv;
  int     ib,ic,iaa;
  int     uv;
  int     hline[8], vline[8];
  int     mode;
  int     best_mode = DC_PRED_8;         //just an initilaization here, should always be overwritten
  int     cost;
  int     min_cost;
  int     diff[16];

  if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
  {
    img_cy   = img->field_pix_c_y;
    img_cy_1 = img->field_pix_c_y-1;
    img_cy_4 = img->field_pix_c_y+4;
    mb_available_up = (img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width].slice_nr);
    mb_available_up_left = (img_cx/BLOCK_SIZE == 0 || img_cy/BLOCK_SIZE == 0) ? 0 : (img->mb_data[mb_nr].slice_nr==img->mb_data[mb_nr-mb_width-1].slice_nr);
  }

  if(input->UseConstrainedIntraPred)
  {
    /*
    if (mb_available_up   && (img->intra_block[mb_nr-mb_width][2]==0 || img->intra_block[mb_nr-mb_width][3]==0))
      mb_available_up   = 0;
    if (mb_available_left && (img->intra_block[mb_nr-       1][1]==0 || img->intra_block[mb_nr       -1][3]==0))
      mb_available_left = 0;
    if (mb_available_up_left && (img->intra_block[mb_nr-mb_width-1][3]==0))
      mb_available_up_left = 0;
      */
  }

  if (mb_up)
    *mb_up = mb_available_up;
  if (mb_left)
    *mb_left = mb_available_left;
  if( mb_up_left )
    *mb_up_left = mb_available_up_left;

  // compute all chroma intra prediction modes for both U and V
  for (uv=0; uv<2; uv++)
  {
/*    if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
    {
      if(img->top_field)
        image = imgUV_top[uv];
      else
        image = imgUV_bot[uv];
    }
    else
*/
    image = enc_picture->imgUV[uv];

    // DC prediction
    for (block_y=0; block_y<8; block_y+=4)
    for (block_x=0; block_x<8; block_x+=4)
    {
      s=128;
      s0=s1=s2=s3=0;
      //===== get prediction value =====
      switch ((block_y>>1) + (block_x>>2))
      {
      case 0:  //===== TOP LEFT =====
        if      (mb_available_up)    for (i=0;i<4;i++)  s0 += image[img_cy_1  ][img_cx  +i];
        if      (mb_available_left)  for (i=0;i<4;i++)  s2 += image[img_cy  +i][img_cx_1  ];
        if      (mb_available_up && mb_available_left)  s  = (s0+s2+4) >> 3;
        else if (mb_available_up)                       s  = (s0   +2) >> 2;
        else if (mb_available_left)                     s  = (s2   +2) >> 2;
        break;
      case 1: //===== TOP RIGHT =====
        if      (mb_available_up)    for (i=0;i<4;i++)  s1 += image[img_cy_1  ][img_cx_4+i];
        else if (mb_available_left)  for (i=0;i<4;i++)  s2 += image[img_cy  +i][img_cx_1  ];
        if      (mb_available_up)                       s  = (s1   +2) >> 2;
        else if (mb_available_left)                     s  = (s2   +2) >> 2;
        break;
      case 2: //===== BOTTOM LEFT =====
        if      (mb_available_left)  for (i=0;i<4;i++)  s3 += image[img_cy_4+i][img_cx_1  ];
        else if (mb_available_up)    for (i=0;i<4;i++)  s0 += image[img_cy_1  ][img_cx  +i];
        if      (mb_available_left)                     s  = (s3   +2) >> 2;
        else if (mb_available_up)                       s  = (s0   +2) >> 2;
        break;
      case 3: //===== BOTTOM RIGHT =====
        if      (mb_available_up)    for (i=0;i<4;i++)  s1 += image[img_cy_1  ][img_cx_4+i];
        if      (mb_available_left)  for (i=0;i<4;i++)  s3 += image[img_cy_4+i][img_cx_1  ];
        if      (mb_available_up && mb_available_left)  s  = (s1+s3+4) >> 3;
        else if (mb_available_up)                       s  = (s1   +2) >> 2;
        else if (mb_available_left)                     s  = (s3   +2) >> 2;
        break;
      }

      //===== prediction =====
      for (j=block_y; j<block_y+4; j++)
      for (i=block_x; i<block_x+4; i++)
      {
        img->mprr_c[uv][DC_PRED_8][i][j] = s;
      }
    }

    // vertical prediction
    if (mb_available_up)
    {
      for (i=0; i<8; i++)
        hline[i] = image[img_cy_1][img_cx+i];
      for (i=0; i<8; i++)
      for (j=0; j<8; j++)
        img->mprr_c[uv][VERT_PRED_8][i][j] = hline[i];
    }

    // horizontal prediction
    if (mb_available_left)
    {
      for (i=0; i<8; i++)
        vline[i] = image[img_cy+i][img_cx_1];
      for (i=0; i<8; i++)
      for (j=0; j<8; j++)
        img->mprr_c[uv][HOR_PRED_8][i][j] = vline[j];
    }

    // plane prediction
    if (mb_available_up_left)
    {
      ih = 4*(hline[7] - image[img_cy_1][img_cx_1]);
      iv = 4*(vline[7] - image[img_cy_1][img_cx_1]);
      for (i=1;i<4;i++)
      {
        ih += i*(hline[3+i] - hline[3-i]);
        iv += i*(vline[3+i] - vline[3-i]);
      }
      ib=(17*ih+16)>>5;
      ic=(17*iv+16)>>5;

      iaa=16*(hline[7]+vline[7]);
      for (j=0; j<8; j++)
      for (i=0; i<8; i++)
        img->mprr_c[uv][PLANE_8][i][j]=max(0,min(255,(iaa+(i-3)*ib +(j-3)*ic + 16)/32));// store plane prediction
    }
  }

  if (!input->rdopt) // the rd-opt part does not work correctly (see encode_one_macroblock)
  {                       // since ipredmodes could be overwritten => encoder-decoder-mismatches
    // pick lowest cost prediction mode
    min_cost = 1<<20;
    for (mode=DC_PRED_8; mode<=PLANE_8; mode++)
    {
      if ((mode==VERT_PRED_8 && !mb_available_up) ||
          (mode==HOR_PRED_8 && !mb_available_left) ||
          (mode==PLANE_8 && (!mb_available_left || !mb_available_up || !mb_available_up_left)))
        continue;

      cost = 0;
      for (uv=0; uv<2; uv++)
      {
        if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
        {
          if(img->top_field)
            image = imgUV_org_top[uv];
          else
            image = imgUV_org_bot[uv];
        }
        else
          image = imgUV_org[uv];
        for (b4=0,block_y=0; block_y<8; block_y+=4)
        for (block_x=0; block_x<8; block_x+=4,b4++)
        {
          for (k=0,j=block_y; j<block_y+4; j++)
          for (i=block_x; i<block_x+4; i++,k++)
          {
            diff[k] = image[img_cy+j][img_cx+i] - img->mprr_c[uv][mode][i][j];
          }
          cost += SATD(diff, input->hadamard);
        }
      }
      if (cost < min_cost)
      {
        best_mode = mode;
        min_cost = cost;
      }
    }

    currMB->c_ipred_mode = best_mode;
  }
}


/*!
 ************************************************************************
 * \brief
 *    Set reference frame information in global arrays
 *    depending on mode decision. Used for motion vector prediction.
 ************************************************************************
 */
void SetRefFrameInfo(int refframe, int bwrefframe)
{
  int i,j;

  if (img->type!=B_SLICE)
  {
      for (j=0; j<4; j++)
      for (i=0; i<4; i++)
      {
        refFrArr[img->block_y+j][img->block_x+i] = refframe;
      }
  }
  else
  {
    for (j=0; j<4; j++)
    for (i=0; i<4; i++)
    {
      fw_refFrArr[img->block_y+j][img->block_x+i] = refframe;
      bw_refFrArr[img->block_y+j][img->block_x+i] = bwrefframe;
    }
  }
}




/*!
 ************************************************************************
 * \brief
 *    Check if all reference frames for a macroblock are zero
 ************************************************************************
 */
int
ZeroRef (Macroblock* currMB)
{
  int i,j;
  int block_y = img->block_y;
  int **frefarr = refFrArr;
  
  if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
  {
    block_y = img->field_block_y;
    frefarr = (img->top_field ? refFrArr_top:refFrArr_bot);
  }

  for (j=0; j<4; j++)
  for (i=0; i<4; i++)
  {
    if (frefarr[block_y+j][img->block_x+i]!=0)
    {
        return 0;
    }
  }
  return 1;
}


/*!
 ************************************************************************
 * \brief
 *    Converts macroblock type to coding value
 ************************************************************************
 */
int
MBType2Value (Macroblock* currMB)
{
  static const int dir1offset[3]    =  { 1,  2, 3};
  static const int dir2offset[3][3] = {{ 0,  4,  8},   // 1. block forward
                                       { 6,  2, 10},   // 1. block backward
                                       {12, 14, 16}};  // 1. block bi-directional

  int mbtype, pdir0, pdir1;

  if (img->type!=B_SLICE && img->type!=BS_IMG)
  {
    if      (currMB->mb_type==I4MB)     return (img->type==I_SLICE ? 0 : 6);
    else if (currMB->mb_type==I16MB)    return (img->type==I_SLICE ? 0 : 6) + img->i16offset;
    else if (currMB->mb_type==P8x8)
    {
      if (input->symbol_mode==UVLC && ZeroRef (currMB))  return 5;
      else                                               return 4;
    }
    else                                return currMB->mb_type;
  }
  else
  {
    mbtype = currMB->mb_type;
  

⌨️ 快捷键说明

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