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

📄 transform8x8.c

📁 h.264 影像壓縮 必須在 .net 的環境 下操作
💻 C
📖 第 1 页 / 共 4 页
字号:
    cur_pred[0][5] = (imgpel) ((P_U + P_S + 2*P_T + 2) >> 2);
    cur_pred[1][1] =
    cur_pred[0][3] = (imgpel) ((P_T + P_R + 2*P_S + 2) >> 2);
    cur_pred[0][1] = (imgpel) ((P_S + P_Q + 2*P_R + 2) >> 2);
  }
}

/*!
 *************************************************************************************
 * \brief
 *    Prefiltering for Intra8x8 prediction
 *************************************************************************************
 */
void LowPassForIntra8x8Pred(imgpel *PredPel, int block_up_left, int block_up, int block_left)
{
  int i;
  static imgpel LoopArray[25];

  memcpy(LoopArray,PredPel, 25 * sizeof(imgpel));

  if(block_up)
  {
    if(block_up_left)
    {
      LoopArray[1] = (((&P_Z)[0] + ((&P_Z)[1]<<1) + (&P_Z)[2] + 2)>>2);
    }
    else
      LoopArray[1] = (((&P_Z)[1] + ((&P_Z)[1]<<1) + (&P_Z)[2] + 2)>>2);


    for(i = 2; i <16; i++)
    {
      LoopArray[i] = (((&P_Z)[i-1] + ((&P_Z)[i]<<1) + (&P_Z)[i+1] + 2)>>2);
    }
    LoopArray[16] = ((P_P + (P_P<<1) + P_O + 2)>>2);
  }

  if(block_up_left)
  {
    if(block_up && block_left)
    {
      LoopArray[0] = ((P_Q + (P_Z<<1) + P_A +2)>>2);
    }
    else
    {
      if(block_up)
        LoopArray[0] = ((P_Z + (P_Z<<1) + P_A +2)>>2);
      else
        if(block_left)
          LoopArray[0] = ((P_Z + (P_Z<<1) + P_Q +2)>>2);
    }
  }

  if(block_left)
  {
    if(block_up_left)
      LoopArray[17] = ((P_Z + (P_Q<<1) + P_R + 2)>>2);
    else
      LoopArray[17] = ((P_Q + (P_Q<<1) + P_R + 2)>>2);

    for(i = 18; i <24; i++)
    {
      LoopArray[i] = (((&P_Z)[i-1] + ((&P_Z)[i]<<1) + (&P_Z)[i+1] + 2)>>2);
    }
    LoopArray[24] = ((P_W + (P_X<<1) + P_X + 2) >> 2);
  }

  memcpy(PredPel, LoopArray, 25 * sizeof(imgpel));
}





/*!
 *************************************************************************************
 * \brief
 *    R-D Cost for an 8x8 Intra block
 *************************************************************************************
 */

double RDCost_for_8x8IntraBlocks(Macroblock *currMB, int *nonzero, int b8, int ipmode, double lambda, double min_rdcost, int mostProbableMode, int c_nzCbCr[3])
{
  double  rdcost = 0.0;
  int     dummy;
  int     x, y, rate;
  int64   distortion  = 0;
  int     block_x     = (b8 & 0x01) << 3;
  int     block_y     = (b8 >> 1) << 3;
  int     pic_pix_x   = img->pix_x + block_x;
  int     pic_pix_y   = img->pix_y + block_y;
  int     pic_opix_y  = img->opix_y + block_y;
  imgpel  *img_org, *img_enc;

  Slice          *currSlice =  img->currentSlice;
  SyntaxElement  se;
  const int      *partMap   = assignSE2partition[input->partition_mode];
  DataPartition  *dataPart;

  //===== perform DCT, Q, IQ, IDCT, Reconstruction =====
  dummy = 0;

  *nonzero = dct_8x8 (currMB, PLANE_Y, b8, &dummy, 1);

  //===== get distortion (SSD) of 8x8 block =====
  for (y=0; y<8; y++)
  {
    img_org = pCurImg[pic_opix_y+y];
    img_enc = enc_picture->imgY[pic_pix_y+y];
    for (x = pic_pix_x; x < pic_pix_x + 8; x++)
      distortion += iabs2( img_org[x] - img_enc[x]);
  }

    if( img->yuv_format==YUV444 && !IS_INDEPENDENT(input) ) // INDEPENDENT_MODE 2006.07.26
    {
      ColorPlane k;

      for (k = PLANE_U; k <= PLANE_V; k++)
      {
        select_plane(k);
    /*    for (j=0; j<8; j++)   //KHHan, I think these line are not necessary
        {
          for (i=0; i<8; i++)
          {         
            img->mpr[k][block_y+j][block_x+i]  = img->mpr_8x8[k][ipmode][j][i];
            img->m7[k][j][i] = pImgOrg[k][img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr_8x8[k][ipmode][j][i];
          }
        }*/
        c_nzCbCr[k]=dct_8x8(currMB, k, b8, &dummy,1);

        for( y = 0; y < 8; y++ )
          for (x=pic_pix_x; x<pic_pix_x+8; x++)
            distortion +=iabs2(pImgOrg[k][pic_opix_y+y][x] - enc_picture->p_curr_img[pic_pix_y+y][x]);
      }
    ipmode_DPCM=NO_INTRA_PMODE;  //For residual DPCM
      select_plane(PLANE_Y);
    }
  else if( img->yuv_format==YUV444 && IS_INDEPENDENT(input) )  //For residual DPCM
  {
    ipmode_DPCM=NO_INTRA_PMODE;  
  }

    
  //===== RATE for INTRA PREDICTION MODE  (SYMBOL MODE MUST BE SET TO CAVLC) =====
  se.value1 = (mostProbableMode == ipmode) ? -1 : ipmode < mostProbableMode ? ipmode : ipmode-1;

  //--- set position and type ---
  se.context = b8;
  se.type    = SE_INTRAPREDMODE;

  //--- choose data partition ---
  if (img->type!=B_SLICE)
    dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
  else
    dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);

  //--- encode and update rate ---
  writeIntraPredMode (&se, dataPart);

  rate = se.len;

  //===== RATE for LUMINANCE COEFFICIENTS =====

  if (input->symbol_mode == CAVLC)
  {      
      if ( img->yuv_format==YUV444 && !IS_INDEPENDENT(input) )
      {
        int b4;
        for(b4=0; b4<4; b4++)
        {
          rate  += writeCoeff4x4_CAVLC (currMB, LUMA, b8, b4, 0);
          rate  += writeCoeff4x4_CAVLC (currMB, CB, b8, b4, 0);
          rate  += writeCoeff4x4_CAVLC (currMB, CR, b8, b4, 0);
        }
      }
      else
      {
        rate  += writeCoeff4x4_CAVLC (currMB, LUMA, b8, 0, 0);
        rate  += writeCoeff4x4_CAVLC (currMB, LUMA, b8, 1, 0);
        rate  += writeCoeff4x4_CAVLC (currMB, LUMA, b8, 2, 0);
        rate  += writeCoeff4x4_CAVLC (currMB, LUMA, b8, 3, 0);
      }
  }
  else
  {
    rate  += writeCoeff8x8_CABAC (currMB, PLANE_Y, b8, 1);
    if( img->yuv_format==YUV444 && !IS_INDEPENDENT(input) )
    {
      rate  += writeCoeff8x8_CABAC (currMB, PLANE_U, b8, 1);
      rate  += writeCoeff8x8_CABAC (currMB, PLANE_V, b8, 1);
    }
  }

  rdcost = (double)distortion + lambda*(double)rate;

  return rdcost;
}

/*!
 ************************************************************************
 * \brief
 *    The routine performs transform,quantization,inverse transform, adds the diff.
 *    to the prediction and writes the result to the decoded luma frame. Includes the
 *    RD constrained quantization also.
 *
 * \par Input:
 *    b8: Block position inside a macro block (0,1,2,3).
 *
 * \par Output:
 *    nonzero: 0 if no levels are nonzero.  1 if there are nonzero levels.
 *    coeff_cost: Counter for nonzero coefficients, used to discard expensive levels.
 ************************************************************************
 */

#define MC(coeff) ((coeff)&3)

int dct_8x8(Macroblock *currMB, ColorPlane pl, int b8,int *coeff_cost, int intra)
{
  int i,j,ilev,coeff_ctr;
  int level,scan_pos = 0,run = -1;
  int nonzero = FALSE;  

  int block_x = 8*(b8 & 0x01);
  int block_y = 8*(b8 >> 1);
  int pl_off = pl<<2;
  int*  ACLevel = img->cofAC[b8+pl_off][0][0];
  int*  ACRun   = img->cofAC[b8+pl_off][0][1];  
  const byte *c_cost     = COEFF_COST8x8[input->disthres];  
  imgpel **img_enc       = enc_picture->p_curr_img;
  imgpel (*curr_mpr)[16] = img->mpr[pl];
  int    (*curr_res)[16] = img->m7[pl];   
  
  int max_imgpel_value   = img->max_imgpel_value;
  int scan_poss[4] = { 0 }, runs[4] = { -1, -1, -1, -1 };
  int MCcoeff = 0;
  static imgpel *img_Y, *predY;
  int *m7;
  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_SCAN8x8 : SNGL_SCAN8x8;

  int qp_per = qp_per_matrix[qp];
  int qp_rem = qp_rem_matrix[qp];
  int q_bits = Q_BITS_8 + qp_per;
  int **fadjust8x8 = img->AdaptiveRounding ? (pl ? &img->fadjust8x8Cr[pl-1][intra][block_y] : &img->fadjust8x8[intra][block_y]) :NULL;
  int **levelscale    = LevelScale8x8Comp   [pl][intra][qp_rem];
  int **invlevelscale = InvLevelScale8x8Comp[pl][intra][qp_rem];
  int **leveloffset   = LevelOffset8x8Comp  [pl][intra][qp];

  if (!lossless_qpprime)
  {
    // forward 8x8 transform
    forward8x8(curr_res, curr_res, block_y, block_x);

    // Quant

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

      run++;
      ilev=0;

      if (currMB->luma_transform_size_8x8_flag && input->symbol_mode == CAVLC)
      {
        MCcoeff = MC(coeff_ctr);
        runs[MCcoeff]++;
      }

      m7 = &curr_res[block_y + j][block_x];
      level = (iabs (m7[i]) * levelscale[j][i] + leveloffset[j][i]) >> q_bits;

      if (level != 0)
      {
        if (img->AdaptiveRounding)
        {
          fadjust8x8[j][block_x + i] = rshift_rnd_sf((AdaptRndWeight * (iabs (m7[i]) * levelscale[j][i] - (level << q_bits))), (q_bits + 1));
        }

        nonzero=TRUE;

        if (currMB->luma_transform_size_8x8_flag && input->symbol_mode == CAVLC)
        {
          *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[runs[MCcoeff]];

          img->cofAC[b8+pl_off][MCcoeff][0][scan_poss[MCcoeff]  ] = isignab(level,m7[i]);
          img->cofAC[b8+pl_off][MCcoeff][1][scan_poss[MCcoeff]++] = runs[MCcoeff];          
          runs[MCcoeff]=-1;
        }
        else
        {
          *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run];
          ACLevel[scan_pos  ] = isignab(level,m7[i]);
          ACRun  [scan_pos++] = run;
          run=-1;                     // reset zero level counter
        }

        level = isignab(level, m7[i]);

        m7[i] = rshift_rnd_sf(level*invlevelscale[j][i]<<qp_per, 6); // dequantization
      }
      else
      {
        if (img->AdaptiveRounding)
          fadjust8x8[j][block_x + i] = 0;
        m7[i] = 0;
      }
    }

    if (!currMB->luma_transform_size_8x8_flag || input->symbol_mode != CAVLC)
      ACLevel[scan_pos] = 0;
    else
    {
      for(i=0; i<4; i++)
        img->cofAC[b8+pl_off][i][0][scan_poss[i]] = 0;
    }

    if (nonzero)
    {
      //    Inverse Transform
      inverse8x8(curr_res, curr_res, block_y, block_x);

      for( j=block_y; j<block_y + BLOCK_SIZE_8x8; j++)
      {
        img_Y = &img_enc[img->pix_y + j][img->pix_x + block_x];
        predY = &curr_mpr[j][block_x];
        m7 = &curr_res[j][block_x];
        for( i=0; i<BLOCK_SIZE_8x8; i++)
        {
          img_Y[i] = iClip1( max_imgpel_value, rshift_rnd_sf((m7[i]),DQ_BITS_8) + predY[i]);          
        }
      }
    }
    else // no transform coefficients
    {      
      for( j=block_y; j< block_y + BLOCK_SIZE_8x8; j++)
      {
        memcpy(&(img_enc[img->pix_y + j][img->pix_x + block_x]),&(curr_mpr[j][block_x]), BLOCK_SIZE_8x8 * sizeof(imgpel));
      }
    }
  }
  else
  {
    // Quant

    runs[0]=runs[1]=runs[2]=runs[3]=-1;
    scan_poss[0]=scan_poss[1]=scan_poss[2]=scan_poss[3]=0;

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

      if (currMB->luma_transform_size_8x8_flag && input->symbol_mode == CAVLC)
      {
        MCcoeff = MC(coeff_ctr);
        runs[MCcoeff]++;
      }

      m7 = &curr_res[block_y + j][block_x];
      level = iabs (m7[i]);

      if (img->AdaptiveRounding)
      {
        fadjust8x8[j][block_x+i] = 0;
      }

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

        if (currMB->luma_transform_size_8x8_flag && input->symbol_mode == CAVLC)
        {
          *coeff_cost += MAX_VALUE;

          img->cofAC[b8+pl_off][MCcoeff][0][scan_poss[MCcoeff]  ] = isignab(level,m7[i]);
          img->cofAC[b8+pl_off][MCcoeff][1][scan_poss[MCcoeff]++] = runs[MCcoeff];
          ++scan_pos;
          runs[MCcoeff]=-1;
        }
        else
        {
          *coeff_cost += MAX_VALUE;
          ACLevel[scan_pos  ] = isignab(level,m7[i]);
          ACRun  [scan_pos++] = run;
          run=-1;                     // reset zero level counter
        }

        level = isignab(level, m7[i]);
        ilev = level;
      }
    }
    if (!currMB->luma_transform_size_8x8_flag || input->symbol_mode != CAVLC)
      ACLevel[scan_pos] = 0;
    else
    {
      for(i=0; i<4; i++)
        img->cofAC[b8+pl_off][i][0][scan_poss[i]] = 0;
    }

   if(ipmode_DPCM<2)  //For residual DPCM
   {
   Inv_Residual_DPCM_8x8(pl, block_y, block_x);
   }

    for( j=block_y; j<block_y + BLOCK_SIZE_8x8; j++)
    {            
      for( i=block_x; i< block_x + BLOCK_SIZE_8x8; i++)
      {
        curr_res[j][i] = curr_res[j][i] + curr_mpr[j][i];
        img_enc[img->pix_y + j][img->pix_x + i]= (imgpel) curr_res[j][i];
      }
    }
  }

  //  Decoded block moved to frame memory
  return nonzero;
}

⌨️ 快捷键说明

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