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

📄 block.c

📁 h.264 影像壓縮 必須在 .net 的環境 下操作
💻 C
📖 第 1 页 / 共 5 页
字号:
    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)[16][16]  = 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;

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

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

  if (!(input->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]= iClip3( 0, 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 qp_const;
  int i,j;
  int ii,jj;
  static int M1[16][16];
  static int M4[4][4];
  static int scaled_coeff;
  static int *m7;
  int run,scan_pos,coeff_ctr,level;
  int ac_coef = 0;
  static imgpel *img_Y, *predY;

  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*  ACLevel;
  int*  ACRun;  
  imgpel **img_enc          = enc_picture->p_curr_img;
  int    max_imgpel_value   = img->max_imgpel_value;
  int    qp                 = currMB->qp_scaled[pl]; 
  Boolean lossless_qpprime = (Boolean) ((qp == 0) && (img->lossless_qpprime_flag == 1));
  const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN;
  imgpel  (*curr_mpr_16x16)[16][16]  = img->mpr_16x16[pl];

  int qp_per = qp_per_matrix[qp];
  int qp_rem = qp_rem_matrix[qp];
  int q_bits = Q_BITS + qp_per;

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

  fadjust4x4 = img->AdaptiveRounding ? (pl ? &img->fadjust4x4Cr[pl-1][2][0] : &img->fadjust4x4[2][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];
    }
  }

  if (!lossless_qpprime)
  {
    // 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);

    // quant
    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++;
      level= (iabs(M4[j][i]) * levelscale[0][0] + (leveloffset[0][0]<<1)) >> (q_bits+1);

      if (level != 0)
      {
        if (input->symbol_mode == CAVLC && img->qp < 10)
          level = imin(level, CAVLC_LEVEL_LIMIT);

        level = isignab(level, M4[j][i]);
        DCLevel[scan_pos  ] = level;
        DCRun  [scan_pos++] = run;
        run=-1;
        M4[j][i] = level;
      }
      else
        M4[j][i] = 0;
    }
    DCLevel[scan_pos]=0;

    // inverse DC transform
    ihadamard4x4(M4, M4);

    // Reset DC coefficients
    for (j=0;j<4;j++)
      for (i=0;i<4;i++)
        M1[j<<2][i<<2] = rshift_rnd_sf(((M4[j][i]) * invlevelscale[0][0]) << qp_per, 6);

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

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

        for (coeff_ctr = 1; coeff_ctr < 16; coeff_ctr++) // set in AC coeff
        {
          i=pos_scan[coeff_ctr][0];
          j=pos_scan[coeff_ctr][1];

          run++;
          m7 = &M1[jpos + j][ipos];
          scaled_coeff = iabs( m7[i]) * levelscale[j][i];
          level = (scaled_coeff + leveloffset[j][i]) >> q_bits;

          if (level != 0)
          {
            if (img->AdaptiveRounding)
              fadjust4x4[jpos + j][ipos + i] = rshift_rnd_sf((AdaptRndWeight * (scaled_coeff - (level << q_bits))), (q_bits + 1));

            ac_coef = 15;
            level = isignab(level, m7[i]);
            ACLevel[scan_pos  ] = level; 
            ACRun  [scan_pos++] = run;
            run=-1;
            
            m7[i] = rshift_rnd_sf((level * invlevelscale[j][i])<<qp_per, 4);
          }          
          else
          {
            m7[i] = 0;          
            if (img->AdaptiveRounding)
              fadjust4x4[jpos + j][ipos + i] = 0;
          }
        }

        ACLevel[scan_pos] = 0;

        //IDCT
        inverse4x4(M1, M1, jpos, ipos);
      }
    }

    for (j=0;j<16;j++)
    {
      img_Y = &img_enc[img->pix_y + j][img->pix_x];
      predY = curr_mpr_16x16[new_intra_mode][j];
      for (i=0;i<16;i++)
        img_Y[i] = iClip1( max_imgpel_value, rshift_rnd_sf(M1[j][i], DQ_BITS) + predY[i]);
    }

    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
    }
  }
  else  // Lossless qpprime code
  {
    // 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++;

      level= iabs(M4[j][i]);

      if (level != 0)
      {
        if (input->symbol_mode == CAVLC && img->qp < 10)
          level = imin(level, CAVLC_LEVEL_LIMIT);

        DCLevel[scan_pos  ] = isignab(level,M4[j][i]);
        DCRun  [scan_pos++] = run;
        run=-1;
      }
    }
    DCLevel[scan_pos]=0;

    // AC inverse trans/quant for MB
    for (jj=0;jj<4;jj++)
    {
      for (ii=0;ii<4;ii++)
      {
        for (j=0;j<4;j++)
        {
          // memcpy(M4[j],&M1[(jj<<2)+j][(ii<<2)], BLOCK_SIZE * sizeof(int));
          //For residual DPCM
          if(new_intra_mode>1)  //non residual DPCM
            memcpy(M4[j],&M1[(jj<<2)+j][(ii<<2)], BLOCK_SIZE * sizeof(int));
          else //residual DPCM
          {
            memcpy(lossless_res[j],&M1[(jj<<2)+j][(ii<<2)], BLOCK_SIZE * sizeof(int)); 
          }
        }

        //For residual DPCM
        if(new_intra_mode<2)
        {
          Residual_DPCM_4x4_for_Intra16x16(new_intra_mode);  

          for (j=0;j<4;j++)
            memcpy(M4[j],lossless_res[j], BLOCK_SIZE * sizeof(int));  
        }

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

        for (coeff_ctr=1;coeff_ctr<16;coeff_ctr++) // set in AC coeff
        {
          i=pos_scan[coeff_ctr][0];
          j=pos_scan[coeff_ctr][1];

          run++;

          level= iabs( M4[j][i]);

          if (level != 0)
          {
            ac_coef = 15;
            ACLevel[scan_pos  ] = isignab(level,M4[j][i]);
            ACRun  [scan_pos++] = run;
            run=-1;
          }
          // set adaptive rounding params to 0 since process is not meaningful here.
          if (img->AdaptiveRounding)
            fadjust4x4[jj*BLOCK_SIZE+j][ii*BLOCK_SIZE+i] = 0;
        }
        ACLevel[scan_pos] = 0;

        ///For residual DPCM.  inv. residual DCPM
        if(new_intra_mode<2)  
        {
          Inv_Residual_DPCM_4x4_for_Intra16x16(new_intra_mode);  

          for (j=0;j<4;j++)
            memcpy(&M1[(jj<<2)+j][(ii<<2)],lossless_res[j], BLOCK_SIZE * sizeof(int)); 

⌨️ 快捷键说明

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