source: 3DVCSoftware/branches/0.3-nokia/source/Lib/TLibEncoder/WeightPredAnalysis.cpp @ 36

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

Clean version with cfg-files

  • Property svn:eol-style set to native
File size: 12.8 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     WeightedPredAnalysis.cpp
37    \brief    encoder class
38*/
39
40#include "../TLibCommon/TypeDef.h"
41#include "../TLibCommon/TComSlice.h"
42#include "../TLibCommon/TComPic.h"
43#include "../TLibCommon/TComPicYuv.h"
44#include "WeightPredAnalysis.h"
45
46#ifdef WEIGHT_PRED
47
48#define ABS(a)    ((a) < 0 ? - (a) : (a))
49
50WeightPredAnalysis::WeightPredAnalysis()
51{
52  for ( Int e=0 ; e<2 ; e++ )
53    for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ ) {
54      for ( int comp=0 ; comp<3 ;comp++ ) {
55        wpScalingParam  *pwp   = &(m_wp[e][iRefIdx][comp]);
56        pwp->bPresentFlag      = false;
57        pwp->uiLog2WeightDenom = 0;
58        pwp->uiLog2WeightDenom = 0;
59        pwp->iWeight           = 1;
60        pwp->iOffset           = 0;
61      }
62    }
63}
64
65Bool  WeightPredAnalysis::xCalcACDCParamSlice(TComSlice *slice)
66{
67  //===== calculate AC/DC value =====
68  //Int iPoc = slice->getPOC();
69  TComPicYuv*   pPic = slice->getPic()->getPicYuvOrg();
70  Int   iSample  = 0;
71
72  // calculate DC/AC value for Y
73  Pel*  pOrg    = pPic->getLumaAddr();
74  Int64  iOrgDCY = xCalcDCValueSlice(slice, pOrg, &iSample);
75  Int64  iOrgNormDCY = ((iOrgDCY+(iSample>>1)) / iSample);
76  pOrg = pPic->getLumaAddr();
77  Int64  iOrgACY  = xCalcACValueSlice(slice, pOrg, iOrgNormDCY);
78
79  // calculate DC/AC value for Cb
80  pOrg = pPic->getCbAddr();
81  Int64  iOrgDCCb = xCalcDCValueUVSlice(slice, pOrg, &iSample);
82  Int64  iOrgNormDCCb = ((iOrgDCCb+(iSample>>1)) / (iSample));
83  pOrg = pPic->getCbAddr();
84  Int64  iOrgACCb  = xCalcACValueUVSlice(slice, pOrg, iOrgNormDCCb);
85
86  // calculate DC/AC value for Cr
87  pOrg = pPic->getCrAddr();
88  Int64  iOrgDCCr = xCalcDCValueUVSlice(slice, pOrg, &iSample);
89  Int64  iOrgNormDCCr = ((iOrgDCCr+(iSample>>1)) / (iSample));
90  pOrg = pPic->getCrAddr();
91  Int64  iOrgACCr  = xCalcACValueUVSlice(slice, pOrg, iOrgNormDCCr);
92
93  wpACDCParam weightACDCParam[3];
94  weightACDCParam[0].iAC = iOrgACY;
95  weightACDCParam[0].iDC = iOrgNormDCY;
96  weightACDCParam[1].iAC = iOrgACCb;
97  weightACDCParam[1].iDC = iOrgNormDCCb;
98  weightACDCParam[2].iAC = iOrgACCr;
99  weightACDCParam[2].iDC = iOrgNormDCCr;
100
101  slice->setWpAcDcParam(weightACDCParam);
102  return (true);
103}
104Bool  WeightPredAnalysis::xEstimateWPParamSlice(TComSlice *slice)
105{
106#define wpTable m_wp //wpScalingParam   weightPredTable[2][MAX_NUM_REF][3];
107
108  //Int iPoc = slice->getPOC();
109  Int iDenom  = 6;
110  Int iDefaultWeight = ((Int)1<<iDenom);
111  Int iRealDenom = iDenom + (g_uiBitDepth+g_uiBitIncrement-8);
112  Int iRealOffset = ((Int)1<<(iRealDenom-1));
113
114  if(slice->getNumRefIdx(REF_PIC_LIST_0)>3)
115  {
116    iDenom  = 7;
117    iDefaultWeight = ((Int)1<<iDenom);
118    iRealDenom = iDenom + (g_uiBitDepth+g_uiBitIncrement-8);
119    iRealOffset = ((Int)1<<(iRealDenom-1));
120  }
121 
122  Int iNumPredDir = slice->isInterP() ? 1 : 2;
123  for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
124  {
125    RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
126    for ( Int iRefIdxTemp = 0; iRefIdxTemp < slice->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
127    {
128      wpACDCParam *CurrWeightACDCParam, *RefWeightACDCParam;
129      slice->getWpAcDcParam(CurrWeightACDCParam);
130      slice->getRefPic(eRefPicList, iRefIdxTemp)->getSlice(0)->getWpAcDcParam(RefWeightACDCParam);
131
132          //Int64 iSADWP=0, iSADnoWP=0;
133      for ( Int iComp = 0; iComp < 3; iComp++ )
134      {
135        //Int irefPoc = slice->getRefPOC(eRefPicList, iRefIdxTemp);
136        // current frame
137        Int64 iCurrDC = CurrWeightACDCParam[iComp].iDC;
138        Int64 iCurrAC = CurrWeightACDCParam[iComp].iAC;
139        // reference frame
140        Int64 iRefDC = RefWeightACDCParam[iComp].iDC;
141        Int64 iRefAC = RefWeightACDCParam[iComp].iAC;
142
143        // calculating iWeight and iOffset params (these two codes are only "Double")
144        Double dWeight = (iRefAC==0) ? (Double)1.0 : ( (Double)(iCurrAC) / (Double)iRefAC);
145        Int iWeight = (Int)( 0.5 + dWeight * (Double)(1<<iDenom) );
146        Int iOffset = (Int)( ((iCurrDC<<iDenom) - ((Int64)iWeight * iRefDC) + (Int64)iRealOffset) >> iRealDenom );
147
148        wpTable[iRefList][iRefIdxTemp][iComp].bPresentFlag = true;
149        wpTable[iRefList][iRefIdxTemp][iComp].iWeight = (Int)iWeight;
150        wpTable[iRefList][iRefIdxTemp][iComp].iOffset = (Int)iOffset;
151        wpTable[iRefList][iRefIdxTemp][iComp].uiLog2WeightDenom = (Int)iDenom;
152      }
153    }
154  }
155
156  // selecting whether WP is used, or not
157  xSelectWP(slice, wpTable, iDenom);
158 
159  slice->setWpScaling( wpTable );
160
161  return (true);
162}
163Bool WeightPredAnalysis::xSelectWP(TComSlice *slice, wpScalingParam     weightPredTable[2][MAX_NUM_REF][3], Int iDenom)
164{
165  //Int iPoc = slice->getPOC();
166  TComPicYuv*   pPic = slice->getPic()->getPicYuvOrg();
167  Int iWidth  = pPic->getWidth();
168  Int iHeight = pPic->getHeight();
169  Int iDefaultWeight = ((Int)1<<iDenom);
170  Int iNumPredDir = slice->isInterP() ? 1 : 2;
171
172  for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
173  {
174    Int64 iSADWP = 0, iSADnoWP = 0;
175    RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
176    for ( Int iRefIdxTemp = 0; iRefIdxTemp < slice->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
177    {
178      Pel*  pOrg    = pPic->getLumaAddr();
179      Pel*  pRef    = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getLumaAddr();
180      Int   iOrgStride = pPic->getStride();
181      Int   iRefStride = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getStride();
182
183      // calculate SAD costs with/without wp for luma
184      iSADWP   = this->xCalcSADvalueWP(pOrg, pRef, iWidth, iHeight, iOrgStride, iRefStride, iDenom, weightPredTable[iRefList][iRefIdxTemp][0].iWeight, weightPredTable[iRefList][iRefIdxTemp][0].iOffset);
185      iSADnoWP = this->xCalcSADvalueWP(pOrg, pRef, iWidth, iHeight, iOrgStride, iRefStride, iDenom, iDefaultWeight, 0);
186
187      pOrg = pPic->getCbAddr();
188      pRef = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getCbAddr();
189      iOrgStride = pPic->getCStride();
190      iRefStride = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getCStride();
191
192      // calculate SAD costs with/without wp for chroma cb
193      iSADWP   += this->xCalcSADvalueWPUV(pOrg, pRef, iWidth>>1, iHeight>>1, iOrgStride, iRefStride, iDenom, weightPredTable[iRefList][iRefIdxTemp][1].iWeight, weightPredTable[iRefList][iRefIdxTemp][1].iOffset);
194      iSADnoWP += this->xCalcSADvalueWPUV(pOrg, pRef, iWidth>>1, iHeight>>1, iOrgStride, iRefStride, iDenom, iDefaultWeight, 0);
195
196      pOrg = pPic->getCrAddr();
197      pRef = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getCrAddr();
198
199      // calculate SAD costs with/without wp for chroma cr
200      iSADWP   += this->xCalcSADvalueWPUV(pOrg, pRef, iWidth>>1, iHeight>>1, iOrgStride, iRefStride, iDenom, weightPredTable[iRefList][iRefIdxTemp][2].iWeight, weightPredTable[iRefList][iRefIdxTemp][2].iOffset);
201      iSADnoWP += this->xCalcSADvalueWPUV(pOrg, pRef, iWidth>>1, iHeight>>1, iOrgStride, iRefStride, iDenom, iDefaultWeight, 0);
202
203      if(iSADWP >= iSADnoWP)
204      {
205        for ( Int iComp = 0; iComp < 3; iComp++ )
206        {
207          weightPredTable[iRefList][iRefIdxTemp][iComp].bPresentFlag = false;
208          weightPredTable[iRefList][iRefIdxTemp][iComp].iOffset = (Int)0;
209          weightPredTable[iRefList][iRefIdxTemp][iComp].iWeight = (Int)iDefaultWeight;
210          weightPredTable[iRefList][iRefIdxTemp][iComp].uiLog2WeightDenom = (Int)iDenom;
211        }
212      }
213    }
214  }
215  return (true);
216}
217Int64 WeightPredAnalysis::xCalcDCValueSlice(TComSlice *slice, Pel *pPel, Int *iSample)
218{
219  TComPicYuv* pPic = slice->getPic()->getPicYuvOrg();
220  Int iStride = pPic->getStride();
221
222  *iSample = 0;
223  Int iWidth  = pPic->getWidth();
224  Int iHeight = pPic->getHeight();
225  *iSample = iWidth*iHeight;
226  Int64 iDC = xCalcDCValue(pPel, iWidth, iHeight, iStride);
227
228  return (iDC);
229}
230Int64 WeightPredAnalysis::xCalcACValueSlice(TComSlice *slice, Pel *pPel, Int64 iDC)
231{
232  TComPicYuv* pPic = slice->getPic()->getPicYuvOrg();
233  Int iStride = pPic->getStride();
234
235  Int iWidth  = pPic->getWidth();
236  Int iHeight = pPic->getHeight();
237  Int64 iAC = xCalcACValue(pPel, iWidth, iHeight, iStride, iDC);
238
239  return (iAC);
240}
241
242Int64 WeightPredAnalysis::xCalcDCValueUVSlice(TComSlice *slice, Pel *pPel, Int *iSample)
243{
244  TComPicYuv* pPic = slice->getPic()->getPicYuvOrg();
245  Int iCStride = pPic->getCStride();
246
247  *iSample = 0;
248  Int iWidth  = pPic->getWidth()>>1;
249  Int iHeight = pPic->getHeight()>>1;
250  *iSample = iWidth*iHeight;
251  Int64 iDC = xCalcDCValueUV(pPel, iWidth, iHeight, iCStride);
252
253  return (iDC);
254}
255Int64 WeightPredAnalysis::xCalcACValueUVSlice(TComSlice *slice, Pel *pPel, Int64 iDC)
256{
257  TComPicYuv* pPic = slice->getPic()->getPicYuvOrg();
258  Int iCStride = pPic->getCStride();
259
260  Int iWidth  = pPic->getWidth()>>1;
261  Int iHeight = pPic->getHeight()>>1;
262  Int64 iAC = xCalcACValueUV(pPel, iWidth, iHeight, iCStride, iDC);
263
264  return (iAC);
265}
266Int64 WeightPredAnalysis::xCalcDCValue(Pel *pPel, Int iWidth, Int iHeight, Int iStride)
267{
268  Int x, y;
269  Int64 iDC = 0;
270  for( y = 0; y < iHeight; y++ )
271  {
272    for( x = 0; x < iWidth; x++ )
273    {
274      iDC += (Int)( pPel[x] );
275    }
276    pPel += iStride;
277  }
278  return (iDC);
279}
280Int64 WeightPredAnalysis::xCalcACValue(Pel *pPel, Int iWidth, Int iHeight, Int iStride, Int64 iDC)
281{
282  Int x, y;
283  Int64 iAC = 0;
284  for( y = 0; y < iHeight; y++ )
285  {
286    for( x = 0; x < iWidth; x++ )
287    {
288      iAC += abs( (Int)pPel[x] - (Int)iDC);
289    }
290    pPel += iStride;
291  }
292  return (iAC);
293}
294Int64 WeightPredAnalysis::xCalcDCValueUV(Pel *pPel, Int iWidth, Int iHeight, Int iStride)
295{
296  Int x, y;
297  Int64 iDC = 0;
298
299  for( y = 0; y < iHeight; y++ )
300  {
301    for( x = 0; x < iWidth; x++ )
302    {
303      iDC += (Int)( pPel[x]);
304    }
305    pPel += iStride;
306  }
307  return (iDC);
308}
309Int64 WeightPredAnalysis::xCalcACValueUV(Pel *pPel, Int iWidth, Int iHeight, Int iStride, Int64 iDC)
310{
311  Int x, y;
312  Int64 iAC = 0;
313
314  for( y = 0; y < iHeight; y++ )
315  {
316    for( x = 0; x < iWidth; x++ )
317    {
318      iAC += abs( (Int)pPel[x] - (Int)iDC);
319    }
320    pPel += iStride;
321  }
322  return (iAC);
323}
324Int64 WeightPredAnalysis::xCalcSADvalueWP(Pel *pOrgPel, Pel *pRefPel, Int iWidth, Int iHeight, Int iOrgStride, Int iRefStride, Int iDenom, Int iWeight, Int iOffset)
325{
326  Int x, y;
327  Int64 iSAD = 0;
328  Int64 iSize   = iWidth*iHeight;
329  Int64 iRealDenom = iDenom + (g_uiBitDepth+g_uiBitIncrement-8);
330  for( y = 0; y < iHeight; y++ )
331  {
332    for( x = 0; x < iWidth; x++ )
333    {
334      iSAD += ABS(( ((Int64)pOrgPel[x]<<(Int64)iDenom) - ( (Int64)pRefPel[x] * (Int64)iWeight + ((Int64)iOffset<<iRealDenom) ) ) );
335    }
336    pOrgPel += iOrgStride;
337    pRefPel += iRefStride;
338  }
339
340  return (iSAD/iSize);
341}
342Int64 WeightPredAnalysis::xCalcSADvalueWPUV(Pel *pOrgPel, Pel *pRefPel, Int iWidth, Int iHeight, Int iOrgStride, Int iRefStride, Int iDenom, Int iWeight, Int iOffset)
343{
344  Int x, y;
345  //Int64 itmpSAD = 0;
346  Int64 iSAD = 0;
347  Int64 iSize   = iWidth*iHeight;
348  Int64 iRealDenom = iDenom + (g_uiBitDepth+g_uiBitIncrement-8);
349
350  for( y = 0; y < iHeight; y++ )
351  {
352    for( x = 0; x < iWidth; x++ )
353    {
354      iSAD += ABS(( ((Int64)pOrgPel[x]<<(Int64)iDenom) - ( (Int64)pRefPel[x] * (Int64)iWeight + ((Int64)iOffset<<iRealDenom) ) ) );
355    }
356    pOrgPel += iOrgStride;
357    pRefPel += iRefStride;
358  }
359
360  return (iSAD/iSize);
361}
362
363#endif  // WEIGHT_PRED
364
Note: See TracBrowser for help on using the repository browser.