source: 3DVCSoftware/branches/HTM-16.0-MV-draft-5/source/Lib/TLibCommon/TComPrediction.cpp

Last change on this file was 1390, checked in by tech, 9 years ago

Removed 3D.

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