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

📄 block.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 3 页
字号:
    {
      for(i=0; i<8; i++)
      {
        temp[i][0] = m7[joff + i][ioff + 0];
        temp[i][1] = m7[joff + i][ioff + 1] + temp[i][0];
        temp[i][2] = m7[joff + i][ioff + 2] + temp[i][1];
        temp[i][3] = m7[joff + i][ioff + 3] + temp[i][2];
        temp[i][4] = m7[joff + i][ioff + 4] + temp[i][3];
        temp[i][5] = m7[joff + i][ioff + 5] + temp[i][4];
        temp[i][6] = m7[joff + i][ioff + 6] + temp[i][5];
        temp[i][7] = m7[joff + i][ioff + 7] + temp[i][6];
      }
      for(i=0; i<8; i++)
      {
        m7[joff+i][ioff+0]=temp[i][0];
        m7[joff+i][ioff+1]=temp[i][1];
        m7[joff+i][ioff+2]=temp[i][2];
        m7[joff+i][ioff+3]=temp[i][3];
        m7[joff+i][ioff+4]=temp[i][4];
        m7[joff+i][ioff+5]=temp[i][5];
        m7[joff+i][ioff+6]=temp[i][6];
        m7[joff+i][ioff+7]=temp[i][7];
      }
    }
    for (j = 0; j < BLOCK_SIZE*2; j++)
      for (i = 0; i < BLOCK_SIZE*2; i++)
        m7[j+joff][i+ioff] +=  (long)mpr[j+joff][i+ioff];
}



/*!
 ***********************************************************************
 * \brief
 *    Luma DC inverse transform
 ***********************************************************************
 */ 
void itrans_2(ImageParameters *img, Macroblock *currMB, ColorPlane pl) //!< image parameters
{
  int i,j;

  int (*cof)[16] = img->cof[pl];
  int qp_scaled = currMB->qp_scaled[pl];

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

  int invLevelScale = InvLevelScale4x4_Intra[pl][qp_rem][0][0];

  // horizontal
  for (j=0; j < 4;j++) 
  {
    for (i=0; i < 4;i++) 
    {
      M4[j][i]=cof[j<<2][i<<2];
    }
  }

  ihadamard4x4(M4, M4);

  // vertical
  for (j=0; j < 4;j++) 
  {
    for (i=0; i < 4;i++) 
    {
      cof[j<<2][i<<2] = rshift_rnd((( M4[j][i] * invLevelScale) << qp_per), 6);
    }
  }
}


void itrans_sp(ImageParameters *img,  //!< image parameters
               ColorPlane pl, 
               int ioff,             //!< index to 4x4 block
               int joff)              //!<
{
  int i,j;  
  int ilev, icof;

  int qp = (img->type == SI_SLICE) ? img->qpsp : img->qp;
  int qp_per = qp_per_matrix[ qp ];
  int qp_rem = qp_rem_matrix[ qp ];

  int qp_per_sp = qp_per_matrix[ img->qpsp ];
  int qp_rem_sp = qp_rem_matrix[ img->qpsp ];
  int q_bits_sp = Q_BITS + qp_per_sp;

  imgpel (*mpr)[16] = img->mb_pred[pl];
  int    (*m7) [16] = img->mb_rres[pl];
  int    (*cof)[16] = img->cof[pl];
  int max_imgpel_value = img->max_imgpel_value_comp[pl];
  
  //int (*InvLevelScale4x4)[4] = InvLevelScale4x4_Intra[0][qp_rem];
  const int (*InvLevelScale4x4)  [4] = dequant_coef[qp_rem];
  const int (*InvLevelScale4x4SP)[4] = dequant_coef[qp_rem_sp];


  for (j=0; j< BLOCK_SIZE; j++)
    for (i=0; i< BLOCK_SIZE; i++)
      PBlock[j][i] = mpr[j+joff][i+ioff];

  forward4x4(PBlock, PBlock, 0, 0);

  if(img->sp_switch || img->type==SI_SLICE)
  {    
    for (j=0;j<BLOCK_SIZE;j++)
    {
      for (i=0;i<BLOCK_SIZE;i++)
      {
        // recovering coefficient since they are already dequantized earlier
        icof = (cof[joff + j][ioff + i] >> qp_per) / InvLevelScale4x4[j][i];
        //icof = ((cof[joff + j][ioff + i] * quant_coef[qp_rem][j][i])>> (qp_per + 15)) ;
        // icof  = rshift_rnd_sf(cof[joff + j][ioff + i] * quant_coef[qp_rem][j][i], qp_per + 15);
        ilev  = rshift_rnd_sf(iabs(PBlock[j][i]) * quant_coef[qp_rem_sp][j][i], q_bits_sp);
        ilev  = isignab(ilev, PBlock[j][i]) + icof;
        cof[joff + j][ioff + i] = ilev * InvLevelScale4x4SP[j][i] << qp_per_sp;
      }
    }
  }
  else
  {
    for (j=0;j<BLOCK_SIZE;j++)
    {
      for (i=0;i<BLOCK_SIZE;i++)
      {
        // recovering coefficient since they are already dequantized earlier
        icof = (cof[joff + j][ioff + i] >> qp_per) / InvLevelScale4x4[j][i];
        //icof = cof[joff + j][ioff + i];
        //icof  = rshift_rnd_sf(cof[joff + j][ioff + i] * quant_coef[qp_rem][j][i], qp_per + 15);
        ilev = PBlock[j][i] + ((icof * InvLevelScale4x4[j][i] * A[j][i] <<  qp_per) >> 6);
        ilev  = isign(ilev) * rshift_rnd_sf(iabs(ilev) * quant_coef[qp_rem_sp][j][i], q_bits_sp);
        //cof[joff + j][ioff + i] = ilev * InvLevelScale4x4SP[j][i] << qp_per_sp;
        cof[joff + j][ioff + i] = ilev * dequant_coef[qp_rem_sp][j][i] << qp_per_sp;
      }
    }
  }

  inverse4x4(cof, m7, joff, ioff);

  for (j=0;j<BLOCK_SIZE;j++)
    for (i=0;i<BLOCK_SIZE;i++)
      m7[j + joff][i + ioff] = iClip1(max_imgpel_value,rshift_rnd_sf(m7[j + joff][i + ioff], DQ_BITS));
}


void itrans_sp_cr(ImageParameters *img, int uv)
{
  int i,j,ilev, icof, n2,n1;
  int mp1[BLOCK_SIZE];
  int qp_per,qp_rem;
  int qp_per_sp,qp_rem_sp,q_bits_sp;
  imgpel (*mpr)[MB_BLOCK_SIZE] = img->mb_pred[uv + 1];
  int    (*cof)[MB_BLOCK_SIZE] = img->cof[uv + 1];

  qp_per    = qp_per_matrix[ ((img->qp < 0 ? img->qp : QP_SCALE_CR[img->qp]))];
  qp_rem    = qp_rem_matrix[ ((img->qp < 0 ? img->qp : QP_SCALE_CR[img->qp]))];

  qp_per_sp = qp_per_matrix[ ((img->qpsp < 0 ? img->qpsp : QP_SCALE_CR[img->qpsp]))];
  qp_rem_sp = qp_rem_matrix[ ((img->qpsp < 0 ? img->qpsp : QP_SCALE_CR[img->qpsp]))];
  q_bits_sp = Q_BITS + qp_per_sp;  

  if (img->type == SI_SLICE)
  {
    qp_per = qp_per_sp;
    qp_rem = qp_rem_sp;
  }

  for (j=0; j < img->mb_cr_size_y; j++)
  {
    for (i=0; i < img->mb_cr_size_x; i++)
    {
      PBlock[j][i] = mpr[j][i];
      mpr[j][i] = 0;
    }
  }

  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(PBlock, PBlock, n2, n1);
    }
  }

  //     2X2 transform of DC coeffs.
  mp1[0] = (PBlock[0][0] + PBlock[4][0] + PBlock[0][4] + PBlock[4][4]);
  mp1[1] = (PBlock[0][0] - PBlock[4][0] + PBlock[0][4] - PBlock[4][4]);
  mp1[2] = (PBlock[0][0] + PBlock[4][0] - PBlock[0][4] - PBlock[4][4]);
  mp1[3] = (PBlock[0][0] - PBlock[4][0] - PBlock[0][4] + PBlock[4][4]);

  if (img->sp_switch || img->type==SI_SLICE)  
  {        
    for (n2=0; n2 < 2; n2 ++)
    {
      for (n1=0; n1 < 2; n1 ++)
      {
        //quantization fo predicted block
        ilev = rshift_rnd_sf(iabs (mp1[n1+n2*2]) * quant_coef[qp_rem_sp][0][0], q_bits_sp + 1);
        //addition
        ilev = isignab(ilev, mp1[n1+n2*2]) + cof[n2<<2][n1<<2];
        //dequantization
        mp1[n1+n2*2] =ilev * dequant_coef[qp_rem_sp][0][0] << qp_per_sp;
      }
    }

    for (n2 = 0; n2 < img->mb_cr_size_y; n2 += BLOCK_SIZE)
    {
      for (n1 = 0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE)
      {
        for (j = 0; j < BLOCK_SIZE; j++)
        {
          for (i = 0; i < BLOCK_SIZE; i++)
          {
            // recovering coefficient since they are already dequantized earlier
            cof[n2 + j][n1 + i] = (cof[n2 + j][n1 + i] >> qp_per) / dequant_coef[qp_rem][j][i];

            //quantization of the predicted block
            ilev = rshift_rnd_sf(iabs(PBlock[n2 + j][n1 + i]) * quant_coef[qp_rem_sp][j][i], q_bits_sp);
            //addition of the residual
            ilev = isignab(ilev,PBlock[n2 + j][n1 + i]) + cof[n2 + j][n1 + i];
            // Inverse quantization
            cof[n2 + j][n1 + i] = ilev * dequant_coef[qp_rem_sp][j][i] << qp_per_sp;
          }
        }
      }
    }
  }
  else
  {
    for (n2=0; n2 < 2; n2 ++)
    {
      for (n1=0; n1 < 2; n1 ++)
      {
        ilev = mp1[n1+n2*2] + (((cof[n2<<2][n1<<2] * dequant_coef[qp_rem][0][0] * A[0][0]) << qp_per) >> 5);
        ilev = isign(ilev) * rshift_rnd_sf(iabs(ilev) * quant_coef[qp_rem_sp][0][0], q_bits_sp + 1);
        //ilev = isignab(rshift_rnd_sf(iabs(ilev)* quant_coef[qp_rem_sp][0][0], q_bits_sp + 1), ilev);
        mp1[n1+n2*2] = ilev * dequant_coef[qp_rem_sp][0][0] << qp_per_sp;
      }
    }

    for (n2 = 0; n2 < img->mb_cr_size_y; n2 += BLOCK_SIZE)
    {
      for (n1 = 0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE)
      {
        for (j = 0; j< BLOCK_SIZE; j++)
        {
          for (i = 0; i< BLOCK_SIZE; i++)
          {
            // recovering coefficient since they are already dequantized earlier
            //icof = ((((cof[n2 + j][n1 + i] << 4) + qp_per/2)>> qp_per) + dequant_coef[qp_rem][j][i]/2) / dequant_coef[qp_rem][j][i];
            icof = (cof[n2 + j][n1 + i] >> qp_per) / dequant_coef[qp_rem][j][i];
            //dequantization and addition of the predicted block      
            ilev = PBlock[n2 + j][n1 + i] + ((icof * dequant_coef[qp_rem][j][i] * A[j][i] << qp_per) >> 6);
            //quantization and dequantization
            ilev = isign(ilev) * rshift_rnd_sf(iabs(ilev) * quant_coef[qp_rem_sp][j][i], q_bits_sp);
            cof[n2 + j][n1 + i] = ilev * dequant_coef[qp_rem_sp][j][i] << qp_per_sp;
            //printf( " %d %d %d\n", j, i, quant_coef[qp_rem_sp][j][i]);
          }
        }
      }
    }
  }

  cof[0][0] = (mp1[0] + mp1[1] + mp1[2] + mp1[3]) >> 1;
  cof[0][4] = (mp1[0] + mp1[1] - mp1[2] - mp1[3]) >> 1;
  cof[4][0] = (mp1[0] - mp1[1] + mp1[2] - mp1[3]) >> 1;
  cof[4][4] = (mp1[0] - mp1[1] - mp1[2] + mp1[3]) >> 1;
}

static const byte decode_block_scan[16] = {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15};

void iMBtrans4x4(ColorPlane pl, ImageParameters *img, int smb)
{
  int i_pos;
  int jj, ii;
  int block8x8;
  int i, j, k;  
  int    (*m7) [16] = img->mb_rres[pl];
  imgpel **curr_img = pl ? &(dec_picture->imgUV[pl - 1][img->pix_y]): &dec_picture->imgY[img->pix_y];

  //For residual DPCM
  Boolean lossless_qpprime = (Boolean) (((img->qp + img->bitdepth_luma_qp_scale) == 0) && (img->lossless_qpprime_flag == 1));  

  // =============== 4x4 itrans ================
  // -------------------------------------------

  itrans_4x4 = (smb) ? itrans_sp : ((!lossless_qpprime) ? itrans4x4 : Inv_Residual_trans_4x4);

  i_pos = img->pix_x;

  for (block8x8=0; block8x8 < MB_BLOCK_SIZE; block8x8 += 4)
  { 
    for (k = block8x8; k < block8x8 + 4; k ++)
    {
      jj = ((decode_block_scan[k] >> 2) & 3) << BLOCK_SHIFT;
      ii = (decode_block_scan[k] & 3) << BLOCK_SHIFT;

      itrans_4x4(img, pl, ii, jj);   // use DCT transform and make 4x4 block m7 from prediction block mpr
      
      for(j = jj; j < jj + BLOCK_SIZE; j++)
      {
        for(i = ii; i < ii + BLOCK_SIZE; i++)
        {
          curr_img[j][i_pos + i] = (imgpel) m7[j][i]; // construct picture from 4x4 blocks
        }
      }
    }
  }
}

void iMBtrans8x8(ImageParameters *img,  Macroblock *currMB, ColorPlane pl)
{
  imgpel **curr_img = pl ? &dec_picture->imgUV[pl - 1][img->pix_y]: &dec_picture->imgY[img->pix_y];
  int    (*m7)[MB_BLOCK_SIZE] = img->mb_rres[pl];
  int block8x8;
  int i,j;
  int ioff, joff;

  for (block8x8=0; block8x8<4; block8x8++)
  {
    // =============== 8x8 itrans ================
    // -------------------------------------------
    ioff = 8 * (block8x8 & 0x01);
    joff = 8 * (block8x8 >> 1);

    itrans8x8(img, currMB, pl, ioff, joff);      // use DCT transform and make 8x8 block m7 from prediction block mpr

    for(j = joff; j < joff + 8; j++)
    {
      for(i = ioff; i < ioff + 8; i++)
      {
        curr_img[j][img->pix_x + i] = (imgpel) m7[j][i];
      }
    }
  }
}

void iTransform(ImageParameters *img,  Macroblock *currMB, ColorPlane pl, int need_4x4_transform, int smb)
{
  static imgpel (*mpr) [16];
  static imgpel **curr_img;
  int j, uv = pl-1; 

  if ((currMB->cbp & 15) != 0 || smb)
  {
    if(need_4x4_transform) // 4x4 inverse transform
    {
      iMBtrans4x4(pl, img, smb); 
    }
    else // 8x8 inverse transform
    {  
      iMBtrans8x8(img, currMB, pl);    
    }
  }
  else
  {
    mpr = img->mb_pred[pl]; 
    curr_img = pl ? &dec_picture->imgUV[uv][img->pix_y] : &dec_picture->imgY[img->pix_y];
    for(j = 0; j < MB_BLOCK_SIZE; j++)
    { 
      memcpy(&(curr_img[j][img->pix_x]), &(img->mb_pred[pl][j][0]), MB_BLOCK_SIZE * sizeof(imgpel));
    }
  }

  if ((dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444)) 
  {
    static imgpel **curUV, *cur_line;
    static int b4, b8;
    static int ioff, joff, ii, jj;
    static int (*m7UV)[16], *m7;

    for(uv=0;uv<2;uv++)
    {
      Boolean lossless_qpprime = (Boolean) ((img->lossless_qpprime_flag == 1) &&((img->qp + dec_picture->chroma_qp_offset[uv] + img->bitdepth_chroma_qp_scale) == 0));  
      itrans_4x4 = (!lossless_qpprime) ? itrans4x4 : itrans4x4_ls;

      // =============== 4x4 itrans ================
      // -------------------------------------------
      curUV = &dec_picture->imgUV[uv][img->pix_c_y]; 
      m7UV  = img->mb_rres[uv+1];

      if (!smb && (currMB->cbp>>4))
      {
        for (b8 = 0; b8 < (img->num_uv_blocks); b8++)
        {
          for(b4 = 0; b4 < 4; b4++)
          {
            joff = subblk_offset_y[1][b8][b4];
            ioff = subblk_offset_x[1][b8][b4];

            itrans_4x4(img, (ColorPlane) (uv + 1), ioff, joff);

            for(jj=joff;jj<joff + 4;jj++)
            {
              cur_line = &curUV[jj][img->pix_c_x + ioff];
              m7 = &m7UV[jj][ioff];
              for(ii=0;ii<4;ii++)
              {
                *(cur_line++) = (imgpel) *(m7++);
              }
            }
          }
        }
      }
      else if (smb)
      {
        itrans_sp_cr(img, uv);

        for (joff = 0; joff < img->mb_cr_size_y; joff += BLOCK_SIZE)
        {
          for(ioff = 0; ioff < img->mb_cr_size_x ;ioff += BLOCK_SIZE)
          {
            itrans_4x4(img, (ColorPlane) (uv + 1), ioff, joff);

            for(jj=joff;jj<joff + 4;jj++)
              for(ii=ioff;ii<ioff + 4;ii++)
              {
                curUV[jj][img->pix_c_x+ii]= (imgpel) m7UV[jj][ii];
              }
          }
        }
      }
      else 
      {
        mpr = img->mb_pred[uv + 1];
        for(jj = 0; jj < img->mb_size[1][1]; jj++)
          memcpy(&(curUV[jj][img->pix_c_x]), &(mpr[jj][0]), img->mb_size[1][0] * sizeof(imgpel));
      }
    }
  }
}

⌨️ 快捷键说明

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