HEVC Test Model (HM)  HM-16.18
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
WeightPredAnalysis.cpp
Go to the documentation of this file.
1 /* The copyright in this software is being made available under the BSD
2  * License, included below. This software may be subject to other third party
3  * and contributor rights, including patent rights, and no such rights are
4  * granted under this license.
5  *
6  * Copyright (c) 2010-2017, ITU/ISO/IEC
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18  * be used to endorse or promote products derived from this software without
19  * specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31  * THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
38 #include "../TLibCommon/CommonDef.h"
39 #include "../TLibCommon/TComSlice.h"
40 #include "../TLibCommon/TComPic.h"
41 #include "../TLibCommon/TComPicYuv.h"
42 #include "WeightPredAnalysis.h"
43 #include <limits>
44 
45 static const Double WEIGHT_PRED_SAD_RELATIVE_TO_NON_WEIGHT_PRED_SAD=0.99; // NOTE: U0040 used 0.95
46 
48 static
49 Int64 xCalcSADvalueWP(const Int bitDepth,
50  const Pel *pOrgPel,
51  const Pel *pRefPel,
52  const Int width,
53  const Int height,
54  const Int orgStride,
55  const Int refStride,
56  const Int log2Denom,
57  const Int weight,
58  const Int offset,
59  const Bool useHighPrecision);
60 
62 static
64  const Pel *pOrgPel,
65  const Pel *pRefPel,
66  const Int width,
67  const Int height,
68  const Int orgStride,
69  const Int refStride,
70  const Int log2Denom,
71  const Int weight,
72  const Int offset,
73  const Bool useHighPrecision,
74  const Bool clipped);
75 
76 // -----------------------------------------------------------------------------
77 // Helper functions
78 
79 
81 static
82 Void xCalcHistogram(const Pel *pPel,
83  std::vector<Int> &histogram,
84  const Int width,
85  const Int height,
86  const Int stride,
87  const Int maxPel)
88 {
89  histogram.clear();
90  histogram.resize(maxPel);
91  for( Int y = 0; y < height; y++ )
92  {
93  for( Int x = 0; x < width; x++ )
94  {
95  const Pel v=pPel[x];
96  histogram[v<0?0:(v>=maxPel)?maxPel-1:v]++;
97  }
98  pPel += stride;
99  }
100 }
101 
102 static
103 Distortion xCalcHistDistortion (const std::vector<Int> &histogram0,
104  const std::vector<Int> &histogram1)
105 {
106  Distortion distortion = 0;
107  assert(histogram0.size()==histogram1.size());
108  const Int numElements=Int(histogram0.size());
109 
110  // Scan histograms to compute histogram distortion
111  for (Int i = 0; i <= numElements; i++)
112  {
113  distortion += (Distortion)(abs(histogram0[i] - histogram1[i]));
114  }
115 
116  return distortion;
117 }
118 
119 static
120 void xScaleHistogram(const std::vector<Int> &histogramInput,
121  std::vector<Int> &histogramOutput, // cannot be the same as the input
122  const Int bitDepth,
123  const Int log2Denom,
124  const Int weight,
125  const Int offset,
126  const Bool bHighPrecision)
127 {
128  assert(&histogramInput != &histogramOutput);
129  const Int numElements=Int(histogramInput.size());
130  histogramOutput.clear();
131  histogramOutput.resize(numElements);
132 
133  const Int64 iRealLog2Denom = bHighPrecision ? 0 : (bitDepth - 8);
134  const Int64 iRealOffset = ((Int64)offset)<<iRealLog2Denom;
135 
136  const Int divOffset = log2Denom == 0 ? 0 : 1 << (log2Denom - 1);
137  // Scan histogram and apply illumination parameters appropriately
138  // Then compute updated histogram.
139  // Note that this technique only works with single list weights/offsets.
140 
141  for (Int i = 0; i < numElements; i++)
142  {
143  const Int j = Clip3(0, numElements - 1, (Int)(((weight * i + divOffset) >> log2Denom) + iRealOffset));
144  histogramOutput[j] += histogramInput[i];
145  }
146 }
147 
148 static
149 Distortion xSearchHistogram(const std::vector<Int> &histogramSource,
150  const std::vector<Int> &histogramRef,
151  std::vector<Int> &outputHistogram,
152  const Int bitDepth,
153  const Int log2Denom,
154  Int &weightToUpdate,
155  Int &offsetToUpdate,
156  const Bool bHighPrecision,
157  const ComponentID compID)
158 {
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);
168 
169  Distortion minDistortion = std::numeric_limits<Distortion>::max();
170  Int bestWeight = initialWeight;
171  Int bestOffset = initialOffset;
172 
173  for (Int searchWeight = minSearchWeight; searchWeight < maxSearchWeight; searchWeight++)
174  {
175  if (compID == COMPONENT_Y)
176  {
177  for (Int searchOffset = std::max<Int>(initialOffset - offsetRange, -maxOffset);
178  searchOffset <= initialOffset + offsetRange && searchOffset<=(maxOffset-1);
179  searchOffset++)
180  {
181  xScaleHistogram(histogramRef, outputHistogram, bitDepth, log2Denom, searchWeight, searchOffset, bHighPrecision);
182  const Distortion distortion = xCalcHistDistortion(histogramSource, outputHistogram);
183 
184  if (distortion < minDistortion)
185  {
186  minDistortion = distortion;
187  bestWeight = searchWeight;
188  bestOffset = searchOffset;
189  }
190  }
191  }
192  else
193  {
194  const Int pred = ( maxOffset - ( ( maxOffset*searchWeight)>>(log2Denom) ) );
195 
196  for (Int searchOffset = initialOffset - offsetRange; searchOffset <= initialOffset + offsetRange; searchOffset++)
197  {
198  const Int deltaOffset = Clip3( -4*maxOffset, 4*maxOffset-1, (searchOffset - pred) ); // signed 10bit (if !bHighPrecision)
199  const Int clippedOffset = Clip3( -1*maxOffset, 1*maxOffset-1, (deltaOffset + pred) ); // signed 8bit (if !bHighPrecision)
200  xScaleHistogram(histogramRef, outputHistogram, bitDepth, log2Denom, searchWeight, clippedOffset, bHighPrecision);
201  const Distortion distortion = xCalcHistDistortion(histogramSource, outputHistogram);
202 
203  if (distortion < minDistortion)
204  {
205  minDistortion = distortion;
206  bestWeight = searchWeight;
207  bestOffset = clippedOffset;
208  }
209  }
210  }
211  }
212 
213  weightToUpdate = bestWeight;
214  offsetToUpdate = bestOffset;
215 
216  // regenerate best histogram
217  xScaleHistogram(histogramRef, outputHistogram, bitDepth, log2Denom, bestWeight, bestOffset, bHighPrecision);
218 
219  return minDistortion;
220 }
221 
222 
223 // -----------------------------------------------------------------------------
224 // Member functions
225 
227 {
228  for ( UInt lst =0 ; lst<NUM_REF_PIC_LIST_01 ; lst++ )
229  {
230  for ( Int refIdx=0 ; refIdx<MAX_NUM_REF ; refIdx++ )
231  {
232  for ( Int comp=0 ; comp<MAX_NUM_COMPONENT ;comp++ )
233  {
234  WPScalingParam *pwp = &(m_wp[lst][refIdx][comp]);
235  pwp->bPresentFlag = false;
236  pwp->uiLog2WeightDenom = 0;
237  pwp->iWeight = 1;
238  pwp->iOffset = 0;
239  }
240  }
241  }
242 }
243 
244 
247 {
248  //===== calculate AC/DC value =====
249  TComPicYuv* pPic = slice->getPic()->getPicYuvOrg();
250 
251  WPACDCParam weightACDCParam[MAX_NUM_COMPONENT];
252 
253  for(Int componentIndex = 0; componentIndex < pPic->getNumberValidComponents(); componentIndex++)
254  {
255  const ComponentID compID = ComponentID(componentIndex);
256 
257  // calculate DC/AC value for channel
258 
259  const Int stride = pPic->getStride(compID);
260  const Int width = pPic->getWidth(compID);
261  const Int height = pPic->getHeight(compID);
262 
263  const Int sample = width*height;
264 
265  Int64 orgDC = 0;
266  {
267  const Pel *pPel = pPic->getAddr(compID);
268 
269  for(Int y = 0; y < height; y++, pPel+=stride )
270  {
271  for(Int x = 0; x < width; x++ )
272  {
273  orgDC += (Int)( pPel[x] );
274  }
275  }
276  }
277 
278  const Int64 orgNormDC = ((orgDC+(sample>>1)) / sample);
279 
280  Int64 orgAC = 0;
281  {
282  const Pel *pPel = pPic->getAddr(compID);
283 
284  for(Int y = 0; y < height; y++, pPel += stride )
285  {
286  for(Int x = 0; x < width; x++ )
287  {
288  orgAC += abs( (Int)pPel[x] - (Int)orgNormDC );
289  }
290  }
291  }
292 
294  weightACDCParam[compID].iDC = (((orgDC<<fixedBitShift)+(sample>>1)) / sample);
295  weightACDCParam[compID].iAC = orgAC;
296  }
297 
298  slice->setWpAcDcParam(weightACDCParam);
299 }
300 
301 
304 {
305  const TComPicYuv *pPic = slice->getPic()->getPicYuvOrg();
306 
307  Int presentCnt = 0;
308  for ( UInt lst=0 ; lst<NUM_REF_PIC_LIST_01 ; lst++ )
309  {
310  for ( Int refIdx=0 ; refIdx<MAX_NUM_REF ; refIdx++ )
311  {
312  for(Int componentIndex = 0; componentIndex < pPic->getNumberValidComponents(); componentIndex++)
313  {
314  WPScalingParam *pwp = &(m_wp[lst][refIdx][componentIndex]);
315  presentCnt += (Int)pwp->bPresentFlag;
316  }
317  }
318  }
319 
320  if(presentCnt==0)
321  {
322  slice->setTestWeightPred(false);
323  slice->setTestWeightBiPred(false);
324 
325  for ( UInt lst=0 ; lst<NUM_REF_PIC_LIST_01 ; lst++ )
326  {
327  for ( Int refIdx=0 ; refIdx<MAX_NUM_REF ; refIdx++ )
328  {
329  for(Int componentIndex = 0; componentIndex < pPic->getNumberValidComponents(); componentIndex++)
330  {
331  WPScalingParam *pwp = &(m_wp[lst][refIdx][componentIndex]);
332 
333  pwp->bPresentFlag = false;
334  pwp->uiLog2WeightDenom = 0;
335  pwp->iWeight = 1;
336  pwp->iOffset = 0;
337  }
338  }
339  }
340  slice->setWpScaling( m_wp );
341  }
342  else
343  {
344  slice->setTestWeightPred (slice->getPPS()->getUseWP());
345  slice->setTestWeightBiPred(slice->getPPS()->getWPBiPred());
346  }
347 }
348 
349 
352 {
353  Int iDenom = 6;
354  Bool validRangeFlag = false;
355 
356  if(slice->getNumRefIdx(REF_PIC_LIST_0)>3)
357  {
358  iDenom = 7;
359  }
360 
361  do
362  {
363  validRangeFlag = xUpdatingWPParameters(slice, iDenom);
364  if (!validRangeFlag)
365  {
366  iDenom--; // decrement to satisfy the range limitation
367  }
368  } while (validRangeFlag == false);
369 
370  // selecting whether WP is used, or not (fast search)
371  // NOTE: This is not operating on a slice, but the entire picture.
372  switch (method)
373  {
375  xSelectWP(slice, iDenom);
376  break;
378  xSelectWPHistExtClip(slice, iDenom, false, false, false);
379  break;
381  xSelectWPHistExtClip(slice, iDenom, false, false, true);
382  break;
384  xSelectWPHistExtClip(slice, iDenom, false, true, true);
385  break;
387  xSelectWPHistExtClip(slice, iDenom, true, true, true);
388  break;
389  default:
390  assert(0);
391  exit(1);
392  }
393 
394  slice->setWpScaling( m_wp );
395 }
396 
397 
400 {
401  const Int numComp = slice->getPic()->getPicYuvOrg()->getNumberValidComponents();
402  const Bool bUseHighPrecisionWeighting = slice->getSPS()->getSpsRangeExtension().getHighPrecisionOffsetsEnabledFlag();
403  const Int numPredDir = slice->isInterP() ? 1 : 2;
404 
405  assert (numPredDir <= Int(NUM_REF_PIC_LIST_01));
406 
407  for ( Int refList = 0; refList < numPredDir; refList++ )
408  {
409  const RefPicList eRefPicList = ( refList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
410 
411  for ( Int refIdxTemp = 0; refIdxTemp < slice->getNumRefIdx(eRefPicList); refIdxTemp++ )
412  {
413  WPACDCParam *currWeightACDCParam, *refWeightACDCParam;
414  slice->getWpAcDcParam(currWeightACDCParam);
415  slice->getRefPic(eRefPicList, refIdxTemp)->getSlice(0)->getWpAcDcParam(refWeightACDCParam);
416 
417  for ( Int comp = 0; comp < numComp; comp++ )
418  {
419  const ComponentID compID = ComponentID(comp);
420  const Int bitDepth = slice->getSPS()->getBitDepth(toChannelType(compID));
421  const Int range = bUseHighPrecisionWeighting ? (1<<bitDepth)/2 : 128;
422  const Int realLog2Denom = log2Denom + (bUseHighPrecisionWeighting ? RExt__PREDICTION_WEIGHTING_ANALYSIS_DC_PRECISION : (bitDepth - 8));
423  const Int realOffset = ((Int)1<<(realLog2Denom-1));
424 
425  // current frame
426  const Int64 currDC = currWeightACDCParam[comp].iDC;
427  const Int64 currAC = currWeightACDCParam[comp].iAC;
428  // reference frame
429  const Int64 refDC = refWeightACDCParam[comp].iDC;
430  const Int64 refAC = refWeightACDCParam[comp].iAC;
431 
432  // calculating iWeight and iOffset params
433  const Double dWeight = (refAC==0) ? (Double)1.0 : Clip3( -16.0, 15.0, ((Double)currAC / (Double)refAC) );
434  const Int weight = (Int)( 0.5 + dWeight * (Double)(1<<log2Denom) );
435  const Int offset = (Int)( ((currDC<<log2Denom) - ((Int64)weight * refDC) + (Int64)realOffset) >> realLog2Denom );
436 
437  Int clippedOffset;
438  if(isChroma(compID)) // Chroma offset range limination
439  {
440  const Int pred = ( range - ( ( range*weight)>>(log2Denom) ) );
441  const Int deltaOffset = Clip3( -4*range, 4*range-1, (offset - pred) ); // signed 10bit
442 
443  clippedOffset = Clip3( -range, range-1, (deltaOffset + pred) ); // signed 8bit
444  }
445  else // Luma offset range limitation
446  {
447  clippedOffset = Clip3( -range, range-1, offset);
448  }
449 
450  // Weighting factor limitation
451  const Int defaultWeight = (1<<log2Denom);
452  const Int deltaWeight = (weight - defaultWeight);
453 
454  if(deltaWeight >= range || deltaWeight < -range)
455  {
456  return false;
457  }
458 
459  m_wp[refList][refIdxTemp][comp].bPresentFlag = true;
460  m_wp[refList][refIdxTemp][comp].iWeight = weight;
461  m_wp[refList][refIdxTemp][comp].iOffset = clippedOffset;
462  m_wp[refList][refIdxTemp][comp].uiLog2WeightDenom = log2Denom;
463  }
464  }
465  }
466  return true;
467 }
468 
469 
475 Bool WeightPredAnalysis::xSelectWPHistExtClip(TComSlice *const slice, const Int log2Denom, const Bool bDoEnhancement, const Bool bClipInitialSADWP, const Bool bUseHistogram)
476 {
477  const TComPicYuv *const pPic = slice->getPic()->getPicYuvOrg();
478  const Int defaultWeight = 1<<log2Denom;
479  const Int numPredDir = slice->isInterP() ? 1 : 2;
480  const Bool useHighPrecision = slice->getSPS()->getSpsRangeExtension().getHighPrecisionOffsetsEnabledFlag();
481 
482  assert (numPredDir <= Int(NUM_REF_PIC_LIST_01));
483 
484  for ( Int refList = 0; refList < numPredDir; refList++ )
485  {
486  const RefPicList eRefPicList = ( refList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
487 
488  for ( Int refIdxTemp = 0; refIdxTemp < slice->getNumRefIdx(eRefPicList); refIdxTemp++ )
489  {
490  Bool useChromaWeight = false;
491 
492  for(Int comp=0; comp<pPic->getNumberValidComponents(); comp++)
493  {
494  const ComponentID compID = ComponentID(comp);
495  const Pel *pOrg = pPic->getAddr(compID);
496  const Pel *pRef = slice->getRefPic(eRefPicList, refIdxTemp)->getPicYuvRec()->getAddr(compID);
497  const Int orgStride = pPic->getStride(compID);
498  const Int refStride = slice->getRefPic(eRefPicList, refIdxTemp)->getPicYuvRec()->getStride(compID);
499  const Int width = pPic->getWidth(compID);
500  const Int height = pPic->getHeight(compID);
501  const Int bitDepth = slice->getSPS()->getBitDepth(toChannelType(compID));
502  WPScalingParam &wp = m_wp[refList][refIdxTemp][compID];
503  Int weight = wp.iWeight;
504  Int offset = wp.iOffset;
505  Int weightDef = defaultWeight;
506  Int offsetDef = 0;
507 
508  // calculate SAD costs with/without wp for luma
509  const Int64 SADnoWP = xCalcSADvalueWPOptionalClip(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, defaultWeight, 0, useHighPrecision, bClipInitialSADWP);
510  if (SADnoWP > 0)
511  {
512  const Int64 SADWP = xCalcSADvalueWPOptionalClip(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weight, offset, useHighPrecision, bClipInitialSADWP);
513  const Double dRatioSAD = (Double)SADWP / (Double)SADnoWP;
514  Double dRatioSr0SAD = std::numeric_limits<Double>::max();
515  Double dRatioSrSAD = std::numeric_limits<Double>::max();
516 
517  if (bUseHistogram)
518  {
519  std::vector<Int> histogramOrg;// = pPic->getHistogram(compID);
520  std::vector<Int> histogramRef;// = slice->getRefPic(eRefPicList, refIdxTemp)->getPicYuvRec()->getHistogram(compID);
521  std::vector<Int> searchedHistogram;
522 
523  // Compute histograms
524  xCalcHistogram(pOrg, histogramOrg, width, height, orgStride, 1 << bitDepth);
525  xCalcHistogram(pRef, histogramRef, width, height, refStride, 1 << bitDepth);
526 
527  // Do a histogram search around DC WP parameters; resulting distortion and 'searchedHistogram' is discarded
528  xSearchHistogram(histogramOrg, histogramRef, searchedHistogram, bitDepth, log2Denom, weight, offset, useHighPrecision, compID);
529  // calculate updated WP SAD
530  const Int64 SADSrWP = xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weight, offset, useHighPrecision);
531  dRatioSrSAD = (Double)SADSrWP / (Double)SADnoWP;
532 
533  if (bDoEnhancement)
534  {
535  // Do the same around the default ones; resulting distortion and 'searchedHistogram' is discarded
536  xSearchHistogram(histogramOrg, histogramRef, searchedHistogram, bitDepth, log2Denom, weightDef, offsetDef, useHighPrecision, compID);
537  // calculate updated WP SAD
538  const Int64 SADSr0WP = xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weightDef, offsetDef, useHighPrecision);
539  dRatioSr0SAD = (Double)SADSr0WP / (Double)SADnoWP;
540  }
541  }
542 
543  if(min(dRatioSr0SAD, min(dRatioSAD, dRatioSrSAD)) >= WEIGHT_PRED_SAD_RELATIVE_TO_NON_WEIGHT_PRED_SAD)
544  {
545  wp.bPresentFlag = false;
546  wp.iOffset = 0;
547  wp.iWeight = defaultWeight;
548  wp.uiLog2WeightDenom = log2Denom;
549  }
550  else
551  {
552  if (compID != COMPONENT_Y)
553  {
554  useChromaWeight = true;
555  }
556 
557  if (dRatioSr0SAD < dRatioSrSAD && dRatioSr0SAD < dRatioSAD)
558  {
559  wp.bPresentFlag = true;
560  wp.iOffset = offsetDef;
561  wp.iWeight = weightDef;
562  wp.uiLog2WeightDenom = log2Denom;
563  }
564  else if (dRatioSrSAD < dRatioSAD)
565  {
566  wp.bPresentFlag = true;
567  wp.iOffset = offset;
568  wp.iWeight = weight;
569  wp.uiLog2WeightDenom = log2Denom;
570  }
571  }
572  }
573  else // (SADnoWP <= 0)
574  {
575  wp.bPresentFlag = false;
576  wp.iOffset = 0;
577  wp.iWeight = defaultWeight;
578  wp.uiLog2WeightDenom = log2Denom;
579  }
580  }
581 
582  for(Int comp=1; comp<pPic->getNumberValidComponents(); comp++)
583  {
584  m_wp[refList][refIdxTemp][comp].bPresentFlag = useChromaWeight;
585  }
586  }
587  }
588 
589  return true;
590 }
591 
593 Bool WeightPredAnalysis::xSelectWP(TComSlice *const slice, const Int log2Denom)
594 {
595  TComPicYuv *const pPic = slice->getPic()->getPicYuvOrg();
596  const Int defaultWeight = 1<<log2Denom;
597  const Int numPredDir = slice->isInterP() ? 1 : 2;
598  const Bool useHighPrecisionPredictionWeighting = slice->getSPS()->getSpsRangeExtension().getHighPrecisionOffsetsEnabledFlag();
599 
600  assert (numPredDir <= Int(NUM_REF_PIC_LIST_01));
601 
602  for ( Int refList = 0; refList < numPredDir; refList++ )
603  {
604  const RefPicList eRefPicList = ( refList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
605 
606  for ( Int refIdxTemp = 0; refIdxTemp < slice->getNumRefIdx(eRefPicList); refIdxTemp++ )
607  {
608  Int64 SADWP = 0, SADnoWP = 0;
609 
610  for(Int comp=0; comp<pPic->getNumberValidComponents(); comp++)
611  {
612  const ComponentID compID = ComponentID(comp);
613  Pel *pOrg = pPic->getAddr(compID);
614  Pel *pRef = slice->getRefPic(eRefPicList, refIdxTemp)->getPicYuvRec()->getAddr(compID);
615  const Int orgStride = pPic->getStride(compID);
616  const Int refStride = slice->getRefPic(eRefPicList, refIdxTemp)->getPicYuvRec()->getStride(compID);
617  const Int width = pPic->getWidth(compID);
618  const Int height = pPic->getHeight(compID);
619  const Int bitDepth = slice->getSPS()->getBitDepth(toChannelType(compID));
620 
621  // calculate SAD costs with/without wp for luma
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);
624  }
625 
626  const Double dRatio = SADnoWP > 0 ? (((Double)SADWP / (Double)SADnoWP)) : std::numeric_limits<Double>::max();
628  {
629  for(Int comp=0; comp<pPic->getNumberValidComponents(); comp++)
630  {
631  WPScalingParam &wp=m_wp[refList][refIdxTemp][comp];
632  wp.bPresentFlag = false;
633  wp.iOffset = 0;
634  wp.iWeight = defaultWeight;
635  wp.uiLog2WeightDenom = log2Denom;
636  }
637  }
638  }
639  }
640 
641  return true;
642 }
643 
644 // Alternatively, a SSE-based measure could be used instead.
645 // The respective function has been removed as it currently redundant.
646 static
647 Int64 xCalcSADvalueWP(const Int bitDepth,
648  const Pel *pOrgPel,
649  const Pel *pRefPel,
650  const Int width,
651  const Int height,
652  const Int orgStride,
653  const Int refStride,
654  const Int log2Denom,
655  const Int weight,
656  const Int offset,
657  const Bool useHighPrecision)
658 {
659  //const Int64 iSize = iWidth*iHeight;
660  const Int64 realLog2Denom = useHighPrecision ? log2Denom : (log2Denom + (bitDepth - 8));
661  const Int64 realOffset = ((Int64)offset)<<realLog2Denom;
662 
663  Int64 SAD = 0;
664  for( Int y = 0; y < height; y++ )
665  {
666  for( Int x = 0; x < width; x++ )
667  {
668  SAD += abs(( ((Int64)pOrgPel[x] << (Int64) log2Denom) - ( (Int64) pRefPel[x] * (Int64) weight + (realOffset) ) ) );
669  }
670  pOrgPel += orgStride;
671  pRefPel += refStride;
672  }
673 
674  //return (iSAD/iSize);
675  return SAD;
676 }
677 
678 static
680  const Pel *pOrgPel,
681  const Pel *pRefPel,
682  const Int width,
683  const Int height,
684  const Int orgStride,
685  const Int refStride,
686  const Int log2Denom,
687  const Int weight,
688  const Int offset,
689  const Bool useHighPrecision,
690  const Bool clipped)
691 {
692  Int64 SAD = 0;
693  if (clipped)
694  {
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;
700 
701  for( Int y = 0; y < height; y++ )
702  {
703  for( Int x = 0; x < width; x++ )
704  {
705  Int64 scaledValue = Clip3(minValue, maxValue, ((((Int64) pRefPel[x] * (Int64) weight + roundOffset) ) >> (Int64) log2Denom) + realOffset);
706  SAD += abs((Int64)pOrgPel[x] - scaledValue);
707  }
708  pOrgPel += orgStride;
709  pRefPel += refStride;
710  }
711  }
712  else
713  {
714  //const Int64 iSize = iWidth*iHeight;
715  const Int64 realLog2Denom = useHighPrecision ? log2Denom : (log2Denom + (bitDepth - 8));
716  const Int64 realOffset = ((Int64)offset)<<realLog2Denom;
717 
718  for( Int y = 0; y < height; y++ )
719  {
720  for( Int x = 0; x < width; x++ )
721  {
722  SAD += abs(( ((Int64)pOrgPel[x] << (Int64) log2Denom) - ( (Int64) pRefPel[x] * (Int64) weight + (realOffset) ) ) );
723  }
724  pOrgPel += orgStride;
725  pRefPel += refStride;
726  }
727  }
728  return SAD;
729 }
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.
picture YUV buffer class
Definition: TComPicYuv.h:55
Void getWpAcDcParam(WPACDCParam *&wp)
get AC and DC values for weighted pred
Definition: TComSlice.cpp:1389
UInt Distortion
distortion measurement
Definition: TypeDef.h:260
void Void
Definition: TypeDef.h:203
Int getStride(const ComponentID id) const
Definition: TComPicYuv.h:121
const TComSPSRExt & getSpsRangeExtension() const
Definition: TComSlice.h:941
Void setWpScaling(WPScalingParam wp[NUM_REF_PIC_LIST_01][MAX_NUM_REF][MAX_NUM_COMPONENT])
Definition: TComSlice.h:1505
Int getHeight(const ComponentID id) const
Definition: TComPicYuv.h:117
TComSlice * getSlice(Int i)
Definition: TComPic.h:113
static Distortion xCalcHistDistortion(const std::vector< Int > &histogram0, const std::vector< Int > &histogram1)
unsigned int UInt
Definition: TypeDef.h:212
Short Pel
pixel type
Definition: TypeDef.h:249
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
Definition: CommonDef.h:125
Bool xUpdatingWPParameters(TComSlice *const slice, const Int log2Denom)
update wp tables for explicit wp w.r.t range limitation
Int getNumRefIdx(RefPicList e) const
Definition: TComSlice.h:1370
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()
Definition: TComPic.h:120
Int getWidth(const ComponentID id) const
Definition: TComPicYuv.h:116
bool Bool
Definition: TypeDef.h:204
long long Int64
Definition: TypeDef.h:232
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.
Definition: CommonDef.h:216
UInt uiLog2WeightDenom
Definition: TComSlice.h:1206
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)
static ChannelType toChannelType(const ComponentID id)
T Clip3(const T minVal, const T maxVal, const T a)
general min/max clip
Definition: CommonDef.h:252
TComPicYuv * getPicYuvOrg()
Definition: TComPic.h:119
reference list 0
Definition: TypeDef.h:372
Int getBitDepth(ChannelType type) const
Definition: TComSlice.h:894
RefPicList
reference list index
Definition: TypeDef.h:370
Void setWpAcDcParam(WPACDCParam wp[MAX_NUM_COMPONENT])
Definition: TComSlice.h:1515
Void setTestWeightBiPred(Bool bValue)
Definition: TComSlice.h:1504
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)
Definition: TComSlice.h:1502
const TComPPS * getPPS() const
Definition: TComSlice.h:1332
Bool getUseWP() const
Definition: TComSlice.h:1134
UInt getNumberValidComponents() const
Definition: TComPicYuv.h:119
reference list 1
Definition: TypeDef.h:373
Bool xSelectWP(TComSlice *const slice, const Int log2Denom)
select whether weighted pred enables or not.
Bool isInterP() const
Definition: TComSlice.h:1425
Void xEstimateWPParamSlice(TComSlice *const slice, const WeightedPredictionMethod method)
estimate wp tables for explicit wp
TComPic * getPic()
Definition: TComSlice.h:1371
weighted prediction encoder class
Pel * getAddr(const ComponentID ch)
Definition: TComPicYuv.h:139
WeightedPredictionMethod
Definition: TypeDef.h:628
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]
int Int
Definition: TypeDef.h:211
static Bool isChroma(const ComponentID id)
ComponentID
Definition: TypeDef.h:308
double Double
Definition: TypeDef.h:213
slice header class
Definition: TComSlice.h:1225
Bool getWPBiPred() const
Definition: TComSlice.h:1135
TComPic * getRefPic(RefPicList e, Int iRefIdx)
Definition: TComSlice.h:1373
const TComSPS * getSPS() const
Definition: TComSlice.h:1329
Bool xSelectWPHistExtClip(TComSlice *const slice, const Int log2Denom, const Bool bDoEnhancement, const Bool bClipInitialSADWP, const Bool bUseHistogram)
Bool getHighPrecisionOffsetsEnabledFlag() const
Definition: TComSlice.h:729