source: SHVCSoftware/trunk/source/Lib/TLibCommon/TComWeightPrediction.cpp @ 1164

Last change on this file since 1164 was 595, checked in by seregin, 11 years ago

merge with SHM-5.0-dev branch

  • Property svn:eol-style set to native
File size: 13.1 KB
Line 
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-2014, 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
34/** \file     TComWeightPrediction.h
35    \brief    weighting prediction class (header)
36*/
37
38// Include files
39#include "TComSlice.h"
40#include "TComWeightPrediction.h"
41#include "TComInterpolationFilter.h"
42
43static inline Pel weightBidirY( Int w0, Pel P0, Int w1, Pel P1, Int round, Int shift, Int offset)
44{
45  return ClipY( ( (w0*(P0 + IF_INTERNAL_OFFS) + w1*(P1 + IF_INTERNAL_OFFS) + round + (offset << (shift-1))) >> shift ) );
46}
47static inline Pel weightBidirC( Int w0, Pel P0, Int w1, Pel P1, Int round, Int shift, Int offset)
48{
49  return ClipC( ( (w0*(P0 + IF_INTERNAL_OFFS) + w1*(P1 + IF_INTERNAL_OFFS) + round + (offset << (shift-1))) >> shift ) );
50}
51
52static inline Pel weightUnidirY( Int w0, Pel P0, Int round, Int shift, Int offset)
53{
54  return ClipY( ( (w0*(P0 + IF_INTERNAL_OFFS) + round) >> shift ) + offset );
55}
56static inline Pel weightUnidirC( Int w0, Pel P0, Int round, Int shift, Int offset)
57{
58  return ClipC( ( (w0*(P0 + IF_INTERNAL_OFFS) + round) >> shift ) + offset );
59}
60
61// ====================================================================================================================
62// Class definition
63// ====================================================================================================================
64TComWeightPrediction::TComWeightPrediction()
65{
66}
67
68/** weighted averaging for bi-pred
69 * \param TComYuv* pcYuvSrc0
70 * \param TComYuv* pcYuvSrc1
71 * \param iPartUnitIdx
72 * \param iWidth
73 * \param iHeight
74 * \param wpScalingParam *wp0
75 * \param wpScalingParam *wp1
76 * \param TComYuv* rpcYuvDst
77 * \returns Void
78 */
79Void TComWeightPrediction::addWeightBi( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt iPartUnitIdx, UInt iWidth, UInt iHeight, wpScalingParam *wp0, wpScalingParam *wp1, TComYuv* rpcYuvDst, Bool bRound )
80{
81  Int x, y;
82
83  Pel* pSrcY0  = pcYuvSrc0->getLumaAddr( iPartUnitIdx );
84  Pel* pSrcU0  = pcYuvSrc0->getCbAddr  ( iPartUnitIdx );
85  Pel* pSrcV0  = pcYuvSrc0->getCrAddr  ( iPartUnitIdx );
86 
87  Pel* pSrcY1  = pcYuvSrc1->getLumaAddr( iPartUnitIdx );
88  Pel* pSrcU1  = pcYuvSrc1->getCbAddr  ( iPartUnitIdx );
89  Pel* pSrcV1  = pcYuvSrc1->getCrAddr  ( iPartUnitIdx );
90 
91  Pel* pDstY   = rpcYuvDst->getLumaAddr( iPartUnitIdx );
92  Pel* pDstU   = rpcYuvDst->getCbAddr  ( iPartUnitIdx );
93  Pel* pDstV   = rpcYuvDst->getCrAddr  ( iPartUnitIdx );
94 
95  // Luma : --------------------------------------------
96  Int w0      = wp0[0].w;
97  Int offset  = wp0[0].offset;
98  Int shiftNum = IF_INTERNAL_PREC - g_bitDepthY;
99  Int shift   = wp0[0].shift + shiftNum;
100  Int round   = shift?(1<<(shift-1)) * bRound:0;
101  Int w1      = wp1[0].w;
102
103  UInt  iSrc0Stride = pcYuvSrc0->getStride();
104  UInt  iSrc1Stride = pcYuvSrc1->getStride();
105  UInt  iDstStride  = rpcYuvDst->getStride();
106  for ( y = iHeight-1; y >= 0; y-- )
107  {
108    for ( x = iWidth-1; x >= 0; )
109    {
110      // note: luma min width is 4
111      pDstY[x] = weightBidirY(w0,pSrcY0[x], w1,pSrcY1[x], round, shift, offset); x--;
112      pDstY[x] = weightBidirY(w0,pSrcY0[x], w1,pSrcY1[x], round, shift, offset); x--;
113      pDstY[x] = weightBidirY(w0,pSrcY0[x], w1,pSrcY1[x], round, shift, offset); x--;
114      pDstY[x] = weightBidirY(w0,pSrcY0[x], w1,pSrcY1[x], round, shift, offset); x--;
115    }
116    pSrcY0 += iSrc0Stride;
117    pSrcY1 += iSrc1Stride;
118    pDstY  += iDstStride;
119  }
120
121 
122  // Chroma U : --------------------------------------------
123  w0      = wp0[1].w;
124  offset  = wp0[1].offset;
125  shiftNum = IF_INTERNAL_PREC - g_bitDepthC;
126  shift   = wp0[1].shift + shiftNum;
127  round   = shift?(1<<(shift-1)):0;
128  w1      = wp1[1].w;
129
130  iSrc0Stride = pcYuvSrc0->getCStride();
131  iSrc1Stride = pcYuvSrc1->getCStride();
132  iDstStride  = rpcYuvDst->getCStride();
133 
134  iWidth  >>=1;
135  iHeight >>=1;
136 
137  for ( y = iHeight-1; y >= 0; y-- )
138  {
139    for ( x = iWidth-1; x >= 0; )
140    {
141      // note: chroma min width is 2
142      pDstU[x] = weightBidirC(w0,pSrcU0[x], w1,pSrcU1[x], round, shift, offset); x--;
143      pDstU[x] = weightBidirC(w0,pSrcU0[x], w1,pSrcU1[x], round, shift, offset); x--;
144    }
145    pSrcU0 += iSrc0Stride;
146    pSrcU1 += iSrc1Stride;
147    pDstU  += iDstStride;
148  }
149
150  // Chroma V : --------------------------------------------
151  w0      = wp0[2].w;
152  offset  = wp0[2].offset;
153  shift   = wp0[2].shift + shiftNum;
154  round   = shift?(1<<(shift-1)):0;
155  w1      = wp1[2].w;
156
157  for ( y = iHeight-1; y >= 0; y-- )
158  {
159    for ( x = iWidth-1; x >= 0; )
160    {
161      // note: chroma min width is 2
162      pDstV[x] = weightBidirC(w0,pSrcV0[x], w1,pSrcV1[x], round, shift, offset); x--;
163      pDstV[x] = weightBidirC(w0,pSrcV0[x], w1,pSrcV1[x], round, shift, offset); x--;
164    }
165    pSrcV0 += iSrc0Stride;
166    pSrcV1 += iSrc1Stride;
167    pDstV  += iDstStride;
168  }
169}
170
171/** weighted averaging for uni-pred
172 * \param TComYuv* pcYuvSrc0
173 * \param iPartUnitIdx
174 * \param iWidth
175 * \param iHeight
176 * \param wpScalingParam *wp0
177 * \param TComYuv* rpcYuvDst
178 * \returns Void
179 */
180Void TComWeightPrediction::addWeightUni( TComYuv* pcYuvSrc0, UInt iPartUnitIdx, UInt iWidth, UInt iHeight, wpScalingParam *wp0, TComYuv* rpcYuvDst )
181{
182  Int x, y;
183 
184  Pel* pSrcY0  = pcYuvSrc0->getLumaAddr( iPartUnitIdx );
185  Pel* pSrcU0  = pcYuvSrc0->getCbAddr  ( iPartUnitIdx );
186  Pel* pSrcV0  = pcYuvSrc0->getCrAddr  ( iPartUnitIdx );
187 
188  Pel* pDstY   = rpcYuvDst->getLumaAddr( iPartUnitIdx );
189  Pel* pDstU   = rpcYuvDst->getCbAddr  ( iPartUnitIdx );
190  Pel* pDstV   = rpcYuvDst->getCrAddr  ( iPartUnitIdx );
191 
192  // Luma : --------------------------------------------
193  Int w0      = wp0[0].w;
194  Int offset  = wp0[0].offset;
195  Int shiftNum = IF_INTERNAL_PREC - g_bitDepthY;
196  Int shift   = wp0[0].shift + shiftNum;
197  Int round   = shift?(1<<(shift-1)):0;
198  UInt  iSrc0Stride = pcYuvSrc0->getStride();
199  UInt  iDstStride  = rpcYuvDst->getStride();
200 
201  for ( y = iHeight-1; y >= 0; y-- )
202  {
203    for ( x = iWidth-1; x >= 0; )
204    {
205      // note: luma min width is 4
206      pDstY[x] = weightUnidirY(w0,pSrcY0[x], round, shift, offset); x--;
207      pDstY[x] = weightUnidirY(w0,pSrcY0[x], round, shift, offset); x--;
208      pDstY[x] = weightUnidirY(w0,pSrcY0[x], round, shift, offset); x--;
209      pDstY[x] = weightUnidirY(w0,pSrcY0[x], round, shift, offset); x--;
210    }
211    pSrcY0 += iSrc0Stride;
212    pDstY  += iDstStride;
213  }
214 
215  // Chroma U : --------------------------------------------
216  w0      = wp0[1].w;
217  offset  = wp0[1].offset;
218  shiftNum = IF_INTERNAL_PREC - g_bitDepthC;
219  shift   = wp0[1].shift + shiftNum;
220  round   = shift?(1<<(shift-1)):0;
221
222  iSrc0Stride = pcYuvSrc0->getCStride();
223  iDstStride  = rpcYuvDst->getCStride();
224 
225  iWidth  >>=1;
226  iHeight >>=1;
227 
228  for ( y = iHeight-1; y >= 0; y-- )
229  {
230    for ( x = iWidth-1; x >= 0; )
231    {
232      // note: chroma min width is 2
233      pDstU[x] = weightUnidirC(w0,pSrcU0[x], round, shift, offset); x--;
234      pDstU[x] = weightUnidirC(w0,pSrcU0[x], round, shift, offset); x--;
235    }
236    pSrcU0 += iSrc0Stride;
237    pDstU  += iDstStride;
238  }
239
240  // Chroma V : --------------------------------------------
241  w0      = wp0[2].w;
242  offset  = wp0[2].offset;
243  shift   = wp0[2].shift + shiftNum;
244  round   = shift?(1<<(shift-1)):0;
245
246  for ( y = iHeight-1; y >= 0; y-- )
247  {
248    for ( x = iWidth-1; x >= 0; )
249    {
250      // note: chroma min width is 2
251      pDstV[x] = weightUnidirC(w0,pSrcV0[x], round, shift, offset); x--;
252      pDstV[x] = weightUnidirC(w0,pSrcV0[x], round, shift, offset); x--;
253    }
254    pSrcV0 += iSrc0Stride;
255    pDstV  += iDstStride;
256  }
257}
258
259//=======================================================
260//  getWpScaling()
261//=======================================================
262/** derivation of wp tables
263 * \param TComDataCU* pcCU
264 * \param iRefIdx0
265 * \param iRefIdx1
266 * \param wpScalingParam *&wp0
267 * \param wpScalingParam *&wp1
268 * \param ibdi
269 * \returns Void
270 */
271Void TComWeightPrediction::getWpScaling( TComDataCU* pcCU, Int iRefIdx0, Int iRefIdx1, wpScalingParam *&wp0, wpScalingParam *&wp1)
272{
273  assert(iRefIdx0 >= 0 || iRefIdx1 >= 0);
274 
275  TComSlice*      pcSlice       = pcCU->getSlice();
276  TComPPS*        pps           = pcCU->getSlice()->getPPS();
277  Bool            wpBiPred = pps->getWPBiPred();
278  wpScalingParam* pwp;
279  Bool            bBiDir        = (iRefIdx0>=0 && iRefIdx1>=0);
280  Bool            bUniDir       = !bBiDir;
281
282  if ( bUniDir || wpBiPred )
283  { // explicit --------------------
284    if ( iRefIdx0 >= 0 )
285    {
286      pcSlice->getWpScaling(REF_PIC_LIST_0, iRefIdx0, wp0);
287    }
288    if ( iRefIdx1 >= 0 )
289    {
290      pcSlice->getWpScaling(REF_PIC_LIST_1, iRefIdx1, wp1);
291    }
292  }
293  else
294  {
295    assert(0);
296  }
297
298  if ( iRefIdx0 < 0 )
299  {
300    wp0 = NULL;
301  }
302  if ( iRefIdx1 < 0 )
303  {
304    wp1 = NULL;
305  }
306
307  if ( bBiDir )
308  { // Bi-Dir case
309    for ( Int yuv=0 ; yuv<3 ; yuv++ )
310    {
311      Int bitDepth = yuv ? g_bitDepthC : g_bitDepthY;
312      wp0[yuv].w      = wp0[yuv].iWeight;
313      wp0[yuv].o      = wp0[yuv].iOffset * (1 << (bitDepth-8));
314      wp1[yuv].w      = wp1[yuv].iWeight;
315      wp1[yuv].o      = wp1[yuv].iOffset * (1 << (bitDepth-8));
316      wp0[yuv].offset = wp0[yuv].o + wp1[yuv].o;
317      wp0[yuv].shift  = wp0[yuv].uiLog2WeightDenom + 1;
318      wp0[yuv].round  = (1 << wp0[yuv].uiLog2WeightDenom);
319      wp1[yuv].offset = wp0[yuv].offset;
320      wp1[yuv].shift  = wp0[yuv].shift;
321      wp1[yuv].round  = wp0[yuv].round;
322    }
323  }
324  else
325  {  // Unidir
326    pwp = (iRefIdx0>=0) ? wp0 : wp1 ;
327    for ( Int yuv=0 ; yuv<3 ; yuv++ )
328    {
329      Int bitDepth = yuv ? g_bitDepthC : g_bitDepthY;
330      pwp[yuv].w      = pwp[yuv].iWeight;
331      pwp[yuv].offset = pwp[yuv].iOffset * (1 << (bitDepth-8));
332      pwp[yuv].shift  = pwp[yuv].uiLog2WeightDenom;
333      pwp[yuv].round  = (pwp[yuv].uiLog2WeightDenom>=1) ? (1 << (pwp[yuv].uiLog2WeightDenom-1)) : (0);
334    }
335  }
336}
337
338/** weighted prediction for bi-pred
339 * \param TComDataCU* pcCU
340 * \param TComYuv* pcYuvSrc0
341 * \param TComYuv* pcYuvSrc1
342 * \param iRefIdx0
343 * \param iRefIdx1
344 * \param uiPartIdx
345 * \param iWidth
346 * \param iHeight
347 * \param TComYuv* rpcYuvDst
348 * \returns Void
349 */
350Void TComWeightPrediction::xWeightedPredictionBi( TComDataCU* pcCU, TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartIdx, Int iWidth, Int iHeight, TComYuv* rpcYuvDst )
351{
352  wpScalingParam  *pwp0, *pwp1;
353  TComPPS         *pps = pcCU->getSlice()->getPPS();
354  assert( pps->getWPBiPred());
355
356  getWpScaling(pcCU, iRefIdx0, iRefIdx1, pwp0, pwp1);
357
358  if( iRefIdx0 >= 0 && iRefIdx1 >= 0 )
359  {
360    addWeightBi(pcYuvSrc0, pcYuvSrc1, uiPartIdx, iWidth, iHeight, pwp0, pwp1, rpcYuvDst );
361  }
362  else if ( iRefIdx0 >= 0 && iRefIdx1 <  0 )
363  {
364    addWeightUni( pcYuvSrc0, uiPartIdx, iWidth, iHeight, pwp0, rpcYuvDst );
365  }
366  else if ( iRefIdx0 <  0 && iRefIdx1 >= 0 )
367  {
368    addWeightUni( pcYuvSrc1, uiPartIdx, iWidth, iHeight, pwp1, rpcYuvDst );
369  }
370  else
371  {
372    assert (0);
373  }
374}
375
376/** weighted prediction for uni-pred
377 * \param TComDataCU* pcCU
378 * \param TComYuv* pcYuvSrc
379 * \param uiPartAddr
380 * \param iWidth
381 * \param iHeight
382 * \param eRefPicList
383 * \param TComYuv*& rpcYuvPred
384 * \param iPartIdx
385 * \param iRefIdx
386 * \returns Void
387 */
388Void TComWeightPrediction::xWeightedPredictionUni( TComDataCU* pcCU, TComYuv* pcYuvSrc, UInt uiPartAddr, Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Int iRefIdx)
389{ 
390  wpScalingParam  *pwp, *pwpTmp;
391  if ( iRefIdx < 0 )
392  {
393    iRefIdx   = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );
394  }
395  assert (iRefIdx >= 0);
396
397  if ( eRefPicList == REF_PIC_LIST_0 )
398  {
399    getWpScaling(pcCU, iRefIdx, -1, pwp, pwpTmp);
400  }
401  else
402  {
403    getWpScaling(pcCU, -1, iRefIdx, pwpTmp, pwp);
404  }
405  addWeightUni( pcYuvSrc, uiPartAddr, iWidth, iHeight, pwp, rpcYuvPred );
406}
407
408
Note: See TracBrowser for help on using the repository browser.