block.c

来自「the newest JM software by h.264 JVT offi」· C语言 代码 · 共 2,206 行 · 第 1/5 页

C
2,206
字号

  /*  Prediction according to 'diagonal' modes */
  if (block_available_left)
  {
    // Mode HOR_UP_PRED
    cur_pred = curr_mpr_4x4[HOR_UP_PRED];
    cur_pred[0][0] = (imgpel) ((P_I + P_J + 1) >> 1);
    cur_pred[0][1] = (imgpel) ((P_I + 2*P_J + P_K + 2) >> 2);
    cur_pred[0][2] =
    cur_pred[1][0] = (imgpel) ((P_J + P_K + 1) >> 1);
    cur_pred[0][3] =
    cur_pred[1][1] = (imgpel) ((P_J + 2*P_K + P_L + 2) >> 2);
    cur_pred[1][2] =
    cur_pred[2][0] = (imgpel) ((P_K + P_L + 1) >> 1);
    cur_pred[1][3] =
    cur_pred[2][1] = (imgpel) ((P_K + 2*P_L + P_L + 2) >> 2);
    cur_pred[3][0] =
    cur_pred[2][2] =
    cur_pred[2][3] =
    cur_pred[3][1] =
    cur_pred[3][2] =
    cur_pred[3][3] = (imgpel) P_L;
  }

  /*  Prediction according to 'diagonal' modes */
  if (block_available_up && block_available_left && block_available_up_left)
  {
    // Mode DIAG_DOWN_RIGHT_PRED
    cur_pred = curr_mpr_4x4[DIAG_DOWN_RIGHT_PRED];
    cur_pred[3][0] = (imgpel) ((P_L + 2*P_K + P_J + 2) >> 2);
    cur_pred[2][0] =
    cur_pred[3][1] = (imgpel) ((P_K + 2*P_J + P_I + 2) >> 2);
    cur_pred[1][0] =
    cur_pred[2][1] =
    cur_pred[3][2] = (imgpel) ((P_J + 2*P_I + P_X + 2) >> 2);
    cur_pred[0][0] =
    cur_pred[1][1] =
    cur_pred[2][2] =
    cur_pred[3][3] = (imgpel) ((P_I + 2*P_X + P_A + 2) >> 2);
    cur_pred[0][1] =
    cur_pred[1][2] =
    cur_pred[2][3] = (imgpel) ((P_X + 2*P_A + P_B + 2) >> 2);
    cur_pred[0][2] =
    cur_pred[1][3] = (imgpel) ((P_A + 2*P_B + P_C + 2) >> 2);
    cur_pred[0][3] = (imgpel) ((P_B + 2*P_C + P_D + 2) >> 2);

    // Mode VERT_RIGHT_PRED
    cur_pred = curr_mpr_4x4[VERT_RIGHT_PRED];
    cur_pred[0][0] =
    cur_pred[2][1] = (imgpel) ((P_X + P_A + 1) >> 1);
    cur_pred[0][1] =
    cur_pred[2][2] = (imgpel) ((P_A + P_B + 1) >> 1);
    cur_pred[0][2] =
    cur_pred[2][3] = (imgpel) ((P_B + P_C + 1) >> 1);
    cur_pred[0][3] = (imgpel) ((P_C + P_D + 1) >> 1);
    cur_pred[1][0] =
    cur_pred[3][1] = (imgpel) ((P_I + 2*P_X + P_A + 2) >> 2);
    cur_pred[1][1] =
    cur_pred[3][2] = (imgpel) ((P_X + 2*P_A + P_B + 2) >> 2);
    cur_pred[1][2] =
    cur_pred[3][3] = (imgpel) ((P_A + 2*P_B + P_C + 2) >> 2);
    cur_pred[1][3] = (imgpel) ((P_B + 2*P_C + P_D + 2) >> 2);
    cur_pred[2][0] = (imgpel) ((P_X + 2*P_I + P_J + 2) >> 2);
    cur_pred[3][0] = (imgpel) ((P_I + 2*P_J + P_K + 2) >> 2);

    // Mode HOR_DOWN_PRED
    cur_pred = curr_mpr_4x4[HOR_DOWN_PRED];
    cur_pred[0][0] =
    cur_pred[1][2] = (imgpel) ((P_X + P_I + 1) >> 1);
    cur_pred[0][1] =
    cur_pred[1][3] = (imgpel) ((P_I + 2*P_X + P_A + 2) >> 2);
    cur_pred[0][2] = (imgpel) ((P_X + 2*P_A + P_B + 2) >> 2);
    cur_pred[0][3] = (imgpel) ((P_A + 2*P_B + P_C + 2) >> 2);
    cur_pred[1][0] =
    cur_pred[2][2] = (imgpel) ((P_I + P_J + 1) >> 1);
    cur_pred[1][1] =
    cur_pred[2][3] = (imgpel) ((P_X + 2*P_I + P_J + 2) >> 2);
    cur_pred[2][0] =
    cur_pred[3][2] = (imgpel) ((P_J + P_K + 1) >> 1);
    cur_pred[2][1] =
    cur_pred[3][3] = (imgpel) ((P_I + 2*P_J + P_K + 2) >> 2);
    cur_pred[3][0] = (imgpel) ((P_K + P_L + 1) >> 1);
    cur_pred[3][1] = (imgpel) ((P_J + 2*P_K + P_L + 2) >> 2);
  }
}


/*!
 ************************************************************************
 * \brief
 *    16x16 based luma prediction
 *
 * \par Input:
 *    Image parameters
 *
 * \par Output:
 *    none
 ************************************************************************
 */
void intrapred_16x16(Macroblock *currMB, ColorPlane pl)
{
  int s0=0,s1,s2;
  imgpel s[2][16];
  int i,j;

  int ih,iv;
  int ib,ic,iaa;

  imgpel **img_enc = enc_picture->p_curr_img;
  imgpel ***curr_mpr_16x16   = img->mpr_16x16[pl];
  unsigned int dc_pred_value = img->dc_pred_value;

  PixelPos up;          //!< pixel position p(0,-1)
  PixelPos left[17];    //!< pixel positions p(-1, -1..15)

  int up_avail, left_avail, left_up_avail;
  int *mb_size = img->mb_size[IS_LUMA];

  for (i=0;i<17;i++)
  {
    getNeighbour(currMB, -1,  i-1, mb_size, &left[i]);
  }

  getNeighbour(currMB,    0,   -1, mb_size, &up);

  if (!(params->UseConstrainedIntraPred))
  {
    up_avail      = up.available;
    left_avail    = left[1].available;
    left_up_avail = left[0].available;
  }
  else
  {
    up_avail      = up.available ? img->intra_block[up.mb_addr] : 0;
    for (i=1, left_avail=1; i<17;i++)
      left_avail  &= left[i].available ? img->intra_block[left[i].mb_addr]: 0;
    left_up_avail = left[0].available ? img->intra_block[left[0].mb_addr]: 0;
  }

  s1=s2=0;
  // make DC prediction
  if (up_avail)
  {
    for (i=up.pos_x; i < up.pos_x + MB_BLOCK_SIZE; i++)
      s1 += img_enc[up.pos_y][i];    // sum hor pix
  }

  if (left_avail)
  {
    for (i=1; i < MB_BLOCK_SIZE + 1; i++)
      s2 += img_enc[left[i].pos_y][left[i].pos_x];    // sum vert pix
  }

  if (up_avail)
  {
    s0= left_avail
      ? rshift_rnd_sf((s1+s2),(MB_BLOCK_SHIFT + 1)) // no edge
      : rshift_rnd_sf(s1, MB_BLOCK_SHIFT);          // left edge
  }
  else
  {
    s0=left_avail
      ? rshift_rnd_sf(s2, MB_BLOCK_SHIFT)           // upper edge
      : dc_pred_value;                              // top left corner, nothing to predict from
  }

  // vertical prediction
  if (up_avail)
    memcpy(s[0], &img_enc[up.pos_y][up.pos_x], MB_BLOCK_SIZE * sizeof(imgpel));

  // horizontal prediction
  if (left_avail)
  {
    for (i=1; i < MB_BLOCK_SIZE + 1; i++)
      s[1][i - 1]=img_enc[left[i].pos_y][left[i].pos_x];
  }

  for (j=0; j < MB_BLOCK_SIZE; j++)
  {
    memcpy(curr_mpr_16x16[VERT_PRED_16][j], s[0], MB_BLOCK_SIZE * sizeof(imgpel)); // store vertical prediction
    for (i=0; i < MB_BLOCK_SIZE; i++)
    {
      curr_mpr_16x16[HOR_PRED_16 ][j][i] = s[1][j]; // store horizontal prediction
      curr_mpr_16x16[DC_PRED_16  ][j][i] = s0;      // store DC prediction
    }
  }
  
  if (!up_avail || !left_avail || !left_up_avail) // edge
    return;

  // 16 bit integer plan pred

  ih=0;
  iv=0;
  for (i=1;i<9;i++)
  {
    if (i<8)
      ih += i*(img_enc[up.pos_y][up.pos_x+7+i] - img_enc[up.pos_y][up.pos_x+7-i]);
    else
      ih += i*(img_enc[up.pos_y][up.pos_x+7+i] - img_enc[left[0].pos_y][left[0].pos_x]);

    iv += i*(img_enc[left[8+i].pos_y][left[8+i].pos_x] - img_enc[left[8-i].pos_y][left[8-i].pos_x]);
  }
  ib=(5*ih+32)>>6;
  ic=(5*iv+32)>>6;

  iaa=16*(img_enc[up.pos_y][up.pos_x+15]+img_enc[left[16].pos_y][left[16].pos_x]);

  for (j=0;j< MB_BLOCK_SIZE;j++)
  {
    for (i=0;i< MB_BLOCK_SIZE;i++)
    {
      curr_mpr_16x16[PLANE_16][j][i]= iClip1( img->max_imgpel_value, rshift_rnd_sf((iaa+(i-7)*ib +(j-7)*ic), 5));// store plane prediction
    }
  }
}


/*!
 ************************************************************************
 * \brief
 *    For new intra pred routines
 *
 * \par Input:
 *    Image par, 16x16 based intra mode
 *
 * \par Output:
 *    none
 ************************************************************************
 */
int dct_16x16(Macroblock *currMB, ColorPlane pl, int new_intra_mode, int is_cavlc)
{
  int i,j;
  int ii,jj;

  int ac_coef = 0;
  static imgpel *img_Y, *predY;
  int nonzero = FALSE;

  int   jpos, ipos;
  int   b8, b4;

  //begin the changes
  int   pl_off = pl<<2;
  int*  DCLevel = img->cofDC[pl][0];
  int*  DCRun   = img->cofDC[pl][1];
  int   ****cofAC = &img->cofAC[pl_off];
  int*  ACLevel;
  int*  ACRun;  
  int coeff_cost;
  imgpel **img_enc          = enc_picture->p_curr_img;
  int    max_imgpel_value   = img->max_imgpel_value;
  int    qp                 = currMB->qp_scaled[pl]; 
  const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN;
  imgpel  ***curr_mpr_16x16 = img->mpr_16x16[pl];

  int qp_per = qp_per_matrix[qp];
  int qp_rem = qp_rem_matrix[qp];

  // select scaling parameters
  levelscale    = LevelScale4x4Comp[pl][1][qp_rem];
  invlevelscale = InvLevelScale4x4Comp[pl][1][qp_rem];
  leveloffset   = ptLevelOffset4x4  [1][qp]; 

  fadjust4x4 = img->AdaptiveRounding ? (&img->ARCofAdj4x4[pl][I16MB][0]): NULL;

  for (j = 0; j < 16; j++)
  {
    predY = curr_mpr_16x16[new_intra_mode][j];
    img_Y = &pCurImg[img->opix_y + j][img->opix_x];
    for (i = 0; i < 16; i++)
    {
      M1[j][i] = img_Y[i] - predY[i];
    }
  }

  // forward 4x4 DCT
  for (j = 0; j < 16; j+=4)
  {
    for (i = 0;i < 16; i+=4)
    {
      forward4x4(M1, M1, j, i);
    }
  }

  // pick out DC coeff
  for (j = 0; j < 4; j++)
    for (i = 0; i < 4; i++)
      M4[j][i]= M1[j << 2][i << 2];

  // hadamard of DC coefficients
  hadamard4x4(M4, M4);

  nonzero = quant_dc4x4(&M4[0], qp, DCLevel, DCRun, levelscale[0][0], invlevelscale[0][0], leveloffset[0][0], pos_scan, is_cavlc);


  // inverse DC transform
  if (nonzero)
  {
    ihadamard4x4(M4, M4);

    // Reset DC coefficients
    for (j = 0; j < MB_BLOCK_SIZE; j += BLOCK_SIZE)
    {
      for (i = 0; i < MB_BLOCK_SIZE;i += BLOCK_SIZE)
      {
        M1[j][i] = rshift_rnd_sf(((M4[j>>2][i>>2]) * invlevelscale[0][0]) << qp_per, 6);
      }
    }
  }
  else // All DC equal to 0.
  {
    for (j = 0; j < MB_BLOCK_SIZE; j += BLOCK_SIZE)
    {
      for (i = 0; i < MB_BLOCK_SIZE; i += BLOCK_SIZE)
      {
        M1[j][i] = 0;
      }
    }
  }

  // AC processing for MB
  for (jj=0;jj<4;jj++)
  {
    jpos = (jj << 2);
    for (ii=0;ii<4;ii++)
    {
      ipos = (ii << 2);

      b8       = 2*(jj >> 1) + (ii >> 1);
      b4       = 2*(jj & 0x01) + (ii & 0x01);
      ACLevel  = cofAC[b8][b4][0];
      ACRun    = cofAC[b8][b4][1];
      img->subblock_y = jj;
      img->subblock_x = ii;

      // Quantization process
      nonzero = quant_ac4x4(&M1[jpos], jpos, ipos, qp, ACLevel, ACRun, &fadjust4x4[jpos], 
        levelscale, invlevelscale, leveloffset, &coeff_cost, pos_scan, COEFF_COST4x4[params->disthres], LUMA_16AC, is_cavlc);

      if (nonzero)
        ac_coef = 15;

      //IDCT
      if (M1[jpos][ipos]!= 0 || nonzero)
        inverse4x4(M1, M1, jpos, ipos);
    }
  }


    // Reconstruct samples
    SampleReconstruct (img_enc, curr_mpr_16x16[new_intra_mode], M1, 0, 0, img->pix_y, img->pix_x, 16, 16, max_imgpel_value, DQ_BITS);

  if(img->type == SP_SLICE)
  {
    for (j = img->pix_y; j < img->pix_y + 16;j++)
      for (i = img->pix_x; i < img->pix_x + 16;i++)
        lrec[j][i]=-16; //signals an I16 block in the SP frame
  }

  return ac_coef;
}


/*!
 ************************************************************************
 * \brief
 *    For new intra pred routines
 *
 * \par Input:
 *    Image par, 16x16 based intra mode
 *
 * \par Output:
 *    none
 ************************************************************************
 */
int dct_16x16_ls(Macroblock *currMB, ColorPlane pl, int new_intra_mode, int is_cavlc)
{
  int i,j;
  int ii,jj;

  int run,scan_pos,coeff_ctr;
  int ac_coef = 0;
  static imgpel *img_Y, *predY;

  int   b8, b4;

  //begin the changes
  int   pl_off = pl<<2;
  int*  DCLevel = img->cofDC[pl][0];
  int*  DCRun   = img->cofDC[pl][1];
  int*  ACLevel;
  int*  ACRun;  
  imgpel **img_enc = enc_picture->p_curr_img;
  int   *m7;

  const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN;
  imgpel  ***curr_mpr_16x16  = img->mpr_16x16[pl];

  for (j = 0; j < 16; j++)
  {
    predY = curr_mpr_16x16[new_intra_mode][j];
    img_Y = &pCurImg[img->opix_y + j][img->opix_x];
    for (i = 0; i < 16; i++)
    {
      M1[j][i] = img_Y[i] - predY[i];
    }
  }
  // pick out DC coeff
  for (j = 0; j < 4;j++)
    for (i = 0; i < 4;i++)
      M4[j][i]= M1[j << 2][i << 2];

  run=-1;
  scan_pos=0;

  for (coeff_ctr=0;coeff_ctr<16;coeff_ctr++)
  {
    i=pos_scan[coeff_ctr][0];
    j=pos_scan[coeff_ctr][1];

    run++;

    m7 = &M4[j][i];

    if (*m7 != 0)
    {
      if (is_cavlc)
        *m7 = iClip3(-CAVLC_LEVEL_LIMIT, CAVLC_LEVEL_LIMIT, *m7);

      DCLevel[scan_pos  ] = *m7;
      DCRun  [scan_pos++] = run;
      run=-1;
    }
  }
  DCLevel[scan_pos]=0;

  // replace DC coeff. This is needed in case of out of limits for CAVLC. Could be done only for CAVLC
  for (j = 0; j < 4;j++)
    for (i = 0; i < 4;i++)
      M1[j << 2][i << 2] = M4[j][i];

⌨️ 快捷键说明

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