source: 3DVCSoftware/branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComPrediction.cpp @ 464

Last change on this file since 464 was 464, checked in by zhang, 11 years ago

Implementation of ARP from QC

  • Property svn:eol-style set to native
File size: 29.7 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-2013, 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 H_3D_ARP
66  m_acYuvPredBase[0].destroy();
67  m_acYuvPredBase[1].destroy();
68#endif
69
70  if( m_pLumaRecBuffer )
71  {
72    delete [] m_pLumaRecBuffer;
73  }
74 
75  Int i, j;
76  for (i = 0; i < 4; i++)
77  {
78    for (j = 0; j < 4; j++)
79    {
80      m_filteredBlock[i][j].destroy();
81    }
82    m_filteredBlockTmp[i].destroy();
83  }
84}
85
86Void TComPrediction::initTempBuff()
87{
88  if( m_piYuvExt == NULL )
89  {
90    Int extWidth  = MAX_CU_SIZE + 16; 
91    Int extHeight = MAX_CU_SIZE + 1;
92    Int i, j;
93    for (i = 0; i < 4; i++)
94    {
95      m_filteredBlockTmp[i].create(extWidth, extHeight + 7);
96      for (j = 0; j < 4; j++)
97      {
98        m_filteredBlock[i][j].create(extWidth, extHeight);
99      }
100    }
101    m_iYuvExtHeight  = ((MAX_CU_SIZE + 2) << 4);
102    m_iYuvExtStride = ((MAX_CU_SIZE  + 8) << 4);
103    m_piYuvExt = new Int[ m_iYuvExtStride * m_iYuvExtHeight ];
104
105    // new structure
106    m_acYuvPred[0] .create( MAX_CU_SIZE, MAX_CU_SIZE );
107    m_acYuvPred[1] .create( MAX_CU_SIZE, MAX_CU_SIZE );
108
109    m_cYuvPredTemp.create( MAX_CU_SIZE, MAX_CU_SIZE );
110#if H_3D_ARP
111    m_acYuvPredBase[0] .create( g_uiMaxCUWidth, g_uiMaxCUHeight );
112    m_acYuvPredBase[1] .create( g_uiMaxCUWidth, g_uiMaxCUHeight );
113#endif
114  }
115
116  if (m_iLumaRecStride != (MAX_CU_SIZE>>1) + 1)
117  {
118    m_iLumaRecStride =  (MAX_CU_SIZE>>1) + 1;
119    if (!m_pLumaRecBuffer)
120    {
121      m_pLumaRecBuffer = new Pel[ m_iLumaRecStride * m_iLumaRecStride ];
122    }
123  }
124}
125
126// ====================================================================================================================
127// Public member functions
128// ====================================================================================================================
129
130// Function for calculating DC value of the reference samples used in Intra prediction
131Pel TComPrediction::predIntraGetPredValDC( Int* pSrc, Int iSrcStride, UInt iWidth, UInt iHeight, Bool bAbove, Bool bLeft )
132{
133  Int iInd, iSum = 0;
134  Pel pDcVal;
135
136  if (bAbove)
137  {
138    for (iInd = 0;iInd < iWidth;iInd++)
139    {
140      iSum += pSrc[iInd-iSrcStride];
141    }
142  }
143  if (bLeft)
144  {
145    for (iInd = 0;iInd < iHeight;iInd++)
146    {
147      iSum += pSrc[iInd*iSrcStride-1];
148    }
149  }
150
151  if (bAbove && bLeft)
152  {
153    pDcVal = (iSum + iWidth) / (iWidth + iHeight);
154  }
155  else if (bAbove)
156  {
157    pDcVal = (iSum + iWidth/2) / iWidth;
158  }
159  else if (bLeft)
160  {
161    pDcVal = (iSum + iHeight/2) / iHeight;
162  }
163  else
164  {
165    pDcVal = pSrc[-1]; // Default DC value already calculated and placed in the prediction array if no neighbors are available
166  }
167 
168  return pDcVal;
169}
170
171// Function for deriving the angular Intra predictions
172
173/** Function for deriving the simplified angular intra predictions.
174 * \param pSrc pointer to reconstructed sample array
175 * \param srcStride the stride of the reconstructed sample array
176 * \param rpDst reference to pointer for the prediction sample array
177 * \param dstStride the stride of the prediction sample array
178 * \param width the width of the block
179 * \param height the height of the block
180 * \param dirMode the intra prediction mode index
181 * \param blkAboveAvailable boolean indication if the block above is available
182 * \param blkLeftAvailable boolean indication if the block to the left is available
183 *
184 * This function derives the prediction samples for the angular mode based on the prediction direction indicated by
185 * the prediction mode index. The prediction direction is given by the displacement of the bottom row of the block and
186 * the reference row above the block in the case of vertical prediction or displacement of the rightmost column
187 * of the block and reference column left from the block in the case of the horizontal prediction. The displacement
188 * is signalled at 1/32 pixel accuracy. When projection of the predicted pixel falls inbetween reference samples,
189 * the predicted value for the pixel is linearly interpolated from the reference samples. All reference samples are taken
190 * from the extended main reference.
191 */
192Void TComPrediction::xPredIntraAng(Int bitDepth, Int* pSrc, Int srcStride, Pel*& rpDst, Int dstStride, UInt width, UInt height, UInt dirMode, Bool blkAboveAvailable, Bool blkLeftAvailable, Bool bFilter )
193{
194  Int k,l;
195  Int blkSize        = width;
196  Pel* pDst          = rpDst;
197
198  // Map the mode index to main prediction direction and angle
199  assert( dirMode > 0 ); //no planar
200  Bool modeDC        = dirMode < 2;
201  Bool modeHor       = !modeDC && (dirMode < 18);
202  Bool modeVer       = !modeDC && !modeHor;
203  Int intraPredAngle = modeVer ? (Int)dirMode - VER_IDX : modeHor ? -((Int)dirMode - HOR_IDX) : 0;
204  Int absAng         = abs(intraPredAngle);
205  Int signAng        = intraPredAngle < 0 ? -1 : 1;
206
207  // Set bitshifts and scale the angle parameter to block size
208  Int angTable[9]    = {0,    2,    5,   9,  13,  17,  21,  26,  32};
209  Int invAngTable[9] = {0, 4096, 1638, 910, 630, 482, 390, 315, 256}; // (256 * 32) / Angle
210  Int invAngle       = invAngTable[absAng];
211  absAng             = angTable[absAng];
212  intraPredAngle     = signAng * absAng;
213
214  // Do the DC prediction
215  if (modeDC)
216  {
217    Pel dcval = predIntraGetPredValDC(pSrc, srcStride, width, height, blkAboveAvailable, blkLeftAvailable);
218
219    for (k=0;k<blkSize;k++)
220    {
221      for (l=0;l<blkSize;l++)
222      {
223        pDst[k*dstStride+l] = dcval;
224      }
225    }
226  }
227
228  // Do angular predictions
229  else
230  {
231    Pel* refMain;
232    Pel* refSide;
233    Pel  refAbove[2*MAX_CU_SIZE+1];
234    Pel  refLeft[2*MAX_CU_SIZE+1];
235
236    // Initialise the Main and Left reference array.
237    if (intraPredAngle < 0)
238    {
239      for (k=0;k<blkSize+1;k++)
240      {
241        refAbove[k+blkSize-1] = pSrc[k-srcStride-1];
242      }
243      for (k=0;k<blkSize+1;k++)
244      {
245        refLeft[k+blkSize-1] = pSrc[(k-1)*srcStride-1];
246      }
247      refMain = (modeVer ? refAbove : refLeft) + (blkSize-1);
248      refSide = (modeVer ? refLeft : refAbove) + (blkSize-1);
249
250      // Extend the Main reference to the left.
251      Int invAngleSum    = 128;       // rounding for (shift by 8)
252      for (k=-1; k>blkSize*intraPredAngle>>5; k--)
253      {
254        invAngleSum += invAngle;
255        refMain[k] = refSide[invAngleSum>>8];
256      }
257    }
258    else
259    {
260      for (k=0;k<2*blkSize+1;k++)
261      {
262        refAbove[k] = pSrc[k-srcStride-1];
263      }
264      for (k=0;k<2*blkSize+1;k++)
265      {
266        refLeft[k] = pSrc[(k-1)*srcStride-1];
267      }
268      refMain = modeVer ? refAbove : refLeft;
269      refSide = modeVer ? refLeft  : refAbove;
270    }
271
272    if (intraPredAngle == 0)
273    {
274      for (k=0;k<blkSize;k++)
275      {
276        for (l=0;l<blkSize;l++)
277        {
278          pDst[k*dstStride+l] = refMain[l+1];
279        }
280      }
281
282      if ( bFilter )
283      {
284        for (k=0;k<blkSize;k++)
285        {
286          pDst[k*dstStride] = Clip3(0, (1<<bitDepth)-1, pDst[k*dstStride] + (( refSide[k+1] - refSide[0] ) >> 1) );
287        }
288      }
289    }
290    else
291    {
292      Int deltaPos=0;
293      Int deltaInt;
294      Int deltaFract;
295      Int refMainIndex;
296
297      for (k=0;k<blkSize;k++)
298      {
299        deltaPos += intraPredAngle;
300        deltaInt   = deltaPos >> 5;
301        deltaFract = deltaPos & (32 - 1);
302
303        if (deltaFract)
304        {
305          // Do linear filtering
306          for (l=0;l<blkSize;l++)
307          {
308            refMainIndex        = l+deltaInt+1;
309            pDst[k*dstStride+l] = (Pel) ( ((32-deltaFract)*refMain[refMainIndex]+deltaFract*refMain[refMainIndex+1]+16) >> 5 );
310          }
311        }
312        else
313        {
314          // Just copy the integer samples
315          for (l=0;l<blkSize;l++)
316          {
317            pDst[k*dstStride+l] = refMain[l+deltaInt+1];
318          }
319        }
320      }
321    }
322
323    // Flip the block if this is the horizontal mode
324    if (modeHor)
325    {
326      Pel  tmp;
327      for (k=0;k<blkSize-1;k++)
328      {
329        for (l=k+1;l<blkSize;l++)
330        {
331          tmp                 = pDst[k*dstStride+l];
332          pDst[k*dstStride+l] = pDst[l*dstStride+k];
333          pDst[l*dstStride+k] = tmp;
334        }
335      }
336    }
337  }
338}
339
340Void TComPrediction::predIntraLumaAng(TComPattern* pcTComPattern, UInt uiDirMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, Bool bAbove, Bool bLeft )
341{
342  Pel *pDst = piPred;
343  Int *ptrSrc;
344
345  assert( g_aucConvertToBit[ iWidth ] >= 0 ); //   4x  4
346  assert( g_aucConvertToBit[ iWidth ] <= 5 ); // 128x128
347  assert( iWidth == iHeight  );
348
349  ptrSrc = pcTComPattern->getPredictorPtr( uiDirMode, g_aucConvertToBit[ iWidth ] + 2, m_piYuvExt );
350
351  // get starting pixel in block
352  Int sw = 2 * iWidth + 1;
353
354  // Create the prediction
355  if ( uiDirMode == PLANAR_IDX )
356  {
357    xPredIntraPlanar( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight );
358  }
359  else
360  {
361    if ( (iWidth > 16) || (iHeight > 16) )
362    {
363      xPredIntraAng(g_bitDepthY, ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode, bAbove, bLeft, false );
364    }
365    else
366    {
367      xPredIntraAng(g_bitDepthY, ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode, bAbove, bLeft, true );
368
369      if( (uiDirMode == DC_IDX ) && bAbove && bLeft )
370      {
371        xDCPredFiltering( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight);
372      }
373    }
374  }
375}
376
377// Angular chroma
378Void TComPrediction::predIntraChromaAng( Int* piSrc, UInt uiDirMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, Bool bAbove, Bool bLeft )
379{
380  Pel *pDst = piPred;
381  Int *ptrSrc = piSrc;
382
383  // get starting pixel in block
384  Int sw = 2 * iWidth + 1;
385
386  if ( uiDirMode == PLANAR_IDX )
387  {
388    xPredIntraPlanar( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight );
389  }
390  else
391  {
392    // Create the prediction
393    xPredIntraAng(g_bitDepthC, ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode, bAbove, bLeft, false );
394  }
395}
396
397/** Function for checking identical motion.
398 * \param TComDataCU* pcCU
399 * \param UInt PartAddr
400 */
401Bool TComPrediction::xCheckIdenticalMotion ( TComDataCU* pcCU, UInt PartAddr )
402{
403  if( pcCU->getSlice()->isInterB() && !pcCU->getSlice()->getPPS()->getWPBiPred() )
404  {
405    if( pcCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(PartAddr) >= 0 && pcCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(PartAddr) >= 0)
406    {
407      Int RefPOCL0 = pcCU->getSlice()->getRefPic(REF_PIC_LIST_0, pcCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(PartAddr))->getPOC();
408      Int RefPOCL1 = pcCU->getSlice()->getRefPic(REF_PIC_LIST_1, pcCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(PartAddr))->getPOC();
409      if(RefPOCL0 == RefPOCL1 && pcCU->getCUMvField(REF_PIC_LIST_0)->getMv(PartAddr) == pcCU->getCUMvField(REF_PIC_LIST_1)->getMv(PartAddr))
410      {
411        return true;
412      }
413    }
414  }
415  return false;
416}
417
418
419Void TComPrediction::motionCompensation ( TComDataCU* pcCU, TComYuv* pcYuvPred, RefPicList eRefPicList, Int iPartIdx )
420{
421  Int         iWidth;
422  Int         iHeight;
423  UInt        uiPartAddr;
424
425  if ( iPartIdx >= 0 )
426  {
427    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
428    if ( eRefPicList != REF_PIC_LIST_X )
429    {
430      if( pcCU->getSlice()->getPPS()->getUseWP())
431      {
432        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, true );
433      }
434      else
435      {
436        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
437      }
438      if ( pcCU->getSlice()->getPPS()->getUseWP() )
439      {
440        xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
441      }
442    }
443    else
444    {
445      if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
446      {
447        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
448      }
449      else
450      {
451        xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );
452      }
453    }
454    return;
455  }
456
457  for ( iPartIdx = 0; iPartIdx < pcCU->getNumPartInter(); iPartIdx++ )
458  {
459    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
460
461    if ( eRefPicList != REF_PIC_LIST_X )
462    {
463      if( pcCU->getSlice()->getPPS()->getUseWP())
464      {
465        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, true );
466      }
467      else
468      {
469        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
470      }
471      if ( pcCU->getSlice()->getPPS()->getUseWP() )
472      {
473        xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
474      }
475    }
476    else
477    {
478      if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
479      {
480        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
481      }
482      else
483      {
484        xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );
485      }
486    }
487  }
488  return;
489}
490
491Void TComPrediction::xPredInterUni ( TComDataCU* pcCU, UInt uiPartAddr, Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Bool bi )
492{
493  Int         iRefIdx     = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );           assert (iRefIdx >= 0);
494  TComMv      cMv         = pcCU->getCUMvField( eRefPicList )->getMv( uiPartAddr );
495  pcCU->clipMv(cMv);
496#if H_3D_ARP
497  if(  pcCU->getARPW( uiPartAddr ) > 0 
498    && pcCU->getPartitionSize(uiPartAddr)==SIZE_2Nx2N
499    && pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPOC()!= pcCU->getSlice()->getPOC() 
500    )
501  {
502    xPredInterUniARP( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, rpcYuvPred, bi );
503  }
504  else
505  {
506#endif
507  xPredInterLumaBlk  ( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi );
508  xPredInterChromaBlk( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi );
509#if H_3D_ARP
510  }
511#endif
512}
513
514#if H_3D_ARP
515Void TComPrediction::xPredInterUniARP( TComDataCU* pcCU, UInt uiPartAddr, Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Bool bi, TComMvField * pNewMvFiled )
516{
517  Int         iRefIdx      = pNewMvFiled ? pNewMvFiled->getRefIdx() : pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );           
518  TComMv      cMv          = pNewMvFiled ? pNewMvFiled->getMv()     : pcCU->getCUMvField( eRefPicList )->getMv( uiPartAddr );
519  Bool        bTobeScaled  = false;
520  TComPic* pcPicYuvBaseCol = NULL;
521  TComPic* pcPicYuvBaseRef = NULL;
522
523#if H_3D_NBDV
524  DisInfo cDistparity;
525  cDistparity.bDV           = pcCU->getDvInfo(uiPartAddr).bDV;
526  if( cDistparity.bDV )
527  {
528    cDistparity.m_acNBDV = pcCU->getDvInfo(0).m_acNBDV;
529    assert(pcCU->getDvInfo(uiPartAddr).bDV ==  pcCU->getDvInfo(0).bDV);
530    cDistparity.m_aVIdxCan = pcCU->getDvInfo(uiPartAddr).m_aVIdxCan;
531  }
532#else
533  assert(0); // ARP can be applied only when a DV is available
534#endif
535
536  UChar dW = cDistparity.bDV ? pcCU->getARPW ( uiPartAddr ) : 0;
537
538  if( cDistparity.bDV ) 
539  {
540    if( dW > 0 && pcCU->getSlice()->getRefPic( eRefPicList, 0 )->getPOC()!= pcCU->getSlice()->getPOC() )
541    {
542      bTobeScaled = true;
543    }
544
545    pcPicYuvBaseCol =  pcCU->getSlice()->getBaseViewRefPic( pcCU->getSlice()->getPOC(),                              cDistparity.m_aVIdxCan );
546    pcPicYuvBaseRef =  pcCU->getSlice()->getBaseViewRefPic( pcCU->getSlice()->getRefPic( eRefPicList, 0 )->getPOC(), cDistparity.m_aVIdxCan );
547   
548    if( ( !pcPicYuvBaseCol || pcPicYuvBaseCol->getPOC() != pcCU->getSlice()->getPOC() ) || ( !pcPicYuvBaseRef || pcPicYuvBaseRef->getPOC() != pcCU->getSlice()->getRefPic( eRefPicList, 0 )->getPOC() ) )
549    {
550      dW = 0;
551      bTobeScaled = false;
552    }
553    else
554    {
555      assert( pcPicYuvBaseCol->getPOC() == pcCU->getSlice()->getPOC() && pcPicYuvBaseRef->getPOC() == pcCU->getSlice()->getRefPic( eRefPicList, 0 )->getPOC() );
556    }
557
558    if(bTobeScaled)
559    {     
560      Int iCurrPOC    = pcCU->getSlice()->getPOC();
561      Int iColRefPOC  = pcCU->getSlice()->getRefPOC( eRefPicList, iRefIdx );
562      Int iCurrRefPOC = pcCU->getSlice()->getRefPOC( eRefPicList,  0);
563      Int iScale = pcCU-> xGetDistScaleFactor(iCurrPOC, iCurrRefPOC, iCurrPOC, iColRefPOC);
564      if ( iScale != 4096 )
565      {
566        cMv = cMv.scaleMv( iScale );
567      }
568      iRefIdx = 0;
569    }
570  }
571
572  pcCU->clipMv(cMv);
573  TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec();
574  xPredInterLumaBlk  ( pcCU, pcPicYuvRef, uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi, true );
575  xPredInterChromaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi, true );
576
577  if( dW > 0 )
578  {
579    TComYuv * pYuvB0 = &m_acYuvPredBase[0];
580    TComYuv * pYuvB1  = &m_acYuvPredBase[1];
581
582    TComMv cMVwithDisparity = cMv + cDistparity.m_acNBDV;
583    pcCU->clipMv(cMVwithDisparity);
584
585    assert ( cDistparity.bDV );
586
587    pcPicYuvRef = pcPicYuvBaseCol->getPicYuvRec();
588    xPredInterLumaBlk  ( pcCU, pcPicYuvRef, uiPartAddr, &cDistparity.m_acNBDV, iWidth, iHeight, pYuvB0, bi, true );
589    xPredInterChromaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cDistparity.m_acNBDV, iWidth, iHeight, pYuvB0, bi, true );
590   
591    pcPicYuvRef = pcPicYuvBaseRef->getPicYuvRec();
592    xPredInterLumaBlk  ( pcCU, pcPicYuvRef, uiPartAddr, &cMVwithDisparity, iWidth, iHeight, pYuvB1, bi, true );
593    xPredInterChromaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMVwithDisparity, iWidth, iHeight, pYuvB1, bi, true );
594
595    pYuvB0->subtractARP( pYuvB0 , pYuvB1 , uiPartAddr , iWidth , iHeight );
596
597    if( 2 == dW )
598    {
599      pYuvB0->multiplyARP( uiPartAddr , iWidth , iHeight , dW );
600    }
601
602    rpcYuvPred->addARP( rpcYuvPred , pYuvB0 , uiPartAddr , iWidth , iHeight , !bi );
603  }
604}
605#endif
606
607Void TComPrediction::xPredInterBi ( TComDataCU* pcCU, UInt uiPartAddr, Int iWidth, Int iHeight, TComYuv*& rpcYuvPred )
608{
609  TComYuv* pcMbYuv;
610  Int      iRefIdx[2] = {-1, -1};
611
612  for ( Int iRefList = 0; iRefList < 2; iRefList++ )
613  {
614    RefPicList eRefPicList = (iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0);
615    iRefIdx[iRefList] = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );
616
617    if ( iRefIdx[iRefList] < 0 )
618    {
619      continue;
620    }
621
622    assert( iRefIdx[iRefList] < pcCU->getSlice()->getNumRefIdx(eRefPicList) );
623
624    pcMbYuv = &m_acYuvPred[iRefList];
625    if( pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiPartAddr ) >= 0 && pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiPartAddr ) >= 0 )
626    {
627      xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv, true );
628    }
629    else
630    {
631      if ( ( pcCU->getSlice()->getPPS()->getUseWP()       && pcCU->getSlice()->getSliceType() == P_SLICE ) || 
632           ( pcCU->getSlice()->getPPS()->getWPBiPred() && pcCU->getSlice()->getSliceType() == B_SLICE ) )
633      {
634        xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv, true );
635      }
636      else
637      {
638        xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv );
639      }
640    }
641  }
642
643  if ( pcCU->getSlice()->getPPS()->getWPBiPred() && pcCU->getSlice()->getSliceType() == B_SLICE  )
644  {
645    xWeightedPredictionBi( pcCU, &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred );
646  } 
647  else if ( pcCU->getSlice()->getPPS()->getUseWP() && pcCU->getSlice()->getSliceType() == P_SLICE )
648  {
649    xWeightedPredictionUni( pcCU, &m_acYuvPred[0], uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, rpcYuvPred ); 
650  }
651  else
652  {
653    xWeightedAverage( &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred );
654  }
655}
656
657/**
658 * \brief Generate motion-compensated luma block
659 *
660 * \param cu       Pointer to current CU
661 * \param refPic   Pointer to reference picture
662 * \param partAddr Address of block within CU
663 * \param mv       Motion vector
664 * \param width    Width of block
665 * \param height   Height of block
666 * \param dstPic   Pointer to destination picture
667 * \param bi       Flag indicating whether bipred is used
668 */
669Void TComPrediction::xPredInterLumaBlk( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi
670#if H_3D_ARP
671    , Bool filterType
672#endif
673  )
674{
675  Int refStride = refPic->getStride(); 
676  Int refOffset = ( mv->getHor() >> 2 ) + ( mv->getVer() >> 2 ) * refStride;
677  Pel *ref      = refPic->getLumaAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
678 
679  Int dstStride = dstPic->getStride();
680  Pel *dst      = dstPic->getLumaAddr( partAddr );
681 
682  Int xFrac = mv->getHor() & 0x3;
683  Int yFrac = mv->getVer() & 0x3;
684
685  if ( yFrac == 0 )
686  {
687    m_if.filterHorLuma( ref, refStride, dst, dstStride, width, height, xFrac,       !bi
688#if H_3D_ARP
689    , filterType
690#endif
691      );
692  }
693  else if ( xFrac == 0 )
694  {
695    m_if.filterVerLuma( ref, refStride, dst, dstStride, width, height, yFrac, true, !bi
696#if H_3D_ARP
697    , filterType
698#endif
699      );
700  }
701  else
702  {
703    Int tmpStride = m_filteredBlockTmp[0].getStride();
704    Short *tmp    = m_filteredBlockTmp[0].getLumaAddr();
705
706    Int filterSize = NTAPS_LUMA;
707    Int halfFilterSize = ( filterSize >> 1 );
708
709    m_if.filterHorLuma(ref - (halfFilterSize-1)*refStride, refStride, tmp, tmpStride, width, height+filterSize-1, xFrac, false     
710#if H_3D_ARP
711    , filterType
712#endif
713      );
714    m_if.filterVerLuma(tmp + (halfFilterSize-1)*tmpStride, tmpStride, dst, dstStride, width, height,              yFrac, false, !bi
715#if H_3D_ARP
716    , filterType
717#endif
718      );   
719  }
720}
721
722/**
723 * \brief Generate motion-compensated chroma block
724 *
725 * \param cu       Pointer to current CU
726 * \param refPic   Pointer to reference picture
727 * \param partAddr Address of block within CU
728 * \param mv       Motion vector
729 * \param width    Width of block
730 * \param height   Height of block
731 * \param dstPic   Pointer to destination picture
732 * \param bi       Flag indicating whether bipred is used
733 */
734Void TComPrediction::xPredInterChromaBlk( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi
735#if H_3D_ARP
736    , Bool filterType
737#endif   
738  )
739{
740  Int     refStride  = refPic->getCStride();
741  Int     dstStride  = dstPic->getCStride();
742 
743  Int     refOffset  = (mv->getHor() >> 3) + (mv->getVer() >> 3) * refStride;
744 
745  Pel*    refCb     = refPic->getCbAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
746  Pel*    refCr     = refPic->getCrAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
747 
748  Pel* dstCb = dstPic->getCbAddr( partAddr );
749  Pel* dstCr = dstPic->getCrAddr( partAddr );
750 
751  Int     xFrac  = mv->getHor() & 0x7;
752  Int     yFrac  = mv->getVer() & 0x7;
753  UInt    cxWidth  = width  >> 1;
754  UInt    cxHeight = height >> 1;
755 
756  Int     extStride = m_filteredBlockTmp[0].getStride();
757  Short*  extY      = m_filteredBlockTmp[0].getLumaAddr();
758 
759  Int filterSize = NTAPS_CHROMA;
760 
761  Int halfFilterSize = (filterSize>>1);
762 
763  if ( yFrac == 0 )
764  {
765    m_if.filterHorChroma(refCb, refStride, dstCb,  dstStride, cxWidth, cxHeight, xFrac, !bi
766#if H_3D_ARP
767    , filterType
768#endif
769    );   
770    m_if.filterHorChroma(refCr, refStride, dstCr,  dstStride, cxWidth, cxHeight, xFrac, !bi
771#if H_3D_ARP
772    , filterType
773#endif
774    );
775  }
776  else if ( xFrac == 0 )
777  {
778    m_if.filterVerChroma(refCb, refStride, dstCb, dstStride, cxWidth, cxHeight, yFrac, true, !bi
779#if H_3D_ARP
780    , filterType
781#endif
782    );
783    m_if.filterVerChroma(refCr, refStride, dstCr, dstStride, cxWidth, cxHeight, yFrac, true, !bi
784#if H_3D_ARP
785    , filterType
786#endif
787    );
788  }
789  else
790  {
791    m_if.filterHorChroma(refCb - (halfFilterSize-1)*refStride, refStride, extY,  extStride, cxWidth, cxHeight+filterSize-1, xFrac, false
792#if H_3D_ARP
793    , filterType
794#endif 
795      );
796    m_if.filterVerChroma(extY  + (halfFilterSize-1)*extStride, extStride, dstCb, dstStride, cxWidth, cxHeight  , yFrac, false, !bi
797#if H_3D_ARP
798    , filterType
799#endif
800      );
801   
802    m_if.filterHorChroma(refCr - (halfFilterSize-1)*refStride, refStride, extY,  extStride, cxWidth, cxHeight+filterSize-1, xFrac, false
803#if H_3D_ARP
804    , filterType
805#endif
806      );
807    m_if.filterVerChroma(extY  + (halfFilterSize-1)*extStride, extStride, dstCr, dstStride, cxWidth, cxHeight  , yFrac, false, !bi
808#if H_3D_ARP
809    , filterType
810#endif
811      );   
812  }
813}
814
815Void TComPrediction::xWeightedAverage( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartIdx, Int iWidth, Int iHeight, TComYuv*& rpcYuvDst )
816{
817  if( iRefIdx0 >= 0 && iRefIdx1 >= 0 )
818  {
819    rpcYuvDst->addAvg( pcYuvSrc0, pcYuvSrc1, uiPartIdx, iWidth, iHeight );
820  }
821  else if ( iRefIdx0 >= 0 && iRefIdx1 <  0 )
822  {
823    pcYuvSrc0->copyPartToPartYuv( rpcYuvDst, uiPartIdx, iWidth, iHeight );
824  }
825  else if ( iRefIdx0 <  0 && iRefIdx1 >= 0 )
826  {
827    pcYuvSrc1->copyPartToPartYuv( rpcYuvDst, uiPartIdx, iWidth, iHeight );
828  }
829}
830
831// AMVP
832Void TComPrediction::getMvPredAMVP( TComDataCU* pcCU, UInt uiPartIdx, UInt uiPartAddr, RefPicList eRefPicList, TComMv& rcMvPred )
833{
834  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
835  if( pcAMVPInfo->iN <= 1 )
836  {
837    rcMvPred = pcAMVPInfo->m_acMvCand[0];
838
839    pcCU->setMVPIdxSubParts( 0, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
840    pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
841    return;
842  }
843
844  assert(pcCU->getMVPIdx(eRefPicList,uiPartAddr) >= 0);
845  rcMvPred = pcAMVPInfo->m_acMvCand[pcCU->getMVPIdx(eRefPicList,uiPartAddr)];
846  return;
847}
848
849/** Function for deriving planar intra prediction.
850 * \param pSrc pointer to reconstructed sample array
851 * \param srcStride the stride of the reconstructed sample array
852 * \param rpDst reference to pointer for the prediction sample array
853 * \param dstStride the stride of the prediction sample array
854 * \param width the width of the block
855 * \param height the height of the block
856 *
857 * This function derives the prediction samples for planar mode (intra coding).
858 */
859Void TComPrediction::xPredIntraPlanar( Int* pSrc, Int srcStride, Pel* rpDst, Int dstStride, UInt width, UInt height )
860{
861  assert(width == height);
862
863  Int k, l, bottomLeft, topRight;
864  Int horPred;
865  Int leftColumn[MAX_CU_SIZE], topRow[MAX_CU_SIZE], bottomRow[MAX_CU_SIZE], rightColumn[MAX_CU_SIZE];
866  UInt blkSize = width;
867  UInt offset2D = width;
868  UInt shift1D = g_aucConvertToBit[ width ] + 2;
869  UInt shift2D = shift1D + 1;
870
871  // Get left and above reference column and row
872  for(k=0;k<blkSize+1;k++)
873  {
874    topRow[k] = pSrc[k-srcStride];
875    leftColumn[k] = pSrc[k*srcStride-1];
876  }
877
878  // Prepare intermediate variables used in interpolation
879  bottomLeft = leftColumn[blkSize];
880  topRight   = topRow[blkSize];
881  for (k=0;k<blkSize;k++)
882  {
883    bottomRow[k]   = bottomLeft - topRow[k];
884    rightColumn[k] = topRight   - leftColumn[k];
885    topRow[k]      <<= shift1D;
886    leftColumn[k]  <<= shift1D;
887  }
888
889  // Generate prediction signal
890  for (k=0;k<blkSize;k++)
891  {
892    horPred = leftColumn[k] + offset2D;
893    for (l=0;l<blkSize;l++)
894    {
895      horPred += rightColumn[k];
896      topRow[l] += bottomRow[l];
897      rpDst[k*dstStride+l] = ( (horPred + topRow[l]) >> shift2D );
898    }
899  }
900}
901
902/** Function for filtering intra DC predictor.
903 * \param pSrc pointer to reconstructed sample array
904 * \param iSrcStride the stride of the reconstructed sample array
905 * \param rpDst reference to pointer for the prediction sample array
906 * \param iDstStride the stride of the prediction sample array
907 * \param iWidth the width of the block
908 * \param iHeight the height of the block
909 *
910 * This function performs filtering left and top edges of the prediction samples for DC mode (intra coding).
911 */
912Void TComPrediction::xDCPredFiltering( Int* pSrc, Int iSrcStride, Pel*& rpDst, Int iDstStride, Int iWidth, Int iHeight )
913{
914  Pel* pDst = rpDst;
915  Int x, y, iDstStride2, iSrcStride2;
916
917  // boundary pixels processing
918  pDst[0] = (Pel)((pSrc[-iSrcStride] + pSrc[-1] + 2 * pDst[0] + 2) >> 2);
919
920  for ( x = 1; x < iWidth; x++ )
921  {
922    pDst[x] = (Pel)((pSrc[x - iSrcStride] +  3 * pDst[x] + 2) >> 2);
923  }
924
925  for ( y = 1, iDstStride2 = iDstStride, iSrcStride2 = iSrcStride-1; y < iHeight; y++, iDstStride2+=iDstStride, iSrcStride2+=iSrcStride )
926  {
927    pDst[iDstStride2] = (Pel)((pSrc[iSrcStride2] + 3 * pDst[iDstStride2] + 2) >> 2);
928  }
929
930  return;
931}
932//! \}
Note: See TracBrowser for help on using the repository browser.