[LMCS] Import LMCS chroma functions from VTM13.0

This commit is contained in:
Marko Viitanen 2021-06-01 09:01:55 +03:00
parent d945ee5d7f
commit fad11a5c92
2 changed files with 118 additions and 8 deletions

View file

@ -1124,7 +1124,7 @@ static void kvz_encoder_state_write_bitstream_picture_header(
if (encoder->chroma_format != KVZ_CSP_400)
{
WRITE_U(stream, 0, 1, "ph_chroma_residual_scale_flag"); // ToDo: LMCS Enable chroma scaling
WRITE_U(stream, state->tile->frame->lmcs_aps->m_sliceReshapeInfo.enableChromaAdj, 1, "ph_chroma_residual_scale_flag");
}
}
}

View file

@ -1363,12 +1363,11 @@ static void code_lmcs_aps(encoder_state_t* const state, lmcs_aps* aps)
WRITE_U(stream, signCW, 1, "lmcs_delta_sign_cw_flag[ i ]");
}
}
// ToDo: LMCS Chroma scaling
/*
int deltaCRS = aps->chromaPresentFlag ? aps->m_sliceReshapeInfo.chrResScalingOffset : 0;
int deltaCRS = state->encoder_control->chroma_format != KVZ_CSP_400 ? aps->m_sliceReshapeInfo.chrResScalingOffset : 0;
int signCRS = (deltaCRS < 0) ? 1 : 0;
int absCRS = (deltaCRS < 0) ? (-deltaCRS) : deltaCRS;
if (pcAPS->chromaPresentFlag)
if (state->encoder_control->chroma_format != KVZ_CSP_400)
{
WRITE_U(stream, absCRS, 3, "lmcs_delta_abs_crs");
}
@ -1376,7 +1375,6 @@ static void code_lmcs_aps(encoder_state_t* const state, lmcs_aps* aps)
{
WRITE_U(stream, signCRS, 1, "lmcs_delta_sign_crs_flag");
}
*/
}
@ -1396,7 +1394,7 @@ void kvz_encode_lmcs_adaptive_parameter_set(encoder_state_t* const state)
WRITE_U(stream, (int)1/*LMCS_APS*/, 3, "aps_params_type");
WRITE_U(stream, 0, 5, "adaptation_parameter_set_id");
WRITE_U(stream, 0/*state->encoder_control->chroma_format != KVZ_CSP_400*/, 1, "aps_chroma_present_flag");
WRITE_U(stream, state->encoder_control->chroma_format != KVZ_CSP_400, 1, "aps_chroma_present_flag");
code_lmcs_aps(state, state->tile->frame->lmcs_aps);
@ -1405,3 +1403,115 @@ void kvz_encode_lmcs_adaptive_parameter_set(encoder_state_t* const state)
}
}
/** find inx of PWL for inverse mapping
* \param average luma pred of TU
* \return idx of PWL for inverse mapping
* From VTM 13.0
*/
static int getPWLIdxInv(lmcs_aps* aps, int lumaVal)
{
int idxS = 0;
for (idxS = aps->m_sliceReshapeInfo.reshaperModelMinBinIdx; (idxS <= aps->m_sliceReshapeInfo.reshaperModelMaxBinIdx); idxS++)
{
if (lumaVal < aps->m_reshapePivot[idxS + 1]) break;
}
return MIN(idxS, PIC_CODE_CW_BINS - 1);
}
/** compute chroma residuce scale for TU
* \param average luma pred of TU
* \return chroma residue scale
* From VTM 13.0
*/
static int calculate_lmcs_chroma_adj(lmcs_aps* aps, kvz_pixel avgLuma)
{
int iAdj = aps->m_chromaAdjHelpLUT[getPWLIdxInv(aps, avgLuma)];
return iAdj;
}
/** compute chroma residuce scale for TU
* \param average luma pred of TU
* \return chroma residue scale
* From VTM 13.0
*/
int kvz_calculate_lmcs_chroma_adj_vpdu_nei(encoder_state_t* const state, lmcs_aps* aps, int x, int y, cu_info_t* cur_cu, lcu_t* lcu)
{
int xPos = x;
int yPos = y;
int x_local = SUB_SCU(x);
int y_local = SUB_SCU(y);
int ctuSize = LCU_WIDTH;
int numNeighbor = MIN(64, ctuSize);
int numNeighborLog = kvz_math_floor_log2(numNeighbor);
xPos = xPos / 64 * 64;
yPos = yPos / 64 * 64;
assert(LCU_WIDTH >= 64);
/*
// ToDo: Optimize the calculations by storing already calculated results
if (isVPDUprocessed(xPos, yPos))
{
return getChromaScale();
}
else*/
{
//setVPDULoc(xPos, yPos);
// ToDo: Handle dualtree
bool left_cu = (x > 0);
bool above_cu = (y > 0);
int strideY = state->tile->frame->rec_lmcs->stride;
int chromaScale = (1 << CSCALE_FP_PREC);
int lumaValue = -1;
kvz_pixel* recSrc0 = &state->tile->frame->rec_lmcs->y[x+y*strideY];
const uint32_t picH = state->tile->frame->height;
const uint32_t picW = state->tile->frame->width;
const kvz_pixel valueDC = 1 << (KVZ_BIT_DEPTH - 1);
int32_t recLuma = 0;
int pelnum = 0;
if (left_cu)
{
for (int i = 0; i < numNeighbor; i++)
{
int k = (yPos + i) >= picH ? (picH - yPos - 1) : i;
recLuma += recSrc0[-1 + k * strideY];
pelnum++;
}
}
if (above_cu)
{
for (int i = 0; i < numNeighbor; i++)
{
int k = (xPos + i) >= picW ? (picW - xPos - 1) : i;
recLuma += recSrc0[-strideY + k];
pelnum++;
}
}
if (pelnum == numNeighbor)
{
lumaValue = (recLuma + (1 << (numNeighborLog - 1))) >> numNeighborLog;
}
else if (pelnum == (numNeighbor << 1))
{
lumaValue = (recLuma + (1 << numNeighborLog)) >> (numNeighborLog + 1);
}
else
{
assert(pelnum == 0);
lumaValue = valueDC;
}
chromaScale = calculate_lmcs_chroma_adj(aps,lumaValue);
aps->m_chromaScale = chromaScale;
return chromaScale;
}
}