source: 3DVCSoftware/branches/HTM-14.1-update-dev0/source/Lib/TLibCommon/TComWeightPrediction.cpp @ 1417

Last change on this file since 1417 was 1200, checked in by tech, 10 years ago

Update to HM-16.5.
Starting point for further re-activation of 3D-tools.

Includes:

active:

  • MV-HEVC
  • 3D-HLS (apart from DLT)
  • VSO

inactive:

  • remaining 3D-HEVC tools.
  • Property svn:eol-style set to native
File size: 13.4 KB
RevLine 
[5]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
[1200]4 * granted under this license.
[5]5 *
[1200]6 * Copyright (c) 2010-2015, ITU/ISO/IEC
[5]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.
[56]17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
[5]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 */
[2]33
34/** \file     TComWeightPrediction.h
35    \brief    weighting prediction class (header)
36*/
37
38// Include files
[1200]39#include "CommonDef.h"
40#include "TComYuv.h"
41#include "TComPic.h"
42#include "TComInterpolationFilter.h"
[2]43#include "TComWeightPrediction.h"
44
[1200]45
46static inline Pel weightBidir( Int w0, Pel P0, Int w1, Pel P1, Int round, Int shift, Int offset, Int clipBD)
[608]47{
[1200]48  return ClipBD( ( (w0*(P0 + IF_INTERNAL_OFFS) + w1*(P1 + IF_INTERNAL_OFFS) + round + (offset << (shift-1))) >> shift ), clipBD );
[608]49}
50
[1200]51
52static inline Pel weightUnidir( Int w0, Pel P0, Int round, Int shift, Int offset, Int clipBD)
[608]53{
[1200]54  return ClipBD( ( (w0*(P0 + IF_INTERNAL_OFFS) + round) >> shift ) + offset, clipBD );
[608]55}
56
[2]57// ====================================================================================================================
58// Class definition
59// ====================================================================================================================
[1200]60
[2]61TComWeightPrediction::TComWeightPrediction()
62{
63}
64
[1200]65
66//! weighted averaging for bi-pred
67Void TComWeightPrediction::addWeightBi( const TComYuv              *pcYuvSrc0,
68                                        const TComYuv              *pcYuvSrc1,
69                                        const BitDepths            &bitDepths,
70                                        const UInt                  iPartUnitIdx,
71                                        const UInt                  uiWidth,
72                                        const UInt                  uiHeight,
73                                        const WPScalingParam *const wp0,
74                                        const WPScalingParam *const wp1,
75                                              TComYuv        *const rpcYuvDst,
76                                        const Bool                  bRoundLuma)
[2]77{
78
[1200]79  const Bool enableRounding[MAX_NUM_COMPONENT]={ bRoundLuma, true, true };
[2]80
[1200]81  const UInt numValidComponent = pcYuvSrc0->getNumberValidComponents();
82
83  for(Int componentIndex=0; componentIndex<numValidComponent; componentIndex++)
[2]84  {
[1200]85    const ComponentID compID=ComponentID(componentIndex);
[56]86
[1200]87    const Pel* pSrc0       = pcYuvSrc0->getAddr( compID,  iPartUnitIdx );
88    const Pel* pSrc1       = pcYuvSrc1->getAddr( compID,  iPartUnitIdx );
89          Pel* pDst        = rpcYuvDst->getAddr( compID,  iPartUnitIdx );
[2]90
[1200]91    // Luma : --------------------------------------------
92    const Int  w0          = wp0[compID].w;
93    const Int  offset      = wp0[compID].offset;
94    const Int  clipBD      = bitDepths.recon[toChannelType(compID)];
95    const Int  shiftNum    = std::max<Int>(2, (IF_INTERNAL_PREC - clipBD));
96    const Int  shift       = wp0[compID].shift + shiftNum;
97    const Int  round       = (enableRounding[compID] && (shift > 0)) ? (1<<(shift-1)) : 0;
98    const Int  w1          = wp1[compID].w;
99    const UInt csx         = pcYuvSrc0->getComponentScaleX(compID);
100    const UInt csy         = pcYuvSrc0->getComponentScaleY(compID);
101    const Int  iHeight     = uiHeight>>csy;
102    const Int  iWidth      = uiWidth>>csx;
[2]103
[1200]104    const UInt iSrc0Stride = pcYuvSrc0->getStride(compID);
105    const UInt iSrc1Stride = pcYuvSrc1->getStride(compID);
106    const UInt iDstStride  = rpcYuvDst->getStride(compID);
[2]107
[1200]108    for ( Int y = iHeight-1; y >= 0; y-- )
[2]109    {
[1200]110      // do it in batches of 4 (partial unroll)
111      Int x = iWidth-1;
112      for ( ; x >= 3; )
113      {
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        pDst[x] = weightBidir(w0,pSrc0[x], w1,pSrc1[x], round, shift, offset, clipBD); x--;
118      }
119      for( ; x >= 0; x-- )
120      {
121        pDst[x] = weightBidir(w0,pSrc0[x], w1,pSrc1[x], round, shift, offset, clipBD);
122      }
123
124      pSrc0 += iSrc0Stride;
125      pSrc1 += iSrc1Stride;
126      pDst  += iDstStride;
127    } // y loop
128  } // compID loop
[2]129}
130
[1200]131
132//! weighted averaging for uni-pred
133Void TComWeightPrediction::addWeightUni( const TComYuv        *const pcYuvSrc0,
134                                         const BitDepths            &bitDepths,
135                                         const UInt                  iPartUnitIdx,
136                                         const UInt                  uiWidth,
137                                         const UInt                  uiHeight,
138                                         const WPScalingParam *const wp0,
139                                               TComYuv        *const pcYuvDst )
[2]140{
[1200]141  const UInt numValidComponent = pcYuvSrc0->getNumberValidComponents();
[2]142
[1200]143  for(Int componentIndex=0; componentIndex<numValidComponent; componentIndex++)
[2]144  {
[1200]145    const ComponentID compID=ComponentID(componentIndex);
[2]146
[1200]147    const Pel* pSrc0       = pcYuvSrc0->getAddr( compID,  iPartUnitIdx );
148          Pel* pDst        = pcYuvDst->getAddr( compID,  iPartUnitIdx );
[2]149
[1200]150    // Luma : --------------------------------------------
151    const Int  w0          = wp0[compID].w;
152    const Int  offset      = wp0[compID].offset;
153    const Int  clipBD      = bitDepths.recon[toChannelType(compID)];
154    const Int  shiftNum    = std::max<Int>(2, (IF_INTERNAL_PREC - clipBD));
155    const Int  shift       = wp0[compID].shift + shiftNum;
156    const Int  round       = (shift > 0) ? (1<<(shift-1)) : 0;
157    const UInt iSrc0Stride = pcYuvSrc0->getStride(compID);
158    const UInt iDstStride  = pcYuvDst->getStride(compID);
159    const UInt csx         = pcYuvSrc0->getComponentScaleX(compID);
160    const UInt csy         = pcYuvSrc0->getComponentScaleY(compID);
161    const Int  iHeight     = uiHeight>>csy;
162    const Int  iWidth      = uiWidth>>csx;
163
164    for (Int y = iHeight-1; y >= 0; y-- )
[2]165    {
[1200]166      Int x = iWidth-1;
167      for ( ; x >= 3; )
168      {
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        pDst[x] = weightUnidir(w0, pSrc0[x], round, shift, offset, clipBD); x--;
172        pDst[x] = weightUnidir(w0, pSrc0[x], round, shift, offset, clipBD); x--;
173      }
174      for( ; x >= 0; x--)
175      {
176        pDst[x] = weightUnidir(w0, pSrc0[x], round, shift, offset, clipBD);
177      }
178      pSrc0 += iSrc0Stride;
179      pDst  += iDstStride;
[56]180    }
[2]181  }
182}
183
[1200]184
[2]185//=======================================================
186//  getWpScaling()
187//=======================================================
[1200]188//! derivation of wp tables
189Void TComWeightPrediction::getWpScaling(       TComDataCU *const pcCU,
190                                         const Int               iRefIdx0,
191                                         const Int               iRefIdx1,
192                                               WPScalingParam  *&wp0,
193                                               WPScalingParam  *&wp1)
[2]194{
[608]195  assert(iRefIdx0 >= 0 || iRefIdx1 >= 0);
[2]196
[1200]197        TComSlice *const pcSlice  = pcCU->getSlice();
198  const Bool             wpBiPred = pcCU->getSlice()->getPPS()->getWPBiPred();
199  const Bool             bBiDir   = (iRefIdx0>=0 && iRefIdx1>=0);
200  const Bool             bUniDir  = !bBiDir;
201
[608]202  if ( bUniDir || wpBiPred )
[2]203  { // explicit --------------------
204    if ( iRefIdx0 >= 0 )
205    {
206      pcSlice->getWpScaling(REF_PIC_LIST_0, iRefIdx0, wp0);
207    }
208    if ( iRefIdx1 >= 0 )
209    {
210      pcSlice->getWpScaling(REF_PIC_LIST_1, iRefIdx1, wp1);
211    }
212  }
213  else
214  {
215    assert(0);
216  }
217
218  if ( iRefIdx0 < 0 )
219  {
220    wp0 = NULL;
221  }
222  if ( iRefIdx1 < 0 )
223  {
224    wp1 = NULL;
225  }
226
[1200]227  const UInt numValidComponent                    = pcCU->getPic()->getNumberValidComponents();
228  const Bool bUseHighPrecisionPredictionWeighting = pcSlice->getSPS()->getSpsRangeExtension().getHighPrecisionOffsetsEnabledFlag();
229
[2]230  if ( bBiDir )
231  { // Bi-Dir case
[1200]232    for ( Int yuv=0 ; yuv<numValidComponent ; yuv++ )
[2]233    {
[1200]234      const Int bitDepth            = pcSlice->getSPS()->getBitDepth(toChannelType(ComponentID(yuv)));
235      const Int offsetScalingFactor = bUseHighPrecisionPredictionWeighting ? 1 : (1 << (bitDepth-8));
236
[2]237      wp0[yuv].w      = wp0[yuv].iWeight;
238      wp1[yuv].w      = wp1[yuv].iWeight;
[1200]239      wp0[yuv].o      = wp0[yuv].iOffset * offsetScalingFactor;
240      wp1[yuv].o      = wp1[yuv].iOffset * offsetScalingFactor;
[56]241      wp0[yuv].offset = wp0[yuv].o + wp1[yuv].o;
[2]242      wp0[yuv].shift  = wp0[yuv].uiLog2WeightDenom + 1;
243      wp0[yuv].round  = (1 << wp0[yuv].uiLog2WeightDenom);
244      wp1[yuv].offset = wp0[yuv].offset;
245      wp1[yuv].shift  = wp0[yuv].shift;
246      wp1[yuv].round  = wp0[yuv].round;
247    }
248  }
249  else
250  {  // Unidir
[1200]251    WPScalingParam *const pwp = (iRefIdx0>=0) ? wp0 : wp1 ;
252
253    for ( Int yuv=0 ; yuv<numValidComponent ; yuv++ )
[2]254    {
[1200]255      const Int bitDepth            = pcSlice->getSPS()->getBitDepth(toChannelType(ComponentID(yuv)));
256      const Int offsetScalingFactor = bUseHighPrecisionPredictionWeighting ? 1 : (1 << (bitDepth-8));
257
[608]258      pwp[yuv].w      = pwp[yuv].iWeight;
[1200]259      pwp[yuv].offset = pwp[yuv].iOffset * offsetScalingFactor;
[608]260      pwp[yuv].shift  = pwp[yuv].uiLog2WeightDenom;
261      pwp[yuv].round  = (pwp[yuv].uiLog2WeightDenom>=1) ? (1 << (pwp[yuv].uiLog2WeightDenom-1)) : (0);
[2]262    }
263  }
264}
265
[1200]266
267//! weighted prediction for bi-pred
268Void TComWeightPrediction::xWeightedPredictionBi(       TComDataCU *const pcCU,
269                                                  const TComYuv    *const pcYuvSrc0,
270                                                  const TComYuv    *const pcYuvSrc1,
271                                                  const Int               iRefIdx0,
272                                                  const Int               iRefIdx1,
273                                                  const UInt              uiPartIdx,
274                                                  const Int               iWidth,
275                                                  const Int               iHeight,
276                                                        TComYuv          *rpcYuvDst )
[2]277{
[1200]278  WPScalingParam  *pwp0;
279  WPScalingParam  *pwp1;
[2]280
[1200]281  assert(pcCU->getSlice()->getPPS()->getWPBiPred());
282
[608]283  getWpScaling(pcCU, iRefIdx0, iRefIdx1, pwp0, pwp1);
[2]284
285  if( iRefIdx0 >= 0 && iRefIdx1 >= 0 )
286  {
[1200]287    addWeightBi(pcYuvSrc0, pcYuvSrc1, pcCU->getSlice()->getSPS()->getBitDepths(), uiPartIdx, iWidth, iHeight, pwp0, pwp1, rpcYuvDst );
[2]288  }
289  else if ( iRefIdx0 >= 0 && iRefIdx1 <  0 )
290  {
[1200]291    addWeightUni( pcYuvSrc0, pcCU->getSlice()->getSPS()->getBitDepths(), uiPartIdx, iWidth, iHeight, pwp0, rpcYuvDst );
[2]292  }
293  else if ( iRefIdx0 <  0 && iRefIdx1 >= 0 )
294  {
[1200]295    addWeightUni( pcYuvSrc1, pcCU->getSlice()->getSPS()->getBitDepths(), uiPartIdx, iWidth, iHeight, pwp1, rpcYuvDst );
[2]296  }
297  else
[56]298  {
[2]299    assert (0);
[56]300  }
301}
[2]302
[1200]303
304//! weighted prediction for uni-pred
305Void TComWeightPrediction::xWeightedPredictionUni(       TComDataCU *const pcCU,
306                                                   const TComYuv    *const pcYuvSrc,
307                                                   const UInt              uiPartAddr,
308                                                   const Int               iWidth,
309                                                   const Int               iHeight,
310                                                   const RefPicList        eRefPicList,
311                                                         TComYuv          *pcYuvPred,
312                                                   const Int               iRefIdx_input)
313{
314  WPScalingParam  *pwp, *pwpTmp;
315
316  Int iRefIdx=iRefIdx_input;
[56]317  if ( iRefIdx < 0 )
318  {
319    iRefIdx   = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );
320  }
321  assert (iRefIdx >= 0);
322
323  if ( eRefPicList == REF_PIC_LIST_0 )
324  {
[608]325    getWpScaling(pcCU, iRefIdx, -1, pwp, pwpTmp);
[56]326  }
327  else
328  {
[608]329    getWpScaling(pcCU, -1, iRefIdx, pwpTmp, pwp);
[56]330  }
[1200]331  addWeightUni( pcYuvSrc, pcCU->getSlice()->getSPS()->getBitDepths(), uiPartAddr, iWidth, iHeight, pwp, pcYuvPred );
[2]332}
Note: See TracBrowser for help on using the repository browser.