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

📄 quant.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 C
📖 第 1 页 / 共 3 页
字号:
      if(flag<0) return OC_BADHEADER;
      if(flag) {
        /* same as corresponding intra */
      } else {
        /* same as previous */
  }
  }
  }

  return 0;
  }

void CopyQTables(PB_INSTANCE *pbi, codec_setup_info *ci) {
  Q_LIST_ENTRY *qmat;

  memcpy(pbi->QThreshTable, ci->QThreshTable, sizeof(pbi->QThreshTable));
  memcpy(pbi->DcScaleFactorTable, ci->DcScaleFactorTable,
         sizeof(pbi->DcScaleFactorTable));

  /* the decoder only supports 6 different base matricies; do the
     best we can with the range table. We assume the first range
     entry is good for all qi values. A NULL range table entry
     indicates we fall back to the previous value. */
  qmat = ci->range_table[0]->qmat;
  memcpy(pbi->Y_coeffs, qmat, sizeof(pbi->Y_coeffs));
  if (ci->range_table[1]) qmat = ci->range_table[1]->qmat;
  memcpy(pbi->U_coeffs, qmat, sizeof(pbi->U_coeffs));
  if (ci->range_table[2]) qmat = ci->range_table[2]->qmat;
  memcpy(pbi->V_coeffs, qmat, sizeof(pbi->V_coeffs));
  if (ci->range_table[3]) qmat = ci->range_table[3]->qmat;
  memcpy(pbi->InterY_coeffs, qmat, sizeof(pbi->InterY_coeffs));
  if (ci->range_table[4]) qmat = ci->range_table[4]->qmat;
  memcpy(pbi->InterU_coeffs, qmat, sizeof(pbi->InterU_coeffs));
  if (ci->range_table[5]) qmat = ci->range_table[5]->qmat;
  memcpy(pbi->InterV_coeffs, qmat, sizeof(pbi->InterV_coeffs));
}

/* Initialize custom qtables using the VP31 values.
   Someday we can change the quant tables to be adaptive, or just plain
    better.*/
void InitQTables( PB_INSTANCE *pbi ){
  memcpy ( pbi->QThreshTable, QThreshTableV1, sizeof( pbi->QThreshTable ) );
  memcpy(pbi->DcScaleFactorTable, DcScaleFactorTableV1,
         sizeof(pbi->DcScaleFactorTable));
  memcpy(pbi->Y_coeffs, Y_coeffsV1, sizeof(pbi->Y_coeffs));
  memcpy(pbi->U_coeffs, UV_coeffsV1, sizeof(pbi->U_coeffs));
  memcpy(pbi->V_coeffs, UV_coeffsV1, sizeof(pbi->V_coeffs));
  memcpy(pbi->InterY_coeffs, Inter_coeffsV1, sizeof(pbi->InterY_coeffs));
  memcpy(pbi->InterU_coeffs, Inter_coeffsV1, sizeof(pbi->InterU_coeffs));
  memcpy(pbi->InterV_coeffs, Inter_coeffsV1, sizeof(pbi->InterV_coeffs));
}

static void BuildZigZagIndex(PB_INSTANCE *pbi){
  ogg_int32_t i,j;

  /* invert the row to zigzag coeffient order lookup table */
  for ( i = 0; i < BLOCK_SIZE; i++ ){
    j = dezigzag_index[i];
    pbi->zigzag_index[j] = i;
  }
}

static void init_quantizer ( CP_INSTANCE *cpi,
		      ogg_uint32_t scale_factor,
		      unsigned char QIndex ){
    int i;
    double ZBinFactor;
    double RoundingFactor;

    double temp_fp_quant_coeffs;
    double temp_fp_quant_round;
    double temp_fp_ZeroBinSize;
    PB_INSTANCE *pbi = &cpi->pb;

    const Q_LIST_ENTRY * Inter_coeffs;
    const Q_LIST_ENTRY * Y_coeffs;
    const Q_LIST_ENTRY * UV_coeffs;
    const Q_LIST_ENTRY * DcScaleFactorTable;

    /* Notes on setup of quantisers.  The initial multiplication by
     the scale factor is done in the ogg_int32_t domain to insure that the
     precision in the quantiser is the same as in the inverse
     quantiser where all calculations are integer.  The "<< 2" is a
     normalisation factor for the forward DCT transform. */

    /* New version rounding and ZB characteristics. */
    Inter_coeffs = Inter_coeffsV1;
    Y_coeffs = Y_coeffsV1;
    UV_coeffs = UV_coeffsV1;
    DcScaleFactorTable = DcScaleFactorTableV1;
    ZBinFactor = 0.9;

    switch(cpi->pb.info.sharpness){
    case 0:
      ZBinFactor = 0.65;
      if ( scale_factor <= 50 )
	RoundingFactor = 0.499;
      else
	RoundingFactor = 0.46;
      break;
    case 1:
      ZBinFactor = 0.75;
      if ( scale_factor <= 50 )
	RoundingFactor = 0.476;
      else
	RoundingFactor = 0.400;
      break;

    default:
      ZBinFactor = 0.9;
      if ( scale_factor <= 50 )
	RoundingFactor = 0.476;
      else
	RoundingFactor = 0.333;
      break;
    }

    /* Use fixed multiplier for intra Y DC */
    temp_fp_quant_coeffs =
      (((ogg_uint32_t)(DcScaleFactorTable[QIndex] * Y_coeffs[0])/100) << 2);
    if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 2 )
      temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 2;

    temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
    pbi->fp_quant_Y_round[0]	= (ogg_int32_t) (0.5 + temp_fp_quant_round);

    temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
    pbi->fp_ZeroBinSize_Y[0]	= (ogg_int32_t) (0.5 + temp_fp_ZeroBinSize);

    temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
    pbi->fp_quant_Y_coeffs[0]	= (0.5 + SHIFT16 * temp_fp_quant_coeffs);

    /* Intra UV */
    temp_fp_quant_coeffs =
      (((ogg_uint32_t)(DcScaleFactorTable[QIndex] * UV_coeffs[0])/100) << 2);
    if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 2)
      temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 2;

    temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
    pbi->fp_quant_UV_round[0]	= (0.5 + temp_fp_quant_round);

    temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
    pbi->fp_ZeroBinSize_UV[0]	= (0.5 + temp_fp_ZeroBinSize);

    temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
    pbi->fp_quant_UV_coeffs[0]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);

    /* Inter Y */
    temp_fp_quant_coeffs =
      (((ogg_uint32_t)(DcScaleFactorTable[QIndex] * Inter_coeffs[0])/100) << 2);
    if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 4)
      temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 4;

    temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
    pbi->fp_quant_Inter_round[0]= (0.5 + temp_fp_quant_round);

    temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
    pbi->fp_ZeroBinSize_Inter[0]= (0.5 + temp_fp_ZeroBinSize);

    temp_fp_quant_coeffs= 1.0 / temp_fp_quant_coeffs;
    pbi->fp_quant_Inter_coeffs[0]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);

    /* Inter UV */
    temp_fp_quant_coeffs =
      (((ogg_uint32_t)(DcScaleFactorTable[QIndex] * Inter_coeffs[0])/100) << 2);
    if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 4)
      temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 4;

    temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
    pbi->fp_quant_InterUV_round[0]= (0.5 + temp_fp_quant_round);

    temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
    pbi->fp_ZeroBinSize_InterUV[0]= (0.5 + temp_fp_ZeroBinSize);

    temp_fp_quant_coeffs= 1.0 / temp_fp_quant_coeffs;
    pbi->fp_quant_InterUV_coeffs[0]=
      (0.5 + SHIFT16 * temp_fp_quant_coeffs);

    for ( i = 1; i < 64; i++ ){
      /* now scale coefficients by required compression factor */
      /* Intra Y */
      temp_fp_quant_coeffs =
	(((ogg_uint32_t)(scale_factor * Y_coeffs[i]) / 100 ) << 2 );
      if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY) )
	temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY);

      temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
      pbi->fp_quant_Y_round[i]	= (0.5 + temp_fp_quant_round);

      temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
      pbi->fp_ZeroBinSize_Y[i]	= (0.5 + temp_fp_ZeroBinSize);

      temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
      pbi->fp_quant_Y_coeffs[i]	= (0.5 + SHIFT16 * temp_fp_quant_coeffs);

      /* Intra UV */
      temp_fp_quant_coeffs =
	(((ogg_uint32_t)(scale_factor * UV_coeffs[i]) / 100 ) << 2 );
      if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY))
	temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY);

      temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
      pbi->fp_quant_UV_round[i]	= (0.5 + temp_fp_quant_round);

      temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
      pbi->fp_ZeroBinSize_UV[i]	= (0.5 + temp_fp_ZeroBinSize);

      temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
      pbi->fp_quant_UV_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);

      /* Inter Y */
      temp_fp_quant_coeffs =
	(((ogg_uint32_t)(scale_factor * Inter_coeffs[i]) / 100 ) << 2 );
      if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY * 2) )
	temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY * 2);

      temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
      pbi->fp_quant_Inter_round[i]= (0.5 + temp_fp_quant_round);

      temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
      pbi->fp_ZeroBinSize_Inter[i]= (0.5 + temp_fp_ZeroBinSize);

      temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
      pbi->fp_quant_Inter_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);

      /* Inter UV */
      temp_fp_quant_coeffs =
	(((ogg_uint32_t)(scale_factor * Inter_coeffs[i]) / 100 ) << 2 );
      if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY * 2) )
	temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY * 2);

      temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
      pbi->fp_quant_InterUV_round[i]= (0.5 + temp_fp_quant_round);

      temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
      pbi->fp_ZeroBinSize_InterUV[i]= (0.5 + temp_fp_ZeroBinSize);

      temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
      pbi->fp_quant_InterUV_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);

    }

    pbi->fquant_coeffs = pbi->fp_quant_Y_coeffs;

}

void select_Y_quantiser ( PB_INSTANCE *pbi ){
  pbi->fquant_coeffs = pbi->fp_quant_Y_coeffs;
  pbi->fquant_round = pbi->fp_quant_Y_round;
  pbi->fquant_ZbSize = pbi->fp_ZeroBinSize_Y;
}

void select_Inter_quantiser ( PB_INSTANCE *pbi ){
  pbi->fquant_coeffs = pbi->fp_quant_Inter_coeffs;
  pbi->fquant_round = pbi->fp_quant_Inter_round;
  pbi->fquant_ZbSize = pbi->fp_ZeroBinSize_Inter;
}

void select_UV_quantiser ( PB_INSTANCE *pbi ){
  pbi->fquant_coeffs = pbi->fp_quant_UV_coeffs;
  pbi->fquant_round = pbi->fp_quant_UV_round;
  pbi->fquant_ZbSize = pbi->fp_quant_UV_round;
}

void select_InterUV_quantiser ( PB_INSTANCE *pbi ){
  pbi->fquant_coeffs = pbi->fp_quant_InterUV_coeffs;
  pbi->fquant_round = pbi->fp_quant_InterUV_round;
  pbi->fquant_ZbSize = pbi->fp_ZeroBinSize_InterUV;
}

void quantize( PB_INSTANCE *pbi,
	       ogg_int16_t * DCT_block,
	       Q_LIST_ENTRY * quantized_list){
  ogg_uint32_t   	i;              /*	Row index */
  Q_LIST_ENTRY  val;            /* Quantised value. */

  ogg_int32_t * FquantRoundPtr = pbi->fquant_round;
  ogg_int32_t * FquantCoeffsPtr = pbi->fquant_coeffs;
  ogg_int32_t * FquantZBinSizePtr = pbi->fquant_ZbSize;
  ogg_int16_t * DCT_blockPtr = DCT_block;
  ogg_uint32_t * ZigZagPtr = (ogg_uint32_t *)pbi->zigzag_index;
  ogg_int32_t temp;

  /* Set the quantized_list to default to 0 */
  memset( quantized_list, 0, 64 * sizeof(Q_LIST_ENTRY) );

  /* Note that we add half divisor to effect rounding on positive number */
  for( i = 0; i < VFRAGPIXELS; i++) {
    /* Column 0  */
    if ( DCT_blockPtr[0] >= FquantZBinSizePtr[0] ) {
      temp = FquantCoeffsPtr[0] * ( DCT_blockPtr[0] + FquantRoundPtr[0] ) ;

⌨️ 快捷键说明

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