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

Last change on this file since 1164 was 1090, checked in by seregin, 9 years ago

cleanup macros: Q0120_PHASE_CALCULATION, P0312_VERT_PHASE_ADJ, Q0200_CONFORMANCE_BL_SIZE, R0220_REMOVE_EL_CLIP, MOVE_SCALED_OFFSET_TO_PPS, R0209_GENERIC_PHASE, REF_REGION_OFFSET, O0215_PHASE_ALIGNMENT_REMOVAL, O0215_PHASE_ALIGNMENT, RESAMPLING_FIX

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