diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index b71b815576eef06e75da4e3e049c0116a5e33b7f..a68b90ae01fe6e578c082dd809363fac7449ad6e 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -53,6 +53,8 @@ #define JVET_Q0512_ENC_CHROMA_TS_ACT 1 // JVET-Q0512: encoder-side improvement on enabling chroma transform-skip for ACT #define JVET_Q0446_MIP_CONST_SHIFT_OFFSET 1 // JVET-Q0446: MIP with constant shift and offset +#define JVET_Q0447_WP_PARAM_ESTIM 1 // JVET-Q0447: Add search iterations for method 2,3 and 4 + #define JVET_Q0820_ACT 1 // JVET-Q0820: ACT bug fixes and reversible ACT transform #define JVET_Q0353_ACT_SW_FIX 1 // JVET-Q0353: Bug fix of ACT diff --git a/source/Lib/EncoderLib/WeightPredAnalysis.cpp b/source/Lib/EncoderLib/WeightPredAnalysis.cpp index 5117c79d98d9a4e5cc9b05c7c79e576a55bc439f..454be151796ba9dc67a0220e4883c5b5858d1636 100644 --- a/source/Lib/EncoderLib/WeightPredAnalysis.cpp +++ b/source/Lib/EncoderLib/WeightPredAnalysis.cpp @@ -98,6 +98,7 @@ void xCalcHistogram(const Pel *pPel, } } +#if !JVET_Q0447_WP_PARAM_ESTIM static Distortion xCalcHistDistortion (const std::vector<int> &histogram0, const std::vector<int> &histogram1) @@ -114,6 +115,7 @@ Distortion xCalcHistDistortion (const std::vector<int> &histogram0, return distortion; } +#endif static void xScaleHistogram(const std::vector<int> &histogramInput, @@ -144,6 +146,28 @@ void xScaleHistogram(const std::vector<int> &histogramInput, } } +#if JVET_Q0447_WP_PARAM_ESTIM +static +Distortion xCalcHistCumulDistortion(const std::vector<int>& histogram0, + const std::vector<int>& histogram1) +{ + Distortion distortion = 0; + CHECK(histogram0.size() != histogram1.size(), "Different histogram sizes"); + const int numElements = int(histogram0.size()); + + int64_t cumul = 0; + + // Scan histograms to compute histogram distortion + for (int i = 0; i < numElements; i++) + { + cumul += (int64_t)histogram0[i] - (int64_t)histogram1[i]; + distortion += (Distortion)(abs(cumul)); + } + + return distortion; +} +#endif + static Distortion xSearchHistogram(const std::vector<int> &histogramSource, const std::vector<int> &histogramRef, @@ -178,7 +202,11 @@ Distortion xSearchHistogram(const std::vector<int> &histogramSource, searchOffset++) { xScaleHistogram(histogramRef, outputHistogram, bitDepth, log2Denom, searchWeight, searchOffset, bHighPrecision); +#if JVET_Q0447_WP_PARAM_ESTIM + const Distortion distortion = xCalcHistCumulDistortion(histogramSource, outputHistogram); +#else const Distortion distortion = xCalcHistDistortion(histogramSource, outputHistogram); +#endif if (distortion < minDistortion) { @@ -197,7 +225,11 @@ Distortion xSearchHistogram(const std::vector<int> &histogramSource, const int deltaOffset = Clip3( -4*maxOffset, 4*maxOffset-1, (searchOffset - pred) ); // signed 10bit (if !bHighPrecision) const int clippedOffset = Clip3( -1*maxOffset, 1*maxOffset-1, (deltaOffset + pred) ); // signed 8bit (if !bHighPrecision) xScaleHistogram(histogramRef, outputHistogram, bitDepth, log2Denom, searchWeight, clippedOffset, bHighPrecision); +#if JVET_Q0447_WP_PARAM_ESTIM + const Distortion distortion = xCalcHistCumulDistortion(histogramSource, outputHistogram); +#else const Distortion distortion = xCalcHistDistortion(histogramSource, outputHistogram); +#endif if (distortion < minDistortion) { @@ -510,28 +542,79 @@ bool WeightPredAnalysis::xSelectWPHistExtClip(Slice *const slice, const int log2 int offsetDef = 0; // calculate SAD costs with/without wp for luma +#if JVET_Q0447_WP_PARAM_ESTIM + std::vector<int> histogramOrg; + std::vector<int> histogramRef; + uint64_t SADnoWP = std::numeric_limits<uint64_t>::max(); + if (bUseHistogram && compID == COMPONENT_Y) + { + xCalcHistogram(pOrg, histogramOrg, width, height, orgStride, 1 << bitDepth); + xCalcHistogram(pRef, histogramRef, width, height, refStride, 1 << bitDepth); + + std::vector<int> histogramRef_noWP; + xScaleHistogram(histogramRef, histogramRef_noWP, bitDepth, log2Denom, defaultWeight, 0, useHighPrecision); + SADnoWP = (uint64_t)xCalcHistCumulDistortion(histogramOrg, histogramRef_noWP); + } + else + { + SADnoWP = (uint64_t)xCalcSADvalueWPOptionalClip(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, defaultWeight, 0, useHighPrecision, bClipInitialSADWP); + } +#else const int64_t SADnoWP = xCalcSADvalueWPOptionalClip(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, defaultWeight, 0, useHighPrecision, bClipInitialSADWP); +#endif if (SADnoWP > 0) { +#if JVET_Q0447_WP_PARAM_ESTIM + uint64_t SADWP = std::numeric_limits<uint64_t>::max(); + if (bUseHistogram && compID == COMPONENT_Y) + { + std::vector<int> histogramRef_WP; + xScaleHistogram(histogramRef, histogramRef_WP, bitDepth, log2Denom, weight, offset, useHighPrecision); + SADWP = (uint64_t)xCalcHistCumulDistortion(histogramOrg, histogramRef_WP); + } + else + { + SADWP = (uint64_t)xCalcSADvalueWPOptionalClip(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weight, offset, useHighPrecision, bClipInitialSADWP); + } +#else const int64_t SADWP = xCalcSADvalueWPOptionalClip(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weight, offset, useHighPrecision, bClipInitialSADWP); +#endif const double dRatioSAD = (double)SADWP / (double)SADnoWP; double dRatioSr0SAD = std::numeric_limits<double>::max(); double dRatioSrSAD = std::numeric_limits<double>::max(); if (bUseHistogram) { +#if !JVET_Q0447_WP_PARAM_ESTIM std::vector<int> histogramOrg;// = pPic->getHistogram(compID); std::vector<int> histogramRef;// = slice->getRefPic(eRefPicList, refIdxTemp)->getPicYuvRec()->getHistogram(compID); +#endif std::vector<int> searchedHistogram; +#if !JVET_Q0447_WP_PARAM_ESTIM // Compute histograms xCalcHistogram(pOrg, histogramOrg, width, height, orgStride, 1 << bitDepth); xCalcHistogram(pRef, histogramRef, width, height, refStride, 1 << bitDepth); +#endif // Do a histogram search around DC WP parameters; resulting distortion and 'searchedHistogram' is discarded xSearchHistogram(histogramOrg, histogramRef, searchedHistogram, bitDepth, log2Denom, weight, offset, useHighPrecision, compID); // calculate updated WP SAD +#if JVET_Q0447_WP_PARAM_ESTIM + uint64_t SADSrWP = std::numeric_limits<uint64_t>::max(); + if (bUseHistogram && compID == COMPONENT_Y) + { + std::vector<int> histogramRef_SrWP; + xScaleHistogram(histogramRef, histogramRef_SrWP, bitDepth, log2Denom, weight, offset, useHighPrecision); + SADSrWP = (uint64_t)xCalcHistCumulDistortion(histogramOrg, histogramRef_SrWP); + } + else + { + SADSrWP = (uint64_t)xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weight, offset, useHighPrecision); + } +#else const int64_t SADSrWP = xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weight, offset, useHighPrecision); +#endif dRatioSrSAD = (double)SADSrWP / (double)SADnoWP; if (bDoEnhancement) @@ -539,7 +622,21 @@ bool WeightPredAnalysis::xSelectWPHistExtClip(Slice *const slice, const int log2 // Do the same around the default ones; resulting distortion and 'searchedHistogram' is discarded xSearchHistogram(histogramOrg, histogramRef, searchedHistogram, bitDepth, log2Denom, weightDef, offsetDef, useHighPrecision, compID); // calculate updated WP SAD +#if JVET_Q0447_WP_PARAM_ESTIM + uint64_t SADSr0WP = std::numeric_limits<uint64_t>::max(); + if (bUseHistogram && compID == COMPONENT_Y) + { + std::vector<int> histogramRef_SrWP; + xScaleHistogram(histogramRef, histogramRef_SrWP, bitDepth, log2Denom, weightDef, offsetDef, useHighPrecision); + SADSr0WP = (uint64_t)xCalcHistCumulDistortion(histogramOrg, histogramRef_SrWP); + } + else + { + SADSr0WP = (uint64_t)xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weightDef, offsetDef, useHighPrecision); + } +#else const int64_t SADSr0WP = xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weightDef, offsetDef, useHighPrecision); +#endif dRatioSr0SAD = (double)SADSr0WP / (double)SADnoWP; } }