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

📄 mc_prediction.c

📁 the newest JM software by h.264 JVT official reference model.
💻 C
📖 第 1 页 / 共 3 页
字号:
  }
  else
  {
    if (p_dir==2)
    {
      MCBiPrediction(&mb_pred[block_y], l0_pred, l1_pred, BLOCK_SIZE, block_x, BLOCK_SIZE);
    }
    else if (p_dir==0)
    {
      MCPrediction(&mb_pred[block_y], l0_pred, BLOCK_SIZE, block_x, BLOCK_SIZE);
    }
    else // (p_dir==1)
    {
      MCPrediction(&mb_pred[block_y], l1_pred, BLOCK_SIZE, block_x, BLOCK_SIZE);
    }
  }
}


/*!
 ************************************************************************
 * \brief
 *    Intra prediction of the chrminance layers of one macroblock
 ************************************************************************
 */
void IntraChromaPrediction (Macroblock *currMB, int *mb_up, int *mb_left, int*mb_up_left)
{
  static int s, s0, s1, s2, s3, i, j, k;
  static int ih,iv, ib, ic, iaa;
  int      uv;
  int      blk_x, blk_y;
  int      b8,b4;
  imgpel**  image;
  imgpel   vline[16];
  int      block_x, block_y;
  int      mb_available_up;
  int      mb_available_left[2];
  int      mb_available_up_left;

  int      mode;
  int      best_mode = DC_PRED_8;  //just an initilaization here, should always be overwritten
  int      cost;
  int      min_cost;
  PixelPos up;        //!< pixel position  p(0,-1)
  PixelPos left[17];  //!< pixel positions p(-1, -1..15)
  int      cr_MB_x = img->mb_cr_size_x;
  int      cr_MB_y = img->mb_cr_size_y;
  static imgpel **cur_pred;
  static imgpel ***curr_mpr_16x16;
  static imgpel *hline;
  static imgpel *img_org, *img_prd;

  int      yuv = img->yuv_format - 1;
  int      dc_pred_value_chroma = img->dc_pred_value_comp[1];
  int      max_imgpel_value_uv  = img->max_imgpel_value_comp[1];

  static const int block_pos[3][4][4]= //[yuv][b8][b4]
  {
    { {0, 1, 2, 3},{0, 0, 0, 0},{0, 0, 0, 0},{0, 0, 0, 0}},
    { {0, 1, 2, 3},{2, 3, 2, 3},{0, 0, 0, 0},{0, 0, 0, 0}},
    { {0, 1, 2, 3},{1, 1, 3, 3},{2, 3, 2, 3},{3, 3, 3, 3}}
  };

  for (i=0;i<cr_MB_y+1;i++)
  {
    getNeighbour(currMB, -1 , i-1 , img->mb_size[IS_CHROMA], &left[i]);
  }
  getNeighbour(currMB, 0 , -1 , img->mb_size[IS_CHROMA], &up);

  mb_available_up                             = up.available;
  mb_available_up_left                        = left[0].available;
  mb_available_left[0] = mb_available_left[1] = left[1].available;

  if(params->UseConstrainedIntraPred)
  {
    mb_available_up = up.available ? img->intra_block[up.mb_addr] : 0;
    for (i=0, mb_available_left[0]=1; i<(cr_MB_y>>1);i++)
      mb_available_left[0]  &= left[i+1].available ? img->intra_block[left[i+1].mb_addr]: 0;
    for (i=(cr_MB_y>>1), mb_available_left[1]=1; i<cr_MB_y;i++)
      mb_available_left[1] &= left[i+1].available ? img->intra_block[left[i+1].mb_addr]: 0;
    mb_available_up_left = left[0].available ? img->intra_block[left[0].mb_addr]: 0;
  }

  if (mb_up)
    *mb_up = mb_available_up;
  if (mb_left)
    *mb_left = mb_available_left[0] && mb_available_left[1];
  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++)
  {
    image          = enc_picture->imgUV[uv];
    curr_mpr_16x16 = img->mpr_16x16[uv + 1];

    // DC prediction
    for(b8=0; b8<img->num_blk8x8_uv >> 1;b8++)
    {
      for (b4 = 0; b4 < 4; b4++)
      {
        block_y = subblk_offset_y[yuv][b8][b4];
        block_x = subblk_offset_x[yuv][b8][b4];
        blk_x = block_x;
        blk_y = block_y + 1;

        s = dc_pred_value_chroma;
        s0 = s1 = s2 = s3 = 0;

        //===== get prediction value =====
        switch (block_pos[yuv][b8][b4])
        {
        case 0:  //===== TOP LEFT =====
          if      (mb_available_up)       
            for (i=blk_x;i<(blk_x+4);i++)  
              s0 += image[up.pos_y][up.pos_x + i];
          if      (mb_available_left[0])  
            for (i=blk_y;i<(blk_y+4);i++)  
              s2 += image[left[i].pos_y][left[i].pos_x];
          if      (mb_available_up && mb_available_left[0])  
            s  = (s0+s2+4) >> 3;
          else if (mb_available_up)                          
            s  = (s0   +2) >> 2;
          else if (mb_available_left[0])                     
            s  = (s2   +2) >> 2;
          break;
        case 1: //===== TOP RIGHT =====
          if      (mb_available_up)       
            for (i=blk_x;i<(blk_x+4);i++)  
              s1 += image[up.pos_y][up.pos_x + i];
          else if (mb_available_left[0])  
            for (i=blk_y;i<(blk_y+4);i++) 
              s2 += image[left[i].pos_y][left[i].pos_x];
          if      (mb_available_up)       
            s  = (s1   +2) >> 2;
          else if (mb_available_left[0])                    
            s  = (s2   +2) >> 2;
          break;
        case 2: //===== BOTTOM LEFT =====
          if      (mb_available_left[1])  
            for (i=blk_y;i<(blk_y+4);i++)  
              s3 += image[left[i].pos_y][left[i].pos_x];
          else if (mb_available_up)       
            for (i=blk_x;i<(blk_x+4);i++)  
              s0 += image[up.pos_y][up.pos_x + i];
          if      (mb_available_left[1])                     
            s  = (s3   +2) >> 2;
          else if (mb_available_up)                          
            s  = (s0   +2) >> 2;
          break;
        case 3: //===== BOTTOM RIGHT =====
          if      (mb_available_up)       
            for (i=blk_x;i<(blk_x+4);i++)  
              s1 += image[up.pos_y][up.pos_x + i];
          if      (mb_available_left[1])  
            for (i=blk_y;i<(blk_y+4);i++)  
              s3 += image[left[i].pos_y][left[i].pos_x];
          if      (mb_available_up && mb_available_left[1])  
            s  = (s1+s3+4) >> 3;
          else if (mb_available_up)                          
            s  = (s1   +2) >> 2;
          else if (mb_available_left[1])                     
            s  = (s3   +2) >> 2;
          break;
        }

        //===== prediction =====
        cur_pred = curr_mpr_16x16[DC_PRED_8];
        for (j=block_y; j<block_y+4; j++)
          for (i=block_x; i<block_x+4; i++)
          {
            cur_pred[j][i] = s;
          }
      }
    }

    // vertical prediction    
    if (mb_available_up)
    {
      cur_pred = curr_mpr_16x16[VERT_PRED_8];
      //memcpy(hline,&image[up.pos_y][up.pos_x], cr_MB_x * sizeof(imgpel));
      hline = &image[up.pos_y][up.pos_x];
      for (j=0; j<cr_MB_y; j++)
        memcpy(cur_pred[j], hline, cr_MB_x * sizeof(imgpel));
    }

    // horizontal prediction
    if (mb_available_left[0] && mb_available_left[1])
    {
      cur_pred = curr_mpr_16x16[HOR_PRED_8];
      for (i=0; i<cr_MB_y; i++)
        vline[i] = image[left[i+1].pos_y][left[i+1].pos_x];
      for (j=0; j<cr_MB_y; j++)
      {
        int predictor = vline[j];
        for (i=0; i<cr_MB_x; i++)        
          cur_pred[j][i] = predictor;
      }
    }

    // plane prediction
    if (mb_available_left[0] && mb_available_left[1] && mb_available_up && mb_available_up_left)
    {
      ih = (cr_MB_x>>1)*(hline[cr_MB_x-1] - image[left[0].pos_y][left[0].pos_x]);
      for (i=0;i<(cr_MB_x>>1)-1;i++)
        ih += (i+1)*(hline[(cr_MB_x>>1)+i] - hline[(cr_MB_x>>1)-2-i]);

      iv = (cr_MB_y>>1)*(vline[cr_MB_y-1] - image[left[0].pos_y][left[0].pos_x]);
      for (i=0;i<(cr_MB_y>>1)-1;i++)
        iv += (i+1)*(vline[(cr_MB_y>>1)+i] - vline[(cr_MB_y>>1)-2-i]);

      ib= ((cr_MB_x == 8?17:5)*ih+2*cr_MB_x)>>(cr_MB_x == 8?5:6);
      ic= ((cr_MB_y == 8?17:5)*iv+2*cr_MB_y)>>(cr_MB_y == 8?5:6);

      iaa=16*(hline[cr_MB_x-1] + vline[cr_MB_y-1]);
      cur_pred = curr_mpr_16x16[PLANE_8];
      for (j=0; j<cr_MB_y; j++)
        for (i=0; i<cr_MB_x; i++)
          cur_pred[j][i]= iClip1( max_imgpel_value_uv, (iaa+(i-(cr_MB_x>>1)+1)*ib+(j-(cr_MB_y>>1)+1)*ic+16)>>5);
    }
  }

  if (!params->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 = INT_MAX;
    for (i=0;i<cr_MB_y;i++)
    {
      getNeighbour(currMB, 0 , i, img->mb_size[IS_CHROMA], &left[i]);
    }

    if ( img->MbaffFrameFlag && img->field_mode )
    {
      for (i=0;i<cr_MB_y;i++)
      {
        left[i].pos_y = left[i].pos_y >> 1;
      }
    }

    for (mode=DC_PRED_8; mode<=PLANE_8; mode++)
    {
      if ((img->type != I_SLICE || !params->IntraDisableInterOnly) && params->ChromaIntraDisable == 1 && mode!=DC_PRED_8)
        continue;

      if ((mode==VERT_PRED_8 && !mb_available_up) ||
        (mode==HOR_PRED_8 && (!mb_available_left[0] || !mb_available_left[1])) ||
        (mode==PLANE_8 && (!mb_available_left[0] || !mb_available_left[1] || !mb_available_up || !mb_available_up_left)))
        continue;

      cost = 0;
      for (uv = 1; uv < 3; uv++)
      {
        image = pImgOrg[uv];
        curr_mpr_16x16 = img->mpr_16x16[uv];
        for (block_y=0; block_y<cr_MB_y; block_y+=4)
          for (block_x = 0; block_x < cr_MB_x; block_x += 4)
          {
            for (k=0, j = block_y; j < block_y + 4; j++)
            {
              img_prd = curr_mpr_16x16[mode][j];
              img_org = &image[left[j].pos_y][left[j].pos_x];
              for (i = block_x; i < block_x + 4; i++)
                diff[k++] = img_org[i] - img_prd[i];
            }
            cost += distortion4x4(diff);
          }
      }
      if (cost < min_cost)
      {
        best_mode = mode;
        min_cost = cost;
      }
    }
    currMB->c_ipred_mode = best_mode;
  }
}

void ComputeResidue (imgpel **curImg, imgpel **mpr, int **mb_rres, int mb_y, int mb_x, int opix_y, int opix_x, int width, int height)
{
  static imgpel *imgOrg, *imgPred;
  static int    *m7;
  int i, j;

  for (j = mb_y; j < mb_y + height; j++)
  {
    imgOrg = &curImg[opix_y + j][opix_x];    
    imgPred = &mpr[j][mb_x];
    m7 = &mb_rres[j][mb_x]; 
    for (i = 0; i < width; i++)
    {
      *m7++ = *imgOrg++ - *imgPred++;
    }
  }
}

void SampleReconstruct (imgpel **curImg, imgpel **mpr, int **mb_rres, int mb_y, int mb_x, int opix_y, int opix_x, int width, int height, int max_imgpel_value, int dq_bits)
{
  static imgpel *imgOrg, *imgPred;
  static int    *m7;
  int i, j;

  for (j = mb_y; j < mb_y + height; j++)
  {
    imgOrg = &curImg[opix_y + j][opix_x];
    imgPred = &mpr[j][mb_x];
    m7 = &mb_rres[j][mb_x]; 
    for (i=0;i<width;i++)
      *imgOrg++ = iClip1( max_imgpel_value, rshift_rnd_sf(*m7++, dq_bits) + *imgPred++);
  }
}


⌨️ 快捷键说明

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