source: 3DVCSoftware/branches/HTM-5.0-dev0/source/Lib/TLibEncoder/WeightPredAnalysis.cpp @ 206

Last change on this file since 206 was 56, checked in by hschwarz, 12 years ago

updated trunk (move to HM6.1)

  • Property svn:eol-style set to native
File size: 14.3 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     WeightedPredAnalysis.cpp
35    \brief    encoder class
36*/
37
38#include "../TLibCommon/TypeDef.h"
39#include "../TLibCommon/TComSlice.h"
40#include "../TLibCommon/TComPic.h"
41#include "../TLibCommon/TComPicYuv.h"
42#include "WeightPredAnalysis.h"
43
44#define ABS(a)    ((a) < 0 ? - (a) : (a))
45#define DTHRESH (0.99)
46
47WeightPredAnalysis::WeightPredAnalysis()
48{
49  m_weighted_pred_flag = 0;
50  m_weighted_bipred_idc = 0;
51
52  for ( Int iList =0 ; iList<2 ; iList++ )
53  {
54    for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ ) 
55    {
56      for ( int comp=0 ; comp<3 ;comp++ ) 
57      {
58        wpScalingParam  *pwp   = &(m_wp[iList][iRefIdx][comp]);
59        pwp->bPresentFlag      = false;
60        pwp->uiLog2WeightDenom = 0;
61        pwp->iWeight           = 1;
62        pwp->iOffset           = 0;
63      }
64    }
65  }
66}
67
68/** calculate AC and DC values for current original image
69 * \param TComSlice *slice
70 * \returns Void
71 */
72Bool  WeightPredAnalysis::xCalcACDCParamSlice(TComSlice *slice)
73{
74  //===== calculate AC/DC value =====
75  TComPicYuv*   pPic = slice->getPic()->getPicYuvOrg();
76  Int   iSample  = 0;
77
78  // calculate DC/AC value for Y
79  Pel*  pOrg    = pPic->getLumaAddr();
80  Int64  iOrgDCY = xCalcDCValueSlice(slice, pOrg, &iSample);
81  Int64  iOrgNormDCY = ((iOrgDCY+(iSample>>1)) / iSample);
82  pOrg = pPic->getLumaAddr();
83  Int64  iOrgACY  = xCalcACValueSlice(slice, pOrg, iOrgNormDCY);
84
85  // calculate DC/AC value for Cb
86  pOrg = pPic->getCbAddr();
87  Int64  iOrgDCCb = xCalcDCValueUVSlice(slice, pOrg, &iSample);
88  Int64  iOrgNormDCCb = ((iOrgDCCb+(iSample>>1)) / (iSample));
89  pOrg = pPic->getCbAddr();
90  Int64  iOrgACCb  = xCalcACValueUVSlice(slice, pOrg, iOrgNormDCCb);
91
92  // calculate DC/AC value for Cr
93  pOrg = pPic->getCrAddr();
94  Int64  iOrgDCCr = xCalcDCValueUVSlice(slice, pOrg, &iSample);
95  Int64  iOrgNormDCCr = ((iOrgDCCr+(iSample>>1)) / (iSample));
96  pOrg = pPic->getCrAddr();
97  Int64  iOrgACCr  = xCalcACValueUVSlice(slice, pOrg, iOrgNormDCCr);
98
99  wpACDCParam weightACDCParam[3];
100  weightACDCParam[0].iAC = iOrgACY;
101  weightACDCParam[0].iDC = iOrgNormDCY;
102  weightACDCParam[1].iAC = iOrgACCb;
103  weightACDCParam[1].iDC = iOrgNormDCCb;
104  weightACDCParam[2].iAC = iOrgACCr;
105  weightACDCParam[2].iDC = iOrgNormDCCr;
106
107  slice->setWpAcDcParam(weightACDCParam);
108  return (true);
109}
110
111/** store weighted_pred_flag and weighted_bipred_idc values
112 * \param weighted_pred_flag
113 * \param weighted_bipred_idc
114 * \returns Void
115 */
116Void  WeightPredAnalysis::xStoreWPparam(Bool weighted_pred_flag, Int weighted_bipred_idc)
117{
118  m_weighted_pred_flag = weighted_pred_flag;
119  m_weighted_bipred_idc = weighted_bipred_idc;
120}
121
122/** restore weighted_pred_flag and weighted_bipred_idc values
123 * \param TComSlice *slice
124 * \returns Void
125 */
126Void  WeightPredAnalysis::xRestoreWPparam(TComSlice *slice)
127{
128  slice->getPPS()->setUseWP(m_weighted_pred_flag);
129  slice->getPPS()->setWPBiPredIdc(m_weighted_bipred_idc);
130}
131
132/** check weighted pred or non-weighted pred
133 * \param TComSlice *slice
134 * \returns Void
135 */
136Void  WeightPredAnalysis::xCheckWPEnable(TComSlice *slice)
137{
138  Int iPresentCnt = 0;
139  for ( Int iList=0 ; iList<2 ; iList++ )
140  {
141    for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ ) 
142    {
143      for ( Int iComp=0 ; iComp<3 ;iComp++ ) 
144      {
145        wpScalingParam  *pwp = &(m_wp[iList][iRefIdx][iComp]);
146        iPresentCnt += (Int)pwp->bPresentFlag;
147      }
148    }
149  }
150
151  if(iPresentCnt==0)
152  {
153    slice->getPPS()->setUseWP(false);
154    slice->getPPS()->setWPBiPredIdc(0);
155    for ( Int iList=0 ; iList<2 ; iList++ )
156    {
157      for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ ) 
158      {
159        for ( Int iComp=0 ; iComp<3 ;iComp++ ) 
160        {
161          wpScalingParam  *pwp = &(m_wp[iList][iRefIdx][iComp]);
162          pwp->bPresentFlag      = false;
163          pwp->uiLog2WeightDenom = 0;
164          pwp->iWeight           = 1;
165          pwp->iOffset           = 0;
166        }
167      }
168    }
169    slice->setWpScaling( m_wp );
170  }
171}
172
173/** estimate wp tables for explicit wp
174 * \param TComSlice *slice
175 * \returns Bool
176 */
177Bool  WeightPredAnalysis::xEstimateWPParamSlice(TComSlice *slice)
178{
179  Int iDenom  = 6;
180  Int iRealDenom = iDenom + (g_uiBitDepth+g_uiBitIncrement-8);
181  Int iRealOffset = ((Int)1<<(iRealDenom-1));
182
183  if(slice->getNumRefIdx(REF_PIC_LIST_0)>3)
184  {
185    iDenom  = 7;
186    iRealDenom = iDenom + (g_uiBitDepth+g_uiBitIncrement-8);
187    iRealOffset = ((Int)1<<(iRealDenom-1));
188  }
189 
190  Int iNumPredDir = slice->isInterP() ? 1 : 2;
191  for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
192  {
193    RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
194    for ( Int iRefIdxTemp = 0; iRefIdxTemp < slice->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
195    {
196      wpACDCParam *CurrWeightACDCParam, *RefWeightACDCParam;
197      slice->getWpAcDcParam(CurrWeightACDCParam);
198      slice->getRefPic(eRefPicList, iRefIdxTemp)->getSlice(0)->getWpAcDcParam(RefWeightACDCParam);
199
200      for ( Int iComp = 0; iComp < 3; iComp++ )
201      {
202        // current frame
203        Int64 iCurrDC = CurrWeightACDCParam[iComp].iDC;
204        Int64 iCurrAC = CurrWeightACDCParam[iComp].iAC;
205        // reference frame
206        Int64 iRefDC = RefWeightACDCParam[iComp].iDC;
207        Int64 iRefAC = RefWeightACDCParam[iComp].iAC;
208
209        // calculating iWeight and iOffset params
210        Double dWeight = (iRefAC==0) ? (Double)1.0 : ( (Double)(iCurrAC) / (Double)iRefAC);
211        Int iWeight = (Int)( 0.5 + dWeight * (Double)(1<<iDenom) );
212        Int iOffset = (Int)( ((iCurrDC<<iDenom) - ((Int64)iWeight * iRefDC) + (Int64)iRealOffset) >> iRealDenom );
213
214        m_wp[iRefList][iRefIdxTemp][iComp].bPresentFlag = true;
215        m_wp[iRefList][iRefIdxTemp][iComp].iWeight = (Int)iWeight;
216        m_wp[iRefList][iRefIdxTemp][iComp].iOffset = (Int)iOffset;
217        m_wp[iRefList][iRefIdxTemp][iComp].uiLog2WeightDenom = (Int)iDenom;
218      }
219    }
220  }
221
222  // selecting whether WP is used, or not
223  xSelectWP(slice, m_wp, iDenom);
224 
225  slice->setWpScaling( m_wp );
226
227  return (true);
228}
229
230/** select whether weighted pred enables or not.
231 * \param TComSlice *slice
232 * \param wpScalingParam
233 * \param iDenom
234 * \returns Bool
235 */
236Bool WeightPredAnalysis::xSelectWP(TComSlice *slice, wpScalingParam weightPredTable[2][MAX_NUM_REF][3], Int iDenom)
237{
238  TComPicYuv*   pPic = slice->getPic()->getPicYuvOrg();
239  Int iWidth  = pPic->getWidth();
240  Int iHeight = pPic->getHeight();
241  Int iDefaultWeight = ((Int)1<<iDenom);
242  Int iNumPredDir = slice->isInterP() ? 1 : 2;
243
244  for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
245  {
246    Int64 iSADWP = 0, iSADnoWP = 0;
247    RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
248    for ( Int iRefIdxTemp = 0; iRefIdxTemp < slice->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
249    {
250      Pel*  pOrg    = pPic->getLumaAddr();
251      Pel*  pRef    = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getLumaAddr();
252      Int   iOrgStride = pPic->getStride();
253      Int   iRefStride = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getStride();
254
255      // calculate SAD costs with/without wp for luma
256      iSADWP   = this->xCalcSADvalueWP(pOrg, pRef, iWidth, iHeight, iOrgStride, iRefStride, iDenom, weightPredTable[iRefList][iRefIdxTemp][0].iWeight, weightPredTable[iRefList][iRefIdxTemp][0].iOffset);
257      iSADnoWP = this->xCalcSADvalueWP(pOrg, pRef, iWidth, iHeight, iOrgStride, iRefStride, iDenom, iDefaultWeight, 0);
258
259      pOrg = pPic->getCbAddr();
260      pRef = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getCbAddr();
261      iOrgStride = pPic->getCStride();
262      iRefStride = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getCStride();
263
264      // calculate SAD costs with/without wp for chroma cb
265      iSADWP   += this->xCalcSADvalueWP(pOrg, pRef, iWidth>>1, iHeight>>1, iOrgStride, iRefStride, iDenom, weightPredTable[iRefList][iRefIdxTemp][1].iWeight, weightPredTable[iRefList][iRefIdxTemp][1].iOffset);
266      iSADnoWP += this->xCalcSADvalueWP(pOrg, pRef, iWidth>>1, iHeight>>1, iOrgStride, iRefStride, iDenom, iDefaultWeight, 0);
267
268      pOrg = pPic->getCrAddr();
269      pRef = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getCrAddr();
270
271      // calculate SAD costs with/without wp for chroma cr
272      iSADWP   += this->xCalcSADvalueWP(pOrg, pRef, iWidth>>1, iHeight>>1, iOrgStride, iRefStride, iDenom, weightPredTable[iRefList][iRefIdxTemp][2].iWeight, weightPredTable[iRefList][iRefIdxTemp][2].iOffset);
273      iSADnoWP += this->xCalcSADvalueWP(pOrg, pRef, iWidth>>1, iHeight>>1, iOrgStride, iRefStride, iDenom, iDefaultWeight, 0);
274
275      Double dRatio = ((Double)iSADWP / (Double)iSADnoWP);
276      if(dRatio >= (Double)DTHRESH)
277      {
278        for ( Int iComp = 0; iComp < 3; iComp++ )
279        {
280          weightPredTable[iRefList][iRefIdxTemp][iComp].bPresentFlag = false;
281          weightPredTable[iRefList][iRefIdxTemp][iComp].iOffset = (Int)0;
282          weightPredTable[iRefList][iRefIdxTemp][iComp].iWeight = (Int)iDefaultWeight;
283          weightPredTable[iRefList][iRefIdxTemp][iComp].uiLog2WeightDenom = (Int)iDenom;
284        }
285      }
286    }
287  }
288  return (true);
289}
290
291/** calculate DC value of original image for luma.
292 * \param TComSlice *slice
293 * \param Pel *pPel
294 * \param Int *iSample
295 * \returns Int64
296 */
297Int64 WeightPredAnalysis::xCalcDCValueSlice(TComSlice *slice, Pel *pPel, Int *iSample)
298{
299  TComPicYuv* pPic = slice->getPic()->getPicYuvOrg();
300  Int iStride = pPic->getStride();
301
302  *iSample = 0;
303  Int iWidth  = pPic->getWidth();
304  Int iHeight = pPic->getHeight();
305  *iSample = iWidth*iHeight;
306  Int64 iDC = xCalcDCValue(pPel, iWidth, iHeight, iStride);
307
308  return (iDC);
309}
310
311/** calculate AC value of original image for luma.
312 * \param TComSlice *slice
313 * \param Pel *pPel
314 * \param Int iDC
315 * \returns Int64
316 */
317Int64 WeightPredAnalysis::xCalcACValueSlice(TComSlice *slice, Pel *pPel, Int64 iDC)
318{
319  TComPicYuv* pPic = slice->getPic()->getPicYuvOrg();
320  Int iStride = pPic->getStride();
321
322  Int iWidth  = pPic->getWidth();
323  Int iHeight = pPic->getHeight();
324  Int64 iAC = xCalcACValue(pPel, iWidth, iHeight, iStride, iDC);
325
326  return (iAC);
327}
328
329/** calculate DC value of original image for chroma.
330 * \param TComSlice *slice
331 * \param Pel *pPel
332 * \param Int *iSample
333 * \returns Int64
334 */
335Int64 WeightPredAnalysis::xCalcDCValueUVSlice(TComSlice *slice, Pel *pPel, Int *iSample)
336{
337  TComPicYuv* pPic = slice->getPic()->getPicYuvOrg();
338  Int iCStride = pPic->getCStride();
339
340  *iSample = 0;
341  Int iWidth  = pPic->getWidth()>>1;
342  Int iHeight = pPic->getHeight()>>1;
343  *iSample = iWidth*iHeight;
344  Int64 iDC = xCalcDCValue(pPel, iWidth, iHeight, iCStride);
345
346  return (iDC);
347}
348
349/** calculate AC value of original image for chroma.
350 * \param TComSlice *slice
351 * \param Pel *pPel
352 * \param Int iDC
353 * \returns Int64
354 */
355Int64 WeightPredAnalysis::xCalcACValueUVSlice(TComSlice *slice, Pel *pPel, Int64 iDC)
356{
357  TComPicYuv* pPic = slice->getPic()->getPicYuvOrg();
358  Int iCStride = pPic->getCStride();
359
360  Int iWidth  = pPic->getWidth()>>1;
361  Int iHeight = pPic->getHeight()>>1;
362  Int64 iAC = xCalcACValue(pPel, iWidth, iHeight, iCStride, iDC);
363
364  return (iAC);
365}
366
367/** calculate DC value.
368 * \param Pel *pPel
369 * \param Int iWidth
370 * \param Int iHeight
371 * \param Int iStride
372 * \returns Int64
373 */
374Int64 WeightPredAnalysis::xCalcDCValue(Pel *pPel, Int iWidth, Int iHeight, Int iStride)
375{
376  Int x, y;
377  Int64 iDC = 0;
378  for( y = 0; y < iHeight; y++ )
379  {
380    for( x = 0; x < iWidth; x++ )
381    {
382      iDC += (Int)( pPel[x] );
383    }
384    pPel += iStride;
385  }
386  return (iDC);
387}
388
389/** calculate AC value.
390 * \param Pel *pPel
391 * \param Int iWidth
392 * \param Int iHeight
393 * \param Int iStride
394 * \param Int iDC
395 * \returns Int64
396 */
397Int64 WeightPredAnalysis::xCalcACValue(Pel *pPel, Int iWidth, Int iHeight, Int iStride, Int64 iDC)
398{
399  Int x, y;
400  Int64 iAC = 0;
401  for( y = 0; y < iHeight; y++ )
402  {
403    for( x = 0; x < iWidth; x++ )
404    {
405      iAC += abs( (Int)pPel[x] - (Int)iDC );
406    }
407    pPel += iStride;
408  }
409  return (iAC);
410}
411
412/** calculate SAD values for both WP version and non-WP version.
413 * \param Pel *pOrgPel
414 * \param Pel *pRefPel
415 * \param Int iWidth
416 * \param Int iHeight
417 * \param Int iOrgStride
418 * \param Int iRefStride
419 * \param Int iDenom
420 * \param Int iWeight
421 * \param Int iOffset
422 * \returns Int64
423 */
424Int64 WeightPredAnalysis::xCalcSADvalueWP(Pel *pOrgPel, Pel *pRefPel, Int iWidth, Int iHeight, Int iOrgStride, Int iRefStride, Int iDenom, Int iWeight, Int iOffset)
425{
426  Int x, y;
427  Int64 iSAD = 0;
428  Int64 iSize   = iWidth*iHeight;
429  Int64 iRealDenom = iDenom + (g_uiBitDepth+g_uiBitIncrement-8);
430  for( y = 0; y < iHeight; y++ )
431  {
432    for( x = 0; x < iWidth; x++ )
433    {
434      iSAD += ABS(( ((Int64)pOrgPel[x]<<(Int64)iDenom) - ( (Int64)pRefPel[x] * (Int64)iWeight + ((Int64)iOffset<<iRealDenom) ) ) );
435    }
436    pOrgPel += iOrgStride;
437    pRefPel += iRefStride;
438  }
439  return (iSAD/iSize);
440}
441
442
Note: See TracBrowser for help on using the repository browser.