source: 3DVCSoftware/trunk/source/Lib/TLibEncoder/WeightPredAnalysis.cpp @ 2

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

inital import

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