HEVC Test Model (HM)  HM-16.3
TComWeightPrediction.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 files
39 #include "CommonDef.h"
40 #include "TComYuv.h"
41 #include "TComPic.h"
43 #include "TComWeightPrediction.h"
44 
45 
46 static inline Pel weightBidir( Int w0, Pel P0, Int w1, Pel P1, Int round, Int shift, Int offset, Int clipBD)
47 {
48  return ClipBD( ( (w0*(P0 + IF_INTERNAL_OFFS) + w1*(P1 + IF_INTERNAL_OFFS) + round + (offset << (shift-1))) >> shift ), clipBD );
49 }
50 
51 
52 static inline Pel weightUnidir( Int w0, Pel P0, Int round, Int shift, Int offset, Int clipBD)
53 {
54  return ClipBD( ( (w0*(P0 + IF_INTERNAL_OFFS) + round) >> shift ) + offset, clipBD );
55 }
56 
57 // ====================================================================================================================
58 // Class definition
59 // ====================================================================================================================
60 
62 {
63 }
64 
65 
68  const TComYuv *pcYuvSrc1,
69  const UInt iPartUnitIdx,
70  const UInt uiWidth,
71  const UInt uiHeight,
72  const WPScalingParam *const wp0,
73  const WPScalingParam *const wp1,
74  TComYuv *const rpcYuvDst,
75  const Bool bRoundLuma )
76 {
77 
78  const Bool enableRounding[MAX_NUM_COMPONENT]={ bRoundLuma, true, true };
79 
80  const UInt numValidComponent = pcYuvSrc0->getNumberValidComponents();
81 
82  for(Int componentIndex=0; componentIndex<numValidComponent; componentIndex++)
83  {
84  const ComponentID compID=ComponentID(componentIndex);
85 
86  const Pel* pSrc0 = pcYuvSrc0->getAddr( compID, iPartUnitIdx );
87  const Pel* pSrc1 = pcYuvSrc1->getAddr( compID, iPartUnitIdx );
88  Pel* pDst = rpcYuvDst->getAddr( compID, iPartUnitIdx );
89 
90  // Luma : --------------------------------------------
91  const Int w0 = wp0[compID].w;
92  const Int offset = wp0[compID].offset;
93  const Int clipBD = g_bitDepth[toChannelType(compID)];
94  const Int shiftNum = std::max<Int>(2, (IF_INTERNAL_PREC - clipBD));
95  const Int shift = wp0[compID].shift + shiftNum;
96  const Int round = (enableRounding[compID] && (shift > 0)) ? (1<<(shift-1)) : 0;
97  const Int w1 = wp1[compID].w;
98  const UInt csx = pcYuvSrc0->getComponentScaleX(compID);
99  const UInt csy = pcYuvSrc0->getComponentScaleY(compID);
100  const Int iHeight = uiHeight>>csy;
101  const Int iWidth = uiWidth>>csx;
102 
103  const UInt iSrc0Stride = pcYuvSrc0->getStride(compID);
104  const UInt iSrc1Stride = pcYuvSrc1->getStride(compID);
105  const UInt iDstStride = rpcYuvDst->getStride(compID);
106 
107  for ( Int y = iHeight-1; y >= 0; y-- )
108  {
109  // do it in batches of 4 (partial unroll)
110  Int x = iWidth-1;
111  for ( ; x >= 3; )
112  {
113  pDst[x] = weightBidir(w0,pSrc0[x], w1,pSrc1[x], round, shift, offset, clipBD); x--;
114  pDst[x] = weightBidir(w0,pSrc0[x], w1,pSrc1[x], round, shift, offset, clipBD); x--;
115  pDst[x] = weightBidir(w0,pSrc0[x], w1,pSrc1[x], round, shift, offset, clipBD); x--;
116  pDst[x] = weightBidir(w0,pSrc0[x], w1,pSrc1[x], round, shift, offset, clipBD); x--;
117  }
118  for( ; x >= 0; x-- )
119  {
120  pDst[x] = weightBidir(w0,pSrc0[x], w1,pSrc1[x], round, shift, offset, clipBD);
121  }
122 
123  pSrc0 += iSrc0Stride;
124  pSrc1 += iSrc1Stride;
125  pDst += iDstStride;
126  } // y loop
127  } // compID loop
128 }
129 
130 
133  const UInt iPartUnitIdx,
134  const UInt uiWidth,
135  const UInt uiHeight,
136  const WPScalingParam *const wp0,
137  TComYuv *const pcYuvDst )
138 {
139  const UInt numValidComponent = pcYuvSrc0->getNumberValidComponents();
140 
141  for(Int componentIndex=0; componentIndex<numValidComponent; componentIndex++)
142  {
143  const ComponentID compID=ComponentID(componentIndex);
144 
145  const Pel* pSrc0 = pcYuvSrc0->getAddr( compID, iPartUnitIdx );
146  Pel* pDst = pcYuvDst->getAddr( compID, iPartUnitIdx );
147 
148  // Luma : --------------------------------------------
149  const Int w0 = wp0[compID].w;
150  const Int offset = wp0[compID].offset;
151  const Int clipBD = g_bitDepth[toChannelType(compID)];
152  const Int shiftNum = std::max<Int>(2, (IF_INTERNAL_PREC - clipBD));
153  const Int shift = wp0[compID].shift + shiftNum;
154  const Int round = (shift > 0) ? (1<<(shift-1)) : 0;
155  const UInt iSrc0Stride = pcYuvSrc0->getStride(compID);
156  const UInt iDstStride = pcYuvDst->getStride(compID);
157  const UInt csx = pcYuvSrc0->getComponentScaleX(compID);
158  const UInt csy = pcYuvSrc0->getComponentScaleY(compID);
159  const Int iHeight = uiHeight>>csy;
160  const Int iWidth = uiWidth>>csx;
161 
162  for (Int y = iHeight-1; y >= 0; y-- )
163  {
164  Int x = iWidth-1;
165  for ( ; x >= 3; )
166  {
167  pDst[x] = weightUnidir(w0, pSrc0[x], round, shift, offset, clipBD); x--;
168  pDst[x] = weightUnidir(w0, pSrc0[x], round, shift, offset, clipBD); x--;
169  pDst[x] = weightUnidir(w0, pSrc0[x], round, shift, offset, clipBD); x--;
170  pDst[x] = weightUnidir(w0, pSrc0[x], round, shift, offset, clipBD); x--;
171  }
172  for( ; x >= 0; x--)
173  {
174  pDst[x] = weightUnidir(w0, pSrc0[x], round, shift, offset, clipBD);
175  }
176  pSrc0 += iSrc0Stride;
177  pDst += iDstStride;
178  }
179  }
180 }
181 
182 
183 //=======================================================
184 // getWpScaling()
185 //=======================================================
188  const Int iRefIdx0,
189  const Int iRefIdx1,
190  WPScalingParam *&wp0,
191  WPScalingParam *&wp1)
192 {
193  assert(iRefIdx0 >= 0 || iRefIdx1 >= 0);
194 
195  TComSlice *const pcSlice = pcCU->getSlice();
196  const Bool wpBiPred = pcCU->getSlice()->getPPS()->getWPBiPred();
197  const Bool bBiDir = (iRefIdx0>=0 && iRefIdx1>=0);
198  const Bool bUniDir = !bBiDir;
199 
200  if ( bUniDir || wpBiPred )
201  { // explicit --------------------
202  if ( iRefIdx0 >= 0 )
203  {
204  pcSlice->getWpScaling(REF_PIC_LIST_0, iRefIdx0, wp0);
205  }
206  if ( iRefIdx1 >= 0 )
207  {
208  pcSlice->getWpScaling(REF_PIC_LIST_1, iRefIdx1, wp1);
209  }
210  }
211  else
212  {
213  assert(0);
214  }
215 
216  if ( iRefIdx0 < 0 )
217  {
218  wp0 = NULL;
219  }
220  if ( iRefIdx1 < 0 )
221  {
222  wp1 = NULL;
223  }
224 
225  const UInt numValidComponent = pcCU->getPic()->getNumberValidComponents();
226  const Bool bUseHighPrecisionPredictionWeighting = pcSlice->getSPS()->getUseHighPrecisionPredictionWeighting();
227 
228  if ( bBiDir )
229  { // Bi-Dir case
230  for ( Int yuv=0 ; yuv<numValidComponent ; yuv++ )
231  {
232  const Int bitDepth = g_bitDepth[toChannelType(ComponentID(yuv))];
233  const Int offsetScalingFactor = bUseHighPrecisionPredictionWeighting ? 1 : (1 << (bitDepth-8));
234 
235  wp0[yuv].w = wp0[yuv].iWeight;
236  wp1[yuv].w = wp1[yuv].iWeight;
237  wp0[yuv].o = wp0[yuv].iOffset * offsetScalingFactor;
238  wp1[yuv].o = wp1[yuv].iOffset * offsetScalingFactor;
239  wp0[yuv].offset = wp0[yuv].o + wp1[yuv].o;
240  wp0[yuv].shift = wp0[yuv].uiLog2WeightDenom + 1;
241  wp0[yuv].round = (1 << wp0[yuv].uiLog2WeightDenom);
242  wp1[yuv].offset = wp0[yuv].offset;
243  wp1[yuv].shift = wp0[yuv].shift;
244  wp1[yuv].round = wp0[yuv].round;
245  }
246  }
247  else
248  { // Unidir
249  WPScalingParam *const pwp = (iRefIdx0>=0) ? wp0 : wp1 ;
250 
251  for ( Int yuv=0 ; yuv<numValidComponent ; yuv++ )
252  {
253  const Int bitDepth = g_bitDepth[toChannelType(ComponentID(yuv))];
254  const Int offsetScalingFactor = bUseHighPrecisionPredictionWeighting ? 1 : (1 << (bitDepth-8));
255 
256  pwp[yuv].w = pwp[yuv].iWeight;
257  pwp[yuv].offset = pwp[yuv].iOffset * offsetScalingFactor;
258  pwp[yuv].shift = pwp[yuv].uiLog2WeightDenom;
259  pwp[yuv].round = (pwp[yuv].uiLog2WeightDenom>=1) ? (1 << (pwp[yuv].uiLog2WeightDenom-1)) : (0);
260  }
261  }
262 }
263 
264 
267  const TComYuv *const pcYuvSrc0,
268  const TComYuv *const pcYuvSrc1,
269  const Int iRefIdx0,
270  const Int iRefIdx1,
271  const UInt uiPartIdx,
272  const Int iWidth,
273  const Int iHeight,
274  TComYuv *rpcYuvDst )
275 {
276  WPScalingParam *pwp0;
277  WPScalingParam *pwp1;
278 
279  assert(pcCU->getSlice()->getPPS()->getWPBiPred());
280 
281  getWpScaling(pcCU, iRefIdx0, iRefIdx1, pwp0, pwp1);
282 
283  if( iRefIdx0 >= 0 && iRefIdx1 >= 0 )
284  {
285  addWeightBi(pcYuvSrc0, pcYuvSrc1, uiPartIdx, iWidth, iHeight, pwp0, pwp1, rpcYuvDst );
286  }
287  else if ( iRefIdx0 >= 0 && iRefIdx1 < 0 )
288  {
289  addWeightUni( pcYuvSrc0, uiPartIdx, iWidth, iHeight, pwp0, rpcYuvDst );
290  }
291  else if ( iRefIdx0 < 0 && iRefIdx1 >= 0 )
292  {
293  addWeightUni( pcYuvSrc1, uiPartIdx, iWidth, iHeight, pwp1, rpcYuvDst );
294  }
295  else
296  {
297  assert (0);
298  }
299 }
300 
301 
304  const TComYuv *const pcYuvSrc,
305  const UInt uiPartAddr,
306  const Int iWidth,
307  const Int iHeight,
308  const RefPicList eRefPicList,
309  TComYuv *pcYuvPred,
310  const Int iRefIdx_input)
311 {
312  WPScalingParam *pwp, *pwpTmp;
313 
314  Int iRefIdx=iRefIdx_input;
315  if ( iRefIdx < 0 )
316  {
317  iRefIdx = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );
318  }
319  assert (iRefIdx >= 0);
320 
321  if ( eRefPicList == REF_PIC_LIST_0 )
322  {
323  getWpScaling(pcCU, iRefIdx, -1, pwp, pwpTmp);
324  }
325  else
326  {
327  getWpScaling(pcCU, -1, iRefIdx, pwpTmp, pwp);
328  }
329  addWeightUni( pcYuvSrc, uiPartAddr, iWidth, iHeight, pwp, pcYuvPred );
330 }
Int getRefIdx(Int iIdx) const
CU data structure class.
Definition: TComDataCU.h:64
Defines constants, macros and tool parameters.
void Void
Definition: TypeDef.h:285
#define NULL
Definition: CommonDef.h:100
Declaration of TComInterpolationFilter class.
general YUV buffer class (header)
Void addWeightBi(const TComYuv *pcYuvSrc0, const TComYuv *pcYuvSrc1, const UInt iPartUnitIdx, const UInt uiWidth, const UInt uiHeight, const WPScalingParam *const wp0, const WPScalingParam *const wp1, TComYuv *const rpcYuvDst, const Bool bRoundLuma=true)
weighted averaging for bi-pred
unsigned int UInt
Definition: TypeDef.h:297
#define IF_INTERNAL_OFFS
Offset used internally.
Short Pel
pixel type
Definition: TypeDef.h:692
UInt getStride(const ComponentID id) const
Definition: TComYuv.h:197
Int getNumberValidComponents() const
Definition: TComPic.h:129
picture class (header)
T ClipBD(const T x, const Int bitDepth)
Definition: CommonDef.h:138
#define IF_INTERNAL_PREC
Number of bits for internal precision.
Void addWeightUni(const TComYuv *const pcYuvSrc0, const UInt iPartUnitIdx, const UInt uiWidth, const UInt uiHeight, const WPScalingParam *const wp0, TComYuv *const rpcYuvDst)
weighted averaging for uni-pred
general YUV buffer class
Definition: TComYuv.h:54
bool Bool
Definition: TypeDef.h:286
UInt getComponentScaleX(const ComponentID id) const
Definition: TComYuv.h:202
UInt uiLog2WeightDenom
Definition: TComSlice.h:1179
UInt getComponentScaleY(const ComponentID id) const
Definition: TComYuv.h:203
static ChannelType toChannelType(const ComponentID id)
reference list 0
Definition: TypeDef.h:417
Pel * getAddr(const ComponentID id)
Definition: TComYuv.h:148
RefPicList
reference list index
Definition: TypeDef.h:415
Bool getUseHighPrecisionPredictionWeighting() const
Definition: TComSlice.h:889
const TComPPS * getPPS() const
Definition: TComSlice.h:1309
static Pel weightUnidir(Int w0, Pel P0, Int round, Int shift, Int offset, Int clipBD)
reference list 1
Definition: TypeDef.h:418
static Pel weightBidir(Int w0, Pel P0, Int w1, Pel P1, Int round, Int shift, Int offset, Int clipBD)
TComPic * getPic()
Definition: TComDataCU.h:203
Int g_bitDepth[MAX_NUM_CHANNEL_TYPE]
Definition: TComRom.cpp:548
TComCUMvField * getCUMvField(RefPicList e)
Definition: TComDataCU.h:294
Void getWpScaling(RefPicList e, Int iRefIdx, WPScalingParam *&wp)
get tables for weighted prediction
Definition: TComSlice.cpp:1465
int Int
Definition: TypeDef.h:296
ComponentID
Definition: TypeDef.h:368
weighting prediction class (header)
Void xWeightedPredictionBi(TComDataCU *const pcCU, const TComYuv *const pcYuvSrc0, const TComYuv *const pcYuvSrc1, const Int iRefIdx0, const Int iRefIdx1, const UInt uiPartIdx, const Int iWidth, const Int iHeight, TComYuv *pcYuvDst)
weighted prediction for bi-pred
slice header class
Definition: TComSlice.h:1198
Void getWpScaling(TComDataCU *const pcCU, const Int iRefIdx0, const Int iRefIdx1, WPScalingParam *&wp0, WPScalingParam *&wp1)
derivation of wp tables
Bool getWPBiPred() const
Definition: TComSlice.h:1103
UInt getNumberValidComponents() const
Definition: TComYuv.h:201
TComSlice * getSlice()
Definition: TComDataCU.h:205
const TComSPS * getSPS() const
Definition: TComSlice.h:1306
Void xWeightedPredictionUni(TComDataCU *const pcCU, const TComYuv *const pcYuvSrc, const UInt uiPartAddr, const Int iWidth, const Int iHeight, const RefPicList eRefPicList, TComYuv *pcYuvPred, const Int iRefIdx=-1)
weighted prediction for uni-pred