📄 quant.c
字号:
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] ) ; val = (Q_LIST_ENTRY) (temp>>16);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -