source: SHVCSoftware/branches/0.1.1-bugfix/source/Lib/TLibCommon/TComPrediction.cpp

Last change on this file was 2, checked in by seregin, 12 years ago

Initial import by Vadim Seregin <vseregin@…>

File size: 33.9 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     TComPrediction.cpp
35    \brief    prediction class
36*/
37
38#include <memory.h>
39#include "TComPrediction.h"
40
41//! \ingroup TLibCommon
42//! \{
43
44// ====================================================================================================================
45// Constructor / destructor / initialize
46// ====================================================================================================================
47
48TComPrediction::TComPrediction()
49: m_pLumaRecBuffer(0)
50, m_iLumaRecStride(0)
51{
52  m_piYuvExt = NULL;
53}
54
55TComPrediction::~TComPrediction()
56{
57 
58  delete[] m_piYuvExt;
59
60  m_acYuvPred[0].destroy();
61  m_acYuvPred[1].destroy();
62
63  m_cYuvPredTemp.destroy();
64
65  if( m_pLumaRecBuffer )
66  {
67    delete [] m_pLumaRecBuffer;
68  }
69 
70  Int i, j;
71  for (i = 0; i < 4; i++)
72  {
73    for (j = 0; j < 4; j++)
74    {
75      m_filteredBlock[i][j].destroy();
76    }
77    m_filteredBlockTmp[i].destroy();
78  }
79}
80
81Void TComPrediction::initTempBuff()
82{
83  if( m_piYuvExt == NULL )
84  {
85    Int extWidth  = g_uiMaxCUWidth + 16; 
86    Int extHeight = g_uiMaxCUHeight + 1;
87    Int i, j;
88    for (i = 0; i < 4; i++)
89    {
90      m_filteredBlockTmp[i].create(extWidth, extHeight + 7);
91      for (j = 0; j < 4; j++)
92      {
93        m_filteredBlock[i][j].create(extWidth, extHeight);
94      }
95    }
96    m_iYuvExtHeight  = ((g_uiMaxCUHeight + 2) << 4);
97    m_iYuvExtStride = ((g_uiMaxCUWidth  + 8) << 4);
98    m_piYuvExt = new Int[ m_iYuvExtStride * m_iYuvExtHeight ];
99
100    // new structure
101    m_acYuvPred[0] .create( g_uiMaxCUWidth, g_uiMaxCUHeight );
102    m_acYuvPred[1] .create( g_uiMaxCUWidth, g_uiMaxCUHeight );
103
104    m_cYuvPredTemp.create( g_uiMaxCUWidth, g_uiMaxCUHeight );
105  }
106
107  if (m_iLumaRecStride != (g_uiMaxCUWidth>>1) + 1)
108  {
109    m_iLumaRecStride =  (g_uiMaxCUWidth>>1) + 1;
110    if (!m_pLumaRecBuffer)
111    {
112      m_pLumaRecBuffer = new Pel[ m_iLumaRecStride * m_iLumaRecStride ];
113    }
114  }
115
116  Int shift = g_uiBitDepth + g_uiBitIncrement + 4;
117
118  for( Int i = 32; i < 64; i++ )
119  {
120    m_uiaShift[i-32] = ( ( 1 << shift ) + i/2 ) / i;
121  }
122}
123
124// ====================================================================================================================
125// Public member functions
126// ====================================================================================================================
127
128// Function for calculating DC value of the reference samples used in Intra prediction
129Pel TComPrediction::predIntraGetPredValDC( Int* pSrc, Int iSrcStride, UInt iWidth, UInt iHeight, Bool bAbove, Bool bLeft )
130{
131  Int iInd, iSum = 0;
132  Pel pDcVal;
133
134  if (bAbove)
135  {
136    for (iInd = 0;iInd < iWidth;iInd++)
137    {
138      iSum += pSrc[iInd-iSrcStride];
139    }
140  }
141  if (bLeft)
142  {
143    for (iInd = 0;iInd < iHeight;iInd++)
144    {
145      iSum += pSrc[iInd*iSrcStride-1];
146    }
147  }
148
149  if (bAbove && bLeft)
150  {
151    pDcVal = (iSum + iWidth) / (iWidth + iHeight);
152  }
153  else if (bAbove)
154  {
155    pDcVal = (iSum + iWidth/2) / iWidth;
156  }
157  else if (bLeft)
158  {
159    pDcVal = (iSum + iHeight/2) / iHeight;
160  }
161  else
162  {
163    pDcVal = pSrc[-1]; // Default DC value already calculated and placed in the prediction array if no neighbors are available
164  }
165 
166  return pDcVal;
167}
168
169// Function for deriving the angular Intra predictions
170
171/** Function for deriving the simplified angular intra predictions.
172 * \param pSrc pointer to reconstructed sample array
173 * \param srcStride the stride of the reconstructed sample array
174 * \param rpDst reference to pointer for the prediction sample array
175 * \param dstStride the stride of the prediction sample array
176 * \param width the width of the block
177 * \param height the height of the block
178 * \param dirMode the intra prediction mode index
179 * \param blkAboveAvailable boolean indication if the block above is available
180 * \param blkLeftAvailable boolean indication if the block to the left is available
181 *
182 * This function derives the prediction samples for the angular mode based on the prediction direction indicated by
183 * the prediction mode index. The prediction direction is given by the displacement of the bottom row of the block and
184 * the reference row above the block in the case of vertical prediction or displacement of the rightmost column
185 * of the block and reference column left from the block in the case of the horizontal prediction. The displacement
186 * is signalled at 1/32 pixel accuracy. When projection of the predicted pixel falls inbetween reference samples,
187 * the predicted value for the pixel is linearly interpolated from the reference samples. All reference samples are taken
188 * from the extended main reference.
189 */
190Void TComPrediction::xPredIntraAng( Int* pSrc, Int srcStride, Pel*& rpDst, Int dstStride, UInt width, UInt height, UInt dirMode, Bool blkAboveAvailable, Bool blkLeftAvailable, Bool bFilter )
191{
192  Int k,l;
193  Int blkSize        = width;
194  Pel* pDst          = rpDst;
195
196  // Map the mode index to main prediction direction and angle
197  assert( dirMode > 0 ); //no planar
198  Bool modeDC        = dirMode < 2;
199  Bool modeHor       = !modeDC && (dirMode < 18);
200  Bool modeVer       = !modeDC && !modeHor;
201  Int intraPredAngle = modeVer ? (Int)dirMode - VER_IDX : modeHor ? -((Int)dirMode - HOR_IDX) : 0;
202  Int absAng         = abs(intraPredAngle);
203  Int signAng        = intraPredAngle < 0 ? -1 : 1;
204
205  // Set bitshifts and scale the angle parameter to block size
206  Int angTable[9]    = {0,    2,    5,   9,  13,  17,  21,  26,  32};
207  Int invAngTable[9] = {0, 4096, 1638, 910, 630, 482, 390, 315, 256}; // (256 * 32) / Angle
208  Int invAngle       = invAngTable[absAng];
209  absAng             = angTable[absAng];
210  intraPredAngle     = signAng * absAng;
211
212  // Do the DC prediction
213  if (modeDC)
214  {
215    Pel dcval = predIntraGetPredValDC(pSrc, srcStride, width, height, blkAboveAvailable, blkLeftAvailable);
216
217    for (k=0;k<blkSize;k++)
218    {
219      for (l=0;l<blkSize;l++)
220      {
221        pDst[k*dstStride+l] = dcval;
222      }
223    }
224  }
225
226  // Do angular predictions
227  else
228  {
229    Pel* refMain;
230    Pel* refSide;
231    Pel  refAbove[2*MAX_CU_SIZE+1];
232    Pel  refLeft[2*MAX_CU_SIZE+1];
233
234    // Initialise the Main and Left reference array.
235    if (intraPredAngle < 0)
236    {
237      for (k=0;k<blkSize+1;k++)
238      {
239        refAbove[k+blkSize-1] = pSrc[k-srcStride-1];
240      }
241      for (k=0;k<blkSize+1;k++)
242      {
243        refLeft[k+blkSize-1] = pSrc[(k-1)*srcStride-1];
244      }
245      refMain = (modeVer ? refAbove : refLeft) + (blkSize-1);
246      refSide = (modeVer ? refLeft : refAbove) + (blkSize-1);
247
248      // Extend the Main reference to the left.
249      Int invAngleSum    = 128;       // rounding for (shift by 8)
250      for (k=-1; k>blkSize*intraPredAngle>>5; k--)
251      {
252        invAngleSum += invAngle;
253        refMain[k] = refSide[invAngleSum>>8];
254      }
255    }
256    else
257    {
258      for (k=0;k<2*blkSize+1;k++)
259      {
260        refAbove[k] = pSrc[k-srcStride-1];
261      }
262      for (k=0;k<2*blkSize+1;k++)
263      {
264        refLeft[k] = pSrc[(k-1)*srcStride-1];
265      }
266      refMain = modeVer ? refAbove : refLeft;
267      refSide = modeVer ? refLeft  : refAbove;
268    }
269
270    if (intraPredAngle == 0)
271    {
272      for (k=0;k<blkSize;k++)
273      {
274        for (l=0;l<blkSize;l++)
275        {
276          pDst[k*dstStride+l] = refMain[l+1];
277        }
278      }
279
280      if ( bFilter )
281      {
282        for (k=0;k<blkSize;k++)
283        {
284          pDst[k*dstStride] = Clip ( pDst[k*dstStride] + (( refSide[k+1] - refSide[0] ) >> 1) );
285        }
286      }
287    }
288    else
289    {
290      Int deltaPos=0;
291      Int deltaInt;
292      Int deltaFract;
293      Int refMainIndex;
294
295      for (k=0;k<blkSize;k++)
296      {
297        deltaPos += intraPredAngle;
298        deltaInt   = deltaPos >> 5;
299        deltaFract = deltaPos & (32 - 1);
300
301        if (deltaFract)
302        {
303          // Do linear filtering
304          for (l=0;l<blkSize;l++)
305          {
306            refMainIndex        = l+deltaInt+1;
307            pDst[k*dstStride+l] = (Pel) ( ((32-deltaFract)*refMain[refMainIndex]+deltaFract*refMain[refMainIndex+1]+16) >> 5 );
308          }
309        }
310        else
311        {
312          // Just copy the integer samples
313          for (l=0;l<blkSize;l++)
314          {
315            pDst[k*dstStride+l] = refMain[l+deltaInt+1];
316          }
317        }
318      }
319    }
320
321    // Flip the block if this is the horizontal mode
322    if (modeHor)
323    {
324      Pel  tmp;
325      for (k=0;k<blkSize-1;k++)
326      {
327        for (l=k+1;l<blkSize;l++)
328        {
329          tmp                 = pDst[k*dstStride+l];
330          pDst[k*dstStride+l] = pDst[l*dstStride+k];
331          pDst[l*dstStride+k] = tmp;
332        }
333      }
334    }
335  }
336}
337
338Void TComPrediction::predIntraLumaAng(TComPattern* pcTComPattern, UInt uiDirMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight,  TComDataCU* pcCU, Bool bAbove, Bool bLeft )
339{
340  Pel *pDst = piPred;
341  Int *ptrSrc;
342
343  assert( g_aucConvertToBit[ iWidth ] >= 0 ); //   4x  4
344  assert( g_aucConvertToBit[ iWidth ] <= 5 ); // 128x128
345  assert( iWidth == iHeight  );
346
347  ptrSrc = pcTComPattern->getPredictorPtr( uiDirMode, g_aucConvertToBit[ iWidth ] + 2, m_piYuvExt );
348
349  // get starting pixel in block
350  Int sw = 2 * iWidth + 1;
351
352  // Create the prediction
353  if ( uiDirMode == PLANAR_IDX )
354  {
355    xPredIntraPlanar( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight );
356  }
357  else
358  {
359    xPredIntraAng( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode, bAbove, bLeft, true );
360
361    if( (uiDirMode == DC_IDX ) && bAbove && bLeft )
362    {
363      xDCPredFiltering( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight);
364    }
365  }
366}
367
368// Angular chroma
369Void TComPrediction::predIntraChromaAng( TComPattern* pcTComPattern, Int* piSrc, UInt uiDirMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, TComDataCU* pcCU, Bool bAbove, Bool bLeft )
370{
371  Pel *pDst = piPred;
372  Int *ptrSrc = piSrc;
373
374  // get starting pixel in block
375  Int sw = 2 * iWidth + 1;
376
377  if ( uiDirMode == PLANAR_IDX )
378  {
379    xPredIntraPlanar( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight );
380  }
381  else
382  {
383    // Create the prediction
384    xPredIntraAng( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode, bAbove, bLeft, false );
385  }
386}
387
388/** Function for checking identical motion.
389 * \param TComDataCU* pcCU
390 * \param UInt PartAddr
391 */
392Bool TComPrediction::xCheckIdenticalMotion ( TComDataCU* pcCU, UInt PartAddr )
393{
394  if( pcCU->getSlice()->isInterB() && !pcCU->getSlice()->getPPS()->getWPBiPred() )
395  {
396    if( pcCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(PartAddr) >= 0 && pcCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(PartAddr) >= 0)
397    {
398      Int RefPOCL0 = pcCU->getSlice()->getRefPic(REF_PIC_LIST_0, pcCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(PartAddr))->getPOC();
399      Int RefPOCL1 = pcCU->getSlice()->getRefPic(REF_PIC_LIST_1, pcCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(PartAddr))->getPOC();
400      if(RefPOCL0 == RefPOCL1 && pcCU->getCUMvField(REF_PIC_LIST_0)->getMv(PartAddr) == pcCU->getCUMvField(REF_PIC_LIST_1)->getMv(PartAddr))
401      {
402        return true;
403      }
404    }
405  }
406  return false;
407}
408
409#if INTRA_BL
410Void TComPrediction::getBaseBlk( TComDataCU* pcCU, TComYuv* pcYuvPred, Int iPartAddr, Int iWidth, Int iHeight )
411{
412  pcCU->getBaseLumaBlk( iWidth, iHeight, iPartAddr, pcYuvPred->getLumaAddr( iPartAddr ), pcYuvPred->getStride() );
413  pcCU->getBaseChromaBlk( iWidth >> 1, iHeight >> 1, iPartAddr, pcYuvPred->getCbAddr( iPartAddr ), pcYuvPred->getCStride(), 0 );
414  pcCU->getBaseChromaBlk( iWidth >> 1, iHeight >> 1, iPartAddr, pcYuvPred->getCrAddr( iPartAddr ), pcYuvPred->getCStride(), 1 );
415}
416#endif
417
418Void TComPrediction::motionCompensation ( TComDataCU* pcCU, TComYuv* pcYuvPred, RefPicList eRefPicList, Int iPartIdx )
419{
420  Int         iWidth;
421  Int         iHeight;
422  UInt        uiPartAddr;
423
424  if ( iPartIdx >= 0 )
425  {
426    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
427    if ( eRefPicList != REF_PIC_LIST_X )
428    {
429      if( pcCU->getSlice()->getPPS()->getUseWP())
430      {
431        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx, true );
432      }
433      else
434      {
435        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx );
436      }
437      if ( pcCU->getSlice()->getPPS()->getUseWP() )
438      {
439        xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx );
440      }
441    }
442    else
443    {
444      if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
445      {
446        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred, iPartIdx );
447      }
448      else
449      {
450        xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred, iPartIdx );
451      }
452    }
453    return;
454  }
455
456  for ( iPartIdx = 0; iPartIdx < pcCU->getNumPartInter(); iPartIdx++ )
457  {
458    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
459
460    if ( eRefPicList != REF_PIC_LIST_X )
461    {
462      if( pcCU->getSlice()->getPPS()->getUseWP())
463      {
464        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx, true );
465      }
466      else
467      {
468        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx );
469      }
470      if ( pcCU->getSlice()->getPPS()->getUseWP() )
471      {
472        xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx );
473      }
474    }
475    else
476    {
477      if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
478      {
479        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred, iPartIdx );
480      }
481      else
482      {
483        xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred, iPartIdx );
484      }
485    }
486  }
487  return;
488}
489
490Void TComPrediction::xPredInterUni ( TComDataCU* pcCU, UInt uiPartAddr, Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Int iPartIdx, Bool bi )
491{
492  Int         iRefIdx     = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );           assert (iRefIdx >= 0);
493  TComMv      cMv         = pcCU->getCUMvField( eRefPicList )->getMv( uiPartAddr );
494  pcCU->clipMv(cMv);
495  xPredInterLumaBlk  ( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi );
496  xPredInterChromaBlk( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi );
497}
498
499Void TComPrediction::xPredInterBi ( TComDataCU* pcCU, UInt uiPartAddr, Int iWidth, Int iHeight, TComYuv*& rpcYuvPred, Int iPartIdx )
500{
501  TComYuv* pcMbYuv;
502  Int      iRefIdx[2] = {-1, -1};
503
504  for ( Int iRefList = 0; iRefList < 2; iRefList++ )
505  {
506    RefPicList eRefPicList = (iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0);
507    iRefIdx[iRefList] = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );
508
509    if ( iRefIdx[iRefList] < 0 )
510    {
511      continue;
512    }
513
514    assert( iRefIdx[iRefList] < pcCU->getSlice()->getNumRefIdx(eRefPicList) );
515
516    pcMbYuv = &m_acYuvPred[iRefList];
517    if( pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiPartAddr ) >= 0 && pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiPartAddr ) >= 0 )
518    {
519      xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv, iPartIdx, true );
520    }
521    else
522    {
523      if ( ( pcCU->getSlice()->getPPS()->getUseWP()       && pcCU->getSlice()->getSliceType() == P_SLICE ) || 
524           ( pcCU->getSlice()->getPPS()->getWPBiPred() && pcCU->getSlice()->getSliceType() == B_SLICE ) )
525      {
526        xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv, iPartIdx, true );
527      }
528      else
529      {
530        xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv, iPartIdx );
531      }
532    }
533  }
534
535  if ( pcCU->getSlice()->getPPS()->getWPBiPred() && pcCU->getSlice()->getSliceType() == B_SLICE  )
536  {
537    xWeightedPredictionBi( pcCU, &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred );
538  } 
539  else if ( pcCU->getSlice()->getPPS()->getUseWP() && pcCU->getSlice()->getSliceType() == P_SLICE )
540  {
541    xWeightedPredictionUni( pcCU, &m_acYuvPred[0], uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, rpcYuvPred, iPartIdx ); 
542  }
543  else
544  {
545    xWeightedAverage( pcCU, &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred );
546  }
547}
548
549/**
550 * \brief Generate motion-compensated luma block
551 *
552 * \param cu       Pointer to current CU
553 * \param refPic   Pointer to reference picture
554 * \param partAddr Address of block within CU
555 * \param mv       Motion vector
556 * \param width    Width of block
557 * \param height   Height of block
558 * \param dstPic   Pointer to destination picture
559 * \param bi       Flag indicating whether bipred is used
560 */
561Void TComPrediction::xPredInterLumaBlk( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi )
562{
563  Int refStride = refPic->getStride(); 
564  Int refOffset = ( mv->getHor() >> 2 ) + ( mv->getVer() >> 2 ) * refStride;
565  Pel *ref      = refPic->getLumaAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
566 
567  Int dstStride = dstPic->getStride();
568  Pel *dst      = dstPic->getLumaAddr( partAddr );
569 
570  Int xFrac = mv->getHor() & 0x3;
571  Int yFrac = mv->getVer() & 0x3;
572
573  if ( yFrac == 0 )
574  {
575    m_if.filterHorLuma( ref, refStride, dst, dstStride, width, height, xFrac,       !bi );
576  }
577  else if ( xFrac == 0 )
578  {
579    m_if.filterVerLuma( ref, refStride, dst, dstStride, width, height, yFrac, true, !bi );
580  }
581  else
582  {
583    Int tmpStride = m_filteredBlockTmp[0].getStride();
584    Short *tmp    = m_filteredBlockTmp[0].getLumaAddr();
585
586    Int filterSize = NTAPS_LUMA;
587    Int halfFilterSize = ( filterSize >> 1 );
588
589    m_if.filterHorLuma(ref - (halfFilterSize-1)*refStride, refStride, tmp, tmpStride, width, height+filterSize-1, xFrac, false     );
590    m_if.filterVerLuma(tmp + (halfFilterSize-1)*tmpStride, tmpStride, dst, dstStride, width, height,              yFrac, false, !bi);   
591  }
592}
593
594/**
595 * \brief Generate motion-compensated chroma block
596 *
597 * \param cu       Pointer to current CU
598 * \param refPic   Pointer to reference picture
599 * \param partAddr Address of block within CU
600 * \param mv       Motion vector
601 * \param width    Width of block
602 * \param height   Height of block
603 * \param dstPic   Pointer to destination picture
604 * \param bi       Flag indicating whether bipred is used
605 */
606Void TComPrediction::xPredInterChromaBlk( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi )
607{
608  Int     refStride  = refPic->getCStride();
609  Int     dstStride  = dstPic->getCStride();
610 
611  Int     refOffset  = (mv->getHor() >> 3) + (mv->getVer() >> 3) * refStride;
612 
613  Pel*    refCb     = refPic->getCbAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
614  Pel*    refCr     = refPic->getCrAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
615 
616  Pel* dstCb = dstPic->getCbAddr( partAddr );
617  Pel* dstCr = dstPic->getCrAddr( partAddr );
618 
619  Int     xFrac  = mv->getHor() & 0x7;
620  Int     yFrac  = mv->getVer() & 0x7;
621  UInt    cxWidth  = width  >> 1;
622  UInt    cxHeight = height >> 1;
623 
624  Int     extStride = m_filteredBlockTmp[0].getStride();
625  Short*  extY      = m_filteredBlockTmp[0].getLumaAddr();
626 
627  Int filterSize = NTAPS_CHROMA;
628 
629  Int halfFilterSize = (filterSize>>1);
630 
631  if ( yFrac == 0 )
632  {
633    m_if.filterHorChroma(refCb, refStride, dstCb,  dstStride, cxWidth, cxHeight, xFrac, !bi);   
634    m_if.filterHorChroma(refCr, refStride, dstCr,  dstStride, cxWidth, cxHeight, xFrac, !bi);   
635  }
636  else if ( xFrac == 0 )
637  {
638    m_if.filterVerChroma(refCb, refStride, dstCb, dstStride, cxWidth, cxHeight, yFrac, true, !bi);   
639    m_if.filterVerChroma(refCr, refStride, dstCr, dstStride, cxWidth, cxHeight, yFrac, true, !bi);   
640  }
641  else
642  {
643    m_if.filterHorChroma(refCb - (halfFilterSize-1)*refStride, refStride, extY,  extStride, cxWidth, cxHeight+filterSize-1, xFrac, false);
644    m_if.filterVerChroma(extY  + (halfFilterSize-1)*extStride, extStride, dstCb, dstStride, cxWidth, cxHeight  , yFrac, false, !bi);
645   
646    m_if.filterHorChroma(refCr - (halfFilterSize-1)*refStride, refStride, extY,  extStride, cxWidth, cxHeight+filterSize-1, xFrac, false);
647    m_if.filterVerChroma(extY  + (halfFilterSize-1)*extStride, extStride, dstCr, dstStride, cxWidth, cxHeight  , yFrac, false, !bi);   
648  }
649}
650
651Void TComPrediction::xWeightedAverage( TComDataCU* pcCU, TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartIdx, Int iWidth, Int iHeight, TComYuv*& rpcYuvDst )
652{
653  if( iRefIdx0 >= 0 && iRefIdx1 >= 0 )
654  {
655    rpcYuvDst->addAvg( pcYuvSrc0, pcYuvSrc1, uiPartIdx, iWidth, iHeight );
656  }
657  else if ( iRefIdx0 >= 0 && iRefIdx1 <  0 )
658  {
659    pcYuvSrc0->copyPartToPartYuv( rpcYuvDst, uiPartIdx, iWidth, iHeight );
660  }
661  else if ( iRefIdx0 <  0 && iRefIdx1 >= 0 )
662  {
663    pcYuvSrc1->copyPartToPartYuv( rpcYuvDst, uiPartIdx, iWidth, iHeight );
664  }
665}
666
667// AMVP
668Void TComPrediction::getMvPredAMVP( TComDataCU* pcCU, UInt uiPartIdx, UInt uiPartAddr, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred )
669{
670  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
671#if !SPS_AMVP_CLEANUP
672  if( pcCU->getAMVPMode(uiPartAddr) == AM_NONE || (pcAMVPInfo->iN <= 1 && pcCU->getAMVPMode(uiPartAddr) == AM_EXPL) )
673#else
674  if( pcAMVPInfo->iN <= 1 )
675#endif
676  {
677    rcMvPred = pcAMVPInfo->m_acMvCand[0];
678
679    pcCU->setMVPIdxSubParts( 0, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
680    pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
681    return;
682  }
683
684  assert(pcCU->getMVPIdx(eRefPicList,uiPartAddr) >= 0);
685  rcMvPred = pcAMVPInfo->m_acMvCand[pcCU->getMVPIdx(eRefPicList,uiPartAddr)];
686  return;
687}
688
689/** Function for deriving planar intra prediction.
690 * \param pSrc pointer to reconstructed sample array
691 * \param srcStride the stride of the reconstructed sample array
692 * \param rpDst reference to pointer for the prediction sample array
693 * \param dstStride the stride of the prediction sample array
694 * \param width the width of the block
695 * \param height the height of the block
696 *
697 * This function derives the prediction samples for planar mode (intra coding).
698 */
699Void TComPrediction::xPredIntraPlanar( Int* pSrc, Int srcStride, Pel* rpDst, Int dstStride, UInt width, UInt height )
700{
701  assert(width == height);
702
703  Int k, l, bottomLeft, topRight;
704  Int horPred;
705  Int leftColumn[MAX_CU_SIZE], topRow[MAX_CU_SIZE], bottomRow[MAX_CU_SIZE], rightColumn[MAX_CU_SIZE];
706  UInt blkSize = width;
707  UInt offset2D = width;
708  UInt shift1D = g_aucConvertToBit[ width ] + 2;
709  UInt shift2D = shift1D + 1;
710
711  // Get left and above reference column and row
712  for(k=0;k<blkSize+1;k++)
713  {
714    topRow[k] = pSrc[k-srcStride];
715    leftColumn[k] = pSrc[k*srcStride-1];
716  }
717
718  // Prepare intermediate variables used in interpolation
719  bottomLeft = leftColumn[blkSize];
720  topRight   = topRow[blkSize];
721  for (k=0;k<blkSize;k++)
722  {
723    bottomRow[k]   = bottomLeft - topRow[k];
724    rightColumn[k] = topRight   - leftColumn[k];
725    topRow[k]      <<= shift1D;
726    leftColumn[k]  <<= shift1D;
727  }
728
729  // Generate prediction signal
730  for (k=0;k<blkSize;k++)
731  {
732    horPred = leftColumn[k] + offset2D;
733    for (l=0;l<blkSize;l++)
734    {
735      horPred += rightColumn[k];
736      topRow[l] += bottomRow[l];
737      rpDst[k*dstStride+l] = ( (horPred + topRow[l]) >> shift2D );
738    }
739  }
740}
741
742#if !REMOVE_LMCHROMA
743/** Function for deriving chroma LM intra prediction.
744 * \param pcPattern pointer to neighbouring pixel access pattern
745 * \param piSrc pointer to reconstructed chroma sample array
746 * \param pPred pointer for the prediction sample array
747 * \param uiPredStride the stride of the prediction sample array
748 * \param uiCWidth the width of the chroma block
749 * \param uiCHeight the height of the chroma block
750 * \param uiChromaId boolean indication of chroma component
751 *
752 * This function derives the prediction samples for chroma LM mode (chroma intra coding)
753 */
754Void TComPrediction::predLMIntraChroma( TComPattern* pcPattern, Int* piSrc, Pel* pPred, UInt uiPredStride, UInt uiCWidth, UInt uiCHeight, UInt uiChromaId )
755{
756  UInt uiWidth  = 2 * uiCWidth;
757
758  xGetLLSPrediction( pcPattern, piSrc+uiWidth+2, uiWidth+1, pPred, uiPredStride, uiCWidth, uiCHeight, 1 ); 
759}
760
761/** Function for deriving downsampled luma sample of current chroma block and its above, left causal pixel
762 * \param pcPattern pointer to neighbouring pixel access pattern
763 * \param uiCWidth the width of the chroma block
764 * \param uiCHeight the height of the chroma block
765 *
766 * This function derives downsampled luma sample of current chroma block and its above, left causal pixel
767 */
768Void TComPrediction::getLumaRecPixels( TComPattern* pcPattern, UInt uiCWidth, UInt uiCHeight )
769{
770  UInt uiWidth  = 2 * uiCWidth;
771  UInt uiHeight = 2 * uiCHeight; 
772
773  Pel* pRecSrc = pcPattern->getROIY();
774  Pel* pDst0 = m_pLumaRecBuffer + m_iLumaRecStride + 1;
775
776  Int iRecSrcStride = pcPattern->getPatternLStride();
777  Int iRecSrcStride2 = iRecSrcStride << 1;
778  Int iDstStride = m_iLumaRecStride;
779  Int iSrcStride = ( max( uiWidth, uiHeight ) << 1 ) + 1;
780
781  Int* ptrSrc = pcPattern->getAdiOrgBuf( uiWidth, uiHeight, m_piYuvExt );
782
783  // initial pointers
784  Pel* pDst = pDst0 - 1 - iDstStride; 
785  Int* piSrc = ptrSrc;
786
787  // top left corner downsampled from ADI buffer
788  // don't need this point
789
790  // top row downsampled from ADI buffer
791  pDst++;     
792  piSrc ++;
793  for (Int i = 0; i < uiCWidth; i++)
794  {
795    pDst[i] = ((piSrc[2*i] * 2 ) + piSrc[2*i - 1] + piSrc[2*i + 1] + 2) >> 2;
796  }
797
798  // left column downsampled from ADI buffer
799  pDst = pDst0 - 1; 
800  piSrc = ptrSrc + iSrcStride;
801  for (Int j = 0; j < uiCHeight; j++)
802  {
803    pDst[0] = ( piSrc[0] + piSrc[iSrcStride] ) >> 1;
804    piSrc += iSrcStride << 1; 
805    pDst += iDstStride;   
806  }
807
808  // inner part from reconstructed picture buffer
809  for( Int j = 0; j < uiCHeight; j++ )
810  {
811    for (Int i = 0; i < uiCWidth; i++)
812    {
813      pDst0[i] = (pRecSrc[2*i] + pRecSrc[2*i + iRecSrcStride]) >> 1;
814    }
815
816    pDst0 += iDstStride;
817    pRecSrc += iRecSrcStride2;
818  }
819}
820
821/** Function for deriving the positon of first non-zero binary bit of a value
822 * \param x input value
823 *
824 * This function derives the positon of first non-zero binary bit of a value
825 */
826Int GetFloorLog2( UInt x )
827{
828  int bits = -1;
829  while( x > 0 )
830  {
831    bits ++;
832    x >>= 1;
833  }
834  return bits;
835}
836
837/** Function for deriving LM intra prediction.
838 * \param pcPattern pointer to neighbouring pixel access pattern
839 * \param pSrc0 pointer to reconstructed chroma sample array
840 * \param iSrcStride the stride of reconstructed chroma sample array
841 * \param pDst0 reference to pointer for the prediction sample array
842 * \param iDstStride the stride of the prediction sample array
843 * \param uiWidth the width of the chroma block
844 * \param uiHeight the height of the chroma block
845 * \param uiExt0 line number of neiggboirng pixels for calculating LM model parameter, default value is 1
846 *
847 * This function derives the prediction samples for chroma LM mode (chroma intra coding)
848 */
849Void TComPrediction::xGetLLSPrediction( TComPattern* pcPattern, Int* pSrc0, Int iSrcStride, Pel* pDst0, Int iDstStride, UInt uiWidth, UInt uiHeight, UInt uiExt0 )
850{
851
852  Pel  *pDst, *pLuma;
853  Int  *pSrc;
854
855  Int  iLumaStride = m_iLumaRecStride;
856  Pel* pLuma0 = m_pLumaRecBuffer + uiExt0 * iLumaStride + uiExt0;
857
858  Int i, j, iCountShift = 0;
859  UInt uiInternalBitDepth = g_uiBitDepth + g_uiBitIncrement;
860
861  UInt uiExt = uiExt0;
862
863  // LLS parameters estimation -->
864
865  Int x = 0, y = 0, xx = 0, xy = 0;
866
867  pSrc  = pSrc0  - iSrcStride;
868  pLuma = pLuma0 - iLumaStride;
869
870  for( j = 0; j < uiWidth; j++ )
871  {
872    x += pLuma[j];
873    y += pSrc[j];
874    xx += pLuma[j] * pLuma[j];
875    xy += pLuma[j] * pSrc[j];
876  }
877
878  pSrc  = pSrc0 - uiExt;
879  pLuma = pLuma0 - uiExt;
880
881  for( i = 0; i < uiHeight; i++ )
882  {
883    x += pLuma[0];
884    y += pSrc[0];
885    xx += pLuma[0] * pLuma[0];
886    xy += pLuma[0] * pSrc[0];
887
888    pSrc  += iSrcStride;
889    pLuma += iLumaStride;
890  }
891  iCountShift = g_aucConvertToBit[ uiWidth ] + 3;
892
893  Int iTempShift = uiInternalBitDepth + iCountShift - 15;
894
895  if(iTempShift > 0)
896  {
897    x  = ( x +  ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
898    y  = ( y +  ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
899    xx = ( xx + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
900    xy = ( xy + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
901    iCountShift -= iTempShift;
902  }
903
904  Int avgLuma =  x   >> iCountShift;
905  Int avgSrc =  y  >> iCountShift;
906  Int RErrLuma = x & ( ( 1 << iCountShift ) - 1 );
907  Int RErrSrc =  y & ( ( 1 << iCountShift ) - 1 );
908
909  Int a, b, iShift = 13;
910
911  Int iB = 7;
912  iShift -= iB;
913
914  if( iCountShift == 0 )
915  {
916    a = 0;
917    b = 1 << (uiInternalBitDepth - 1);
918    iShift = 0;
919  }
920  else
921  {
922    Int a1 = xy - ( avgLuma*avgSrc << iCountShift ) - avgLuma*RErrSrc - avgSrc*RErrLuma;
923    Int a2 = xx - ( avgLuma*avgLuma << iCountShift ) - 2*avgLuma*RErrLuma;
924
925    const Int iShiftA1 = uiInternalBitDepth - 2;
926    const Int iShiftA2 = 5;
927    const Int iAccuracyShift = uiInternalBitDepth + 4;
928
929    Int iScaleShiftA2 = 0;
930    Int iScaleShiftA1 = 0;
931    Int a1s = a1;
932    Int a2s = a2;
933
934    iScaleShiftA1 = a1 == 0 ? 0 : GetFloorLog2( abs( a1 ) ) - iShiftA1;
935    iScaleShiftA2 = a2 == 0 ? 0 : GetFloorLog2( abs( a2 ) ) - iShiftA2;
936
937    if( iScaleShiftA1 < 0 )
938    {
939      iScaleShiftA1 = 0;
940    }
941   
942    if( iScaleShiftA2 < 0 )
943    {
944      iScaleShiftA2 = 0;
945    }
946
947    Int iScaleShiftA = iScaleShiftA2 + iAccuracyShift - iShift - iScaleShiftA1;
948
949    a2s = a2 >> iScaleShiftA2;
950
951    a1s = a1 >> iScaleShiftA1;
952
953    if (a2s >= 32)
954    {
955      UInt a2t = m_uiaShift[ a2s - 32 ] ;
956      a2t = Clip( a2t );
957      a = a1s * a2t;
958    }
959    else
960    {
961      a = 0;
962    }
963   
964    if( iScaleShiftA < 0 )
965    {
966      a = a << -iScaleShiftA;
967    }
968    else
969    {
970      a = a >> iScaleShiftA;
971    }
972    a = Clip3(-( 1 << (15-iB) ), ( 1 << (15-iB )) - 1, a);
973    a = a << iB;
974   
975    Short n = 0;
976    if (a != 0)
977    {
978      n = GetFloorLog2(abs( a ) + ( (a < 0 ? -1 : 1) - 1)/2 ) - 5;
979    }
980   
981    iShift =(iShift+iB)-n;
982    a = a>>n;
983
984    b =  avgSrc - ( (  a * avgLuma ) >> iShift );
985  }   
986
987  // <-- end of LLS parameters estimation
988
989  // get prediction -->
990  uiExt = uiExt0;
991  pLuma = pLuma0;
992  pDst = pDst0;
993
994  for( i = 0; i < uiHeight; i++ )
995  {
996    for( j = 0; j < uiWidth; j++ )
997    {
998      pDst[j] = Clip( ( ( a * pLuma[j] ) >> iShift ) + b );
999    }
1000   
1001    pDst  += iDstStride;
1002    pLuma += iLumaStride;
1003  }
1004  // <-- end of get prediction
1005
1006}
1007#endif
1008
1009/** Function for filtering intra DC predictor.
1010 * \param pSrc pointer to reconstructed sample array
1011 * \param iSrcStride the stride of the reconstructed sample array
1012 * \param rpDst reference to pointer for the prediction sample array
1013 * \param iDstStride the stride of the prediction sample array
1014 * \param iWidth the width of the block
1015 * \param iHeight the height of the block
1016 *
1017 * This function performs filtering left and top edges of the prediction samples for DC mode (intra coding).
1018 */
1019Void TComPrediction::xDCPredFiltering( Int* pSrc, Int iSrcStride, Pel*& rpDst, Int iDstStride, Int iWidth, Int iHeight )
1020{
1021  Pel* pDst = rpDst;
1022  Int x, y, iDstStride2, iSrcStride2;
1023
1024  // boundary pixels processing
1025  pDst[0] = (Pel)((pSrc[-iSrcStride] + pSrc[-1] + 2 * pDst[0] + 2) >> 2);
1026
1027  for ( x = 1; x < iWidth; x++ )
1028  {
1029    pDst[x] = (Pel)((pSrc[x - iSrcStride] +  3 * pDst[x] + 2) >> 2);
1030  }
1031
1032  for ( y = 1, iDstStride2 = iDstStride, iSrcStride2 = iSrcStride-1; y < iHeight; y++, iDstStride2+=iDstStride, iSrcStride2+=iSrcStride )
1033  {
1034    pDst[iDstStride2] = (Pel)((pSrc[iSrcStride2] + 3 * pDst[iDstStride2] + 2) >> 2);
1035  }
1036
1037  return;
1038}
1039
1040#if SVC_UPSAMPLING
1041Void TComPrediction::upsampleBasePic( TComPicYuv* pcUsPic, TComPicYuv* pcBasePic, TComPicYuv* pcTempPic)
1042{
1043  m_cUsf.upsampleBasePic( pcUsPic, pcBasePic, pcTempPic);
1044}
1045#endif
1046//! \}
Note: See TracBrowser for help on using the repository browser.