source: 3DVCSoftware/branches/0.1-poznan-univ/source/Lib/TLibCommon/TComWeightPrediction.cpp @ 1417

Last change on this file since 1417 was 2, checked in by hhi, 13 years ago

inital import

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