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

📄 sbrhfadj.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 C
📖 第 1 页 / 共 3 页
字号:
			q = MULSHIFT32(sumEOrigMapped, gainMax);	/* Q(fbitsDQ - ACC_SCALE - 2), gainMax = Q30  */
			z = CLZ(sumECurr) - 1;
			r = InvRNormalized(sumECurr << z);	/* in =  Q(z - eCurrExpMax), out = Q(29 + 31 - z + eCurrExpMax) */
			gainMax = MULSHIFT32(q, r);			/* Q(29 + 31 - z + eCurrExpMax + fbitsDQ - ACC_SCALE - 2 - 32) */
			psi->gainMaxFBits = 26 - z + eCurrExpMax + fbitsDQ - ACC_SCALE;
		}
	}
	psi->sumEOrigMapped = sumEOrigMapped;
	psi->gainMax = gainMax;
}

/**************************************************************************************
 * Function:    CalcNoiseDivFactors
 *
 * Description: calculate 1/(1+Q) and Q/(1+Q) (4.6.18.7.4; 4.6.18.7.5)
 *
 * Inputs:      dequantized noise floor scalefactor
 *
 * Outputs:     1/(1+Q) and Q/(1+Q), format = Q31
 *
 * Return:      none
 **************************************************************************************/
static void CalcNoiseDivFactors(int q, int *qp1Inv, int *qqp1Inv)
{
	int z, qp1, t, s;

	/* 1 + Q_orig */
	qp1  = (q >> 1);
	qp1 += (1 << (FBITS_OUT_DQ_NOISE - 1));		/* >> 1 to avoid overflow when adding 1.0 */
	z = CLZ(qp1) - 1;							/* z <= 31 - FBITS_OUT_DQ_NOISE */
	qp1 <<= z;									/* Q(FBITS_OUT_DQ_NOISE + z) = Q31 * 2^-(31 - (FBITS_OUT_DQ_NOISE + z)) */
	t = InvRNormalized(qp1) << 1;				/* Q30 * 2^(31 - (FBITS_OUT_DQ_NOISE + z)), guaranteed not to overflow */

	/* normalize to Q31 */
	s = (31 - (FBITS_OUT_DQ_NOISE - 1) - z - 1);	/* clearly z >= 0, z <= (30 - (FBITS_OUT_DQ_NOISE - 1)) */
	*qp1Inv = (t >> s);								/* s = [0, 31 - FBITS_OUT_DQ_NOISE] */
	*qqp1Inv = MULSHIFT32(t, q) << (32 - FBITS_OUT_DQ_NOISE - s);
}

/**************************************************************************************
 * Function:    CalcComponentGains
 *
 * Description: calculate gain of envelope, sinusoids, and noise in one limiter band
 *                (4.6.18.7.5)
 *
 * Inputs:      initialized PSInfoSBR struct
 *              initialized SBRHeader struct for this SCE/CPE block
 *              initialized SBRGrid struct for this channel
 *              initialized SBRFreq struct for this SCE/CPE block
 *              initialized SBRChan struct for this channel
 *              index of current channel (0 for SCE, 0 or 1 for CPE)
 *              index of current envelope
 *              index of current limiter band
 *              number of fraction bits in dequantized envelope
 *
 * Outputs:     gains for envelope, sinusoids and noise
 *              number of fraction bits for envelope gain
 *              sum of the total gain for each component in this band
 *              other updated state variables
 *
 * Return:      none
 **************************************************************************************/
static void CalcComponentGains(PSInfoSBR *psi, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch, int env, int lim, int fbitsDQ)
{
	int d, m, mStart, mEnd, q, qm, noiseFloor, sIndexMapped;
	int shift, eCurr, maxFlag, gainMax, gainMaxFBits;
	int gain, sm, z, r, fbitsGain, gainScale;
	unsigned char *freqBandTab;

	mStart = sbrFreq->freqLimiter[lim];   /* these are offsets from kStart */
	mEnd =   sbrFreq->freqLimiter[lim + 1];

	gainMax = psi->gainMax;
	gainMaxFBits = psi->gainMaxFBits;

	d = (env == psi->la || env == sbrChan->laPrev ? 0 : 1);
	freqBandTab = (sbrGrid->freqRes[env] ? sbrFreq->freqHigh : sbrFreq->freqLow);

	/* figure out which noise floor this envelope is in (only 1 or 2 noise floors allowed) */
	noiseFloor = 0;
	if (sbrGrid->numNoiseFloors == 2 && sbrGrid->noiseTimeBorder[1] <= sbrGrid->envTimeBorder[env])
		noiseFloor++;

	psi->sumECurrGLim = 0;
	psi->sumSM = 0;
	psi->sumQM = 0;
	/* calculate energy of noise to add in this limiter band */
	for (m = mStart; m < mEnd; m++) {
		if (m == sbrFreq->freqNoise[psi->noiseFloorBand + 1] - sbrFreq->kStart) {
			/* map current QMF band to appropriate noise floor band (NOTE: freqLimiter[0] == freqLow[0] = freqHigh[0]) */
			psi->noiseFloorBand++;
			CalcNoiseDivFactors(psi->noiseDataDequant[ch][noiseFloor][psi->noiseFloorBand], &(psi->qp1Inv), &(psi->qqp1Inv));
		}
		if (m == sbrFreq->freqHigh[psi->highBand + 1] - sbrFreq->kStart)
			psi->highBand++;
		if (m == freqBandTab[psi->sBand + 1] - sbrFreq->kStart) {
			psi->sBand++;
			psi->sMapped = GetSMapped(sbrGrid, sbrFreq, sbrChan, env, psi->sBand, psi->la);
		}

		/* get sIndexMapped for this QMF subband */
		sIndexMapped = 0;
		r = ((sbrFreq->freqHigh[psi->highBand+1] + sbrFreq->freqHigh[psi->highBand]) >> 1);
		if (m + sbrFreq->kStart == r) {
			/* r = center frequency, deltaStep = (env >= la || sIndexMapped'(r, numEnv'-1) == 1) */
			if (env >= psi->la || sbrChan->addHarmonic[0][r] == 1)
				sIndexMapped = sbrChan->addHarmonic[1][psi->highBand];
		}

		/* save sine flags from last envelope in this frame:
		 *   addHarmonic[0][0...63] = saved sine present flag from previous frame, for each QMF subband
		 *   addHarmonic[1][0...nHigh-1] = addHarmonic bit from current frame, for each high-res frequency band
		 * from MPEG reference code - slightly different from spec
		 *   (sIndexMapped'(m,LE'-1) can still be 0 when numEnv == psi->la)
		 */
		if (env == sbrGrid->numEnv - 1) {
			if (m + sbrFreq->kStart == r)
				sbrChan->addHarmonic[0][m + sbrFreq->kStart] = sbrChan->addHarmonic[1][psi->highBand];
			else
				sbrChan->addHarmonic[0][m + sbrFreq->kStart] = 0;
		}

		gain = psi->envDataDequant[ch][env][psi->sBand];
		qm = MULSHIFT32(gain, psi->qqp1Inv) << 1;
		sm = (sIndexMapped ? MULSHIFT32(gain, psi->qp1Inv) << 1 : 0);

		/* three cases: (sMapped == 0 && delta == 1), (sMapped == 0 && delta == 0), (sMapped == 1) */
		if (d == 1 && psi->sMapped == 0)
			gain = MULSHIFT32(psi->qp1Inv, gain) << 1;
		else if (psi->sMapped != 0)
			gain = MULSHIFT32(psi->qqp1Inv, gain) << 1;

		/* gain, qm, sm = Q(fbitsDQ), gainMax = Q(fbitsGainMax) */
		eCurr = psi->eCurr[m];
		if (eCurr) {
			z = CLZ(eCurr) - 1;
			r = InvRNormalized(eCurr << z);		/* in = Q(z - eCurrExp), out = Q(29 + 31 - z + eCurrExp) */
			gainScale = MULSHIFT32(gain, r);	/* out = Q(29 + 31 - z + eCurrExp + fbitsDQ - 32) */
			fbitsGain = 29 + 31 - z + psi->eCurrExp[m] + fbitsDQ - 32;
		} else {
			/* if eCurr == 0, then gain is unchanged (divide by EPS = 1) */
			gainScale = gain;
			fbitsGain = fbitsDQ;
		}

		/* see if gain for this band exceeds max gain */
		maxFlag = 0;
		if (gainMax != (int)0x80000000) {
			if (fbitsGain >= gainMaxFBits) {
				shift = MIN(fbitsGain - gainMaxFBits, 31);
				maxFlag = ((gainScale >> shift) > gainMax ? 1 : 0);
			} else {
				shift = MIN(gainMaxFBits - fbitsGain, 31);
				maxFlag = (gainScale > (gainMax >> shift) ? 1 : 0);
			}
		}

		if (maxFlag) {
			/* gainScale > gainMax, calculate ratio with 32/16 division */
			q = 0;
			r = gainScale;	/* guaranteed > 0, else maxFlag could not have been set */
			z = CLZ(r);
			if (z < 16) {
				q = 16 - z;
				r >>= q;	/* out = Q(fbitsGain - q) */
			}

			z = CLZ(gainMax) - 1;
			r = (gainMax << z) / r;		/* out = Q((fbitsGainMax + z) - (fbitsGain - q)) */
			q = (gainMaxFBits + z) - (fbitsGain - q);	/* r = Q(q) */
			if (q > 30) {
				r >>= MIN(q - 30, 31);
			} else {
				z = MIN(30 - q, 30);
				CLIP_2N_SHIFT30(r, z);	/* let r = Q30 since range = [0.0, 1.0) (clip to 0x3fffffff = 0.99999) */
			}

			qm = MULSHIFT32(qm, r) << 2;
			gain = MULSHIFT32(gain, r) << 2;
			psi->gLimBuf[m] = gainMax;
			psi->gLimFbits[m] = gainMaxFBits;
		} else {
			psi->gLimBuf[m] = gainScale;
			psi->gLimFbits[m] = fbitsGain;
		}

		/* sumSM, sumQM, sumECurrGLim = Q(fbitsDQ - ACC_SCALE) */
		psi->smBuf[m] = sm;
		psi->sumSM += (sm >> ACC_SCALE);

		psi->qmLimBuf[m] = qm;
		if (env != psi->la && env != sbrChan->laPrev && sm == 0)
			psi->sumQM += (qm >> ACC_SCALE);

		/* eCurr * gain^2 same as gain^2, before division by eCurr
		 * (but note that gain != 0 even if eCurr == 0, since it's divided by eps)
		 */
		if (eCurr)
			psi->sumECurrGLim += (gain >> ACC_SCALE);
	}
}

/**************************************************************************************
 * Function:    ApplyBoost
 *
 * Description: calculate and apply boost factor for envelope, sinusoids, and noise
 *                in this limiter band (4.6.18.7.5)
 *
 * Inputs:      initialized PSInfoSBR struct
 *              initialized SBRFreq struct for this SCE/CPE block
 *              index of current limiter band
 *              number of fraction bits in dequantized envelope
 *
 * Outputs:     envelope gain, sinusoids and noise after scaling by gBoost
 *              format = Q(FBITS_GLIM_BOOST) for envelope gain,
 *                     = Q(FBITS_QLIM_BOOST) for noise
 *                     = Q(FBITS_OUT_QMFA) for sinusoids
 *
 * Return:      none
 *
 * Notes:       after scaling, each component has at least 1 GB
 **************************************************************************************/
static void ApplyBoost(PSInfoSBR *psi, SBRFreq *sbrFreq, int lim, int fbitsDQ)
{
	int m, mStart, mEnd, q, z, r;
	int sumEOrigMapped, gBoost;

	mStart = sbrFreq->freqLimiter[lim];   /* these are offsets from kStart */
	mEnd =   sbrFreq->freqLimiter[lim + 1];

	sumEOrigMapped = psi->sumEOrigMapped >> 1;
	r = (psi->sumECurrGLim >> 1) + (psi->sumSM >> 1) + (psi->sumQM >> 1);	/* 1 GB fine (sm and qm are mutually exclusive in acc) */
	if (r < (1 << (31-28))) {
		/* any non-zero numerator * 1/EPS_0 is > GBOOST_MAX
		 * round very small r to zero to avoid scaling problems
		 */
		gBoost = (sumEOrigMapped == 0 ? (1 << 28) : GBOOST_MAX);
		z = 0;
	} else if (sumEOrigMapped == 0) {
		/* 1/(any non-zero denominator) * EPS_0 is appx. 0 */
		gBoost = 0;
		z = 0;
	} else {
		/* numerator (sumEOrigMapped) and denominator (r) have same Q format (before << z) */
		z = CLZ(r) - 1;	/* z = [0, 27] */
		r = InvRNormalized(r << z);
		gBoost = MULSHIFT32(sumEOrigMapped, r);
	}

	/* gBoost = Q(28 - z) */
	if (gBoost > (GBOOST_MAX >> z)) {
		gBoost = GBOOST_MAX;
		z = 0;
	}
	gBoost <<= z;	/* gBoost = Q28, minimum 1 GB */

	/* convert gain, noise, sinusoids to fixed Q format, clipping if necessary
	 *   (rare, usually only happens at very low bitrates, introduces slight
	 *    distortion into final HF mapping, but should be inaudible)
	 */
	for (m = mStart; m < mEnd; m++) {
		/* let gLimBoost = Q24, since in practice the max values are usually 16 to 20
		 *   unless limiterGains == 3 (limiter off) and eCurr ~= 0 (i.e. huge gain, but only
		 *   because the envelope has 0 power anyway)
		 */
		q = MULSHIFT32(psi->gLimBuf[m], gBoost) << 2;	/* Q(gLimFbits) * Q(28) --> Q(gLimFbits[m]-2) */
		r = SqrtFix(q, psi->gLimFbits[m] - 2, &z);
		z -= FBITS_GLIM_BOOST;
		if (z >= 0) {
			psi->gLimBoost[m] = r >> MIN(z, 31);
		} else {
			z = MIN(30, -z);
			CLIP_2N_SHIFT30(r, z);
			psi->gLimBoost[m] = r;
		}

		q = MULSHIFT32(psi->qmLimBuf[m], gBoost) << 2;	/* Q(fbitsDQ) * Q(28) --> Q(fbitsDQ-2) */
		r = SqrtFix(q, fbitsDQ - 2, &z);
		z -= FBITS_QLIM_BOOST;		/* << by 14, since integer sqrt of x < 2^16, and we want to leave 1 GB */
		if (z >= 0) {
			psi->qmLimBoost[m] = r >> MIN(31, z);
		} else {
			z = MIN(30, -z);
			CLIP_2N_SHIFT30(r, z);
			psi->qmLimBoost[m] = r;

⌨️ 快捷键说明

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