📄 vbrquantize.c
字号:
} } } /* returning a scalefac without distortion, if possible */ if (sf_ok <= 255) { sf = sf_ok; } return sf;}/*********************************************************************** * * calc_short_block_vbr_sf() * calc_long_block_vbr_sf() * * Mark Taylor 2000-??-?? * Robert Hegemann 2000-10-25 made functions of it * ***********************************************************************//* a variation for vbr-mtrh */static intblock_sf(algo_t * that, const FLOAT l3_xmin[576], int vbrsf[SFBMAX], int vbrsfmin[SFBMAX]){ FLOAT max_xr34; const FLOAT *xr = &that->cod_info->xr[0]; const FLOAT *xr34_orig = &that->xr34orig[0]; const int *width = &that->cod_info->width[0]; const int max_nonzero_coeff = that->cod_info->max_nonzero_coeff; int maxsf = 0; int sfb = 0, j = 0, i = 0; int const psymax = that->cod_info->psymax; that->mingain_l = 0; that->mingain_s[0] = 0; that->mingain_s[1] = 0; that->mingain_s[2] = 0; while (j <= max_nonzero_coeff) { int l, w = l = width[sfb]; int m = max_nonzero_coeff - j + 1, m1, m2; if (l > m) { l = m; } max_xr34 = max_x34(&xr34_orig[j], l); m1 = find_lowest_scalefac(max_xr34); vbrsfmin[sfb] = m1; if (that->mingain_l < m1) { that->mingain_l = m1; } if (that->mingain_s[i] < m1) { that->mingain_s[i] = m1; } if (i < 2) { ++i; } else { i = 0; } if (sfb < psymax) { m2 = that->find(&xr[j], &xr34_orig[j], l3_xmin[sfb], l, m1); if (maxsf < m2) { maxsf = m2; } } else { if (maxsf < m1) { maxsf = m1; } m2 = maxsf; } vbrsf[sfb] = m2; ++sfb; j += w; } for (; sfb < SFBMAX; ++sfb) { vbrsf[sfb] = maxsf; vbrsfmin[sfb] = 0; } return maxsf;}/*********************************************************************** * * quantize xr34 based on scalefactors * * block_xr34 * * Mark Taylor 2000-??-?? * Robert Hegemann 2000-10-20 made functions of them * ***********************************************************************/static voidquantize_x34(const algo_t * that){ DOUBLEX x[4]; const FLOAT *xr34_orig = that->xr34orig; gr_info *cod_info = that->cod_info; int *l3 = cod_info->l3_enc; int j = 0, sfb = 0; const int max_nonzero_coeff = cod_info->max_nonzero_coeff; while (j <= max_nonzero_coeff) { const int s = ((cod_info->scalefac[sfb] + (cod_info->preflag ? pretab[sfb] : 0)) << (cod_info->scalefac_scale + 1)) + cod_info->subblock_gain[cod_info->window[sfb]] * 8; const int sfac = valid_sf(cod_info->global_gain - s); const FLOAT sfpow34 = IPOW20(sfac); int remaining; int l , w = l = cod_info->width[sfb]; int m = max_nonzero_coeff - j + 1; if (l > m) { l = m; } j += w; ++sfb; l >>= 1; remaining = l % 2; for (l >>= 1; l > 0; --l) { x[0] = sfpow34 * xr34_orig[0]; x[1] = sfpow34 * xr34_orig[1]; x[2] = sfpow34 * xr34_orig[2]; x[3] = sfpow34 * xr34_orig[3]; k_34_4(x, l3); l3 += 4; xr34_orig += 4; } if (remaining) { x[0] = sfpow34 * xr34_orig[0]; x[1] = sfpow34 * xr34_orig[1]; k_34_2(x, l3); l3 += 2; xr34_orig += 2; } }}static voidquantize_ISO(const algo_t * that){ DOUBLEX x[4]; const FLOAT *xr34_orig = that->xr34orig; gr_info *cod_info = that->cod_info; int *l3 = cod_info->l3_enc; int j = 0, sfb = 0; const int max_nonzero_coeff = cod_info->max_nonzero_coeff; while (j <= max_nonzero_coeff) { const int s = ((cod_info->scalefac[sfb] + (cod_info->preflag ? pretab[sfb] : 0)) << (cod_info->scalefac_scale + 1)) + cod_info->subblock_gain[cod_info->window[sfb]] * 8; const int sfac = valid_sf(cod_info->global_gain - s); const FLOAT sfpow34 = IPOW20(sfac); int remaining; int l, w = l = cod_info->width[sfb]; int m = max_nonzero_coeff - j + 1; if (l > m) { l = m; } j += w; ++sfb; l >>= 1; remaining = l % 2; for (l >>= 1; l > 0; --l) { x[0] = sfpow34 * xr34_orig[0]; x[1] = sfpow34 * xr34_orig[1]; x[2] = sfpow34 * xr34_orig[2]; x[3] = sfpow34 * xr34_orig[3]; k_iso_4(x, l3); l3 += 4; xr34_orig += 4; } if (remaining) { x[0] = sfpow34 * xr34_orig[0]; x[1] = sfpow34 * xr34_orig[1]; k_iso_2(x, l3); l3 += 2; xr34_orig += 2; } }}static const int max_range_short[SBMAX_s * 3] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0};static const int max_range_long[SBMAX_l] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0};static const int max_range_long_lsf_pretab[SBMAX_l] = { 7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };/* sfb=0..5 scalefac < 16 sfb>5 scalefac < 8 ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4; ol_sf = (cod_info->global_gain-210.0); ol_sf -= 8*cod_info->subblock_gain[i]; ol_sf -= ifqstep*scalefac[gr][ch].s[sfb][i];*/static voidset_subblock_gain(gr_info * cod_info, const int mingain_s[3], int sf[]){ const int maxrange1 = 15, maxrange2 = 7; const int ifqstepShift = (cod_info->scalefac_scale == 0) ? 1 : 2; int *sbg = cod_info->subblock_gain; int psymax = cod_info->psymax; int psydiv = 18; int sbg0, sbg1, sbg2; int sfb, i; if (psydiv > psymax) { psydiv = psymax; } for (i = 0; i < 3; ++i) { int maxsf1 = 0, maxsf2 = 0, minsf = 1000; /* see if we should use subblock gain */ for (sfb = i; sfb < psydiv; sfb += 3) { /* part 1 */ int v = -sf[sfb]; if (maxsf1 < v) { maxsf1 = v; } if (minsf > v) { minsf = v; } } for (; sfb < SFBMAX; sfb += 3) { /* part 2 */ int v = -sf[sfb]; if (maxsf2 < v) { maxsf2 = v; } if (minsf > v) { minsf = v; } } /* boost subblock gain as little as possible so we can * reach maxsf1 with scalefactors * 8*sbg >= maxsf1 */ { int m1 = maxsf1 - (maxrange1 << ifqstepShift); int m2 = maxsf2 - (maxrange2 << ifqstepShift); maxsf1 = Max(m1, m2); } if (minsf > 0) { sbg[i] = minsf >> 3; } else { sbg[i] = 0; } if (maxsf1 > 0) { int m1 = sbg[i]; int m2 = (maxsf1 + 7) >> 3; sbg[i] = Max(m1, m2); } if (sbg[i] > 0 && mingain_s[i] > (cod_info->global_gain - sbg[i] * 8)) { sbg[i] = (cod_info->global_gain - mingain_s[i]) >> 3; } if (sbg[i] > 7) { sbg[i] = 7; } } sbg0 = sbg[0] << 3; sbg1 = sbg[1] << 3; sbg2 = sbg[2] << 3; for (sfb = 0; sfb < SFBMAX; sfb += 3) { sf[sfb + 0] += sbg0; sf[sfb + 1] += sbg1; sf[sfb + 2] += sbg2; }}/* ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4; ol_sf = (cod_info->global_gain-210.0); ol_sf -= ifqstep*scalefac[gr][ch].l[sfb]; if (cod_info->preflag && sfb>=11) ol_sf -= ifqstep*pretab[sfb];*/static voidset_scalefacs(gr_info * cod_info, const int *vbrsfmin, int sf[], const int *max_range){ const int ifqstep = (cod_info->scalefac_scale == 0) ? 2 : 4; const int ifqstepShift = (cod_info->scalefac_scale == 0) ? 1 : 2; int *scalefac = cod_info->scalefac; int sfb, sfbmax = cod_info->sfbmax; int *sbg = cod_info->subblock_gain; int *window = cod_info->window; int preflag = cod_info->preflag; if (preflag) { for (sfb = 11; sfb < sfbmax; ++sfb) { sf[sfb] += pretab[sfb] << ifqstepShift; } } for (sfb = 0; sfb < sfbmax; ++sfb) { int gain = cod_info->global_gain - (sbg[window[sfb]] << 3) - ((preflag ? pretab[sfb] : 0) << ifqstepShift); if (sf[sfb] < 0) { int m = gain - vbrsfmin[sfb]; /* ifqstep*scalefac >= -sf[sfb], so round UP */ scalefac[sfb] = (ifqstep - 1 - sf[sfb]) >> ifqstepShift; if (scalefac[sfb] > max_range[sfb]) { scalefac[sfb] = max_range[sfb]; } if (scalefac[sfb] > 0 && (scalefac[sfb] << ifqstepShift) > m) { scalefac[sfb] = m >> ifqstepShift; } } else { scalefac[sfb] = 0; } } for (; sfb < SFBMAX; ++sfb) { scalefac[sfb] = 0; /* sfb21 */ }}static intcheckScalefactor(const gr_info * cod_info, const int vbrsfmin[SFBMAX]){ int sfb; for (sfb = 0; sfb < cod_info->psymax; ++sfb) { const int s = ((cod_info->scalefac[sfb] + (cod_info->preflag ? pretab[sfb] : 0)) << (cod_info-> scalefac_scale + 1)) + cod_info->subblock_gain[cod_info->window[sfb]] * 8; if ((cod_info->global_gain - s) < vbrsfmin[sfb]) { /* fprintf( stdout, "sf %d\n", sfb ); fprintf( stdout, "min %d\n", vbrsfmin[sfb] ); fprintf( stdout, "ggain %d\n", cod_info->global_gain ); fprintf( stdout, "scalefac %d\n", cod_info->scalefac[sfb] ); fprintf( stdout, "pretab %d\n", (cod_info->preflag ? pretab[sfb] : 0) ); fprintf( stdout, "scale %d\n", (cod_info->scalefac_scale + 1) ); fprintf( stdout, "subgain %d\n", cod_info->subblock_gain[cod_info->window[sfb]] * 8 ); fflush( stdout ); exit(-1); */ return 0; } } return 1;}/****************************************************************** * * short block scalefacs * ******************************************************************/static intshort_block_constrain(const algo_t * that, int vbrsf[SFBMAX], const int vbrsfmin[SFBMAX], int vbrmax){ gr_info *cod_info = that->cod_info; lame_internal_flags *gfc = that->gfc; int const maxminsfb = that->mingain_l; int mover, maxover0 = 0, maxover1 = 0, delta = 0; int v, v0, v1; int sfb; int psymax = cod_info->psymax; for (sfb = 0; sfb < psymax; ++sfb) { assert( vbrsf[sfb] >= vbrsfmin[sfb] ); v = vbrmax - vbrsf[sfb]; if (delta < v) { delta = v; } v0 = v - (4 * 14 + 2 * max_range_short[sfb]); v1 = v - (4 * 14 + 4 * max_range_short[sfb]); if (maxover0 < v0) { maxover0 = v0; } if (maxover1 < v1) { maxover1 = v1; } } if (gfc->noise_shaping == 2) { /* allow scalefac_scale=1 */ mover = Min(maxover0, maxover1); } else { mover = maxover0; } if (delta > mover) { delta = mover; } vbrmax -= delta; maxover0 -= mover; maxover1 -= mover; if (maxover0 == 0) { cod_info->scalefac_scale = 0; } else if (maxover1 == 0) { cod_info->scalefac_scale = 1; } if (vbrmax < maxminsfb) { vbrmax = maxminsfb; } cod_info->global_gain = vbrmax; if (cod_info->global_gain < 0) { cod_info->global_gain = 0; } else if (cod_info->global_gain > 255) { cod_info->global_gain = 255; } for (sfb = 0; sfb < SFBMAX; ++sfb) { vbrsf[sfb] -= vbrmax; } set_subblock_gain(cod_info, &that->mingain_s[0], vbrsf); set_scalefacs(cod_info, vbrsfmin, vbrsf, max_range_short); assert(checkScalefactor(cod_info, vbrsfmin));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -