Newer
Older
*/
void EncReshape::initLUTfromdQPModel()
{
initModelParam();
int pwlFwdLUTsize = PIC_CODE_CW_BINS;
int pwlFwdBinLen = m_reshapeLUTSize / PIC_CODE_CW_BINS;
int p1 = m_dQPModel.ScaleFracPrec; //=16, precision of 0.015
int p2 = m_dQPModel.OffsetFracPrec; //=1, precision of 7.5
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 << total_shift);
int minFP = minQP * (1 << total_shift);
int temp, signval, absval;
int dQPDIV6_FP;
int32_t * SlopeLUT = new int32_t[m_reshapeLUTSize]();
int32_t * fLUT_HP = 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;
dQPDIV6_FP = signval * (((absval + 3) / 6 + (1 << (total_shift - 17))) >> (total_shift - 16));
SlopeLUT[i] = calcEXP2(dQPDIV6_FP);
}
if (m_dQPModel.FullRangeInputFlag == 0)
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++)
fLUT_HP[i + 1] = fLUT_HP[i] + SlopeLUT[i];
if (SlopeLUT != nullptr) { delete[] SlopeLUT; SlopeLUT = nullptr; }
int max_Y = (fLUT_HP[m_reshapeLUTSize - 1] + (1 << 7)) >> 8;
for (int i = 0; i < m_reshapeLUTSize; i++)
forwardReshapingLUT[i] = (short)(((fLUT_HP[i] >> 8) * (m_reshapeLUTSize - 1) + Roffset) / max_Y);
}
if (fLUT_HP != nullptr) { delete[] fLUT_HP; fLUT_HP = nullptr; }
m_sliceReshapeInfo.reshape_model_min_bin_idx = 1;
m_sliceReshapeInfo.reshape_model_max_bin_idx = 14;
for (int i = 0; i < pwlFwdLUTsize; i++)
{
int16_t X1 = i * pwlFwdBinLen;
m_reshapePivot[i] = forwardReshapingLUT[X1];
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.reshape_model_min_bin_idx; i <= m_sliceReshapeInfo.reshape_model_max_bin_idx; i++)
{
DeltaCW = (int)m_binCW[i] - (int)m_initCW;
m_sliceReshapeInfo.reshape_model_bin_CW_delta[i] = DeltaCW;
AbsDeltaCW = (DeltaCW < 0) ? (-DeltaCW) : DeltaCW;
if (AbsDeltaCW > maxAbsDeltaCW) { maxAbsDeltaCW = AbsDeltaCW; }
}
m_sliceReshapeInfo.maxNbitsNeededDeltaCW = g_aucLog2[maxAbsDeltaCW << 1];
for (int i = 0; i < pwlFwdLUTsize; i++)
{
int16_t Y1 = m_reshapePivot[i];
int16_t Y2 = m_reshapePivot[i + 1];
forwardReshapingLUT[i*pwlFwdBinLen] = Clip3((Pel)0, (Pel)((1 << m_lumaBD) - 1), (Pel)Y1);
int log2_pwlFwdBinLen = g_aucLog2[pwlFwdBinLen];
int32_t scale = ((int32_t)(Y2 - Y1) * (1 << FP_PREC) + (1 << (log2_pwlFwdBinLen - 1))) >> (log2_pwlFwdBinLen);
for (int j = 1; j < pwlFwdBinLen; j++)
{
int tempVal = Y1 + (((int32_t)scale * (int32_t)j + (1 << (FP_PREC - 1))) >> FP_PREC);
forwardReshapingLUT[i*pwlFwdBinLen + j] = Clip3((Pel)0, (Pel)((1<<m_lumaBD) -1), (Pel)tempVal);
reverseLUT(forwardReshapingLUT, inverseReshapingLUT, m_reshapeLUTSize);
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
updateChromaDQPLUT();
}
/**
-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 used_codewords;
int hist_lens = m_initCWAnalyze;
int log2_hist_lens = g_aucLog2[hist_lens];
int16_t *Y_LUT_all = new int16_t[m_reshapeLUTSize + 1]();
int i, j;
int cw_scale_bins1, cw_scale_bins2;
int max_allow_cw = tot_cw;
cw_scale_bins1 = m_reshapeCW.BinCW[0];
cw_scale_bins2 = m_reshapeCW.BinCW[1];
used_codewords = 0;
for (i = 0; i < hist_bins; i++)
if (used_codewords > max_allow_cw)
{
int cnt0 = 0, cnt1 = 0, cnt2 = 0;
for (i = 0; i < hist_bins; i++)
{
if (m_binCW[i] == hist_lens + 1) cnt0++;
else if (m_binCW[i] == cw_scale_bins1) cnt1++;
else if (m_binCW[i] == cw_scale_bins2) cnt2++;
}
int delta_cw = used_codewords - max_allow_cw;
int cw_reduce1 = (cw_scale_bins1 - hist_lens - 1) * cnt1;
int cw_reduce2 = (hist_lens + 1 - cw_scale_bins2) * cnt0;
if (delta_cw <= cw_reduce1)
{
int idx = 0;
while (delta_cw > 0)
{
delta_cw--;
}
idx++;
if (idx == hist_bins)
idx = 0;
}
}
else if (delta_cw > cw_reduce1 && delta_cw <= (cw_reduce1 + cw_reduce2))
{
delta_cw -= cw_reduce1;
int idx = 0;
while (delta_cw > 0)
{
if (m_binCW[idx] > cw_scale_bins2 && m_binCW[idx] < cw_scale_bins1)
delta_cw--;
}
idx++;
if (idx == hist_bins)
idx = 0;
}
for (i = 0; i < hist_bins; i++)
{
if (m_binCW[i] == cw_scale_bins1)
m_binCW[i] = hist_lens + 1;
}
}
else if (delta_cw > (cw_reduce1 + cw_reduce2))
{
delta_cw -= (cw_reduce1 + cw_reduce2);
int idx = 0;
while (delta_cw > 0)
{
if (m_binCW[idx] > 0 && m_binCW[idx] < (hist_lens + 1))
delta_cw--;
}
idx++;
if (idx == hist_bins)
idx = 0;
}
for (i = 0; i < hist_bins; i++)
{
if (m_binCW[i] == m_initCWAnalyze + 1)
m_binCW[i] = cw_scale_bins2;
if (m_binCW[i] == cw_scale_bins1)
m_binCW[i] = m_initCWAnalyze + 1;
}
}
}
for (int i = 0; i < PIC_CODE_CW_BINS; i++)
{
m_binCW[i] = m_binCW[2 * i] + m_binCW[2 * i + 1];
}
m_sliceReshapeInfo.reshape_model_min_bin_idx = 0;
m_sliceReshapeInfo.reshape_model_max_bin_idx = PIC_CODE_CW_BINS - 1;
for (int i = 0; i < PIC_CODE_CW_BINS; i++)
{
{
m_sliceReshapeInfo.reshape_model_min_bin_idx = i;
break;
}
}
for (int i = PIC_CODE_CW_BINS - 1; i >= 0; i--)
{
{
m_sliceReshapeInfo.reshape_model_max_bin_idx = i;
break;
}
}
int maxAbsDeltaCW = 0, AbsDeltaCW = 0, DeltaCW = 0;
for (int i = m_sliceReshapeInfo.reshape_model_min_bin_idx; i <= m_sliceReshapeInfo.reshape_model_max_bin_idx; i++)
{
DeltaCW = (int)m_binCW[i] - (int)m_initCW;
m_sliceReshapeInfo.reshape_model_bin_CW_delta[i] = DeltaCW;
AbsDeltaCW = (DeltaCW < 0) ? (-DeltaCW) : DeltaCW;
if (AbsDeltaCW > maxAbsDeltaCW) { maxAbsDeltaCW = AbsDeltaCW; }
}
m_sliceReshapeInfo.maxNbitsNeededDeltaCW = g_aucLog2[maxAbsDeltaCW << 1];
hist_bins = PIC_CODE_CW_BINS;
hist_lens = m_initCW;
log2_hist_lens = g_aucLog2[hist_lens];
for (i = 0; i < hist_bins; i++) { sum_bins += m_binCW[i]; }
CHECK(sum_bins > max_allow_cw, "SDR CW assignment is wrong!!");
memset(Y_LUT_all, 0, (m_reshapeLUTSize + 1) * sizeof(int16_t));
Y_LUT_all[0] = 0;
for (i = 0; i < hist_bins; i++)
{
Y_LUT_all[(i + 1)*hist_lens] = Y_LUT_all[i*hist_lens] + m_binCW[i];
int16_t Y1 = Y_LUT_all[i*hist_lens];
int16_t Y2 = Y_LUT_all[(i + 1)*hist_lens];
int32_t scale = ((int32_t)(Y2 - Y1) * (1 << FP_PREC) + (1 << (log2_hist_lens - 1))) >> (log2_hist_lens);
forwardReshapingLUT[i*hist_lens] = Clip3((Pel)0, (Pel)((1 << m_lumaBD) - 1), (Pel)Y1);
for (j = 1; j < hist_lens; j++)
{
Y_LUT_all[i*hist_lens + j] = Y1 + (((int32_t)scale * (int32_t)j + (1 << (FP_PREC - 1))) >> FP_PREC);
forwardReshapingLUT[i*hist_lens + j] = Clip3((Pel)0, (Pel)((1 << m_lumaBD) - 1), (Pel)Y_LUT_all[i*hist_lens + j]);
}
}
for (i = 0; i < PIC_CODE_CW_BINS; i++)
{
int i_start = i*hist_lens;
int i_end = (i + 1)*hist_lens - 1;
m_cwLumaWeight[i] = forwardReshapingLUT[i_end] - forwardReshapingLUT[i_start];
}
if (Y_LUT_all != nullptr) { delete[] Y_LUT_all; Y_LUT_all = nullptr; }
reverseLUT(forwardReshapingLUT, inverseReshapingLUT, m_reshapeLUTSize);