HEVC Test Model (HM)  HM-16.3
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-2015, 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/TypeDef.h"
39 #include "../TLibCommon/TComSlice.h"
40 #include "../TLibCommon/TComPic.h"
41 #include "../TLibCommon/TComPicYuv.h"
42 #include "WeightPredAnalysis.h"
43 
44 #define ABS(a) ((a) < 0 ? - (a) : (a))
45 #define DTHRESH (0.99)
46 
48 {
49  for ( UInt lst =0 ; lst<NUM_REF_PIC_LIST_01 ; lst++ )
50  {
51  for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ )
52  {
53  for ( Int comp=0 ; comp<MAX_NUM_COMPONENT ;comp++ )
54  {
55  WPScalingParam *pwp = &(m_wp[lst][iRefIdx][comp]);
56  pwp->bPresentFlag = false;
57  pwp->uiLog2WeightDenom = 0;
58  pwp->iWeight = 1;
59  pwp->iOffset = 0;
60  }
61  }
62  }
63 }
64 
65 
68 {
69  //===== calculate AC/DC value =====
70  TComPicYuv* pPic = slice->getPic()->getPicYuvOrg();
71 
72  WPACDCParam weightACDCParam[MAX_NUM_COMPONENT];
73 
74  for(Int componentIndex = 0; componentIndex < pPic->getNumberValidComponents(); componentIndex++)
75  {
76  const ComponentID compID = ComponentID(componentIndex);
77 
78  // calculate DC/AC value for channel
79 
80  const Int iStride = pPic->getStride(compID);
81  const Int iWidth = pPic->getWidth(compID);
82  const Int iHeight = pPic->getHeight(compID);
83 
84  const Int iSample = iWidth*iHeight;
85 
86  Int64 iOrgDC = 0;
87  {
88  const Pel *pPel = pPic->getAddr(compID);
89 
90  for(Int y = 0; y < iHeight; y++, pPel+=iStride )
91  {
92  for(Int x = 0; x < iWidth; x++ )
93  {
94  iOrgDC += (Int)( pPel[x] );
95  }
96  }
97  }
98 
99  const Int64 iOrgNormDC = ((iOrgDC+(iSample>>1)) / iSample);
100 
101  Int64 iOrgAC = 0;
102  {
103  const Pel *pPel = pPic->getAddr(compID);
104 
105  for(Int y = 0; y < iHeight; y++, pPel += iStride )
106  {
107  for(Int x = 0; x < iWidth; x++ )
108  {
109  iOrgAC += abs( (Int)pPel[x] - (Int)iOrgNormDC );
110  }
111  }
112  }
113 
115  weightACDCParam[compID].iDC = (((iOrgDC<<fixedBitShift)+(iSample>>1)) / iSample);
116  weightACDCParam[compID].iAC = iOrgAC;
117  }
118 
119  slice->setWpAcDcParam(weightACDCParam);
120 }
121 
122 
125 {
126  const TComPicYuv *pPic = slice->getPic()->getPicYuvOrg();
127 
128  Int iPresentCnt = 0;
129  for ( UInt lst=0 ; lst<NUM_REF_PIC_LIST_01 ; lst++ )
130  {
131  for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ )
132  {
133  for(Int componentIndex = 0; componentIndex < pPic->getNumberValidComponents(); componentIndex++)
134  {
135  WPScalingParam *pwp = &(m_wp[lst][iRefIdx][componentIndex]);
136  iPresentCnt += (Int)pwp->bPresentFlag;
137  }
138  }
139  }
140 
141  if(iPresentCnt==0)
142  {
143  slice->setTestWeightPred(false);
144  slice->setTestWeightBiPred(false);
145 
146  for ( UInt lst=0 ; lst<NUM_REF_PIC_LIST_01 ; lst++ )
147  {
148  for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ )
149  {
150  for(Int componentIndex = 0; componentIndex < pPic->getNumberValidComponents(); componentIndex++)
151  {
152  WPScalingParam *pwp = &(m_wp[lst][iRefIdx][componentIndex]);
153 
154  pwp->bPresentFlag = false;
155  pwp->uiLog2WeightDenom = 0;
156  pwp->iWeight = 1;
157  pwp->iOffset = 0;
158  }
159  }
160  }
161  slice->setWpScaling( m_wp );
162  }
163  else
164  {
165  slice->setTestWeightPred(slice->getPPS()->getUseWP());
166  slice->setTestWeightBiPred(slice->getPPS()->getWPBiPred());
167  }
168 }
169 
170 
173 {
174  Int iDenom = 6;
175  Bool validRangeFlag = false;
176 
177  if(slice->getNumRefIdx(REF_PIC_LIST_0)>3)
178  {
179  iDenom = 7;
180  }
181 
182  do
183  {
184  validRangeFlag = xUpdatingWPParameters(slice, iDenom);
185  if (!validRangeFlag)
186  {
187  iDenom--; // decrement to satisfy the range limitation
188  }
189  } while (validRangeFlag == false);
190 
191  // selecting whether WP is used, or not (fast search)
192  // NOTE: This is not operating on a slice, but the entire picture.
193  xSelectWP(slice, iDenom);
194 
195  slice->setWpScaling( m_wp );
196 }
197 
198 
201 {
202  const Int numComp = slice->getPic()->getPicYuvOrg()->getNumberValidComponents();
203  const Bool bUseHighPrecisionWeighting = slice->getSPS()->getUseHighPrecisionPredictionWeighting();
204  const Int numPredDir = slice->isInterP() ? 1 : 2;
205 
206  assert (numPredDir <= Int(NUM_REF_PIC_LIST_01));
207 
208  for ( Int refList = 0; refList < numPredDir; refList++ )
209  {
210  const RefPicList eRefPicList = ( refList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
211 
212  for ( Int refIdxTemp = 0; refIdxTemp < slice->getNumRefIdx(eRefPicList); refIdxTemp++ )
213  {
214  WPACDCParam *currWeightACDCParam, *refWeightACDCParam;
215  slice->getWpAcDcParam(currWeightACDCParam);
216  slice->getRefPic(eRefPicList, refIdxTemp)->getSlice(0)->getWpAcDcParam(refWeightACDCParam);
217 
218  for ( Int comp = 0; comp < numComp; comp++ )
219  {
220  const ComponentID compID = ComponentID(comp);
221  const Int range = bUseHighPrecisionWeighting ? (1<<g_bitDepth[toChannelType(compID)])/2 : 128;
222  const Int realLog2Denom = log2Denom + (bUseHighPrecisionWeighting ? RExt__PREDICTION_WEIGHTING_ANALYSIS_DC_PRECISION : (g_bitDepth[toChannelType(compID)] - 8));
223  const Int realOffset = ((Int)1<<(realLog2Denom-1));
224 
225  // current frame
226  const Int64 currDC = currWeightACDCParam[comp].iDC;
227  const Int64 currAC = currWeightACDCParam[comp].iAC;
228  // reference frame
229  const Int64 refDC = refWeightACDCParam[comp].iDC;
230  const Int64 refAC = refWeightACDCParam[comp].iAC;
231 
232  // calculating iWeight and iOffset params
233  const Double dWeight = (refAC==0) ? (Double)1.0 : Clip3( -16.0, 15.0, ((Double)currAC / (Double)refAC) );
234  const Int weight = (Int)( 0.5 + dWeight * (Double)(1<<log2Denom) );
235  const Int offset = (Int)( ((currDC<<log2Denom) - ((Int64)weight * refDC) + (Int64)realOffset) >> realLog2Denom );
236 
237  Int clippedOffset;
238  if(isChroma(compID)) // Chroma offset range limination
239  {
240  const Int pred = ( range - ( ( range*weight)>>(log2Denom) ) );
241  const Int deltaOffset = Clip3( -4*range, 4*range-1, (offset - pred) ); // signed 10bit
242 
243  clippedOffset = Clip3( -range, range-1, (deltaOffset + pred) ); // signed 8bit
244  }
245  else // Luma offset range limitation
246  {
247  clippedOffset = Clip3( -range, range-1, offset);
248  }
249 
250  // Weighting factor limitation
251  const Int defaultWeight = (1<<log2Denom);
252  const Int deltaWeight = (defaultWeight - weight);
253 
254  if(deltaWeight >= range || deltaWeight < -range)
255  {
256  return false;
257  }
258 
259  m_wp[refList][refIdxTemp][comp].bPresentFlag = true;
260  m_wp[refList][refIdxTemp][comp].iWeight = weight;
261  m_wp[refList][refIdxTemp][comp].iOffset = clippedOffset;
262  m_wp[refList][refIdxTemp][comp].uiLog2WeightDenom = log2Denom;
263  }
264  }
265  }
266  return true;
267 }
268 
269 
271 Bool WeightPredAnalysis::xSelectWP(TComSlice *const slice, const Int log2Denom)
272 {
273  TComPicYuv *const pPic = slice->getPic()->getPicYuvOrg();
274  const Int iDefaultWeight = ((Int)1<<log2Denom);
275  const Int iNumPredDir = slice->isInterP() ? 1 : 2;
276  const Bool useHighPrecisionPredictionWeighting = slice->getSPS()->getUseHighPrecisionPredictionWeighting();
277 
278  assert (iNumPredDir <= Int(NUM_REF_PIC_LIST_01));
279 
280  for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
281  {
282  const RefPicList eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
283 
284  for ( Int iRefIdxTemp = 0; iRefIdxTemp < slice->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
285  {
286  Int64 iSADWP = 0, iSADnoWP = 0;
287 
288  for(Int comp=0; comp<pPic->getNumberValidComponents(); comp++)
289  {
290  const ComponentID compID = ComponentID(comp);
291  Pel *pOrg = pPic->getAddr(compID);
292  Pel *pRef = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getAddr(compID);
293  const Int iOrgStride = pPic->getStride(compID);
294  const Int iRefStride = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getStride(compID);
295  const Int iWidth = pPic->getWidth(compID);
296  const Int iHeight = pPic->getHeight(compID);
297  const Int bitDepth = g_bitDepth[toChannelType(compID)];
298 
299  // calculate SAD costs with/without wp for luma
300  iSADWP += xCalcSADvalueWP(bitDepth, pOrg, pRef, iWidth, iHeight, iOrgStride, iRefStride, log2Denom, m_wp[iRefList][iRefIdxTemp][compID].iWeight, m_wp[iRefList][iRefIdxTemp][compID].iOffset, useHighPrecisionPredictionWeighting);
301  iSADnoWP += xCalcSADvalueWP(bitDepth, pOrg, pRef, iWidth, iHeight, iOrgStride, iRefStride, log2Denom, iDefaultWeight, 0, useHighPrecisionPredictionWeighting);
302  }
303 
304  const Double dRatio = ((Double)iSADWP / (Double)iSADnoWP);
305  if(dRatio >= (Double)DTHRESH)
306  {
307  for(Int comp=0; comp<pPic->getNumberValidComponents(); comp++)
308  {
309  m_wp[iRefList][iRefIdxTemp][comp].bPresentFlag = false;
310  m_wp[iRefList][iRefIdxTemp][comp].iOffset = 0;
311  m_wp[iRefList][iRefIdxTemp][comp].iWeight = iDefaultWeight;
312  m_wp[iRefList][iRefIdxTemp][comp].uiLog2WeightDenom = log2Denom;
313  }
314  }
315  }
316  }
317 
318  return true;
319 }
320 
321 
324  const Pel *pOrgPel,
325  const Pel *pRefPel,
326  const Int iWidth,
327  const Int iHeight,
328  const Int iOrgStride,
329  const Int iRefStride,
330  const Int iLog2Denom,
331  const Int iWeight,
332  const Int iOffset,
333  const Bool useHighPrecisionPredictionWeighting)
334 {
335  const Int64 iSize = iWidth*iHeight;
336  const Int64 iRealLog2Denom = useHighPrecisionPredictionWeighting ? iLog2Denom : (iLog2Denom + (bitDepth - 8));
337 
338  Int64 iSAD = 0;
339  for( Int y = 0; y < iHeight; y++ )
340  {
341  for( Int x = 0; x < iWidth; x++ )
342  {
343  iSAD += ABS(( ((Int64)pOrgPel[x]<<(Int64)iLog2Denom) - ( (Int64)pRefPel[x] * (Int64)iWeight + ((Int64)iOffset<<iRealLog2Denom) ) ) );
344  }
345  pOrgPel += iOrgStride;
346  pRefPel += iRefStride;
347  }
348 
349  return (iSAD/iSize);
350 }
WPScalingParam m_wp[NUM_REF_PIC_LIST_01][16][MAX_NUM_COMPONENT]
picture YUV buffer class
Definition: TComPicYuv.h:55
void Void
Definition: TypeDef.h:285
Int getStride(const ComponentID id) const
Definition: TComPicYuv.h:113
Int getHeight(const ComponentID id) const
Definition: TComPicYuv.h:109
TComSlice * getSlice(Int i)
Definition: TComPic.h:103
unsigned int UInt
Definition: TypeDef.h:297
Short Pel
pixel type
Definition: TypeDef.h:692
Void getWpAcDcParam(WPACDCParam *&wp)
get AC and DC values for weighted pred
Definition: TComSlice.cpp:1449
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:1353
Void xEstimateWPParamSlice(TComSlice *const slice)
estimate wp tables for explicit wp
Void xCheckWPEnable(TComSlice *const slice)
check weighted pred or non-weighted pred
TComPicYuv * getPicYuvRec()
Definition: TComPic.h:109
Int getWidth(const ComponentID id) const
Definition: TComPicYuv.h:108
bool Bool
Definition: TypeDef.h:286
long long Int64
Definition: TypeDef.h:317
UInt uiLog2WeightDenom
Definition: TComSlice.h:1179
static ChannelType toChannelType(const ComponentID id)
T Clip3(const T minVal, const T maxVal, const T a)
general min/max clip
Definition: CommonDef.h:137
TComPicYuv * getPicYuvOrg()
Definition: TComPic.h:108
reference list 0
Definition: TypeDef.h:417
RefPicList
reference list index
Definition: TypeDef.h:415
Void setWpAcDcParam(WPACDCParam wp[MAX_NUM_COMPONENT])
Definition: TComSlice.h:1501
#define DTHRESH
#define ABS(a)
Bool getUseHighPrecisionPredictionWeighting() const
Definition: TComSlice.h:889
Void setTestWeightBiPred(Bool bValue)
Definition: TComSlice.h:1490
Void setTestWeightPred(Bool bValue)
Definition: TComSlice.h:1488
const TComPPS * getPPS() const
Definition: TComSlice.h:1309
#define 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: TypeDef.h:250
Bool getUseWP() const
Definition: TComSlice.h:1102
UInt getNumberValidComponents() const
Definition: TComPicYuv.h:111
#define MAX_NUM_REF
max. number of entries in picture reference list
Definition: CommonDef.h:113
reference list 1
Definition: TypeDef.h:418
Bool xSelectWP(TComSlice *const slice, const Int log2Denom)
select whether weighted pred enables or not.
Bool isInterP() const
Definition: TComSlice.h:1406
Int64 xCalcSADvalueWP(const Int bitDepth, const Pel *pOrgPel, const Pel *pRefPel, const Int iWidth, const Int iHeight, const Int iOrgStride, const Int iRefStride, const Int iLog2Denom, const Int iWeight, const Int iOffset, const Bool useHighPrecisionPredictionWeighting)
calculate SAD values for both WP version and non-WP version.
Int g_bitDepth[MAX_NUM_CHANNEL_TYPE]
Definition: TComRom.cpp:548
Void setWpScaling(WPScalingParam wp[NUM_REF_PIC_LIST_01][16][MAX_NUM_COMPONENT])
Definition: TComSlice.h:1491
TComPic * getPic()
Definition: TComSlice.h:1354
weighted prediction encoder class
Pel * getAddr(const ComponentID ch)
Definition: TComPicYuv.h:127
Void xCalcACDCParamSlice(TComSlice *const slice)
calculate AC and DC values for current original image
int Int
Definition: TypeDef.h:296
static Bool isChroma(const ComponentID id)
ComponentID
Definition: TypeDef.h:368
double Double
Definition: TypeDef.h:298
slice header class
Definition: TComSlice.h:1198
Bool getWPBiPred() const
Definition: TComSlice.h:1103
TComPic * getRefPic(RefPicList e, Int iRefIdx)
Definition: TComSlice.h:1355
const TComSPS * getSPS() const
Definition: TComSlice.h:1306