source: 3DVCSoftware/branches/HTM-3.1-Nokia/source/Lib/TLibCommon/TComWeightPrediction.cpp @ 980

Last change on this file since 980 was 56, checked in by hschwarz, 13 years ago

updated trunk (move to HM6.1)

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