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

📄 block.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 5 页
字号:
  {
    i = pos_scan[coeff_ctr][0];
    j = pos_scan[coeff_ctr][1];

    run++;
    ilev=0;

    // decide prediction

    // case 1
    level1 = (iabs (M1[j][i]) * levelscale_sp[j][i] + qp_const2) >> q_bits_sp;
    level1 = (level1 << q_bits_sp) / levelscale_sp[j][i];
    c_err1 = mb_rres[j][i] - isignab(level1, M1[j][i]);
    level1 = (iabs (c_err1) * levelscale[j][i] + qp_const) >> q_bits;

    // case 2
    c_err2 = mb_rres[j][i] - M1[j][i];
    level2 = (iabs (c_err2) * levelscale[j][i] + qp_const) >> q_bits;

    // select prediction
    if ((level1 != level2) && (level1 != 0) && (level2 != 0))
    {
      D_dis1 = mb_rres[j][i] - ((isignab(level1,c_err1) * invlevelscale[j][i] * A[j][i]<< qp_per) >>6) - M1[j][i];
      levrun_linfo_inter(level1, run, &len, &info);
      D_dis1 = D_dis1 * D_dis1 + lambda_mode * len;

      D_dis2 = mb_rres[j][i] - ((isignab(level2,c_err2)*invlevelscale[j][i] * A[j][i]<< qp_per) >>6) - M1[j][i];
      levrun_linfo_inter(level2, run, &len, &info);
      D_dis2 = D_dis2 * D_dis2 + lambda_mode * len;

      if (D_dis1 == D_dis2)
        level = (iabs(level1) < iabs(level2)) ? level1 : level2;
      else if (D_dis1 < D_dis2)
        level = level1;
      else
        level = level2;

      c_err = (level == level1) ? c_err1 : c_err2;
    }
    else if (level1 == level2)
    {
      level = level1;
      c_err = c_err1;
    }
    else
    {
      level = (level1 == 0) ? level1 : level2;
      c_err = (level1 == 0) ? c_err1 : c_err2;
    }

    if (level != 0)
    {
      nonzero = TRUE;

      *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run];

      level = isignab(level,c_err);
      ACLevel[scan_pos] = level;
      ACRun  [scan_pos] = run;
      ++scan_pos;
      run=-1;                     // reset zero level counter
      ilev=((level * invlevelscale[j][i] * A[j][i] << qp_per) >>6);
    }

    ilev += M1[j][i];

    if(!si_frame_indicator && !sp2_frame_indicator)//stores the SP frame coefficients in lrec, will be useful to encode these and create SI or SP switching frame
    {
      lrec[img->pix_y+block_y+j][img->pix_x+block_x+i]=
        isignab((iabs(ilev) * levelscale_sp[j][i] + qp_const2) >> q_bits_sp, ilev);
    }    
    mb_rres[j][i] = isignab((iabs(ilev) * levelscale_sp[j][i] + qp_const2)>> q_bits_sp, ilev) * invlevelscale_sp[j][i] << qp_per_sp;
  }
  ACLevel[scan_pos] = 0;

  // inverse transform
  // inverse4x4(mb_rres, mb_rres, block_y, block_x);
  inverse4x4(M1, mb_rres, 0, 0);

  for (j=0; j < BLOCK_SIZE; j++)
    for (i=0; i < BLOCK_SIZE; i++)
    {
      //printf("%d ",mb_rres[j][i]);
      mb_rres[j][i] = iClip1 (img->max_imgpel_value, rshift_rnd_sf(mb_rres[j][i], DQ_BITS));
       //printf("%d\n",mb_rres[j][i]);
    }

  //  Decoded block moved to frame memory
  for (j=0; j < BLOCK_SIZE; j++)
  {
    for (i=0; i < BLOCK_SIZE; i++)
    {
      img_enc[img->pix_y+block_y+j][img->pix_x+block_x+i]= (imgpel) mb_rres[j][i];
  //printf("%d\n",mb_rres[j][i]);
    }
  }
  return nonzero;
}

/*!
 ************************************************************************
 * \brief
 *    Transform,quantization,inverse transform for chroma.
 *    The main reason why this is done in a separate routine is the
 *    additional 2x2 transform of DC-coeffs. This routine is called
 *    once for each of the chroma components.
 *
 * \par Input:
 *    uv    : Make difference between the U and V chroma component               \n
 *    cr_cbp: chroma coded block pattern
 *
 * \par Output:
 *    cr_cbp: Updated chroma coded block pattern.
 ************************************************************************
 */
int dct_chroma_sp(Macroblock *currMB, int uv,int cr_cbp, int is_cavlc)
{
  int i, j, n2, n1, coeff_ctr;
  static int m1[BLOCK_SIZE];
  int coeff_cost = 0;
  int cr_cbp_tmp = 0;
  int DCzero = FALSE;
  int nonzero[4][4] = {{FALSE}};
  int nonezero = FALSE;

  const byte *c_cost = COEFF_COST4x4[params->disthres];

  int   b4;
  int*  DCLevel = img->cofDC[uv+1][0];
  int*  DCRun   = img->cofDC[uv+1][1];
  int*  ACLevel;
  int*  ACRun;
  int   intra = IS_INTRA (currMB);
  int   uv_scale = uv * (img->num_blk8x8_uv >> 1);

  //FRExt
  static const int64 cbpblk_pattern[4]={0, 0xf0000, 0xff0000, 0xffff0000};
  int yuv = img->yuv_format;
  int b8;  

  const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN;
  int cur_qp = currMB->qpc[uv] + img->bitdepth_chroma_qp_scale;  

  int qp_rem = qp_rem_matrix[cur_qp];

  int max_imgpel_value_uv = img->max_imgpel_value_comp[uv + 1];

  int    (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[uv + 1]; 
  int    (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[uv + 1]; 
  imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[uv + 1]; 

  levelscale    = LevelScale4x4Comp   [uv + 1][intra][qp_rem];
  leveloffset   = LevelOffset4x4Comp  [uv + 1][intra][cur_qp];
  invlevelscale = InvLevelScale4x4Comp[uv + 1][intra][qp_rem];
  fadjust4x4    = img->AdaptiveRounding ? img->fadjust4x4Cr[intra][uv] : NULL;

  //============= dct transform ===============
  for (n2=0; n2 < img->mb_cr_size_y; n2 += BLOCK_SIZE)
  {
    for (n1=0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE)
    {
      forward4x4(mb_ores, mb_rres, n2, n1);
    }
  }

  if (yuv == YUV420)
  {
    //================== CHROMA DC YUV420 ===================
  
    // forward 2x2 hadamard
    hadamard2x2(mb_rres, m1);

    // Quantization process of chroma 2X2 hadamard transformed DC coeffs.
    DCzero = quant_dc_cr(&m1, cur_qp, DCLevel, DCRun, fadjust2x2, levelscale[0][0], invlevelscale[0][0], leveloffset, pos_scan, is_cavlc);

    if (DCzero) 
    {
        currMB->cbp_blk |= 0xf0000 << (uv << 2) ;    // if one of the 2x2-DC levels is != 0 set the
        cr_cbp=imax(1,cr_cbp);                     // coded-bit all 4 4x4 blocks (bit 16-19 or 20-23)
    }

    //  Inverse transform of 2x2 DC levels
    ihadamard2x2(m1, m1);

    mb_rres[0][0] = m1[0];
    mb_rres[0][4] = m1[1];
    mb_rres[4][0] = m1[2];
    mb_rres[4][4] = m1[3];
  }
  else if (yuv == YUV422)
  {
    //for YUV422 only
    int cur_qp_dc = currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale;
    int qp_rem_dc = qp_rem_matrix[cur_qp_dc];

    invlevelscaleDC = InvLevelScale4x4Comp[uv + 1][intra][qp_rem_dc];
    levelscaleDC    = LevelScale4x4Comp   [uv + 1][intra][qp_rem_dc];
    leveloffsetDC   = LevelOffset4x4Comp  [uv + 1][intra][cur_qp_dc];

    //================== CHROMA DC YUV422 ===================
    //pick out DC coeff    
    for (j=0; j < img->mb_cr_size_y; j+=BLOCK_SIZE)
    {
      for (i=0; i < img->mb_cr_size_x; i+=BLOCK_SIZE)
        M4[i>>2][j>>2]= mb_rres[j][i];
    }

    // forward hadamard transform. Note that coeffs have been transposed (4x2 instead of 2x4) which makes transform a bit faster
    hadamard4x2(M4, M4);

    // Quantization process of chroma transformed DC coeffs.
    DCzero = quant_dc_cr(M4, cur_qp_dc, DCLevel, DCRun, fadjust4x2, levelscaleDC[0][0], invlevelscaleDC[0][0], leveloffsetDC, SCAN_YUV422, is_cavlc);

    if (DCzero)
    {
      currMB->cbp_blk |= 0xff0000 << (uv << 3) ;   // if one of the DC levels is != 0 set the
      cr_cbp=imax(1,cr_cbp);                       // coded-bit all 4 4x4 blocks (bit 16-31 or 32-47) //YUV444
    }

    //inverse DC transform. Note that now M4 is transposed back
    ihadamard4x2(M4, M4);    

    // This code assumes sizeof(int) > 16. Therefore, no need to have conditional
    for (j = 0; j < 4; j++)
    {
      mb_rres[j << 2 ][0] = M4[j][0];
      mb_rres[j << 2 ][4] = M4[j][1];
    }
  }

  //     Quant of chroma AC-coeffs.
  for (b8=0; b8 < (img->num_blk8x8_uv >> 1); b8++)
  {
    for (b4=0; b4 < 4; b4++)
    {
      int64 uv_cbpblk = ((int64)1) << cbp_blk_chroma[b8 + uv_scale][b4];      
      n1 = hor_offset[yuv][b8][b4];
      n2 = ver_offset[yuv][b8][b4];
      ACLevel = img->cofAC[4 + b8 + uv_scale][b4][0];
      ACRun   = img->cofAC[4 + b8 + uv_scale][b4][1];

      // Quantization process
      nonzero[n2>>2][n1>>2] = quant_ac4x4cr(&mb_rres[n2], n2, n1, cur_qp, ACLevel, ACRun, &fadjust4x4[n2], 
        levelscale, invlevelscale, leveloffset, &coeff_cost, pos_scan, c_cost, CHROMA_AC, is_cavlc);

      if (nonzero[n2>>2][n1>>2])
      {
        currMB->cbp_blk |= uv_cbpblk;
        cr_cbp_tmp = 2;
        nonezero = TRUE;
      }
    }
  }

  // Perform thresholding
  // * reset chroma coeffs
  if(nonezero && coeff_cost < _CHROMA_COEFF_COST_)
  {
    int64 uv_cbpblk = ((int64)cbpblk_pattern[yuv] << (uv << (1+yuv)));
    cr_cbp_tmp = 0;

    for (b8 = 0; b8 < (img->num_blk8x8_uv >> 1); b8++)
    {
      for (b4 = 0; b4 < 4; b4++)
      {
        n1 = hor_offset[yuv][b8][b4];
        n2 = ver_offset[yuv][b8][b4];
        if (nonzero[n2>>2][n1>>2] == TRUE)
        {
          nonzero[n2>>2][n1>>2] = FALSE;
          ACLevel = img->cofAC[4 + b8 + uv_scale][b4][0];
          ACRun   = img->cofAC[4 + b8 + uv_scale][b4][1];

          if (DCzero == 0)
            currMB->cbp_blk &= ~(uv_cbpblk);  // if no chroma DC's: then reset coded-bits of this chroma subblock

          ACLevel[0] = 0;

          for (coeff_ctr=1; coeff_ctr < 16; coeff_ctr++)// ac coeff
          {
            mb_rres[n2 + pos_scan[coeff_ctr][1]][n1 + pos_scan[coeff_ctr][0]] = 0;
            ACLevel[coeff_ctr]  = 0;
          }
        }
      }
    }
  }

  //     IDCT.
  //     Horizontal.
  if(cr_cbp_tmp == 2)
    cr_cbp = 2;

  nonezero = FALSE;
  for (n2=0; n2 < img->mb_cr_size_y; n2 += BLOCK_SIZE)
  {
    for (n1=0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE)
    {
      if (mb_rres[n2][n1] != 0 || nonzero[n2>>2][n1>>2] == TRUE)
      {
        inverse4x4(mb_rres, mb_rres, n2, n1);
        nonezero = TRUE;
      }
    }
  }

  //  Decoded block moved to memory
  if (nonezero == TRUE)
  {
    SampleReconstruct (enc_picture->imgUV[uv], mb_pred, mb_rres, 0, 0, img->pix_c_y, img->pix_c_x, img->mb_cr_size_x, img->mb_cr_size_y, max_imgpel_value_uv, DQ_BITS);
  }
  else
  {
    for (j=0; j < img->mb_cr_size_y; j++)
    {
      memcpy(&enc_picture->imgUV[uv][img->pix_c_y + j][img->pix_c_x], mb_pred[j], img->mb_cr_size_x * sizeof(imgpel));
    }
  }

  return cr_cbp;
}

int dct_chroma_sp_old(Macroblock *currMB, int uv,int cr_cbp, int is_cavlc)
{
  int i,j,ilev,n2,n1,coeff_ctr,c_err,level ,scan_pos,run;
  int m1[BLOCK_SIZE];
  int coeff_cost;
  int cr_cbp_tmp;
  int mp1[BLOCK_SIZE];
  const byte *c_cost = COEFF_COST4x4[params->disthres];
  const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN;

  int   intra = IS_INTRA (currMB);

  int   b4;
  int*  DCLevel = img->cofDC[uv+1][0];
  int*  DCRun   = img->cofDC[uv+1][1];
  int*  ACLevel;
  int*  ACRun;

  int c_err1, c_err2, level1, level2;
  int len, info;
  double D_dis1, D_dis2;
  double lambda_mode   = 0.85 * pow (2, (currMB->qp -SHIFT_QP)/3.0) * 4;
  int max_imgpel_value_uv = img->max_imgpel_value_comp[1];

  int qpChroma = currMB->qpc[uv] + img->bitdepth_chroma_qp_scale;   
  int qpChromaSP=iClip3(-img->bitdepth_chroma_qp_scale, 51, currMB->qpsp + active_pps->chroma_qp_index_offset);
  int    (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[uv + 1]; 
  int    (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[uv + 1]; 
  imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[uv + 1]; 

  int qp_per    = qp_per_matrix[qpChroma];
  int qp_rem    = qp_rem_matrix[qpChroma];
  int q_bits    = Q_BITS + qp_per;
  int qp_const  = (1<<q_bits)/6;    // inter
  int qp_per_sp = qp_per_matrix[qpChromaSP];
  int qp_rem_sp = qp_rem_matrix[qpChromaSP];
  int q_bits_sp = Q_BITS + qp_per_sp;
  int qp_const2 = (1<<q_bits_sp)/2;  //sp_pred
  
  levelscale    = LevelScale4x4Comp   [uv + 1][intra][qp_rem];
  invlevelscale = InvLevelScale4x4Comp[uv + 1][intra][qp_rem];
  leveloffset   = LevelOffset4x4Comp  [uv + 1][intra][qpChroma];

  levelscale_sp    = LevelScale4x4Comp   [uv + 1][intra][qp_rem_sp];
  invlevelscale_sp = InvLevelScale4x4Comp[uv + 1][intra][qp_rem_sp];
  leveloffset_sp   = LevelOffset4x4Comp  [uv + 1][intra][qpChromaSP];

  for (j=0; j < img->mb_cr_size_y; j++)
  {
    for (i=0; i < img->mb_cr_size_x; i++)
    {
      mb_rres[j][i]  = mb_ores[j][i];
      mb_rres[j][i] += mb_pred[j][i];
      M1[j][i] = mb_pred[j][i];
    }
  }
  
  for (n2=0; n2 < img->mb_cr_size_y; n2 += BLOCK_SIZE)
  {
    for (n1=0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE)
    {
      forward4x4(mb_rres, mb_rres, n2, n1);      
      forward4x4(M1, M1, n2, n1);
    }
  }

  //     2X2 transform of DC coeffs.
  hadamard2x2(mb_rres, m1);
  hadamard2x2(M1, mp1);

  run=-1;
  scan_pos=0;

  for (coeff_ctr = 0; coeff_ctr < 4; coeff_ctr++)
  {
    run++;
    ilev=0;

    // case 1
    c_err1 = (iabs (mp1[coeff_ctr]) * levelscale_sp[0][0] + 2 * qp_const2) >> (q_bits_sp + 1);
    c_err1 = (c_err1 << (q_bits_sp + 1)) / levelscale_sp[0][0];
    c_err1 = m1[coeff_ctr] - isignab(c_err1, mp1[coeff_ctr]);
    level1 = (iabs(c_err1) * levelscale[0][0] + 2 * qp_const) >> (q_bits+1);

    // case 2
    c_err2 = m1[coeff_ctr] - mp1[coeff_ctr];
    level2 = (iabs(c_err2) * levelscale[0][0] + 2 * qp_const) >> (q_bits+1);

    if (level1 != level2 && level1 != 0 && level2 != 0)
    {
      D_dis1 = m1[coeff_ctr] - ((isignab(level1,c_err1)*invlevelscale[0][0] * A[0][0]<< qp_per) >>5)- mp1[coeff_ctr];
      levrun_linfo_c2x2(level1, run, &len, &info);
      D_dis1 = D_dis1 * D_dis1 + lambda_mode * len;

      D_dis2 = m1[coeff_ctr] - ((isignab(level2,c_err2)*invlevelscale[0][0] * A[0][0]<< qp_per) >>5)- mp1[coeff_ctr];
      levrun_linfo_c2x2(level2, run, &len, &info);
      D_dis2 = D_dis2 * D_dis2 + lambda_mode * len;

      if (D_dis1 == D_dis2)
        level = (iabs(level1) < iabs(level2)) ? level1 

⌨️ 快捷键说明

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