source: 3DVCSoftware/branches/0.3-nokia/source/Lib/TLibCommon/TComWeightPrediction.cpp @ 122

Last change on this file since 122 was 5, checked in by hhi, 13 years ago

Clean version with cfg-files

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