📄 quant.cpp
字号:
}
/*--------------- INVERSE QUANTIZATION --------------------------*/
/*
Function:
---------
initInvQuantSingleStage - Initialization of the single-stage inverse
quantizer for a given Q index.
Arguments:
----------
quantState *state - PoInter to the state data structure.
Int *statePrevQ - PoInter to previous quantized value state.
Return Value:
-------------
<None>
Description:
------------
This must be called prior to single-stage inverse quantization. A seperate
state structure must be kept for each value that is quantized in parallel.
Single-stage inverse quantization is just successive calls to
invQuantSingleStage. For each value, need only be called once, before
the first call to invQuantSingleStage.
*/
Void CVTCCommon::initInvQuantSingleStage(quantState *state, Int *statePrevQ)
{
state->residualValue = 0;
state->partitionType = 0x2; /* fromReduced = 0 and fromDeadZone = 1 */
*statePrevQ = 0;
}
#define QLEVMID(q) (((q))/2) // 1124
/* Mapping of start of quantization level, sign, and quantization level size
to specific value.
*/
#define GETVAL(start, sgn, q) ((start) \
? ((start) + (sgn)*QLEVMID((q))) \
: 0)
/*
Function:
---------
invQuantSingleStage - Single-stage inverse quantizer.
Arguments:
----------
QIndex - Quantized value for this stage.
Q - Quantization value. Represents desired quantization level size.
state - State of quantizer.
Int *statePrevQ - PoInter to previous quantized value state.
Int updatePrevQ - 0 means don't update the statePrevQ variable. !0 means
update it.
Return Value:
-------------
Inverse quantization value for this stage.
Description:
------------
initInvQuantSingleStage must be called prior to using this function the
first time for a given value. It will compute the new, updated value
based on the current index and state associated with the value.
*/
Int CVTCCommon::invQuantSingleStage(Int QIndex, Int Q, quantState *state, Int *statePrevQ,
Int updatePrevQ)
{
Int refLevs; /* how many refinement levels in new stage */
Int val; /* new value to return for this stage */
Int sgn;
/*--------------- INITIAL QUANTIZATION STAGE -------------------*/
if (*statePrevQ==0)
{
val = QIndex*Q + SGN(QIndex)*(QIndex ? QLEVMID(Q) : 0);
/* update state */
state->residualValue = QIndex*Q;
CLR_fromReduced(state->partitionType);
if (QIndex)
CLR_fromDeadZone(state->partitionType);
else
SET_fromDeadZone(state->partitionType);
if (updatePrevQ)
*statePrevQ = Q;
return val;
}
/*--------------- NON-INITIAL QUANTIZATION STAGES -------------------*/
/* get the number of refinement levels from lastQUsed state */
refLevs = IROUND(*statePrevQ,Q);
/* Catch condition where there's no refinement being done.
State information is not changed.
*/
sgn = (state->residualValue < 0 || QIndex < 0) ? -1 : 1;
if (refLevs<=1)
val = GETVAL(state->residualValue,sgn,*statePrevQ);
else
{
Int inDeadZone; /* are we still in the dead zone */
Int lastQUsed; /* The "real" Q value last used */
Int lastLevSize; /* Size of quantization level used last */
Int newQUsed, newStateQ;
Int excess;
Int absQIndex;
/* Initialize the last quant value used */
lastQUsed = *statePrevQ;
/* update new Q value state */
newStateQ = newQUsed = ICEIL(lastQUsed,refLevs);
if (updatePrevQ)
*statePrevQ = newStateQ;
/* Get last level size */
lastLevSize = lastQUsed-fromReduced(state->partitionType);
/* check if a reduced level can span the last level */
if (refLevs*(newQUsed-1) >= lastLevSize)
{
--newQUsed;
/* might overshoot (?) but can't reduce anymore */
excess=0;
#if 1
if (lastLevSize-refLevs*newQUsed)
fprintf(stderr,"Excess in reduced partition\n");
#endif
}
else
/* get excess (overshoot) */
excess=lastLevSize-refLevs*newQUsed;
/* Set dead zone indicator */
inDeadZone = fromDeadZone(state->partitionType);
/*--- Calculate val. Update residualValue and fromReduced states ---*/
absQIndex = abs(QIndex);
if (excess==0)
{
if (newQUsed < newStateQ)
SET_fromReduced(state->partitionType);
else
CLR_fromReduced(state->partitionType);
state->residualValue += sgn*absQIndex*newQUsed;
}
else
{
Int reducedIdx;
Int fullLevs;
fullLevs = refLevs+excess;
if (absQIndex >= fullLevs)
{
SET_fromReduced(state->partitionType);
state->residualValue += sgn*fullLevs*newQUsed;
--newQUsed;
reducedIdx = absQIndex-fullLevs;
state->residualValue += sgn*reducedIdx*newQUsed;
}
else
{
CLR_fromReduced(state->partitionType);
state->residualValue += sgn*absQIndex*newQUsed;
}
}
val = GETVAL(state->residualValue, sgn, newQUsed);
if (inDeadZone && QIndex)
CLR_fromDeadZone(state->partitionType);
}
return val;
}
/*--------- DERIVED QUANTIZATION VALUES AND REFINEMENT LEVELS ----------*/
/*
函数输入:
Int curQ: 当前输入的量化值;
Int *lastQUsed: 上一次量化修正后的量化值,它将在函数中完成更新;
Int whichQ: 量化器所处的量化级。
函数返回值:
量化系数的级别数。
函数功能描述:
计算得到在给定量化级条件下的细化级别数并更新量化值。
*/
Int CVTCCommon::quantRefLev(Int curQ, Int *lastQUsed, Int whichQ)
{
Int refLevs;
Int newQUsed;
//计算得到量化细化的级别数
refLevs = IROUND(*lastQUsed,curQ);
if (whichQ==0 || refLevs>1)
{
//新的级别数
newQUsed = ICEIL(*lastQUsed,refLevs);
//更新量化值
*lastQUsed = newQUsed;
}
return refLevs;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -