diff --git a/source/Lib/CommonLib/Quant.cpp b/source/Lib/CommonLib/Quant.cpp index 1d7a37f18e0db8030d4ce9be51fb888196ecf0bd..85420985187418d1e0692dbc35b9fd461031185d 100644 --- a/source/Lib/CommonLib/Quant.cpp +++ b/source/Lib/CommonLib/Quant.cpp @@ -529,17 +529,33 @@ void Quant::setScalingList(ScalingList *scalingList, const int maxLog2TrDynamicR const int minimumQp = 0; const int maximumQp = SCALING_LIST_REM_NUM; +#if JVET_P01034_PRED_1D_SCALING_LIST + int scalingListId = 0; + int recScalingListId = 0; +#endif for(uint32_t size = SCALING_LIST_FIRST_CODED; size <= SCALING_LIST_LAST_CODED; size++) //2x2->64x64 { for(uint32_t list = 0; list < SCALING_LIST_NUM; list++) { +#if JVET_P01034_PRED_1D_SCALING_LIST + if ((size == SCALING_LIST_2x2 && list < 4) || (size == SCALING_LIST_64x64 && list % (SCALING_LIST_NUM / SCALING_LIST_PRED_MODES) != 0)) // skip 2x2 luma +#else if (size == SCALING_LIST_2x2 && list % (SCALING_LIST_NUM / SCALING_LIST_PRED_MODES) == 0) // skip 2x2 luma +#endif continue; for(int qp = minimumQp; qp < maximumQp; qp++) { +#if JVET_P01034_PRED_1D_SCALING_LIST + xSetScalingListEnc(scalingList, list, size, qp, scalingListId); + xSetScalingListDec(*scalingList, list, size, qp, scalingListId); +#else xSetScalingListEnc(scalingList,list,size,qp); xSetScalingListDec(*scalingList,list,size,qp); +#endif } +#if JVET_P01034_PRED_1D_SCALING_LIST + scalingListId++; +#endif } } //based on square result and apply downsample technology @@ -550,10 +566,21 @@ void Quant::setScalingList(ScalingList *scalingList, const int maxLog2TrDynamicR if (sizew == sizeh || (sizew == SCALING_LIST_1x1 && sizeh<SCALING_LIST_4x4) || (sizeh == SCALING_LIST_1x1 && sizew<SCALING_LIST_4x4)) continue; for (uint32_t list = 0; list < SCALING_LIST_NUM; list++) //9 { +#if JVET_P01034_PRED_1D_SCALING_LIST + int largerSide = (sizew > sizeh) ? sizew : sizeh; + if (largerSide == SCALING_LIST_64x64 && list % (SCALING_LIST_NUM / SCALING_LIST_PRED_MODES) != 0) continue; + if (largerSide < SCALING_LIST_4x4) printf("Rectangle Error !\n"); + recScalingListId = SCALING_LIST_NUM * (largerSide - 2) + 2 + (list / ((largerSide == SCALING_LIST_64x64) ? 3 : 1)); +#endif for (int qp = minimumQp; qp < maximumQp; qp++) { +#if JVET_P01034_PRED_1D_SCALING_LIST + xSetRecScalingListEnc(scalingList, list, sizew, sizeh, qp, recScalingListId); + xSetRecScalingListDec(*scalingList, list, sizew, sizeh, qp, recScalingListId); +#else xSetRecScalingListEnc(scalingList, list, sizew, sizeh, qp); xSetRecScalingListDec(*scalingList, list, sizew, sizeh, qp); +#endif } } } @@ -568,16 +595,31 @@ void Quant::setScalingListDec(const ScalingList &scalingList) const int minimumQp = 0; const int maximumQp = SCALING_LIST_REM_NUM; +#if JVET_P01034_PRED_1D_SCALING_LIST + int scalingListId = 0; + int recScalingListId = 0; +#endif for (uint32_t size = SCALING_LIST_FIRST_CODED; size <= SCALING_LIST_LAST_CODED; size++) { for(uint32_t list = 0; list < SCALING_LIST_NUM; list++) { +#if JVET_P01034_PRED_1D_SCALING_LIST + if ((size == SCALING_LIST_2x2 && list < 4) || (size == SCALING_LIST_64x64 && list % (SCALING_LIST_NUM / SCALING_LIST_PRED_MODES) != 0)) // skip 2x2 luma +#else if (size == SCALING_LIST_2x2 && list % (SCALING_LIST_NUM / SCALING_LIST_PRED_MODES) == 0) // skip 2x2 luma +#endif continue; for(int qp = minimumQp; qp < maximumQp; qp++) { +#if JVET_P01034_PRED_1D_SCALING_LIST + xSetScalingListDec(scalingList, list, size, qp, scalingListId); +#else xSetScalingListDec(scalingList,list,size,qp); +#endif } +#if JVET_P01034_PRED_1D_SCALING_LIST + scalingListId++; +#endif } } //based on square result and apply downsample technology @@ -589,9 +631,19 @@ void Quant::setScalingListDec(const ScalingList &scalingList) if (sizew == sizeh || (sizew == SCALING_LIST_1x1 && sizeh<SCALING_LIST_4x4) || (sizeh == SCALING_LIST_1x1 && sizew<SCALING_LIST_4x4)) continue; for (uint32_t list = 0; list < SCALING_LIST_NUM; list++) //9 { +#if JVET_P01034_PRED_1D_SCALING_LIST + int largerSide = (sizew > sizeh) ? sizew : sizeh; + if (largerSide == SCALING_LIST_64x64 && list % (SCALING_LIST_NUM / SCALING_LIST_PRED_MODES) != 0) continue; + if (largerSide < SCALING_LIST_4x4) printf("Rectangle Error !\n"); + recScalingListId = SCALING_LIST_NUM * (largerSide - 2) + 2 + (list / ((largerSide == SCALING_LIST_64x64) ? 3 : 1)); +#endif for (int qp = minimumQp; qp < maximumQp; qp++) { +#if JVET_P01034_PRED_1D_SCALING_LIST + xSetRecScalingListDec(scalingList, list, sizew, sizeh, qp, recScalingListId); +#else xSetRecScalingListDec(scalingList, list, sizew, sizeh, qp); +#endif } } } @@ -606,13 +658,21 @@ void Quant::setScalingListDec(const ScalingList &scalingList) * \param qp Quantization parameter * \param format chroma format */ +#if JVET_P01034_PRED_1D_SCALING_LIST +void Quant::xSetScalingListEnc(ScalingList *scalingList, uint32_t listId, uint32_t sizeId, int qp, uint32_t scalingListId) +#else void Quant::xSetScalingListEnc(ScalingList *scalingList, uint32_t listId, uint32_t sizeId, int qp) +#endif { uint32_t width = g_scalingListSizeX[sizeId]; uint32_t height = g_scalingListSizeX[sizeId]; uint32_t ratio = g_scalingListSizeX[sizeId]/std::min(MAX_MATRIX_SIZE_NUM,(int)g_scalingListSizeX[sizeId]); int *quantcoeff; +#if JVET_P01034_PRED_1D_SCALING_LIST + int *coeff = scalingList->getScalingListAddress(scalingListId); +#else int *coeff = scalingList->getScalingListAddress(sizeId,listId); +#endif quantcoeff = getQuantCoeff(listId, qp, sizeId, sizeId); const bool blockIsNotPowerOf4 = ((floorLog2(width) + floorLog2(height)) & 1) == 1; @@ -623,7 +683,11 @@ void Quant::xSetScalingListEnc(ScalingList *scalingList, uint32_t listId, uint32 (quantScales << LOG2_SCALING_LIST_NEUTRAL_VALUE), height, width, ratio, std::min(MAX_MATRIX_SIZE_NUM, (int)g_scalingListSizeX[sizeId]), +#if JVET_P01034_PRED_1D_SCALING_LIST + scalingList->getScalingListDC(scalingListId)); +#else scalingList->getScalingListDC(sizeId,listId)); +#endif } /** set quantized matrix coefficient for decode @@ -633,13 +697,21 @@ void Quant::xSetScalingListEnc(ScalingList *scalingList, uint32_t listId, uint32 * \param qp Quantization parameter * \param format chroma format */ +#if JVET_P01034_PRED_1D_SCALING_LIST +void Quant::xSetScalingListDec(const ScalingList &scalingList, uint32_t listId, uint32_t sizeId, int qp, uint32_t scalingListId) +#else void Quant::xSetScalingListDec(const ScalingList &scalingList, uint32_t listId, uint32_t sizeId, int qp) +#endif { uint32_t width = g_scalingListSizeX[sizeId]; uint32_t height = g_scalingListSizeX[sizeId]; uint32_t ratio = g_scalingListSizeX[sizeId]/std::min(MAX_MATRIX_SIZE_NUM,(int)g_scalingListSizeX[sizeId]); int *dequantcoeff; +#if JVET_P01034_PRED_1D_SCALING_LIST + const int *coeff = scalingList.getScalingListAddress(scalingListId); +#else const int *coeff = scalingList.getScalingListAddress(sizeId,listId); +#endif dequantcoeff = getDequantCoeff(listId, qp, sizeId, sizeId); @@ -651,7 +723,11 @@ void Quant::xSetScalingListDec(const ScalingList &scalingList, uint32_t listId, invQuantScale, height, width, ratio, std::min(MAX_MATRIX_SIZE_NUM, (int)g_scalingListSizeX[sizeId]), +#if JVET_P01034_PRED_1D_SCALING_LIST + scalingList.getScalingListDC(scalingListId)); +#else scalingList.getScalingListDC(sizeId,listId)); +#endif } /** set quantized matrix coefficient for encode @@ -661,7 +737,11 @@ void Quant::xSetScalingListDec(const ScalingList &scalingList, uint32_t listId, * \param qp Quantization parameter * \param format chroma format */ +#if JVET_P01034_PRED_1D_SCALING_LIST +void Quant::xSetRecScalingListEnc(ScalingList *scalingList, uint32_t listId, uint32_t sizeIdw, uint32_t sizeIdh, int qp, uint32_t scalingListId) +#else void Quant::xSetRecScalingListEnc(ScalingList *scalingList, uint32_t listId, uint32_t sizeIdw, uint32_t sizeIdh, int qp) +#endif { if (sizeIdw == sizeIdh) return; @@ -669,7 +749,11 @@ void Quant::xSetRecScalingListEnc(ScalingList *scalingList, uint32_t listId, uin uint32_t height = g_scalingListSizeX[sizeIdh]; uint32_t largeSideId = (sizeIdw > sizeIdh) ? sizeIdw : sizeIdh; //16 int *quantcoeff; +#if JVET_P01034_PRED_1D_SCALING_LIST + int *coeff = scalingList->getScalingListAddress(scalingListId);//4x4, 8x8 +#else int *coeff = scalingList->getScalingListAddress(largeSideId, listId);//4x4, 8x8 +#endif quantcoeff = getQuantCoeff(listId, qp, sizeIdw, sizeIdh);//final quantCoeff (downsample) const bool blockIsNotPowerOf4 = ((floorLog2(width) + floorLog2(height)) & 1) == 1; int quantScales = g_quantScales[blockIsNotPowerOf4?1:0][qp]; @@ -680,7 +764,11 @@ void Quant::xSetRecScalingListEnc(ScalingList *scalingList, uint32_t listId, uin height, width, ((largeSideId>3) ? 2 : 1), ((largeSideId >= 3) ? 8 : 4), +#if JVET_P01034_PRED_1D_SCALING_LIST + scalingList->getScalingListDC(scalingListId)); +#else scalingList->getScalingListDC(largeSideId, listId)); +#endif } /** set quantized matrix coefficient for decode * \param scalingList quantaized matrix address @@ -689,14 +777,22 @@ void Quant::xSetRecScalingListEnc(ScalingList *scalingList, uint32_t listId, uin * \param qp Quantization parameter * \param format chroma format */ +#if JVET_P01034_PRED_1D_SCALING_LIST +void Quant::xSetRecScalingListDec(const ScalingList &scalingList, uint32_t listId, uint32_t sizeIdw, uint32_t sizeIdh, int qp, uint32_t scalingListId) +#else void Quant::xSetRecScalingListDec(const ScalingList &scalingList, uint32_t listId, uint32_t sizeIdw, uint32_t sizeIdh, int qp) +#endif { if (sizeIdw == sizeIdh) return; uint32_t width = g_scalingListSizeX[sizeIdw]; uint32_t height = g_scalingListSizeX[sizeIdh]; uint32_t largeSideId = (sizeIdw > sizeIdh) ? sizeIdw : sizeIdh; //16 +#if JVET_P01034_PRED_1D_SCALING_LIST + const int *coeff = scalingList.getScalingListAddress(scalingListId); +#else const int *coeff = scalingList.getScalingListAddress(largeSideId, listId); +#endif int *dequantcoeff; dequantcoeff = getDequantCoeff(listId, qp, sizeIdw, sizeIdh); const bool blockIsNotPowerOf4 = ((floorLog2(width) + floorLog2(height)) & 1) == 1; @@ -706,7 +802,11 @@ void Quant::xSetRecScalingListDec(const ScalingList &scalingList, uint32_t listI invQuantScale, height, width, (largeSideId>3) ? 2 : 1, (largeSideId >= 3 ? 8 : 4), +#if JVET_P01034_PRED_1D_SCALING_LIST + scalingList.getScalingListDC(scalingListId)); +#else scalingList.getScalingListDC(largeSideId, listId)); +#endif } /** set flat matrix value to quantized coefficient */ diff --git a/source/Lib/CommonLib/Quant.h b/source/Lib/CommonLib/Quant.h index 4ce303767b71f747e38ee576b7f229f5a287145f..58505c399bb30e5d6e650873b7e40a7fda1e664e 100644 --- a/source/Lib/CommonLib/Quant.h +++ b/source/Lib/CommonLib/Quant.h @@ -160,10 +160,17 @@ private: void xInitScalingList ( const Quant* other ); void xDestroyScalingList(); void xSetFlatScalingList( uint32_t list, uint32_t sizeX, uint32_t sizeY, int qp ); +#if JVET_P01034_PRED_1D_SCALING_LIST + void xSetScalingListEnc(ScalingList *scalingList, uint32_t list, uint32_t size, int qp, uint32_t scalingListId); + void xSetScalingListDec(const ScalingList &scalingList, uint32_t list, uint32_t size, int qp, uint32_t scalingListId); + void xSetRecScalingListEnc(ScalingList *scalingList, uint32_t list, uint32_t sizew, uint32_t sizeh, int qp, uint32_t scalingListId); + void xSetRecScalingListDec(const ScalingList &scalingList, uint32_t list, uint32_t sizew, uint32_t sizeh, int qp, uint32_t scalingListId); +#else void xSetScalingListEnc ( ScalingList *scalingList, uint32_t list, uint32_t size, int qp ); void xSetScalingListDec ( const ScalingList &scalingList, uint32_t list, uint32_t size, int qp ); void xSetRecScalingListEnc( ScalingList *scalingList, uint32_t list, uint32_t sizew, uint32_t sizeh, int qp ); void xSetRecScalingListDec( const ScalingList &scalingList, uint32_t list, uint32_t sizew, uint32_t sizeh, int qp ); +#endif private: void xSignBitHidingHDQ (TCoeff* pQCoef, const TCoeff* pCoef, TCoeff* deltaU, const CoeffCodingContext& cctx, const int maxLog2TrDynamicRange); diff --git a/source/Lib/CommonLib/Rom.cpp b/source/Lib/CommonLib/Rom.cpp index 35b9935c9f3782ead07802dcd0fd8fd714a6b298..59e5c0d496d1b181ab422f2312374b940f491051 100644 --- a/source/Lib/CommonLib/Rom.cpp +++ b/source/Lib/CommonLib/Rom.cpp @@ -659,11 +659,21 @@ const char *MatrixType[SCALING_LIST_SIZE_NUM][SCALING_LIST_NUM] = }, { "INTRA64X64_LUMA", +#if JVET_P01034_PRED_1D_SCALING_LIST + "INTRA64X64_CHROMAU", + "INTRA64X64_CHROMAV", +#else "INTRA64X64_CHROMAU_FROM16x16_CHROMAU", "INTRA64X64_CHROMAV_FROM16x16_CHROMAV", +#endif "INTER64X64_LUMA", +#if JVET_P01034_PRED_1D_SCALING_LIST + "INTER64X64_CHROMAU", + "INTER64X64_CHROMAV" +#else "INTER64X64_CHROMAU_FROM16x16_CHROMAU", "INTER64X64_CHROMAV_FROM16x16_CHROMAV" +#endif }, { }, @@ -697,11 +707,21 @@ const char *MatrixType_DC[SCALING_LIST_SIZE_NUM][SCALING_LIST_NUM] = }, { "INTRA64X64_LUMA_DC", +#if JVET_P01034_PRED_1D_SCALING_LIST + "INTRA64X64_CHROMAU_DC", + "INTRA64X64_CHROMAV_DC", +#else "INTRA64X64_CHROMAU_DC_FROM16x16_CHROMAU", "INTRA64X64_CHROMAV_DC_FROM16x16_CHROMAV", +#endif "INTER64X64_LUMA_DC", +#if JVET_P01034_PRED_1D_SCALING_LIST + "INTER64X64_CHROMAU_DC", + "INTER64X64_CHROMAV_DC" +#else "INTER64X64_CHROMAU_DC_FROM16x16_CHROMAU", "INTER64X64_CHROMAV_DC_FROM16x16_CHROMAV" +#endif }, { }, diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index a521961fab9d5af5e2ed02c5252d121ece87f7a1..4de64a70d68d2a9116a8e9c64411741b1975549b 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -1961,6 +1961,13 @@ void ReferencePictureList::printRefPicInfo() const ScalingList::ScalingList() { +#if JVET_P01034_PRED_1D_SCALING_LIST + for (uint32_t scalingListId = 0; scalingListId < 28; scalingListId++) + { + int matrixSize = (scalingListId < SCALING_LIST_1D_START_4x4) ? 2 : (scalingListId < SCALING_LIST_1D_START_8x8) ? 4 : 8; + m_scalingListCoef[scalingListId].resize(matrixSize*matrixSize); + } +#else for(uint32_t sizeId = 0; sizeId < SCALING_LIST_SIZE_NUM; sizeId++) { for(uint32_t listId = 0; listId < SCALING_LIST_NUM; listId++) @@ -1968,12 +1975,19 @@ ScalingList::ScalingList() m_scalingListCoef[sizeId][listId].resize(std::min<int>(MAX_MATRIX_COEF_NUM,(int)g_scalingListSize[sizeId])); } } +#endif } /** set default quantization matrix to array */ void ScalingList::setDefaultScalingList() { +#if JVET_P01034_PRED_1D_SCALING_LIST + for (uint32_t scalingListId = 0; scalingListId < 28; scalingListId++) + { + processDefaultMatrix(scalingListId); + } +#else for(uint32_t sizeId = 0; sizeId < SCALING_LIST_SIZE_NUM; sizeId++) { for(uint32_t listId=0;listId<SCALING_LIST_NUM;listId++) @@ -1981,6 +1995,7 @@ void ScalingList::setDefaultScalingList() processDefaultMatrix(sizeId, listId); } } +#endif } /** check if use default quantization matrix * \returns true if the scaling list is not equal to the default quantization matrix @@ -1988,6 +2003,29 @@ void ScalingList::setDefaultScalingList() bool ScalingList::isNotDefaultScalingList() { bool isAllDefault = true; +#if JVET_P01034_PRED_1D_SCALING_LIST + for (uint32_t scalingListId = 0; scalingListId < 28; scalingListId++) + { + int matrixSize = (scalingListId < SCALING_LIST_1D_START_4x4) ? 2 : (scalingListId < SCALING_LIST_1D_START_8x8) ? 4 : 8; + if (scalingListId < SCALING_LIST_1D_START_16x16) + { + if (::memcmp(getScalingListAddress(scalingListId), getScalingListDefaultAddress(scalingListId), sizeof(int) * matrixSize * matrixSize)) + { + isAllDefault = false; + break; + } + } + else + { + if ((::memcmp(getScalingListAddress(scalingListId), getScalingListDefaultAddress(scalingListId), sizeof(int) * MAX_MATRIX_COEF_NUM)) || (getScalingListDC(scalingListId) != 16)) + { + isAllDefault = false; + break; + } + } + if (!isAllDefault) break; + } +#else for ( uint32_t sizeId = SCALING_LIST_2x2; sizeId <= SCALING_LIST_64x64; sizeId++) { for(uint32_t listId=0;listId<SCALING_LIST_NUM;listId++) @@ -2016,6 +2054,7 @@ bool ScalingList::isNotDefaultScalingList() } if (!isAllDefault) break; } +#endif return !isAllDefault; } @@ -2025,11 +2064,174 @@ bool ScalingList::isNotDefaultScalingList() * \param listId index of input matrix * \param refListId index of reference matrix */ -void ScalingList::processRefMatrix( uint32_t sizeId, uint32_t listId , uint32_t refListId ) +#if JVET_P01034_PRED_1D_SCALING_LIST +int ScalingList::lengthUvlc(int uiCode) +{ + if (uiCode < 0) printf("Error UVLC! \n"); + + int uiLength = 1; + int uiTemp = ++uiCode; + + CHECK(!uiTemp, "Integer overflow"); + + while (1 != uiTemp) + { + uiTemp >>= 1; + uiLength += 2; + } + return (uiLength >> 1) + ((uiLength + 1) >> 1); +} +int ScalingList::lengthSvlc(int uiCode) +{ + uint32_t uiCode2 = uint32_t(uiCode <= 0 ? (-uiCode) << 1 : (uiCode << 1) - 1); + int uiLength = 1; + int uiTemp = ++uiCode2; + + CHECK(!uiTemp, "Integer overflow"); + + while (1 != uiTemp) + { + uiTemp >>= 1; + uiLength += 2; + } + return (uiLength >> 1) + ((uiLength + 1) >> 1); +} +void ScalingList::codePredScalingList(int* scalingList, const int* scalingListPred, int scalingListDC, int scalingListPredDC, int scalingListId, int& bitsCost) //sizeId, listId is current to-be-coded matrix idx +{ + int deltaValue = 0; + int matrixSize = (scalingListId < SCALING_LIST_1D_START_4x4) ? 2 : (scalingListId < SCALING_LIST_1D_START_8x8) ? 4 : 8; + int coefNum = matrixSize*matrixSize; + ScanElement *scan = g_scanOrder[SCAN_UNGROUPED][SCAN_DIAG][gp_sizeIdxInfo->idxFrom(matrixSize)][gp_sizeIdxInfo->idxFrom(matrixSize)]; + int nextCoef = 0; + + int8_t data; + const int *src = scalingList; + const int *srcPred = scalingListPred; + if (scalingListDC!=-1 && scalingListPredDC!=-1) + { + bitsCost += lengthSvlc((int8_t)(scalingListDC - scalingListPredDC - nextCoef)); + nextCoef = scalingListDC - scalingListPredDC; + } + else if ((scalingListDC != -1 && scalingListPredDC == -1)) + { + bitsCost += lengthSvlc((int8_t)(scalingListDC - srcPred[scan[0].idx] - nextCoef)); + nextCoef = scalingListDC - srcPred[scan[0].idx]; + } + else if ((scalingListDC == -1 && scalingListPredDC == -1)) + { + } + else + { + printf("Predictor DC mismatch! \n"); + } + for (int i = 0; i < coefNum; i++) + { + if (scalingListId >= SCALING_LIST_1D_START_64x64 && scan[i].x >= 4 && scan[i].y >= 4) + continue; + deltaValue = (src[scan[i].idx] - srcPred[scan[i].idx]); + data = (int8_t)(deltaValue - nextCoef); + nextCoef = deltaValue; + + bitsCost += lengthSvlc(data); + } +} +void ScalingList::codeScalingList(int* scalingList, int scalingListDC, int scalingListId, int& bitsCost) //sizeId, listId is current to-be-coded matrix idx +{ + int matrixSize = (scalingListId < SCALING_LIST_1D_START_4x4) ? 2 : (scalingListId < SCALING_LIST_1D_START_8x8) ? 4 : 8; + int coefNum = matrixSize * matrixSize; + ScanElement *scan = g_scanOrder[SCAN_UNGROUPED][SCAN_DIAG][gp_sizeIdxInfo->idxFrom(matrixSize)][gp_sizeIdxInfo->idxFrom(matrixSize)]; + int nextCoef = SCALING_LIST_START_VALUE; + int8_t data; + const int *src = scalingList; + + if (scalingListId >= SCALING_LIST_1D_START_16x16) + { + bitsCost += lengthSvlc(int8_t(getScalingListDC(scalingListId) - nextCoef)); + nextCoef = getScalingListDC(scalingListId); + } + + for (int i = 0; i < coefNum; i++) + { + if (scalingListId >= SCALING_LIST_1D_START_64x64 && scan[i].x >= 4 && scan[i].y >= 4) + continue; + data = int8_t(src[scan[i].idx] - nextCoef); + nextCoef = src[scan[i].idx]; + + bitsCost += lengthSvlc(data); + } +} +void ScalingList::CheckBestPredScalingList(int scalingListId, int predListId, int& BitsCount) +{ + //check previously coded matrix as a predictor, code "lengthUvlc" function + int *scalingList = getScalingListAddress(scalingListId); + const int *scalingListPred = (scalingListId == predListId) ? ((predListId < SCALING_LIST_1D_START_8x8) ? g_quantTSDefault4x4 : g_quantIntraDefault8x8) : getScalingListAddress(predListId); + int scalingListDC = (scalingListId >= SCALING_LIST_1D_START_16x16) ? getScalingListDC(scalingListId) : -1; + int scalingListPredDC = (predListId >= SCALING_LIST_1D_START_16x16) ? ((scalingListId == predListId) ? 16 : getScalingListDC(predListId)) : -1; + + int bitsCost = 0; + int matrixSize = (scalingListId < SCALING_LIST_1D_START_4x4) ? 2 : (scalingListId < SCALING_LIST_1D_START_8x8) ? 4 : 8; + int predMatrixSize = (predListId < SCALING_LIST_1D_START_4x4) ? 2 : (predListId < SCALING_LIST_1D_START_8x8) ? 4 : 8; + + if (matrixSize != predMatrixSize) printf("Predictor size mismatch! \n"); + + bitsCost = 2 + lengthUvlc(scalingListId - predListId); + //copy-flag + predictor-mode-flag + deltaListId + codePredScalingList(scalingList, scalingListPred, scalingListDC, scalingListPredDC, scalingListId, bitsCost); + BitsCount = bitsCost; +} +void ScalingList::processRefMatrix(uint32_t scalinListId, uint32_t refListId) { - ::memcpy(getScalingListAddress(sizeId, listId),((listId == refListId)? getScalingListDefaultAddress(sizeId, refListId): getScalingListAddress(sizeId, refListId)),sizeof(int)*std::min(MAX_MATRIX_COEF_NUM,(int)g_scalingListSize[sizeId])); + int matrixSize = (scalinListId < SCALING_LIST_1D_START_4x4) ? 2 : (scalinListId < SCALING_LIST_1D_START_8x8) ? 4 : 8; + ::memcpy(getScalingListAddress(scalinListId), ((scalinListId == refListId) ? getScalingListDefaultAddress(refListId) : getScalingListAddress(refListId)), sizeof(int)*matrixSize*matrixSize); } +void ScalingList::checkPredMode(uint32_t scalingListId) +{ + int bestBitsCount = MAX_INT; + int BitsCount = 2; + setScalingListPreditorModeFlag(scalingListId, false); + codeScalingList(getScalingListAddress(scalingListId), ((scalingListId >= SCALING_LIST_1D_START_16x16) ? getScalingListDC(scalingListId) : -1), scalingListId, BitsCount); + bestBitsCount = BitsCount; + + for (int predListIdx = (int)scalingListId; predListIdx >= 0; predListIdx--) + { + int matrixSize = (scalingListId < SCALING_LIST_1D_START_4x4) ? 2 : (scalingListId < SCALING_LIST_1D_START_8x8) ? 4 : 8; + int predMatrixSize = (predListIdx < SCALING_LIST_1D_START_4x4) ? 2 : (predListIdx < SCALING_LIST_1D_START_8x8) ? 4 : 8; + if (((scalingListId == SCALING_LIST_1D_START_2x2 || scalingListId == SCALING_LIST_1D_START_4x4 || scalingListId == SCALING_LIST_1D_START_8x8) && predListIdx != (int)scalingListId) || matrixSize != predMatrixSize) + continue; + const int* refScalingList = (scalingListId == predListIdx) ? getScalingListDefaultAddress(predListIdx) : getScalingListAddress(predListIdx); + const int refDC = (predListIdx < SCALING_LIST_1D_START_16x16) ? refScalingList[0] : (scalingListId == predListIdx) ? 16 : getScalingListDC(predListIdx); + if (!::memcmp(getScalingListAddress(scalingListId), refScalingList, sizeof(int)*matrixSize*matrixSize) // check value of matrix + // check DC value + && (scalingListId < SCALING_LIST_1D_START_16x16 || getScalingListDC(scalingListId) == refDC)) + { + //copy mode + setRefMatrixId(scalingListId, predListIdx); + setScalingListCopyModeFlag(scalingListId, true); + setScalingListPreditorModeFlag(scalingListId, false); + return; + } + else + { + //predictor mode + //use previously coded matrix as a predictor + CheckBestPredScalingList(scalingListId, predListIdx, BitsCount); + if (BitsCount < bestBitsCount) + { + bestBitsCount = BitsCount; + setScalingListCopyModeFlag(scalingListId, false); + setScalingListPreditorModeFlag(scalingListId, true); + setRefMatrixId(scalingListId, predListIdx); + } + } + } + setScalingListCopyModeFlag(scalingListId, false); +} +#else +void ScalingList::processRefMatrix(uint32_t sizeId, uint32_t listId, uint32_t refListId) +{ + ::memcpy(getScalingListAddress(sizeId, listId), ((listId == refListId) ? getScalingListDefaultAddress(sizeId, refListId) : getScalingListAddress(sizeId, refListId)), sizeof(int)*std::min(MAX_MATRIX_COEF_NUM, (int)g_scalingListSize[sizeId])); +} void ScalingList::checkPredMode(uint32_t sizeId, uint32_t listId) { for (int predListIdx = (int)listId; predListIdx >= 0; predListIdx--) @@ -2047,6 +2249,7 @@ void ScalingList::checkPredMode(uint32_t sizeId, uint32_t listId) } setScalingListPredModeFlag(sizeId, listId, true); } +#endif static void outputScalingListHelp(std::ostream &os) { @@ -2080,14 +2283,25 @@ static void outputScalingListHelp(std::ostream &os) void ScalingList::outputScalingLists(std::ostream &os) const { +#if JVET_P01034_PRED_1D_SCALING_LIST + int scalingListId = 0; +#endif for (uint32_t sizeIdc = SCALING_LIST_2x2; sizeIdc <= SCALING_LIST_64x64; sizeIdc++) { const uint32_t size = (sizeIdc == 1) ? 2 : ((sizeIdc == 2) ? 4 : 8); for(uint32_t listIdc = 0; listIdc < SCALING_LIST_NUM; listIdc++) { +#if JVET_P01034_PRED_1D_SCALING_LIST + if (!((sizeIdc== SCALING_LIST_64x64 && listIdc % (SCALING_LIST_NUM / SCALING_LIST_PRED_MODES) != 0) || (sizeIdc == SCALING_LIST_2x2 && listIdc < 4))) +#else if (!(((sizeIdc == SCALING_LIST_64x64) && (listIdc % (SCALING_LIST_NUM / SCALING_LIST_PRED_MODES) != 0)) || ((sizeIdc == SCALING_LIST_2x2) && (listIdc % (SCALING_LIST_NUM / SCALING_LIST_PRED_MODES) == 0)))) +#endif { +#if JVET_P01034_PRED_1D_SCALING_LIST + const int *src = getScalingListAddress(scalingListId); +#else const int *src = getScalingListAddress(sizeIdc, listIdc); +#endif os << (MatrixType[sizeIdc][listIdc]) << " =\n "; for(uint32_t y=0; y<size; y++) { @@ -2099,9 +2313,16 @@ void ScalingList::outputScalingLists(std::ostream &os) const } if(sizeIdc > SCALING_LIST_8x8) { +#if JVET_P01034_PRED_1D_SCALING_LIST + os << MatrixType_DC[sizeIdc][listIdc] << " = \n " << std::setw(3) << getScalingListDC(scalingListId) << "\n"; +#else os << MatrixType_DC[sizeIdc][listIdc] << " = \n " << std::setw(3) << getScalingListDC(sizeIdc, listIdc) << "\n"; +#endif } os << "\n"; +#if JVET_P01034_PRED_1D_SCALING_LIST + scalingListId++; +#endif } } } @@ -2127,20 +2348,32 @@ bool ScalingList::xParseScalingList(const std::string &fileName) return true; } +#if JVET_P01034_PRED_1D_SCALING_LIST + int scalingListId = 0; +#endif for (uint32_t sizeIdc = SCALING_LIST_2x2; sizeIdc <= SCALING_LIST_64x64; sizeIdc++)//2x2-128x128 { const uint32_t size = std::min(MAX_MATRIX_COEF_NUM,(int)g_scalingListSize[sizeIdc]); for(uint32_t listIdc = 0; listIdc < SCALING_LIST_NUM; listIdc++) { +#if !JVET_P01034_PRED_1D_SCALING_LIST int * const src = getScalingListAddress(sizeIdc, listIdc); +#endif +#if JVET_P01034_PRED_1D_SCALING_LIST + if ((sizeIdc == SCALING_LIST_64x64 && listIdc % (SCALING_LIST_NUM / SCALING_LIST_PRED_MODES) != 0) || (sizeIdc == SCALING_LIST_2x2 && listIdc < 4)) +#else if (((sizeIdc == SCALING_LIST_64x64) && (listIdc % (SCALING_LIST_NUM / SCALING_LIST_PRED_MODES) != 0)) || ((sizeIdc == SCALING_LIST_2x2) && (listIdc % (SCALING_LIST_NUM / SCALING_LIST_PRED_MODES) == 0))) +#endif { continue; } else { +#if JVET_P01034_PRED_1D_SCALING_LIST + int * const src = getScalingListAddress(scalingListId); +#endif { fseek(fp, 0, SEEK_SET); bool bFound=false; @@ -2158,6 +2391,7 @@ bool ScalingList::xParseScalingList(const std::string &fileName) { msg( ERROR, "Error: cannot find Matrix %s from scaling list file %s\n", MatrixType[sizeIdc][listIdc], fileName.c_str()); return true; + } } for (uint32_t i=0; i<size; i++) @@ -2177,7 +2411,11 @@ bool ScalingList::xParseScalingList(const std::string &fileName) } //set DC value for default matrix check - setScalingListDC(sizeIdc,listIdc,src[0]); +#if JVET_P01034_PRED_1D_SCALING_LIST + setScalingListDC(scalingListId, src[0]); +#else + setScalingListDC(sizeIdc, listIdc, src[0]); +#endif if(sizeIdc > SCALING_LIST_8x8) { @@ -2212,9 +2450,16 @@ bool ScalingList::xParseScalingList(const std::string &fileName) return true; } //overwrite DC value when size of matrix is larger than 16x16 - setScalingListDC(sizeIdc,listIdc,data); +#if JVET_P01034_PRED_1D_SCALING_LIST + setScalingListDC(scalingListId, data); +#else + setScalingListDC(sizeIdc, listIdc, data); +#endif } } +#if JVET_P01034_PRED_1D_SCALING_LIST + scalingListId++; +#endif } } // std::cout << "\n\nRead scaling lists of:\n\n"; @@ -2230,10 +2475,19 @@ bool ScalingList::xParseScalingList(const std::string &fileName) * \param listId list index * \returns pointer of quantization matrix */ +#if JVET_P01034_PRED_1D_SCALING_LIST +const int* ScalingList::getScalingListDefaultAddress(uint32_t scalingListId) +#else const int* ScalingList::getScalingListDefaultAddress(uint32_t sizeId, uint32_t listId) +#endif { const int *src = 0; +#if JVET_P01034_PRED_1D_SCALING_LIST + int sizeId = (scalingListId < SCALING_LIST_1D_START_8x8) ? 2 : 3; + switch (sizeId) +#else switch(sizeId) +#endif { case SCALING_LIST_1x1: case SCALING_LIST_2x2: @@ -2245,7 +2499,11 @@ const int* ScalingList::getScalingListDefaultAddress(uint32_t sizeId, uint32_t l case SCALING_LIST_32x32: case SCALING_LIST_64x64: case SCALING_LIST_128x128: +#if JVET_P01034_PRED_1D_SCALING_LIST + src = g_quantInterDefault8x8; +#else src = (listId < (SCALING_LIST_NUM / SCALING_LIST_PRED_MODES)) ? g_quantIntraDefault8x8 : g_quantInterDefault8x8; +#endif break; default: THROW( "Invalid scaling list" ); @@ -2259,6 +2517,28 @@ const int* ScalingList::getScalingListDefaultAddress(uint32_t sizeId, uint32_t l * \param sizeId size index * \param listId index of input matrix */ +#if JVET_P01034_PRED_1D_SCALING_LIST +void ScalingList::processDefaultMatrix(uint32_t scalingListId) +{ + int matrixSize = (scalingListId < SCALING_LIST_1D_START_4x4) ? 2 : (scalingListId < SCALING_LIST_1D_START_8x8) ? 4 : 8; + ::memcpy(getScalingListAddress(scalingListId), getScalingListDefaultAddress(scalingListId), sizeof(int)*matrixSize*matrixSize); + setScalingListDC(scalingListId, SCALING_LIST_DC); +} + +/** check DC value of matrix for default matrix signaling + */ +void ScalingList::checkDcOfMatrix() +{ + for (uint32_t scalingListId = 0; scalingListId < 28; scalingListId++) + { + //check default matrix? + if (getScalingListDC(scalingListId) == 0) + { + processDefaultMatrix(scalingListId); + } + } +} +#else void ScalingList::processDefaultMatrix(uint32_t sizeId, uint32_t listId) { ::memcpy(getScalingListAddress(sizeId, listId),getScalingListDefaultAddress(sizeId,listId),sizeof(int)*std::min(MAX_MATRIX_COEF_NUM,(int)g_scalingListSize[sizeId])); @@ -2281,6 +2561,7 @@ void ScalingList::checkDcOfMatrix() } } } +#endif ParameterSetManager::ParameterSetManager() : m_spsMap(MAX_NUM_SPS) diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 5dd6a66648ab66a08a4d3bf7d0e89a2bd13c4e57..c0d36fcd88c380e8f29e08c15b9cfcf88e8a0f22 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -144,8 +144,34 @@ class ScalingList public: ScalingList(); virtual ~ScalingList() { } - int* getScalingListAddress(uint32_t sizeId, uint32_t listId) { return &(m_scalingListCoef[sizeId][listId][0]); } //!< get matrix coefficient - const int* getScalingListAddress(uint32_t sizeId, uint32_t listId) const { return &(m_scalingListCoef[sizeId][listId][0]); } //!< get matrix coefficient +#if JVET_P01034_PRED_1D_SCALING_LIST + int* getScalingListAddress(uint32_t scalingListId) { return &(m_scalingListCoef[scalingListId][0]); } //!< get matrix coefficient + const int* getScalingListAddress(uint32_t scalingListId) const { return &(m_scalingListCoef[scalingListId][0]); } //!< get matrix coefficient + void checkPredMode(uint32_t scalingListId); + + void setRefMatrixId(uint32_t scalingListId, uint32_t u) { m_refMatrixId[scalingListId] = u; } //!< set reference matrix ID + uint32_t getRefMatrixId(uint32_t scalingListId) const { return m_refMatrixId[scalingListId]; } //!< get reference matrix ID + + static const int* getScalingListDefaultAddress(uint32_t scalinListId); //!< get default matrix coefficient + void processDefaultMatrix(uint32_t scalinListId); + + void setScalingListDC(uint32_t scalinListId, uint32_t u) { m_scalingListDC[scalinListId] = u; } //!< set DC value + int getScalingListDC(uint32_t scalinListId) const { return m_scalingListDC[scalinListId]; } //!< get DC value + + void setScalingListCopyModeFlag(uint32_t scalinListId, bool bIsCopy) { m_scalingListPredModeFlagIsCopy[scalinListId] = bIsCopy; } + bool getScalingListCopyModeFlag(uint32_t scalinListId) const { return m_scalingListPredModeFlagIsCopy[scalinListId]; } //getScalingListPredModeFlag + void processRefMatrix(uint32_t scalingListId, uint32_t refListId); + + int lengthUvlc(int uiCode); + int lengthSvlc(int uiCode); + void CheckBestPredScalingList(int scalingListId, int predListIdx, int& BitsCount); + void codePredScalingList(int* scalingList, const int* scalingListPred, int scalingListDC, int scalingListPredDC, int scalinListId, int& bitsCost); + void codeScalingList(int* scalingList, int scalingListDC, int scalinListId, int& bitsCost); + void setScalingListPreditorModeFlag(uint32_t scalingListId, bool bIsPred) { m_scalingListPreditorModeFlag[scalingListId] = bIsPred; } + bool getScalingListPreditorModeFlag(uint32_t scalingListId) const { return m_scalingListPreditorModeFlag[scalingListId]; } +#else + int* getScalingListAddress(uint32_t sizeId, uint32_t listId) { return &(m_scalingListCoef[sizeId][listId][0]); } //!< get matrix coefficient + const int* getScalingListAddress(uint32_t sizeId, uint32_t listId) const { return &(m_scalingListCoef[sizeId][listId][0]); } //!< get matrix coefficient void checkPredMode(uint32_t sizeId, uint32_t listId); void setRefMatrixId(uint32_t sizeId, uint32_t listId, uint32_t u) { m_refMatrixId[sizeId][listId] = u; } //!< set reference matrix ID @@ -159,16 +185,21 @@ public: void setScalingListPredModeFlag(uint32_t sizeId, uint32_t listId, bool bIsDPCM) { m_scalingListPredModeFlagIsDPCM[sizeId][listId] = bIsDPCM; } bool getScalingListPredModeFlag(uint32_t sizeId, uint32_t listId) const { return m_scalingListPredModeFlagIsDPCM[sizeId][listId]; } + void processRefMatrix(uint32_t sizeId, uint32_t listId , uint32_t refListId ); +#endif void checkDcOfMatrix(); - void processRefMatrix(uint32_t sizeId, uint32_t listId , uint32_t refListId ); bool xParseScalingList(const std::string &fileName); void setDefaultScalingList(); bool isNotDefaultScalingList(); bool operator==( const ScalingList& other ) { +#if JVET_P01034_PRED_1D_SCALING_LIST + if (memcmp(m_scalingListPredModeFlagIsCopy, other.m_scalingListPredModeFlagIsCopy, sizeof(m_scalingListPredModeFlagIsCopy))) +#else if( memcmp( m_scalingListPredModeFlagIsDPCM, other.m_scalingListPredModeFlagIsDPCM, sizeof( m_scalingListPredModeFlagIsDPCM ) ) ) +#endif { return false; } @@ -195,10 +226,18 @@ public: private: void outputScalingLists(std::ostream &os) const; +#if JVET_P01034_PRED_1D_SCALING_LIST + bool m_scalingListPredModeFlagIsCopy [30]; //!< reference list index + int m_scalingListDC [30]; //!< the DC value of the matrix coefficient for 16x16 + uint32_t m_refMatrixId [30]; //!< RefMatrixID + bool m_scalingListPreditorModeFlag [30]; //!< reference list index + std::vector<int> m_scalingListCoef [30]; //!< quantization matrix +#else bool m_scalingListPredModeFlagIsDPCM [SCALING_LIST_SIZE_NUM][SCALING_LIST_NUM]; //!< reference list index int m_scalingListDC [SCALING_LIST_SIZE_NUM][SCALING_LIST_NUM]; //!< the DC value of the matrix coefficient for 16x16 uint32_t m_refMatrixId [SCALING_LIST_SIZE_NUM][SCALING_LIST_NUM]; //!< RefMatrixID std::vector<int> m_scalingListCoef [SCALING_LIST_SIZE_NUM][SCALING_LIST_NUM]; //!< quantization matrix +#endif }; class ConstraintInfo diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 40f60c8e438ceaa325d79f0db8874d1882df8a88..e4cfb8d141dc78d406f1ebc0aa80a4f2808ffdc0 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -49,6 +49,7 @@ #include <cstring> #include <assert.h> #include <cassert> +#define JVET_P01034_PRED_1D_SCALING_LIST 1 // JVET-P1034: 1D Scaling list index and add predictor mode #define JVET_P0345_LD_GOP_8 1 // JVET-P0345: low-delay gop size 8 @@ -737,6 +738,17 @@ enum ScalingListSize SCALING_LIST_LAST_CODED = SCALING_LIST_64x64 }; +#if JVET_P01034_PRED_1D_SCALING_LIST +enum ScalingList1dStartIdx +{ + SCALING_LIST_1D_START_2x2 = 0, + SCALING_LIST_1D_START_4x4 = 2, + SCALING_LIST_1D_START_8x8 = 8, + SCALING_LIST_1D_START_16x16 = 14, + SCALING_LIST_1D_START_32x32 = 20, + SCALING_LIST_1D_START_64x64 = 26, +}; +#endif // Slice / Slice segment encoding modes enum SliceConstraint { diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 21fe0fb280e8d31272bdc2df5007700d45ac75fe..0e695a0f891385fdf056a233b952652009ecf9b3 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -2825,6 +2825,47 @@ void HLSyntaxReader::parsePredWeightTable( Slice* pcSlice, const SPS *sps ) */ void HLSyntaxReader::parseScalingList(ScalingList* scalingList) { +#if JVET_P01034_PRED_1D_SCALING_LIST + uint32_t code; + bool scalingListCopyModeFlag; + + for (int scalingListId = 0; scalingListId < 28; scalingListId++) + { + READ_FLAG(code, "scaling_list_copy_mode_flag"); + scalingListCopyModeFlag = (code) ? true : false; + scalingList->setScalingListCopyModeFlag(scalingListId, scalingListCopyModeFlag); + + scalingList->setScalingListPreditorModeFlag(scalingListId, false); + if (!scalingListCopyModeFlag) + { + READ_FLAG(code, "scaling_list_predictor_mode_flag"); + scalingList->setScalingListPreditorModeFlag(scalingListId, code); + } + + if ((scalingListCopyModeFlag || scalingList->getScalingListPreditorModeFlag(scalingListId)) && scalingListId!= SCALING_LIST_1D_START_2x2 && scalingListId!= SCALING_LIST_1D_START_4x4 && scalingListId!= SCALING_LIST_1D_START_8x8) //Copy Mode + { + READ_UVLC(code, "scaling_list_pred_matrix_id_delta"); + scalingList->setRefMatrixId(scalingListId, (uint32_t)((int)(scalingListId)-(code))); + } + else if (scalingListCopyModeFlag || scalingList->getScalingListPreditorModeFlag(scalingListId)) + { + scalingList->setRefMatrixId(scalingListId, (uint32_t)((int)(scalingListId))); + } + if (scalingListCopyModeFlag)//copy + { + if (scalingListId >= SCALING_LIST_1D_START_16x16) + { + scalingList->setScalingListDC(scalingListId, + ((scalingListId == scalingList->getRefMatrixId(scalingListId)) ? 16 + : (scalingList->getRefMatrixId(scalingListId) < SCALING_LIST_1D_START_16x16) ? scalingList->getScalingListAddress(scalingList->getRefMatrixId(scalingListId))[0] : scalingList->getScalingListDC(scalingList->getRefMatrixId(scalingListId)))); + } + scalingList->processRefMatrix(scalingListId, scalingList->getRefMatrixId(scalingListId)); + } + else + { + decodeScalingList(scalingList, scalingListId, scalingList->getScalingListPreditorModeFlag(scalingListId)); + } +#else uint32_t code, sizeId, listId; bool scalingListPredModeFlag; //for each size @@ -2860,6 +2901,7 @@ void HLSyntaxReader::parseScalingList(ScalingList* scalingList) } } } +#endif } return; @@ -2870,11 +2912,40 @@ void HLSyntaxReader::parseScalingList(ScalingList* scalingList) * \param sizeId size index * \param listId list index */ +#if JVET_P01034_PRED_1D_SCALING_LIST +void HLSyntaxReader::decodeScalingList(ScalingList *scalingList, uint32_t scalingListId, bool isPredictor) +#else void HLSyntaxReader::decodeScalingList(ScalingList *scalingList, uint32_t sizeId, uint32_t listId) +#endif { +#if JVET_P01034_PRED_1D_SCALING_LIST + int matrixSize = (scalingListId < SCALING_LIST_1D_START_4x4) ? 2 : (scalingListId < SCALING_LIST_1D_START_8x8) ? 4 : 8; + int i, coefNum = matrixSize * matrixSize; +#else int i,coefNum = std::min(MAX_MATRIX_COEF_NUM,(int)g_scalingListSize[sizeId]); +#endif int data; int scalingListDcCoefMinus8 = 0; +#if JVET_P01034_PRED_1D_SCALING_LIST + int nextCoef = (isPredictor) ? 0 : SCALING_LIST_START_VALUE; + ScanElement *scan = g_scanOrder[SCAN_UNGROUPED][SCAN_DIAG][gp_sizeIdxInfo->idxFrom(matrixSize)][gp_sizeIdxInfo->idxFrom(matrixSize)]; + int *dst = scalingList->getScalingListAddress(scalingListId); + + int PredListId = scalingList->getRefMatrixId(scalingListId); + if (PredListId > scalingListId) printf("Scaling List error predictor! \n"); + const int *srcPred = (isPredictor) ? ((scalingListId == PredListId) ? scalingList->getScalingListDefaultAddress(scalingListId) : scalingList->getScalingListAddress(PredListId)) : NULL; + int predCoef = 0; + + if (scalingListId >= SCALING_LIST_1D_START_16x16) + { + READ_SVLC(scalingListDcCoefMinus8, "scaling_list_dc_coef_minus8"); + nextCoef += scalingListDcCoefMinus8; + if (isPredictor) + { + predCoef = (PredListId >= SCALING_LIST_1D_START_16x16) ? scalingList->getScalingListDC(PredListId) : srcPred[0]; + } + scalingList->setScalingListDC(scalingListId, (nextCoef + predCoef + 256) % 256); +#else int nextCoef = SCALING_LIST_START_VALUE; ScanElement *scan = g_scanOrder[SCAN_UNGROUPED][SCAN_DIAG][gp_sizeIdxInfo->idxFrom(1 << (sizeId == SCALING_LIST_2x2 ? 1 : (sizeId == SCALING_LIST_4x4 ? 2 : 3)))][gp_sizeIdxInfo->idxFrom(1 << (sizeId == SCALING_LIST_2x2 ? 1 : (sizeId == SCALING_LIST_4x4 ? 2 : 3)))]; int *dst = scalingList->getScalingListAddress(sizeId, listId); @@ -2884,18 +2955,29 @@ void HLSyntaxReader::decodeScalingList(ScalingList *scalingList, uint32_t sizeId READ_SVLC( scalingListDcCoefMinus8, "scaling_list_dc_coef_minus8"); scalingList->setScalingListDC(sizeId,listId,scalingListDcCoefMinus8 + 8); nextCoef = scalingList->getScalingListDC(sizeId,listId); +#endif } for(i = 0; i < coefNum; i++) { +#if JVET_P01034_PRED_1D_SCALING_LIST + if (scalingListId >= SCALING_LIST_1D_START_64x64 && scan[i].x >= 4 && scan[i].y >= 4) +#else if (sizeId == SCALING_LIST_64x64 && scan[i].x >= 4 && scan[i].y >= 4) +#endif { dst[scan[i].idx] = 0; continue; } READ_SVLC( data, "scaling_list_delta_coef"); - nextCoef = (nextCoef + data + 256 ) % 256; - dst[scan[i].idx] = nextCoef;//[scan[scanIdx].idx] +#if JVET_P01034_PRED_1D_SCALING_LIST + nextCoef += data; + predCoef = (isPredictor) ? srcPred[scan[i].idx] : 0; + dst[scan[i].idx] = (nextCoef + predCoef + 256) % 256; +#else + nextCoef = (nextCoef + data + 256) % 256; + dst[scan[i].idx] = nextCoef; +#endif } } diff --git a/source/Lib/DecoderLib/VLCReader.h b/source/Lib/DecoderLib/VLCReader.h index 0c976026a10c17565c87c5688af6b2a7e6a71006..3b0c58719127558e998ab0187f11c301d2ee5309 100644 --- a/source/Lib/DecoderLib/VLCReader.h +++ b/source/Lib/DecoderLib/VLCReader.h @@ -164,7 +164,11 @@ public: void parsePredWeightTable( Slice* pcSlice, const SPS *sps ); void parseScalingList ( ScalingList* scalingList ); +#if JVET_P01034_PRED_1D_SCALING_LIST + void decodeScalingList ( ScalingList *scalingList, uint32_t scalingListId, bool isPredictor); +#else void decodeScalingList ( ScalingList *scalingList, uint32_t sizeId, uint32_t listId); +#endif void parseReshaper ( SliceReshapeInfo& sliceReshaperInfo, const SPS* pcSPS, const bool isIntra ); void alfFilter( AlfParam& alfParam, const bool isChroma, const int altIdx ); diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index b541f35c6ad395daa16e6d64452e146188bbc85a..3ca835b86a3a02439b8acf1a65bf1d8513cd14ed 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -493,6 +493,12 @@ void EncLib::xInitScalingLists( SPS &sps, APS &aps ) if( getUseScalingListId() == SCALING_LIST_FILE_READ ) { // Prepare delta's: +#if JVET_P01034_PRED_1D_SCALING_LIST + for (uint32_t scalingListId = 0; scalingListId < 28; scalingListId++) + { + aps.getScalingList().checkPredMode(scalingListId); + } +#else for (uint32_t sizeId = SCALING_LIST_2x2; sizeId <= SCALING_LIST_64x64; sizeId++) { for (uint32_t listId = 0; listId < SCALING_LIST_NUM; listId++) @@ -505,6 +511,7 @@ void EncLib::xInitScalingLists( SPS &sps, APS &aps ) aps.getScalingList().checkPredMode( sizeId, listId ); } } +#endif } } diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 44386f2b13694037693c20f59a6e0958c19cff9e..023d0a90c7e8f632f37134fbb2a20e84c32b5b9b 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -1775,6 +1775,25 @@ void HLSWriter::xCodePredWeightTable( Slice* pcSlice ) void HLSWriter::codeScalingList( const ScalingList &scalingList ) { //for each size +#if JVET_P01034_PRED_1D_SCALING_LIST + for (uint32_t scalingListId = 0; scalingListId < 28; scalingListId++) + { + bool scalingListCopyModeFlag = scalingList.getScalingListCopyModeFlag(scalingListId); + WRITE_FLAG(scalingListCopyModeFlag, "scaling_list_copy_mode_flag"); //copy mode + if (!scalingListCopyModeFlag)// Copy Mode + { + WRITE_FLAG(scalingList.getScalingListPreditorModeFlag(scalingListId), "scaling_list_predictor_mode_flag"); + } + if ((scalingListCopyModeFlag || scalingList.getScalingListPreditorModeFlag(scalingListId)) && scalingListId!= SCALING_LIST_1D_START_2x2 && scalingListId != SCALING_LIST_1D_START_4x4 && scalingListId != SCALING_LIST_1D_START_8x8) + { + WRITE_UVLC((int)scalingListId - (int)scalingList.getRefMatrixId(scalingListId), "scaling_list_pred_matrix_id_delta"); + } + if (!scalingListCopyModeFlag) + { + //DPCM + xCodeScalingList(&scalingList, scalingListId, scalingList.getScalingListPreditorModeFlag(scalingListId)); + } +#else for(uint32_t sizeId = SCALING_LIST_FIRST_CODED; sizeId <= SCALING_LIST_LAST_CODED; sizeId++) { const int predListStep = (sizeId > SCALING_LIST_32x32 ? (SCALING_LIST_NUM / SCALING_LIST_PRED_MODES) : 1); // if 64x64, skip over chroma entries. @@ -1804,6 +1823,7 @@ void HLSWriter::codeScalingList( const ScalingList &scalingList ) xCodeScalingList(&scalingList, sizeId, listId); } } +#endif } return; } @@ -1812,34 +1832,88 @@ void HLSWriter::codeScalingList( const ScalingList &scalingList ) * \param sizeId size index * \param listId list index */ +#if JVET_P01034_PRED_1D_SCALING_LIST +void HLSWriter::xCodeScalingList(const ScalingList* scalingList, uint32_t scalingListId, bool isPredictor) +#else void HLSWriter::xCodeScalingList(const ScalingList* scalingList, uint32_t sizeId, uint32_t listId) +#endif { +#if JVET_P01034_PRED_1D_SCALING_LIST + int matrixSize = (scalingListId < SCALING_LIST_1D_START_4x4) ? 2 : ((scalingListId < SCALING_LIST_1D_START_8x8) ? 4 : 8); + int coefNum = matrixSize * matrixSize; + ScanElement *scan = g_scanOrder[SCAN_UNGROUPED][SCAN_DIAG][gp_sizeIdxInfo->idxFrom(matrixSize)][gp_sizeIdxInfo->idxFrom(matrixSize)]; + int nextCoef = (isPredictor) ? 0 : SCALING_LIST_START_VALUE; +#else int coefNum = std::min( MAX_MATRIX_COEF_NUM, ( int ) g_scalingListSize[sizeId] ); ScanElement *scan = g_scanOrder[SCAN_UNGROUPED][SCAN_DIAG][gp_sizeIdxInfo->idxFrom(1 << (sizeId == SCALING_LIST_2x2 ? 1 : (sizeId == SCALING_LIST_4x4 ? 2 : 3)))][gp_sizeIdxInfo->idxFrom(1 << (sizeId == SCALING_LIST_2x2 ? 1 : (sizeId == SCALING_LIST_4x4 ? 2 : 3)))]; int nextCoef = SCALING_LIST_START_VALUE; +#endif + int data; +#if JVET_P01034_PRED_1D_SCALING_LIST + const int *src = scalingList->getScalingListAddress(scalingListId); + int PredListId = scalingList->getRefMatrixId(scalingListId); + const int *srcPred = (isPredictor) ? ((scalingListId==PredListId) ? scalingList->getScalingListDefaultAddress(scalingListId) : scalingList->getScalingListAddress(PredListId)) : NULL; + int deltasrc[65] = { 0 }; + + if (isPredictor) + { + if (scalingListId >= SCALING_LIST_1D_START_16x16) + { + deltasrc[64] = scalingList->getScalingListDC(scalingListId) - ((PredListId >= SCALING_LIST_1D_START_16x16) ? ((scalingListId == PredListId) ? 16 : scalingList->getScalingListDC(PredListId)) : srcPred[scan[0].idx]); + } + for (int i = 0; i < coefNum; i++) + { + deltasrc[i] = (src[scan[i].idx] - srcPred[scan[i].idx]); + } + } + if (scalingListId >= SCALING_LIST_1D_START_16x16) + { + if (isPredictor) + { + data = deltasrc[64]; + nextCoef = deltasrc[64]; + } + else + { + data = scalingList->getScalingListDC(scalingListId) - nextCoef; + nextCoef = scalingList->getScalingListDC(scalingListId); + } + WRITE_SVLC((int8_t)data, "scaling_list_dc_coef"); +#else const int *src = scalingList->getScalingListAddress(sizeId, listId); if( sizeId > SCALING_LIST_8x8 ) { WRITE_SVLC( scalingList->getScalingListDC(sizeId,listId) - 8, "scaling_list_dc_coef_minus8"); nextCoef = scalingList->getScalingListDC(sizeId,listId); +#endif } for(int i=0;i<coefNum;i++) { +#if JVET_P01034_PRED_1D_SCALING_LIST + if (scalingListId >= SCALING_LIST_1D_START_64x64 && scan[i].x >= 4 && scan[i].y >= 4) +#else if (sizeId == SCALING_LIST_64x64 && scan[i].x >= 4 && scan[i].y >= 4) +#endif continue; +#if JVET_P01034_PRED_1D_SCALING_LIST + data = (isPredictor) ? (deltasrc[i] - nextCoef) : (src[scan[i].idx] - nextCoef); + nextCoef = (isPredictor) ? deltasrc[i] : src[scan[i].idx]; + WRITE_SVLC((int8_t)data, "scaling_list_delta_coef"); +#else data = src[scan[i].idx] - nextCoef; nextCoef = src[scan[i].idx]; - if(data > 127) + if (data > 127) { data = data - 256; } - if(data < -128) + if (data < -128) { data = data + 256; } WRITE_SVLC( data, "scaling_list_delta_coef"); +#endif } } diff --git a/source/Lib/EncoderLib/VLCWriter.h b/source/Lib/EncoderLib/VLCWriter.h index efc78e67db393ea0410ff56b91c49cf1397678ad..662c6f99cdd97c4ddf2c8d6bd29d4010b3120f83 100644 --- a/source/Lib/EncoderLib/VLCWriter.h +++ b/source/Lib/EncoderLib/VLCWriter.h @@ -114,7 +114,11 @@ private: void xCodeRefPicList( const ReferencePictureList* rpl, bool isLongTermPresent, uint32_t ltLsbBitsCount, const bool isForbiddenZeroDeltaPoc ); bool xFindMatchingLTRP ( Slice* pcSlice, uint32_t *ltrpsIndex, int ltrpPOC, bool usedFlag ); void xCodePredWeightTable ( Slice* pcSlice ); +#if JVET_P01034_PRED_1D_SCALING_LIST + void xCodeScalingList ( const ScalingList* scalingList, uint32_t scalinListId, bool isPredictor); +#else void xCodeScalingList ( const ScalingList* scalingList, uint32_t sizeId, uint32_t listId); +#endif public: void setBitstream ( OutputBitstream* p ) { m_pcBitIf = p; } uint32_t getNumberOfWrittenBits () { return m_pcBitIf->getNumberOfWrittenBits(); }