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