Newer
Older
if (binVarSortDsdCDF[firstBinVarLessThanVal2] > 0.5 && maxBinVar < 4.7)
}
}
}
}
void EncReshape::deriveReshapeParameters(double *array, int start, int end, ReshapeCW respCW, double &alpha, double &beta)
{
double minVar = 10.0, maxVar = 0.0;
for (int b = start; b <= end; b++)
{
if (array[b] < minVar) minVar = array[b];
if (array[b] > maxVar) maxVar = array[b];
}
double maxCW = (double)respCW.binCW[0];
double minCW = (double)respCW.binCW[1];
alpha = (minCW - maxCW) / (maxVar - minVar);
beta = (maxCW*maxVar - minCW*minVar) / (maxVar - minVar);
}
/**
-Init reshaping LUT from dQP model
*/
void EncReshape::initLUTfromdQPModel()
{
initModelParam();
int pwlFwdLUTsize = PIC_CODE_CW_BINS;
int pwlFwdBinLen = m_reshapeLUTSize / PIC_CODE_CW_BINS;
int p1 = m_dQPModel.scaleFracPrec;
int p2 = m_dQPModel.offsetFracPrec;
int scaleFP = (1 - 2 * m_dQPModel.scaleSign) * m_dQPModel.scaleAbs;
int offsetFP = (1 - 2 * m_dQPModel.offsetSign) * m_dQPModel.offsetAbs;
int maxQP = (1 - 2 * m_dQPModel.maxQPSign) * m_dQPModel.maxQPAbs;
int minQP = (1 - 2 * m_dQPModel.minQPSign) * m_dQPModel.minQPAbs;
int maxFP = maxQP * (1 << totalShift);
int minFP = minQP * (1 << totalShift);
int dQPDiv6FP;
int32_t * slopeLUT = new int32_t[m_reshapeLUTSize]();
int32_t * fwdLUTHighPrec = new int32_t[m_reshapeLUTSize]();
for (int i = 0; i < m_reshapeLUTSize; i++)
int inputY = m_lumaBD < 10 ? i << (10 - m_lumaBD) : m_lumaBD > 10 ? i >> (m_lumaBD - 10) : i;
temp = int64_t((scaleFP*inputY) * (1 << p2)) + int64_t(offsetFP * (1 << p1));
temp = temp > maxFP ? maxFP : temp < minFP ? minFP : temp;
signval = temp >= 0 ? 1 : -1;
absval = signval * temp;
dQPDiv6FP = signval * (((absval + 3) / 6 + (1 << (totalShift - 17))) >> (totalShift - 16));
for (int i = 0; i < (16 << (m_lumaBD - 8)); i++) { slopeLUT[i] = 0; }
for (int i = (235 << (m_lumaBD - 8)); i < m_reshapeLUTSize; i++) { slopeLUT[i] = 0; }
for (int i = 0; i < m_reshapeLUTSize - 1; i++)
fwdLUTHighPrec[i + 1] = fwdLUTHighPrec[i] + slopeLUT[i];
if (slopeLUT != nullptr) { delete[] slopeLUT; slopeLUT = nullptr; }
for (int i = 0; i < m_reshapeLUTSize; i++)
m_fwdLUT[i] = (short)(((fwdLUTHighPrec[i] >> 8) * (m_reshapeLUTSize - 1) + Roffset) / max_Y);
if (fwdLUTHighPrec != nullptr) { delete[] fwdLUTHighPrec; fwdLUTHighPrec = nullptr; }
m_sliceReshapeInfo.reshaperModelMinBinIdx = 1;
m_sliceReshapeInfo.reshaperModelMaxBinIdx = 14;
for (int i = 0; i < pwlFwdLUTsize; i++)
{
int16_t X1 = i * pwlFwdBinLen;
m_reshapePivot[pwlFwdLUTsize] = ((1 << m_lumaBD) - 1);
for (int i = 0; i < pwlFwdLUTsize; i++)
{
m_binCW[i] = m_reshapePivot[i + 1] - m_reshapePivot[i];
int maxAbsDeltaCW = 0, absDeltaCW = 0, deltaCW = 0;
for (int i = m_sliceReshapeInfo.reshaperModelMinBinIdx; i <= m_sliceReshapeInfo.reshaperModelMaxBinIdx; i++)
deltaCW = (int)m_binCW[i] - (int)m_initCW;
m_sliceReshapeInfo.reshaperModelBinCWDelta[i] = deltaCW;
absDeltaCW = (deltaCW < 0) ? (-deltaCW) : deltaCW;
if (absDeltaCW > maxAbsDeltaCW) { maxAbsDeltaCW = absDeltaCW; }
m_sliceReshapeInfo.maxNbitsNeededDeltaCW = std::max(1, 1 + floorLog2(maxAbsDeltaCW));
for (int i = 0; i < pwlFwdLUTsize; i++)
{
int16_t Y1 = m_reshapePivot[i];
int16_t Y2 = m_reshapePivot[i + 1];
m_fwdLUT[i*pwlFwdBinLen] = Clip3((Pel)0, (Pel)((1 << m_lumaBD) - 1), (Pel)Y1);
int log2PwlFwdBinLen = floorLog2(pwlFwdBinLen);
int32_t scale = ((int32_t)(Y2 - Y1) * (1 << FP_PREC) + (1 << (log2PwlFwdBinLen - 1))) >> (log2PwlFwdBinLen);
for (int j = 1; j < pwlFwdBinLen; j++)
{
int tempVal = Y1 + (((int32_t)scale * (int32_t)j + (1 << (FP_PREC - 1))) >> FP_PREC);
m_fwdLUT[i*pwlFwdBinLen + j] = Clip3((Pel)0, (Pel)((1<<m_lumaBD) -1), (Pel)tempVal);
reverseLUT(m_fwdLUT, m_invLUT, m_reshapeLUTSize);
updateChromaScaleLUT();
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
}
/**
-Perform fixe point exp2 calculation
\param val input value
\retval output value = exp2(val)
*/
int EncReshape::calcEXP2(int val)
{
int32_t i, f, r, s;
r = 0x00000e20;
i = ((int32_t)(val)+0x8000) & ~0xffff;
f = (int32_t)(val)-i;
s = ((15 << 16) - i) >> 16;
r = (r * f + 0x3e1cc333) >> 17;
r = (r * f + 0x58bd46a6) >> 16;
r = r * f + 0x7ffde4a3;
return (uint32_t)r >> s;
}
void EncReshape::constructReshaperSDR()
{
int bdShift = m_lumaBD - 10;
int usedCW = 0;
int totCW = bdShift != 0 ? (bdShift > 0 ? m_reshapeLUTSize / (1<<bdShift) : m_reshapeLUTSize * (1 << (-bdShift))) : m_reshapeLUTSize;
int histBins = PIC_ANALYZE_CW_BINS;
int histLenth = totCW/histBins;
int log2HistLenth = floorLog2(histLenth);
cwScaleBins1 = m_reshapeCW.binCW[0];
cwScaleBins2 = m_reshapeCW.binCW[1];
if (m_binCW[i] == histLenth + 1) cnt0++;
else if (m_binCW[i] == cwScaleBins1) cnt1++;
else if (m_binCW[i] == cwScaleBins2) cnt2++;
int resCW = usedCW - maxAllowedCW;
int cwReduce1 = (cwScaleBins1 - histLenth - 1) * cnt1;
int cwReduce2 = (histLenth + 1 - cwScaleBins2) * cnt0;
if (m_binCW[i] == histLenth + 1)
m_binCW[i] = cwScaleBins2;
if (m_binCW[i] == cwScaleBins1)
m_binCW[i] = histLenth + 1;
if (bdShift != 0)
{
for (int i = 0; i < PIC_ANALYZE_CW_BINS; i++)
{
m_binCW[i] = bdShift > 0 ? m_binCW[i] * (1 << bdShift) : m_binCW[i] / (1 << (-bdShift));
}
}
for (int i = 0; i < PIC_CODE_CW_BINS; i++)
{
m_binCW[i] = m_binCW[2 * i] + m_binCW[2 * i + 1];
m_sliceReshapeInfo.reshaperModelMinBinIdx = 0;
m_sliceReshapeInfo.reshaperModelMaxBinIdx = PIC_CODE_CW_BINS - 1;
for (int i = 0; i < PIC_CODE_CW_BINS; i++)
{
break;
}
}
for (int i = PIC_CODE_CW_BINS - 1; i >= 0; i--)
{
int maxAbsDeltaCW = 0, absDeltaCW = 0, deltaCW = 0;
for (int i = m_sliceReshapeInfo.reshaperModelMinBinIdx; i <= m_sliceReshapeInfo.reshaperModelMaxBinIdx; i++)
deltaCW = (int)m_binCW[i] - (int)m_initCW;
m_sliceReshapeInfo.reshaperModelBinCWDelta[i] = deltaCW;
absDeltaCW = (deltaCW < 0) ? (-deltaCW) : deltaCW;
if (absDeltaCW > maxAbsDeltaCW) { maxAbsDeltaCW = absDeltaCW; }
m_sliceReshapeInfo.maxNbitsNeededDeltaCW = std::max(1, 1 + floorLog2(maxAbsDeltaCW));
log2HistLenth = floorLog2(histLenth);
int sumBins = 0;
for (i = 0; i < PIC_CODE_CW_BINS; i++) { sumBins += m_binCW[i]; }
CHECK(sumBins >= m_reshapeLUTSize, "SDR CW assignment is wrong!!");
memset(tempFwdLUT, 0, (m_reshapeLUTSize + 1) * sizeof(int16_t));
tempFwdLUT[0] = 0;
tempFwdLUT[(i + 1)*histLenth] = tempFwdLUT[i*histLenth] + m_binCW[i];
int16_t Y1 = tempFwdLUT[i*histLenth];
int16_t Y2 = tempFwdLUT[(i + 1)*histLenth];
int32_t scale = ((int32_t)(Y2 - Y1) * (1 << FP_PREC) + (1 << (log2HistLenth - 1))) >> (log2HistLenth);
m_fwdLUT[i*histLenth] = Clip3((Pel)0, (Pel)((1 << m_lumaBD) - 1), (Pel)Y1);
for (j = 1; j < histLenth; j++)
tempFwdLUT[i*histLenth + j] = Y1 + (((int32_t)scale * (int32_t)j + (1 << (FP_PREC - 1))) >> FP_PREC);
m_fwdLUT[i*histLenth + j] = Clip3((Pel)0, (Pel)((1 << m_lumaBD) - 1), (Pel)tempFwdLUT[i*histLenth + j]);
}
}
for (i = 0; i < PIC_CODE_CW_BINS; i++)
{
int start = i*histLenth;
int end = (i + 1)*histLenth - 1;
m_cwLumaWeight[i] = m_fwdLUT[end] - m_fwdLUT[start];
if (tempFwdLUT != nullptr) { delete[] tempFwdLUT; tempFwdLUT = nullptr; }
reverseLUT(m_fwdLUT, m_invLUT, m_reshapeLUTSize);
updateChromaScaleLUT();