source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibCommon/TComPrediction.cpp @ 1263

Last change on this file since 1263 was 1262, checked in by seregin, 9 years ago

port rev 4259

  • Property svn:eol-style set to native
File size: 29.8 KB
RevLine 
[1238]1/* The copyright in this software is being made available under the BSD
[313]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
[1029]4 * granted under this license.
[313]5 *
[1259]6 * Copyright (c) 2010-2015, ITU/ISO/IEC
[313]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"
[1262]40#include "TComPic.h"
[1029]41#include "TComTU.h"
[313]42
43//! \ingroup TLibCommon
44//! \{
45
46// ====================================================================================================================
[1029]47// Tables
48// ====================================================================================================================
49
50const UChar TComPrediction::m_aucIntraFilter[MAX_NUM_CHANNEL_TYPE][MAX_INTRA_FILTER_DEPTHS] =
51{
52  { // Luma
53    10, //4x4
54    7, //8x8
55    1, //16x16
56    0, //32x32
57    10, //64x64
58  },
59  { // Chroma
60    10, //4xn
61    7, //8xn
62    1, //16xn
63    0, //32xn
64    10, //64xn
65  }
66
67};
68
69// ====================================================================================================================
[313]70// Constructor / destructor / initialize
71// ====================================================================================================================
72
73TComPrediction::TComPrediction()
74: m_pLumaRecBuffer(0)
75, m_iLumaRecStride(0)
76{
[1029]77  for(UInt ch=0; ch<MAX_NUM_COMPONENT; ch++)
78  {
79    for(UInt buf=0; buf<2; buf++)
80    {
81      m_piYuvExt[ch][buf] = NULL;
82    }
83  }
[313]84}
85
86TComPrediction::~TComPrediction()
87{
[1029]88  destroy();
89}
[313]90
[1029]91Void TComPrediction::destroy()
92{
93  for(UInt ch=0; ch<MAX_NUM_COMPONENT; ch++)
94  {
95    for(UInt buf=0; buf<NUM_PRED_BUF; buf++)
96    {
97      delete [] m_piYuvExt[ch][buf];
98      m_piYuvExt[ch][buf] = NULL;
99    }
100  }
[313]101
[1029]102  for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
103  {
104    m_acYuvPred[i].destroy();
105  }
106
[313]107  m_cYuvPredTemp.destroy();
108
109  if( m_pLumaRecBuffer )
110  {
111    delete [] m_pLumaRecBuffer;
[1029]112    m_pLumaRecBuffer = 0;
[313]113  }
[1029]114  m_iLumaRecStride = 0;
115
116  for (UInt i = 0; i < LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS; i++)
[313]117  {
[1029]118    for (UInt j = 0; j < LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS; j++)
[313]119    {
120      m_filteredBlock[i][j].destroy();
121    }
122    m_filteredBlockTmp[i].destroy();
123  }
124}
125
[1029]126Void TComPrediction::initTempBuff(ChromaFormat chromaFormatIDC)
[313]127{
[1029]128  // if it has been initialised before, but the chroma format has changed, release the memory and start again.
129  if( m_piYuvExt[COMPONENT_Y][PRED_BUF_UNFILTERED] != NULL && m_cYuvPredTemp.getChromaFormat()!=chromaFormatIDC)
[313]130  {
[1029]131    destroy();
132  }
133
134  if( m_piYuvExt[COMPONENT_Y][PRED_BUF_UNFILTERED] == NULL ) // check if first is null (in which case, nothing initialised yet)
135  {
136    Int extWidth  = MAX_CU_SIZE + 16;
[313]137    Int extHeight = MAX_CU_SIZE + 1;
[1029]138
139    for (UInt i = 0; i < LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS; i++)
[313]140    {
[1029]141      m_filteredBlockTmp[i].create(extWidth, extHeight + 7, chromaFormatIDC);
142      for (UInt j = 0; j < LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS; j++)
[313]143      {
[1029]144        m_filteredBlock[i][j].create(extWidth, extHeight, chromaFormatIDC);
[313]145      }
146    }
147
[1029]148    m_iYuvExtSize = (MAX_CU_SIZE*2+1) * (MAX_CU_SIZE*2+1);
149    for(UInt ch=0; ch<MAX_NUM_COMPONENT; ch++)
150    {
151      for(UInt buf=0; buf<NUM_PRED_BUF; buf++)
152      {
153        m_piYuvExt[ch][buf] = new Pel[ m_iYuvExtSize ];
154      }
155    }
156
[313]157    // new structure
[1029]158    for(UInt i=0; i<NUM_REF_PIC_LIST_01; i++)
159    {
160      m_acYuvPred[i] .create( MAX_CU_SIZE, MAX_CU_SIZE, chromaFormatIDC );
161    }
[313]162
[1029]163    m_cYuvPredTemp.create( MAX_CU_SIZE, MAX_CU_SIZE, chromaFormatIDC );
[313]164  }
165
[1029]166
[313]167  if (m_iLumaRecStride != (MAX_CU_SIZE>>1) + 1)
168  {
169    m_iLumaRecStride =  (MAX_CU_SIZE>>1) + 1;
170    if (!m_pLumaRecBuffer)
171    {
172      m_pLumaRecBuffer = new Pel[ m_iLumaRecStride * m_iLumaRecStride ];
173    }
174  }
175}
176
177// ====================================================================================================================
178// Public member functions
179// ====================================================================================================================
180
181// Function for calculating DC value of the reference samples used in Intra prediction
[1029]182//NOTE: Bit-Limit - 25-bit source
183Pel TComPrediction::predIntraGetPredValDC( const Pel* pSrc, Int iSrcStride, UInt iWidth, UInt iHeight, ChannelType channelType, ChromaFormat format, Bool bAbove, Bool bLeft )
[313]184{
185  assert(iWidth > 0 && iHeight > 0);
186  Int iInd, iSum = 0;
187  Pel pDcVal;
188
189  if (bAbove)
190  {
191    for (iInd = 0;iInd < iWidth;iInd++)
192    {
193      iSum += pSrc[iInd-iSrcStride];
194    }
195  }
196  if (bLeft)
197  {
198    for (iInd = 0;iInd < iHeight;iInd++)
199    {
200      iSum += pSrc[iInd*iSrcStride-1];
201    }
202  }
203
204  if (bAbove && bLeft)
205  {
206    pDcVal = (iSum + iWidth) / (iWidth + iHeight);
207  }
208  else if (bAbove)
209  {
210    pDcVal = (iSum + iWidth/2) / iWidth;
211  }
212  else if (bLeft)
213  {
214    pDcVal = (iSum + iHeight/2) / iHeight;
215  }
216  else
217  {
218    pDcVal = pSrc[-1]; // Default DC value already calculated and placed in the prediction array if no neighbors are available
219  }
[1029]220
[313]221  return pDcVal;
222}
223
224// Function for deriving the angular Intra predictions
225
226/** Function for deriving the simplified angular intra predictions.
[1260]227 * \param bitDepth           bit depth
228 * \param pSrc               pointer to reconstructed sample array
229 * \param srcStride          the stride of the reconstructed sample array
230 * \param pTrueDst           reference to pointer for the prediction sample array
231 * \param dstStrideTrue      the stride of the prediction sample array
232 * \param uiWidth            the width of the block
233 * \param uiHeight           the height of the block
234 * \param channelType        type of pel array (luma/chroma)
235 * \param format             chroma format
236 * \param dirMode            the intra prediction mode index
237 * \param blkAboveAvailable  boolean indication if the block above is available
238 * \param blkLeftAvailable   boolean indication if the block to the left is available
239 * \param bEnableEdgeFilters indication whether to enable edge filters
[313]240 *
241 * This function derives the prediction samples for the angular mode based on the prediction direction indicated by
242 * the prediction mode index. The prediction direction is given by the displacement of the bottom row of the block and
243 * the reference row above the block in the case of vertical prediction or displacement of the rightmost column
244 * of the block and reference column left from the block in the case of the horizontal prediction. The displacement
245 * is signalled at 1/32 pixel accuracy. When projection of the predicted pixel falls inbetween reference samples,
246 * the predicted value for the pixel is linearly interpolated from the reference samples. All reference samples are taken
247 * from the extended main reference.
248 */
[1029]249//NOTE: Bit-Limit - 25-bit source
250Void TComPrediction::xPredIntraAng(       Int bitDepth,
251                                    const Pel* pSrc,     Int srcStride,
252                                          Pel* pTrueDst, Int dstStrideTrue,
253                                          UInt uiWidth, UInt uiHeight, ChannelType channelType, ChromaFormat format,
254                                          UInt dirMode, Bool blkAboveAvailable, Bool blkLeftAvailable
255                                  , const Bool bEnableEdgeFilters
256                                  )
[313]257{
[1029]258  Int width=Int(uiWidth);
259  Int height=Int(uiHeight);
[313]260
261  // Map the mode index to main prediction direction and angle
[1029]262  assert( dirMode != PLANAR_IDX ); //no planar
263  const Bool modeDC        = dirMode==DC_IDX;
[313]264
265  // Do the DC prediction
266  if (modeDC)
267  {
[1029]268    const Pel dcval = predIntraGetPredValDC(pSrc, srcStride, width, height, channelType, format, blkAboveAvailable, blkLeftAvailable);
[313]269
[1029]270    for (Int y=height;y>0;y--, pTrueDst+=dstStrideTrue)
[313]271    {
[1029]272      for (Int x=0; x<width;) // width is always a multiple of 4.
[313]273      {
[1029]274        pTrueDst[x++] = dcval;
[313]275      }
276    }
277  }
[1029]278  else // Do angular predictions
279  {
280    const Bool       bIsModeVer         = (dirMode >= 18);
281    const Int        intraPredAngleMode = (bIsModeVer) ? (Int)dirMode - VER_IDX :  -((Int)dirMode - HOR_IDX);
282    const Int        absAngMode         = abs(intraPredAngleMode);
283    const Int        signAng            = intraPredAngleMode < 0 ? -1 : 1;
284    const Bool       edgeFilter         = bEnableEdgeFilters && isLuma(channelType) && (width <= MAXIMUM_INTRA_FILTERED_WIDTH) && (height <= MAXIMUM_INTRA_FILTERED_HEIGHT);
[313]285
[1029]286    // Set bitshifts and scale the angle parameter to block size
287    static const Int angTable[9]    = {0,    2,    5,   9,  13,  17,  21,  26,  32};
288    static const Int invAngTable[9] = {0, 4096, 1638, 910, 630, 482, 390, 315, 256}; // (256 * 32) / Angle
289    Int invAngle                    = invAngTable[absAngMode];
290    Int absAng                      = angTable[absAngMode];
291    Int intraPredAngle              = signAng * absAng;
292
[313]293    Pel* refMain;
294    Pel* refSide;
[1029]295
[313]296    Pel  refAbove[2*MAX_CU_SIZE+1];
297    Pel  refLeft[2*MAX_CU_SIZE+1];
298
299    // Initialise the Main and Left reference array.
300    if (intraPredAngle < 0)
301    {
[1029]302      const Int refMainOffsetPreScale = (bIsModeVer ? height : width ) - 1;
303      const Int refMainOffset         = height - 1;
304      for (Int x=0;x<width+1;x++)
[313]305      {
[1029]306        refAbove[x+refMainOffset] = pSrc[x-srcStride-1];
[313]307      }
[1029]308      for (Int y=0;y<height+1;y++)
[313]309      {
[1029]310        refLeft[y+refMainOffset] = pSrc[(y-1)*srcStride-1];
[313]311      }
[1029]312      refMain = (bIsModeVer ? refAbove : refLeft)  + refMainOffset;
313      refSide = (bIsModeVer ? refLeft  : refAbove) + refMainOffset;
[313]314
315      // Extend the Main reference to the left.
316      Int invAngleSum    = 128;       // rounding for (shift by 8)
[1029]317      for (Int k=-1; k>(refMainOffsetPreScale+1)*intraPredAngle>>5; k--)
[313]318      {
319        invAngleSum += invAngle;
320        refMain[k] = refSide[invAngleSum>>8];
321      }
322    }
323    else
324    {
[1029]325      for (Int x=0;x<2*width+1;x++)
[313]326      {
[1029]327        refAbove[x] = pSrc[x-srcStride-1];
[313]328      }
[1029]329      for (Int y=0;y<2*height+1;y++)
[313]330      {
[1029]331        refLeft[y] = pSrc[(y-1)*srcStride-1];
[313]332      }
[1029]333      refMain = bIsModeVer ? refAbove : refLeft ;
334      refSide = bIsModeVer ? refLeft  : refAbove;
[313]335    }
336
[1029]337    // swap width/height if we are doing a horizontal mode:
338    Pel tempArray[MAX_CU_SIZE*MAX_CU_SIZE];
339    const Int dstStride = bIsModeVer ? dstStrideTrue : MAX_CU_SIZE;
340    Pel *pDst = bIsModeVer ? pTrueDst : tempArray;
341    if (!bIsModeVer)
[313]342    {
[1029]343      std::swap(width, height);
344    }
345
346    if (intraPredAngle == 0)  // pure vertical or pure horizontal
347    {
348      for (Int y=0;y<height;y++)
[313]349      {
[1029]350        for (Int x=0;x<width;x++)
[313]351        {
[1029]352          pDst[y*dstStride+x] = refMain[x+1];
[313]353        }
354      }
355
[1029]356      if (edgeFilter)
[313]357      {
[1029]358        for (Int y=0;y<height;y++)
[313]359        {
[1029]360          pDst[y*dstStride] = Clip3 (0, ((1 << bitDepth) - 1), pDst[y*dstStride] + (( refSide[y+1] - refSide[0] ) >> 1) );
[313]361        }
362      }
363    }
364    else
365    {
[1029]366      Pel *pDsty=pDst;
[313]367
[1029]368      for (Int y=0, deltaPos=intraPredAngle; y<height; y++, deltaPos+=intraPredAngle, pDsty+=dstStride)
[313]369      {
[1029]370        const Int deltaInt   = deltaPos >> 5;
371        const Int deltaFract = deltaPos & (32 - 1);
[313]372
373        if (deltaFract)
374        {
375          // Do linear filtering
[1029]376          const Pel *pRM=refMain+deltaInt+1;
377          Int lastRefMainPel=*pRM++;
378          for (Int x=0;x<width;pRM++,x++)
[313]379          {
[1029]380            Int thisRefMainPel=*pRM;
381            pDsty[x+0] = (Pel) ( ((32-deltaFract)*lastRefMainPel + deltaFract*thisRefMainPel +16) >> 5 );
382            lastRefMainPel=thisRefMainPel;
[313]383          }
384        }
385        else
386        {
387          // Just copy the integer samples
[1029]388          for (Int x=0;x<width; x++)
[313]389          {
[1029]390            pDsty[x] = refMain[x+deltaInt+1];
[313]391          }
392        }
393      }
394    }
395
396    // Flip the block if this is the horizontal mode
[1029]397    if (!bIsModeVer)
[313]398    {
[1029]399      for (Int y=0; y<height; y++)
[313]400      {
[1029]401        for (Int x=0; x<width; x++)
[313]402        {
[1029]403          pTrueDst[x*dstStrideTrue] = pDst[x];
[313]404        }
[1029]405        pTrueDst++;
406        pDst+=dstStride;
[313]407      }
408    }
409  }
410}
411
[1029]412Void TComPrediction::predIntraAng( const ComponentID compID, UInt uiDirMode, Pel* piOrg /* Will be null for decoding */, UInt uiOrgStride, Pel* piPred, UInt uiStride, TComTU &rTu, Bool bAbove, Bool bLeft, const Bool bUseFilteredPredSamples, const Bool bUseLosslessDPCM )
[313]413{
[1029]414  const ChromaFormat   format      = rTu.GetChromaFormat();
415  const ChannelType    channelType = toChannelType(compID);
416  const TComRectangle &rect        = rTu.getRect(isLuma(compID) ? COMPONENT_Y : COMPONENT_Cb);
417  const Int            iWidth      = rect.width;
418  const Int            iHeight     = rect.height;
[313]419
420  assert( g_aucConvertToBit[ iWidth ] >= 0 ); //   4x  4
421  assert( g_aucConvertToBit[ iWidth ] <= 5 ); // 128x128
[1029]422  //assert( iWidth == iHeight  );
[313]423
[1029]424        Pel *pDst = piPred;
[313]425
426  // get starting pixel in block
[1029]427  const Int sw = (2 * iWidth + 1);
[313]428
[1029]429  if ( bUseLosslessDPCM )
[313]430  {
[1029]431    const Pel *ptrSrc = getPredictorPtr( compID, false );
432    // Sample Adaptive intra-Prediction (SAP)
433    if (uiDirMode==HOR_IDX)
434    {
435      // left column filled with reference samples
436      // remaining columns filled with piOrg data (if available).
437      for(Int y=0; y<iHeight; y++)
438      {
439        piPred[y*uiStride+0] = ptrSrc[(y+1)*sw];
440      }
441      if (piOrg!=0)
442      {
443        piPred+=1; // miss off first column
444        for(Int y=0; y<iHeight; y++, piPred+=uiStride, piOrg+=uiOrgStride)
445        {
446          memcpy(piPred, piOrg, (iWidth-1)*sizeof(Pel));
447        }
448      }
449    }
450    else // VER_IDX
451    {
452      // top row filled with reference samples
453      // remaining rows filled with piOrd data (if available)
454      for(Int x=0; x<iWidth; x++)
455      {
456        piPred[x] = ptrSrc[x+1];
457      }
458      if (piOrg!=0)
459      {
460        piPred+=uiStride; // miss off the first row
461        for(Int y=1; y<iHeight; y++, piPred+=uiStride, piOrg+=uiOrgStride)
462        {
463          memcpy(piPred, piOrg, iWidth*sizeof(Pel));
464        }
465      }
466    }
[313]467  }
468  else
469  {
[1029]470    const Pel *ptrSrc = getPredictorPtr( compID, bUseFilteredPredSamples );
471
472    if ( uiDirMode == PLANAR_IDX )
[313]473    {
[1029]474      xPredIntraPlanar( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, channelType, format );
[313]475    }
476    else
477    {
[1029]478      // Create the prediction
479            TComDataCU *const pcCU              = rTu.getCU();
480      const UInt              uiAbsPartIdx      = rTu.GetAbsPartIdxTU();
481      const Bool              enableEdgeFilters = !(pcCU->isRDPCMEnabled(uiAbsPartIdx) && pcCU->getCUTransquantBypass(uiAbsPartIdx));
[313]482
[1029]483#if O0043_BEST_EFFORT_DECODING
484      xPredIntraAng( g_bitDepthInStream[channelType], ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, channelType, format, uiDirMode, bAbove, bLeft, enableEdgeFilters );
485#else
486      xPredIntraAng( g_bitDepth[channelType], ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, channelType, format, uiDirMode, bAbove, bLeft, enableEdgeFilters );
487#endif
488
489      if(( uiDirMode == DC_IDX ) && bAbove && bLeft )
[313]490      {
[1029]491        xDCPredFiltering( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, channelType );
[313]492      }
493    }
494  }
495
496}
497
[1260]498/** Check for identical motion in both motion vector direction of a bi-directional predicted CU
499  * \returns true, if motion vectors and reference pictures match
[313]500 */
501Bool TComPrediction::xCheckIdenticalMotion ( TComDataCU* pcCU, UInt PartAddr )
502{
503  if( pcCU->getSlice()->isInterB() && !pcCU->getSlice()->getPPS()->getWPBiPred() )
504  {
505    if( pcCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(PartAddr) >= 0 && pcCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(PartAddr) >= 0)
506    {
507      Int RefPOCL0 = pcCU->getSlice()->getRefPic(REF_PIC_LIST_0, pcCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(PartAddr))->getPOC();
508      Int RefPOCL1 = pcCU->getSlice()->getRefPic(REF_PIC_LIST_1, pcCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(PartAddr))->getPOC();
509      if(RefPOCL0 == RefPOCL1 && pcCU->getCUMvField(REF_PIC_LIST_0)->getMv(PartAddr) == pcCU->getCUMvField(REF_PIC_LIST_1)->getMv(PartAddr))
510      {
511        return true;
512      }
513    }
514  }
515  return false;
516}
517
518Void TComPrediction::motionCompensation ( TComDataCU* pcCU, TComYuv* pcYuvPred, RefPicList eRefPicList, Int iPartIdx )
519{
520  Int         iWidth;
521  Int         iHeight;
522  UInt        uiPartAddr;
523
524  if ( iPartIdx >= 0 )
525  {
526    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
527    if ( eRefPicList != REF_PIC_LIST_X )
528    {
529      if( pcCU->getSlice()->getPPS()->getUseWP())
530      {
531        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, true );
532      }
533      else
534      {
535        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
536      }
537      if ( pcCU->getSlice()->getPPS()->getUseWP() )
538      {
539        xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
540      }
541    }
542    else
543    {
544      if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
545      {
546        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
547      }
548      else
549      {
550        xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );
551      }
552    }
553    return;
554  }
555
[713]556  for ( iPartIdx = 0; iPartIdx < pcCU->getNumPartitions(); iPartIdx++ )
[313]557  {
558    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
559
560    if ( eRefPicList != REF_PIC_LIST_X )
561    {
562      if( pcCU->getSlice()->getPPS()->getUseWP())
563      {
564        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, true );
565      }
566      else
567      {
568        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
569      }
570      if ( pcCU->getSlice()->getPPS()->getUseWP() )
571      {
572        xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
573      }
574    }
575    else
576    {
577      if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
578      {
579        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
580      }
581      else
582      {
583        xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );
584      }
585    }
586  }
587  return;
588}
589
[1029]590Void TComPrediction::xPredInterUni ( TComDataCU* pcCU, UInt uiPartAddr, Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv* pcYuvPred, Bool bi )
[313]591{
592  Int         iRefIdx     = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );           assert (iRefIdx >= 0);
593  TComMv      cMv         = pcCU->getCUMvField( eRefPicList )->getMv( uiPartAddr );
594  pcCU->clipMv(cMv);
595
[815]596#if SVC_EXTENSION
597  if( pcCU->getLayerId() > 0 )
598  {
599    TComPic* refPic = pcCU->getSlice()->getRefPic(eRefPicList, iRefIdx);
600
601    if( refPic->isILR(pcCU->getLayerId()) )
602    {
603      // It is a requirement of bitstream conformance that when the reference picture represented by the variable refIdxLX is an inter-layer reference picture,
604      // VpsInterLayerSamplePredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture
[1057]605      assert( pcCU->getSlice()->getVPS()->isSamplePredictionType( pcCU->getLayerIdx(), refPic->getLayerIdx() ) );
[815]606
[313]607#if REF_IDX_ME_ZEROMV
[815]608      // It is a requirement of bitstream conformance that the variables mvLX[ 0 ] and mvLX[ 1 ] shall be equal to 0 if the value of refIdxLX corresponds to an inter-layer reference picture.
609      assert( cMv.getHor() == 0 && cMv.getVer() == 0 );
[313]610#endif
[815]611    }
[313]612
[815]613  }
614#endif
615
[1029]616  for (UInt ch=COMPONENT_Y; ch<pcYuvPred->getNumberValidComponents(); ch++)
[1246]617  {
[1029]618    xPredInterBlk  (ComponentID(ch),  pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, pcYuvPred, bi );
[1246]619  }
[313]620}
621
[1029]622Void TComPrediction::xPredInterBi ( TComDataCU* pcCU, UInt uiPartAddr, Int iWidth, Int iHeight, TComYuv* pcYuvPred )
[313]623{
624  TComYuv* pcMbYuv;
[1029]625  Int      iRefIdx[NUM_REF_PIC_LIST_01] = {-1, -1};
[313]626
[1029]627  for ( UInt refList = 0; refList < NUM_REF_PIC_LIST_01; refList++ )
[313]628  {
[1029]629    RefPicList eRefPicList = (refList ? REF_PIC_LIST_1 : REF_PIC_LIST_0);
630    iRefIdx[refList] = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );
[313]631
[1029]632    if ( iRefIdx[refList] < 0 )
[313]633    {
634      continue;
635    }
636
[1029]637    assert( iRefIdx[refList] < pcCU->getSlice()->getNumRefIdx(eRefPicList) );
[313]638
[1029]639    pcMbYuv = &m_acYuvPred[refList];
[313]640    if( pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiPartAddr ) >= 0 && pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiPartAddr ) >= 0 )
641    {
642      xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv, true );
643    }
644    else
645    {
[1029]646      if ( ( pcCU->getSlice()->getPPS()->getUseWP()       && pcCU->getSlice()->getSliceType() == P_SLICE ) ||
647           ( pcCU->getSlice()->getPPS()->getWPBiPred()    && pcCU->getSlice()->getSliceType() == B_SLICE ) )
[313]648      {
649        xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv, true );
650      }
651      else
652      {
653        xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv );
654      }
655    }
656  }
657
[1029]658  if ( pcCU->getSlice()->getPPS()->getWPBiPred()    && pcCU->getSlice()->getSliceType() == B_SLICE  )
[313]659  {
[1029]660    xWeightedPredictionBi( pcCU, &m_acYuvPred[REF_PIC_LIST_0], &m_acYuvPred[REF_PIC_LIST_1], iRefIdx[REF_PIC_LIST_0], iRefIdx[REF_PIC_LIST_1], uiPartAddr, iWidth, iHeight, pcYuvPred );
661  }
[313]662  else if ( pcCU->getSlice()->getPPS()->getUseWP() && pcCU->getSlice()->getSliceType() == P_SLICE )
663  {
[1029]664    xWeightedPredictionUni( pcCU, &m_acYuvPred[REF_PIC_LIST_0], uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
[313]665  }
666  else
667  {
[1029]668    xWeightedAverage( &m_acYuvPred[REF_PIC_LIST_0], &m_acYuvPred[REF_PIC_LIST_1], iRefIdx[REF_PIC_LIST_0], iRefIdx[REF_PIC_LIST_1], uiPartAddr, iWidth, iHeight, pcYuvPred );
[313]669  }
670}
671
672/**
[1029]673 * \brief Generate motion-compensated block
[313]674 *
[1260]675 * \param compID   Colour component ID
[313]676 * \param cu       Pointer to current CU
677 * \param refPic   Pointer to reference picture
678 * \param partAddr Address of block within CU
679 * \param mv       Motion vector
680 * \param width    Width of block
681 * \param height   Height of block
682 * \param dstPic   Pointer to destination picture
683 * \param bi       Flag indicating whether bipred is used
684 */
[1029]685
686
687Void TComPrediction::xPredInterBlk(const ComponentID compID, TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *dstPic, Bool bi )
[313]688{
[1029]689  Int     refStride  = refPic->getStride(compID);
690  Int     dstStride  = dstPic->getStride(compID);
691  Int shiftHor=(2+refPic->getComponentScaleX(compID));
692  Int shiftVer=(2+refPic->getComponentScaleY(compID));
[313]693
[1029]694  Int     refOffset  = (mv->getHor() >> shiftHor) + (mv->getVer() >> shiftVer) * refStride;
[313]695
[1029]696  Pel*    ref     = refPic->getAddr(compID, cu->getCtuRsAddr(), cu->getZorderIdxInCtu() + partAddr ) + refOffset;
[313]697
[1029]698  Pel*    dst = dstPic->getAddr( compID, partAddr );
[313]699
[1029]700  Int     xFrac  = mv->getHor() & ((1<<shiftHor)-1);
701  Int     yFrac  = mv->getVer() & ((1<<shiftVer)-1);
702  UInt    cxWidth  = width  >> refPic->getComponentScaleX(compID);
703  UInt    cxHeight = height >> refPic->getComponentScaleY(compID);
704
705  const ChromaFormat chFmt = cu->getPic()->getChromaFormat();
706
[313]707  if ( yFrac == 0 )
708  {
[1029]709    m_if.filterHor(compID, ref, refStride, dst,  dstStride, cxWidth, cxHeight, xFrac, !bi, chFmt);
[313]710  }
711  else if ( xFrac == 0 )
712  {
[1029]713    m_if.filterVer(compID, ref, refStride, dst, dstStride, cxWidth, cxHeight, yFrac, true, !bi, chFmt);
[313]714  }
715  else
716  {
[1029]717    Int   tmpStride = m_filteredBlockTmp[0].getStride(compID);
718    Pel*  tmp       = m_filteredBlockTmp[0].getAddr(compID);
719
720    const Int vFilterSize = isLuma(compID) ? NTAPS_LUMA : NTAPS_CHROMA;
721
722    m_if.filterHor(compID, ref - ((vFilterSize>>1) -1)*refStride, refStride, tmp, tmpStride, cxWidth, cxHeight+vFilterSize-1, xFrac, false,      chFmt);
723    m_if.filterVer(compID, tmp + ((vFilterSize>>1) -1)*tmpStride, tmpStride, dst, dstStride, cxWidth, cxHeight,               yFrac, false, !bi, chFmt);
[313]724  }
725}
726
[1029]727Void TComPrediction::xWeightedAverage( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartIdx, Int iWidth, Int iHeight, TComYuv* pcYuvDst )
[313]728{
729  if( iRefIdx0 >= 0 && iRefIdx1 >= 0 )
730  {
[1029]731    pcYuvDst->addAvg( pcYuvSrc0, pcYuvSrc1, uiPartIdx, iWidth, iHeight );
[313]732  }
733  else if ( iRefIdx0 >= 0 && iRefIdx1 <  0 )
734  {
[1029]735    pcYuvSrc0->copyPartToPartYuv( pcYuvDst, uiPartIdx, iWidth, iHeight );
[313]736  }
737  else if ( iRefIdx0 <  0 && iRefIdx1 >= 0 )
738  {
[1029]739    pcYuvSrc1->copyPartToPartYuv( pcYuvDst, uiPartIdx, iWidth, iHeight );
[313]740  }
741}
742
743// AMVP
744Void TComPrediction::getMvPredAMVP( TComDataCU* pcCU, UInt uiPartIdx, UInt uiPartAddr, RefPicList eRefPicList, TComMv& rcMvPred )
745{
746  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
[1029]747
[313]748  if( pcAMVPInfo->iN <= 1 )
749  {
750    rcMvPred = pcAMVPInfo->m_acMvCand[0];
751
752    pcCU->setMVPIdxSubParts( 0, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
753    pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
754    return;
755  }
756
757  assert(pcCU->getMVPIdx(eRefPicList,uiPartAddr) >= 0);
758  rcMvPred = pcAMVPInfo->m_acMvCand[pcCU->getMVPIdx(eRefPicList,uiPartAddr)];
759  return;
760}
761
762/** Function for deriving planar intra prediction.
[1260]763 * \param pSrc        pointer to reconstructed sample array
764 * \param srcStride   the stride of the reconstructed sample array
765 * \param rpDst       reference to pointer for the prediction sample array
766 * \param dstStride   the stride of the prediction sample array
767 * \param width       the width of the block
768 * \param height      the height of the block
769 * \param channelType type of pel array (luma, chroma)
770 * \param format      chroma format
[313]771 *
772 * This function derives the prediction samples for planar mode (intra coding).
773 */
[1029]774//NOTE: Bit-Limit - 24-bit source
775Void TComPrediction::xPredIntraPlanar( const Pel* pSrc, Int srcStride, Pel* rpDst, Int dstStride, UInt width, UInt height, ChannelType channelType, ChromaFormat format )
[313]776{
[1029]777  assert(width <= height);
[313]778
[442]779  Int leftColumn[MAX_CU_SIZE+1], topRow[MAX_CU_SIZE+1], bottomRow[MAX_CU_SIZE], rightColumn[MAX_CU_SIZE];
[1029]780  UInt shift1Dhor = g_aucConvertToBit[ width ] + 2;
781  UInt shift1Dver = g_aucConvertToBit[ height ] + 2;
[313]782
783  // Get left and above reference column and row
[1029]784  for(Int k=0;k<width+1;k++)
[313]785  {
786    topRow[k] = pSrc[k-srcStride];
[1029]787  }
788
789  for (Int k=0; k < height+1; k++)
790  {
[313]791    leftColumn[k] = pSrc[k*srcStride-1];
792  }
793
794  // Prepare intermediate variables used in interpolation
[1029]795  Int bottomLeft = leftColumn[height];
796  Int topRight   = topRow[width];
797
798  for(Int k=0;k<width;k++)
[313]799  {
[1029]800    bottomRow[k]  = bottomLeft - topRow[k];
801    topRow[k]     <<= shift1Dver;
[313]802  }
803
[1029]804  for(Int k=0;k<height;k++)
805  {
806    rightColumn[k]  = topRight - leftColumn[k];
807    leftColumn[k]   <<= shift1Dhor;
808  }
809
810  const UInt topRowShift = 0;
811
[313]812  // Generate prediction signal
[1029]813  for (Int y=0;y<height;y++)
[313]814  {
[1029]815    Int horPred = leftColumn[y] + width;
816    for (Int x=0;x<width;x++)
[313]817    {
[1029]818      horPred += rightColumn[y];
819      topRow[x] += bottomRow[x];
820
821      Int vertPred = ((topRow[x] + topRowShift)>>topRowShift);
822      rpDst[y*dstStride+x] = ( horPred + vertPred ) >> (shift1Dhor+1);
[313]823    }
824  }
825}
826
827/** Function for filtering intra DC predictor.
828 * \param pSrc pointer to reconstructed sample array
829 * \param iSrcStride the stride of the reconstructed sample array
[1260]830 * \param pDst reference to pointer for the prediction sample array
[313]831 * \param iDstStride the stride of the prediction sample array
832 * \param iWidth the width of the block
833 * \param iHeight the height of the block
[1260]834 * \param channelType type of pel array (luma, chroma)
[313]835 *
836 * This function performs filtering left and top edges of the prediction samples for DC mode (intra coding).
837 */
[1029]838Void TComPrediction::xDCPredFiltering( const Pel* pSrc, Int iSrcStride, Pel* pDst, Int iDstStride, Int iWidth, Int iHeight, ChannelType channelType )
[313]839{
840  Int x, y, iDstStride2, iSrcStride2;
841
[1029]842  if (isLuma(channelType) && (iWidth <= MAXIMUM_INTRA_FILTERED_WIDTH) && (iHeight <= MAXIMUM_INTRA_FILTERED_HEIGHT))
[313]843  {
[1029]844    //top-left
845    pDst[0] = (Pel)((pSrc[-iSrcStride] + pSrc[-1] + 2 * pDst[0] + 2) >> 2);
[313]846
[1029]847    //top row (vertical filter)
848    for ( x = 1; x < iWidth; x++ )
849    {
850      pDst[x] = (Pel)((pSrc[x - iSrcStride] +  3 * pDst[x] + 2) >> 2);
851    }
852
853    //left column (horizontal filter)
854    for ( y = 1, iDstStride2 = iDstStride, iSrcStride2 = iSrcStride-1; y < iHeight; y++, iDstStride2+=iDstStride, iSrcStride2+=iSrcStride )
855    {
856      pDst[iDstStride2] = (Pel)((pSrc[iSrcStride2] + 3 * pDst[iDstStride2] + 2) >> 2);
857    }
[313]858  }
859
860  return;
861}
862
[1029]863/* Static member function */
864Bool TComPrediction::UseDPCMForFirstPassIntraEstimation(TComTU &rTu, const UInt uiDirMode)
865{
866  return (rTu.getCU()->isRDPCMEnabled(rTu.GetAbsPartIdxTU()) ) &&
867          rTu.getCU()->getCUTransquantBypass(rTu.GetAbsPartIdxTU()) &&
868          (uiDirMode==HOR_IDX || uiDirMode==VER_IDX);
869}
870
[815]871#if SVC_EXTENSION
[944]872Void TComPrediction::upsampleBasePic( TComSlice* currSlice, UInt refLayerIdc, TComPicYuv* pcUsPic, TComPicYuv* pcBasePic, TComPicYuv* pcTempPic )
873{
874  m_cUsf.upsampleBasePic( currSlice, refLayerIdc, pcUsPic, pcBasePic, pcTempPic );
875}
[815]876#endif //SVC_EXTENSION
[313]877//! \}
Note: See TracBrowser for help on using the repository browser.