38 #include "../TLibCommon/CommonDef.h"
39 #include "../TLibCommon/TComSlice.h"
40 #include "../TLibCommon/TComPic.h"
41 #include "../TLibCommon/TComPicYuv.h"
59 const Bool useHighPrecision);
73 const Bool useHighPrecision,
83 std::vector<Int> &histogram,
90 histogram.resize(maxPel);
91 for(
Int y = 0; y < height; y++ )
93 for(
Int x = 0; x < width; x++ )
96 histogram[v<0?0:(v>=maxPel)?maxPel-1:v]++;
104 const std::vector<Int> &histogram1)
107 assert(histogram0.size()==histogram1.size());
108 const Int numElements=
Int(histogram0.size());
111 for (
Int i = 0; i <= numElements; i++)
113 distortion += (
Distortion)(abs(histogram0[i] - histogram1[i]));
121 std::vector<Int> &histogramOutput,
126 const Bool bHighPrecision)
128 assert(&histogramInput != &histogramOutput);
129 const Int numElements=
Int(histogramInput.size());
130 histogramOutput.clear();
131 histogramOutput.resize(numElements);
133 const Int64 iRealLog2Denom = bHighPrecision ? 0 : (bitDepth - 8);
134 const Int64 iRealOffset = ((
Int64)offset)<<iRealLog2Denom;
136 const Int divOffset = log2Denom == 0 ? 0 : 1 << (log2Denom - 1);
141 for (
Int i = 0; i < numElements; i++)
143 const Int j =
Clip3(0, numElements - 1, (
Int)(((weight * i + divOffset) >> log2Denom) + iRealOffset));
144 histogramOutput[j] += histogramInput[i];
150 const std::vector<Int> &histogramRef,
151 std::vector<Int> &outputHistogram,
156 const Bool bHighPrecision,
159 const Int initialWeight = weightToUpdate;
160 const Int initialOffset = offsetToUpdate;
161 const Int weightRange = 10;
162 const Int offsetRange = 10;
163 const Int maxOffset = 1 << ((bHighPrecision ==
true) ? (bitDepth - 1) : 7);
164 const Int range = bHighPrecision ? (1<<bitDepth) / 2 : 128;
165 const Int defaultWeight = (1<<log2Denom);
166 const Int minSearchWeight = std::max<Int>(initialWeight - weightRange, defaultWeight - range);
167 const Int maxSearchWeight = std::min<Int>(initialWeight + weightRange+1, defaultWeight + range);
169 Distortion minDistortion = std::numeric_limits<Distortion>::max();
170 Int bestWeight = initialWeight;
171 Int bestOffset = initialOffset;
173 for (
Int searchWeight = minSearchWeight; searchWeight < maxSearchWeight; searchWeight++)
177 for (
Int searchOffset = std::max<Int>(initialOffset - offsetRange, -maxOffset);
178 searchOffset <= initialOffset + offsetRange && searchOffset<=(maxOffset-1);
181 xScaleHistogram(histogramRef, outputHistogram, bitDepth, log2Denom, searchWeight, searchOffset, bHighPrecision);
184 if (distortion < minDistortion)
186 minDistortion = distortion;
187 bestWeight = searchWeight;
188 bestOffset = searchOffset;
194 const Int pred = ( maxOffset - ( ( maxOffset*searchWeight)>>(log2Denom) ) );
196 for (
Int searchOffset = initialOffset - offsetRange; searchOffset <= initialOffset + offsetRange; searchOffset++)
198 const Int deltaOffset =
Clip3( -4*maxOffset, 4*maxOffset-1, (searchOffset - pred) );
199 const Int clippedOffset =
Clip3( -1*maxOffset, 1*maxOffset-1, (deltaOffset + pred) );
200 xScaleHistogram(histogramRef, outputHistogram, bitDepth, log2Denom, searchWeight, clippedOffset, bHighPrecision);
203 if (distortion < minDistortion)
205 minDistortion = distortion;
206 bestWeight = searchWeight;
207 bestOffset = clippedOffset;
213 weightToUpdate = bestWeight;
214 offsetToUpdate = bestOffset;
217 xScaleHistogram(histogramRef, outputHistogram, bitDepth, log2Denom, bestWeight, bestOffset, bHighPrecision);
219 return minDistortion;
263 const Int sample = width*height;
269 for(
Int y = 0; y < height; y++, pPel+=stride )
271 for(
Int x = 0; x < width; x++ )
273 orgDC += (
Int)( pPel[x] );
278 const Int64 orgNormDC = ((orgDC+(sample>>1)) / sample);
284 for(
Int y = 0; y < height; y++, pPel += stride )
286 for(
Int x = 0; x < width; x++ )
288 orgAC += abs( (
Int)pPel[x] - (
Int)orgNormDC );
294 weightACDCParam[compID].
iDC = (((orgDC<<fixedBitShift)+(sample>>1)) / sample);
295 weightACDCParam[compID].
iAC = orgAC;
354 Bool validRangeFlag =
false;
368 }
while (validRangeFlag ==
false);
407 for (
Int refList = 0; refList < numPredDir; refList++ )
411 for (
Int refIdxTemp = 0; refIdxTemp < slice->
getNumRefIdx(eRefPicList); refIdxTemp++ )
413 WPACDCParam *currWeightACDCParam, *refWeightACDCParam;
417 for (
Int comp = 0; comp < numComp; comp++ )
421 const Int range = bUseHighPrecisionWeighting ? (1<<bitDepth)/2 : 128;
423 const Int realOffset = ((
Int)1<<(realLog2Denom-1));
426 const Int64 currDC = currWeightACDCParam[comp].
iDC;
427 const Int64 currAC = currWeightACDCParam[comp].
iAC;
429 const Int64 refDC = refWeightACDCParam[comp].
iDC;
430 const Int64 refAC = refWeightACDCParam[comp].
iAC;
434 const Int weight = (
Int)( 0.5 + dWeight * (
Double)(1<<log2Denom) );
435 const Int offset = (
Int)( ((currDC<<log2Denom) - ((
Int64)weight * refDC) + (
Int64)realOffset) >> realLog2Denom );
440 const Int pred = ( range - ( ( range*weight)>>(log2Denom) ) );
441 const Int deltaOffset =
Clip3( -4*range, 4*range-1, (offset - pred) );
443 clippedOffset =
Clip3( -range, range-1, (deltaOffset + pred) );
447 clippedOffset =
Clip3( -range, range-1, offset);
451 const Int defaultWeight = (1<<log2Denom);
452 const Int deltaWeight = (weight - defaultWeight);
454 if(deltaWeight >= range || deltaWeight < -range)
461 m_wp[refList][refIdxTemp][comp].
iOffset = clippedOffset;
478 const Int defaultWeight = 1<<log2Denom;
484 for (
Int refList = 0; refList < numPredDir; refList++ )
488 for (
Int refIdxTemp = 0; refIdxTemp < slice->
getNumRefIdx(eRefPicList); refIdxTemp++ )
490 Bool useChromaWeight =
false;
505 Int weightDef = defaultWeight;
509 const Int64 SADnoWP =
xCalcSADvalueWPOptionalClip(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, defaultWeight, 0, useHighPrecision, bClipInitialSADWP);
512 const Int64 SADWP =
xCalcSADvalueWPOptionalClip(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weight, offset, useHighPrecision, bClipInitialSADWP);
514 Double dRatioSr0SAD = std::numeric_limits<Double>::max();
515 Double dRatioSrSAD = std::numeric_limits<Double>::max();
519 std::vector<Int> histogramOrg;
520 std::vector<Int> histogramRef;
521 std::vector<Int> searchedHistogram;
524 xCalcHistogram(pOrg, histogramOrg, width, height, orgStride, 1 << bitDepth);
525 xCalcHistogram(pRef, histogramRef, width, height, refStride, 1 << bitDepth);
528 xSearchHistogram(histogramOrg, histogramRef, searchedHistogram, bitDepth, log2Denom, weight, offset, useHighPrecision, compID);
530 const Int64 SADSrWP =
xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weight, offset, useHighPrecision);
536 xSearchHistogram(histogramOrg, histogramRef, searchedHistogram, bitDepth, log2Denom, weightDef, offsetDef, useHighPrecision, compID);
538 const Int64 SADSr0WP =
xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weightDef, offsetDef, useHighPrecision);
554 useChromaWeight =
true;
557 if (dRatioSr0SAD < dRatioSrSAD && dRatioSr0SAD < dRatioSAD)
564 else if (dRatioSrSAD < dRatioSAD)
596 const Int defaultWeight = 1<<log2Denom;
602 for (
Int refList = 0; refList < numPredDir; refList++ )
606 for (
Int refIdxTemp = 0; refIdxTemp < slice->
getNumRefIdx(eRefPicList); refIdxTemp++ )
608 Int64 SADWP = 0, SADnoWP = 0;
622 SADWP +=
xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom,
m_wp[refList][refIdxTemp][compID].iWeight,
m_wp[refList][refIdxTemp][compID].iOffset, useHighPrecisionPredictionWeighting);
623 SADnoWP +=
xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, defaultWeight, 0, useHighPrecisionPredictionWeighting);
626 const Double dRatio = SADnoWP > 0 ? (((
Double)SADWP / (
Double)SADnoWP)) : std::numeric_limits<Double>::max();
657 const Bool useHighPrecision)
660 const Int64 realLog2Denom = useHighPrecision ? log2Denom : (log2Denom + (bitDepth - 8));
661 const Int64 realOffset = ((
Int64)offset)<<realLog2Denom;
664 for(
Int y = 0; y < height; y++ )
666 for(
Int x = 0; x < width; x++ )
668 SAD += abs(( ((
Int64)pOrgPel[x] << (
Int64) log2Denom) - ( (
Int64) pRefPel[x] * (
Int64) weight + (realOffset) ) ) );
670 pOrgPel += orgStride;
671 pRefPel += refStride;
689 const Bool useHighPrecision,
695 const Int64 realLog2Denom = useHighPrecision ? 0 : (bitDepth - 8);
696 const Int64 realOffset = (
Int64)offset<<realLog2Denom;
697 const Int64 roundOffset = (log2Denom == 0) ? 0 : 1 << (log2Denom - 1);
698 const Int64 minValue = 0;
699 const Int64 maxValue = (1 << bitDepth) - 1;
701 for(
Int y = 0; y < height; y++ )
703 for(
Int x = 0; x < width; x++ )
705 Int64 scaledValue =
Clip3(minValue, maxValue, ((((
Int64) pRefPel[x] * (
Int64) weight + roundOffset) ) >> (
Int64) log2Denom) + realOffset);
706 SAD += abs((
Int64)pOrgPel[x] - scaledValue);
708 pOrgPel += orgStride;
709 pRefPel += refStride;
715 const Int64 realLog2Denom = useHighPrecision ? log2Denom : (log2Denom + (bitDepth - 8));
716 const Int64 realOffset = ((
Int64)offset)<<realLog2Denom;
718 for(
Int y = 0; y < height; y++ )
720 for(
Int x = 0; x < width; x++ )
722 SAD += abs(( ((
Int64)pOrgPel[x] << (
Int64) log2Denom) - ( (
Int64) pRefPel[x] * (
Int64) weight + (realOffset) ) ) );
724 pOrgPel += orgStride;
725 pRefPel += refStride;
static Int64 xCalcSADvalueWP(const Int bitDepth, const Pel *pOrgPel, const Pel *pRefPel, const Int width, const Int height, const Int orgStride, const Int refStride, const Int log2Denom, const Int weight, const Int offset, const Bool useHighPrecision)
calculate SAD values for both WP version and non-WP version.
Void getWpAcDcParam(WPACDCParam *&wp)
get AC and DC values for weighted pred
UInt Distortion
distortion measurement
Int getStride(const ComponentID id) const
const TComSPSRExt & getSpsRangeExtension() const
Void setWpScaling(WPScalingParam wp[NUM_REF_PIC_LIST_01][MAX_NUM_REF][MAX_NUM_COMPONENT])
Int getHeight(const ComponentID id) const
TComSlice * getSlice(Int i)
static Distortion xCalcHistDistortion(const std::vector< Int > &histogram0, const std::vector< Int > &histogram1)
static const Double WEIGHT_PRED_SAD_RELATIVE_TO_NON_WEIGHT_PRED_SAD
static Int64 xCalcSADvalueWPOptionalClip(const Int bitDepth, const Pel *pOrgPel, const Pel *pRefPel, const Int width, const Int height, const Int orgStride, const Int refStride, const Int log2Denom, const Int weight, const Int offset, const Bool useHighPrecision, const Bool clipped)
calculate SAD values for both WP version and non-WP version.
static const Int MAX_NUM_REF
max. number of entries in picture reference list
Bool xUpdatingWPParameters(TComSlice *const slice, const Int log2Denom)
update wp tables for explicit wp w.r.t range limitation
Int getNumRefIdx(RefPicList e) const
static Void xCalcHistogram(const Pel *pPel, std::vector< Int > &histogram, const Int width, const Int height, const Int stride, const Int maxPel)
calculate Histogram for array of pixels
Void xCheckWPEnable(TComSlice *const slice)
check weighted pred or non-weighted pred
TComPicYuv * getPicYuvRec()
Int getWidth(const ComponentID id) const
static const Int RExt__PREDICTION_WEIGHTING_ANALYSIS_DC_PRECISION
Additional fixed bit precision used during encoder-side weighting prediction analysis. Currently only used when high_precision_prediction_weighting_flag is set, for backwards compatibility reasons.
static void xScaleHistogram(const std::vector< Int > &histogramInput, std::vector< Int > &histogramOutput, const Int bitDepth, const Int log2Denom, const Int weight, const Int offset, const Bool bHighPrecision)
T Clip3(const T minVal, const T maxVal, const T a)
general min/max clip
TComPicYuv * getPicYuvOrg()
Int getBitDepth(ChannelType type) const
RefPicList
reference list index
Void setWpAcDcParam(WPACDCParam wp[MAX_NUM_COMPONENT])
Void setTestWeightBiPred(Bool bValue)
static Distortion xSearchHistogram(const std::vector< Int > &histogramSource, const std::vector< Int > &histogramRef, std::vector< Int > &outputHistogram, const Int bitDepth, const Int log2Denom, Int &weightToUpdate, Int &offsetToUpdate, const Bool bHighPrecision, const ComponentID compID)
Void setTestWeightPred(Bool bValue)
const TComPPS * getPPS() const
UInt getNumberValidComponents() const
Bool xSelectWP(TComSlice *const slice, const Int log2Denom)
select whether weighted pred enables or not.
Void xEstimateWPParamSlice(TComSlice *const slice, const WeightedPredictionMethod method)
estimate wp tables for explicit wp
weighted prediction encoder class
Pel * getAddr(const ComponentID ch)
Void xCalcACDCParamSlice(TComSlice *const slice)
calculate AC and DC values for current original image
WPScalingParam m_wp[NUM_REF_PIC_LIST_01][MAX_NUM_REF][MAX_NUM_COMPONENT]
TComPic * getRefPic(RefPicList e, Int iRefIdx)
const TComSPS * getSPS() const
Bool xSelectWPHistExtClip(TComSlice *const slice, const Int log2Denom, const Bool bDoEnhancement, const Bool bClipInitialSADWP, const Bool bUseHistogram)
Bool getHighPrecisionOffsetsEnabledFlag() const