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

Last change on this file since 467 was 467, checked in by rwth, 11 years ago

Integration of depth intra methods in macro H_3D_DIM, including:

  • Simplified Depth Coding (SDC) in H_3D_DIM_SDC
  • Depth Lookup Table (DLT) in H_3D_DIM_DLT
  • Property svn:eol-style set to native
File size: 49.7 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6 * Copyright (c) 2010-2013, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TComPrediction.cpp
35    \brief    prediction class
36*/
37
38#include <memory.h>
39#include "TComPrediction.h"
40
41//! \ingroup TLibCommon
42//! \{
43
44// ====================================================================================================================
45// Constructor / destructor / initialize
46// ====================================================================================================================
47
48TComPrediction::TComPrediction()
49: m_pLumaRecBuffer(0)
50, m_iLumaRecStride(0)
51{
52  m_piYuvExt = NULL;
53}
54
55TComPrediction::~TComPrediction()
56{
57 
58  delete[] m_piYuvExt;
59
60  m_acYuvPred[0].destroy();
61  m_acYuvPred[1].destroy();
62
63  m_cYuvPredTemp.destroy();
64
65  if( m_pLumaRecBuffer )
66  {
67    delete [] m_pLumaRecBuffer;
68  }
69 
70  Int i, j;
71  for (i = 0; i < 4; i++)
72  {
73    for (j = 0; j < 4; j++)
74    {
75      m_filteredBlock[i][j].destroy();
76    }
77    m_filteredBlockTmp[i].destroy();
78  }
79}
80
81Void TComPrediction::initTempBuff()
82{
83  if( m_piYuvExt == NULL )
84  {
85    Int extWidth  = MAX_CU_SIZE + 16; 
86    Int extHeight = MAX_CU_SIZE + 1;
87    Int i, j;
88    for (i = 0; i < 4; i++)
89    {
90      m_filteredBlockTmp[i].create(extWidth, extHeight + 7);
91      for (j = 0; j < 4; j++)
92      {
93        m_filteredBlock[i][j].create(extWidth, extHeight);
94      }
95    }
96    m_iYuvExtHeight  = ((MAX_CU_SIZE + 2) << 4);
97    m_iYuvExtStride = ((MAX_CU_SIZE  + 8) << 4);
98    m_piYuvExt = new Int[ m_iYuvExtStride * m_iYuvExtHeight ];
99
100    // new structure
101    m_acYuvPred[0] .create( MAX_CU_SIZE, MAX_CU_SIZE );
102    m_acYuvPred[1] .create( MAX_CU_SIZE, MAX_CU_SIZE );
103
104    m_cYuvPredTemp.create( MAX_CU_SIZE, MAX_CU_SIZE );
105  }
106
107  if (m_iLumaRecStride != (MAX_CU_SIZE>>1) + 1)
108  {
109    m_iLumaRecStride =  (MAX_CU_SIZE>>1) + 1;
110    if (!m_pLumaRecBuffer)
111    {
112      m_pLumaRecBuffer = new Pel[ m_iLumaRecStride * m_iLumaRecStride ];
113    }
114  }
115}
116
117// ====================================================================================================================
118// Public member functions
119// ====================================================================================================================
120
121// Function for calculating DC value of the reference samples used in Intra prediction
122Pel TComPrediction::predIntraGetPredValDC( Int* pSrc, Int iSrcStride, UInt iWidth, UInt iHeight, Bool bAbove, Bool bLeft )
123{
124  Int iInd, iSum = 0;
125  Pel pDcVal;
126
127  if (bAbove)
128  {
129    for (iInd = 0;iInd < iWidth;iInd++)
130    {
131      iSum += pSrc[iInd-iSrcStride];
132    }
133  }
134  if (bLeft)
135  {
136    for (iInd = 0;iInd < iHeight;iInd++)
137    {
138      iSum += pSrc[iInd*iSrcStride-1];
139    }
140  }
141
142  if (bAbove && bLeft)
143  {
144    pDcVal = (iSum + iWidth) / (iWidth + iHeight);
145  }
146  else if (bAbove)
147  {
148    pDcVal = (iSum + iWidth/2) / iWidth;
149  }
150  else if (bLeft)
151  {
152    pDcVal = (iSum + iHeight/2) / iHeight;
153  }
154  else
155  {
156    pDcVal = pSrc[-1]; // Default DC value already calculated and placed in the prediction array if no neighbors are available
157  }
158 
159  return pDcVal;
160}
161
162// Function for deriving the angular Intra predictions
163
164/** Function for deriving the simplified angular intra predictions.
165 * \param pSrc pointer to reconstructed sample array
166 * \param srcStride the stride of the reconstructed sample array
167 * \param rpDst reference to pointer for the prediction sample array
168 * \param dstStride the stride of the prediction sample array
169 * \param width the width of the block
170 * \param height the height of the block
171 * \param dirMode the intra prediction mode index
172 * \param blkAboveAvailable boolean indication if the block above is available
173 * \param blkLeftAvailable boolean indication if the block to the left is available
174 *
175 * This function derives the prediction samples for the angular mode based on the prediction direction indicated by
176 * the prediction mode index. The prediction direction is given by the displacement of the bottom row of the block and
177 * the reference row above the block in the case of vertical prediction or displacement of the rightmost column
178 * of the block and reference column left from the block in the case of the horizontal prediction. The displacement
179 * is signalled at 1/32 pixel accuracy. When projection of the predicted pixel falls inbetween reference samples,
180 * the predicted value for the pixel is linearly interpolated from the reference samples. All reference samples are taken
181 * from the extended main reference.
182 */
183Void TComPrediction::xPredIntraAng(Int bitDepth, Int* pSrc, Int srcStride, Pel*& rpDst, Int dstStride, UInt width, UInt height, UInt dirMode, Bool blkAboveAvailable, Bool blkLeftAvailable, Bool bFilter )
184{
185  Int k,l;
186  Int blkSize        = width;
187  Pel* pDst          = rpDst;
188
189  // Map the mode index to main prediction direction and angle
190  assert( dirMode > 0 ); //no planar
191  Bool modeDC        = dirMode < 2;
192  Bool modeHor       = !modeDC && (dirMode < 18);
193  Bool modeVer       = !modeDC && !modeHor;
194  Int intraPredAngle = modeVer ? (Int)dirMode - VER_IDX : modeHor ? -((Int)dirMode - HOR_IDX) : 0;
195  Int absAng         = abs(intraPredAngle);
196  Int signAng        = intraPredAngle < 0 ? -1 : 1;
197
198  // Set bitshifts and scale the angle parameter to block size
199  Int angTable[9]    = {0,    2,    5,   9,  13,  17,  21,  26,  32};
200  Int invAngTable[9] = {0, 4096, 1638, 910, 630, 482, 390, 315, 256}; // (256 * 32) / Angle
201  Int invAngle       = invAngTable[absAng];
202  absAng             = angTable[absAng];
203  intraPredAngle     = signAng * absAng;
204
205  // Do the DC prediction
206  if (modeDC)
207  {
208    Pel dcval = predIntraGetPredValDC(pSrc, srcStride, width, height, blkAboveAvailable, blkLeftAvailable);
209
210    for (k=0;k<blkSize;k++)
211    {
212      for (l=0;l<blkSize;l++)
213      {
214        pDst[k*dstStride+l] = dcval;
215      }
216    }
217  }
218
219  // Do angular predictions
220  else
221  {
222    Pel* refMain;
223    Pel* refSide;
224    Pel  refAbove[2*MAX_CU_SIZE+1];
225    Pel  refLeft[2*MAX_CU_SIZE+1];
226
227    // Initialise the Main and Left reference array.
228    if (intraPredAngle < 0)
229    {
230      for (k=0;k<blkSize+1;k++)
231      {
232        refAbove[k+blkSize-1] = pSrc[k-srcStride-1];
233      }
234      for (k=0;k<blkSize+1;k++)
235      {
236        refLeft[k+blkSize-1] = pSrc[(k-1)*srcStride-1];
237      }
238      refMain = (modeVer ? refAbove : refLeft) + (blkSize-1);
239      refSide = (modeVer ? refLeft : refAbove) + (blkSize-1);
240
241      // Extend the Main reference to the left.
242      Int invAngleSum    = 128;       // rounding for (shift by 8)
243      for (k=-1; k>blkSize*intraPredAngle>>5; k--)
244      {
245        invAngleSum += invAngle;
246        refMain[k] = refSide[invAngleSum>>8];
247      }
248    }
249    else
250    {
251      for (k=0;k<2*blkSize+1;k++)
252      {
253        refAbove[k] = pSrc[k-srcStride-1];
254      }
255      for (k=0;k<2*blkSize+1;k++)
256      {
257        refLeft[k] = pSrc[(k-1)*srcStride-1];
258      }
259      refMain = modeVer ? refAbove : refLeft;
260      refSide = modeVer ? refLeft  : refAbove;
261    }
262
263    if (intraPredAngle == 0)
264    {
265      for (k=0;k<blkSize;k++)
266      {
267        for (l=0;l<blkSize;l++)
268        {
269          pDst[k*dstStride+l] = refMain[l+1];
270        }
271      }
272
273      if ( bFilter )
274      {
275        for (k=0;k<blkSize;k++)
276        {
277          pDst[k*dstStride] = Clip3(0, (1<<bitDepth)-1, pDst[k*dstStride] + (( refSide[k+1] - refSide[0] ) >> 1) );
278        }
279      }
280    }
281    else
282    {
283      Int deltaPos=0;
284      Int deltaInt;
285      Int deltaFract;
286      Int refMainIndex;
287
288      for (k=0;k<blkSize;k++)
289      {
290        deltaPos += intraPredAngle;
291        deltaInt   = deltaPos >> 5;
292        deltaFract = deltaPos & (32 - 1);
293
294        if (deltaFract)
295        {
296          // Do linear filtering
297          for (l=0;l<blkSize;l++)
298          {
299            refMainIndex        = l+deltaInt+1;
300            pDst[k*dstStride+l] = (Pel) ( ((32-deltaFract)*refMain[refMainIndex]+deltaFract*refMain[refMainIndex+1]+16) >> 5 );
301          }
302        }
303        else
304        {
305          // Just copy the integer samples
306          for (l=0;l<blkSize;l++)
307          {
308            pDst[k*dstStride+l] = refMain[l+deltaInt+1];
309          }
310        }
311      }
312    }
313
314    // Flip the block if this is the horizontal mode
315    if (modeHor)
316    {
317      Pel  tmp;
318      for (k=0;k<blkSize-1;k++)
319      {
320        for (l=k+1;l<blkSize;l++)
321        {
322          tmp                 = pDst[k*dstStride+l];
323          pDst[k*dstStride+l] = pDst[l*dstStride+k];
324          pDst[l*dstStride+k] = tmp;
325        }
326      }
327    }
328  }
329}
330
331Void TComPrediction::predIntraLumaAng(TComPattern* pcTComPattern, UInt uiDirMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, Bool bAbove, Bool bLeft )
332{
333  Pel *pDst = piPred;
334  Int *ptrSrc;
335
336  assert( g_aucConvertToBit[ iWidth ] >= 0 ); //   4x  4
337  assert( g_aucConvertToBit[ iWidth ] <= 5 ); // 128x128
338  assert( iWidth == iHeight  );
339
340  ptrSrc = pcTComPattern->getPredictorPtr( uiDirMode, g_aucConvertToBit[ iWidth ] + 2, m_piYuvExt );
341
342  // get starting pixel in block
343  Int sw = 2 * iWidth + 1;
344
345  // Create the prediction
346  if ( uiDirMode == PLANAR_IDX )
347  {
348    xPredIntraPlanar( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight );
349  }
350  else
351  {
352    if ( (iWidth > 16) || (iHeight > 16) )
353    {
354      xPredIntraAng(g_bitDepthY, ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode, bAbove, bLeft, false );
355    }
356    else
357    {
358      xPredIntraAng(g_bitDepthY, ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode, bAbove, bLeft, true );
359
360      if( (uiDirMode == DC_IDX ) && bAbove && bLeft )
361      {
362        xDCPredFiltering( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight);
363      }
364    }
365  }
366}
367
368// Angular chroma
369Void TComPrediction::predIntraChromaAng( Int* piSrc, UInt uiDirMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, Bool bAbove, Bool bLeft )
370{
371  Pel *pDst = piPred;
372  Int *ptrSrc = piSrc;
373
374  // get starting pixel in block
375  Int sw = 2 * iWidth + 1;
376
377  if ( uiDirMode == PLANAR_IDX )
378  {
379    xPredIntraPlanar( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight );
380  }
381  else
382  {
383    // Create the prediction
384    xPredIntraAng(g_bitDepthC, ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode, bAbove, bLeft, false );
385  }
386}
387
388#if H_3D_DIM
389Void TComPrediction::predIntraLumaDepth( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiIntraMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, Bool bFastEnc )
390{
391  assert( iWidth == iHeight  );
392  assert( iWidth >= DIM_MIN_SIZE && iWidth <= DIM_MAX_SIZE );
393  assert( isDimMode( uiIntraMode ) );
394
395  UInt dimType    = getDimType  ( uiIntraMode );
396  Bool dimDeltaDC = isDimDeltaDC( uiIntraMode );   
397  Bool isDmmMode  = (dimType <  DMM_NUM_TYPE);
398  Bool isRbcMode  = (dimType == RBC_IDX);
399
400  Bool* biSegPattern  = NULL;
401  UInt  patternStride = 0;
402
403  // get partiton
404#if H_3D_DIM_DMM
405  TComWedgelet* dmmSegmentation = NULL;
406  if( isDmmMode )
407  {
408    switch( dimType )
409    {
410    case( DMM1_IDX ): 
411      {
412        dmmSegmentation = &(g_dmmWedgeLists[ g_aucConvertToBit[iWidth] ][ pcCU->getDmmWedgeTabIdx( dimType, uiAbsPartIdx ) ]);
413      } break;
414    case( DMM2_IDX ):
415      {
416        UInt uiTabIdx = 0;
417        if( bFastEnc ) { uiTabIdx = pcCU->getDmmWedgeTabIdx( dimType, uiAbsPartIdx ); }
418        else
419        {
420          uiTabIdx = xPredWedgeFromIntra( pcCU, uiAbsPartIdx, iWidth, iHeight, pcCU->getDmm2DeltaEnd( uiAbsPartIdx ) );
421          pcCU->setDmmWedgeTabIdxSubParts( uiTabIdx, dimType, uiAbsPartIdx, (pcCU->getDepth(0) + (pcCU->getPartitionSize(0) == SIZE_2Nx2N ? 0 : 1)) );
422        }
423        dmmSegmentation = &(g_dmmWedgeLists[ g_aucConvertToBit[iWidth] ][ uiTabIdx ]);
424      } break;
425    case( DMM3_IDX ): 
426      {
427        UInt uiTabIdx = 0;
428        if( bFastEnc ) { uiTabIdx = pcCU->getDmmWedgeTabIdx( dimType, uiAbsPartIdx ); }
429        else
430        {
431          uiTabIdx = xPredWedgeFromTex( pcCU, uiAbsPartIdx, iWidth, iHeight, pcCU->getDmm3IntraTabIdx( uiAbsPartIdx ) );
432          pcCU->setDmmWedgeTabIdxSubParts( uiTabIdx, dimType, uiAbsPartIdx, (pcCU->getDepth(0) + (pcCU->getPartitionSize(0) == SIZE_2Nx2N ? 0 : 1)) );
433        }
434        dmmSegmentation = &(g_dmmWedgeLists[ g_aucConvertToBit[iWidth] ][ uiTabIdx ]);
435      } break;
436    case( DMM4_IDX ): 
437      {
438        dmmSegmentation = new TComWedgelet( iWidth, iHeight );
439        xPredContourFromTex( pcCU, uiAbsPartIdx, iWidth, iHeight, dmmSegmentation );
440      } break;
441    default: assert(0);
442    }
443    assert( dmmSegmentation );
444    biSegPattern  = dmmSegmentation->getPattern();
445    patternStride = dmmSegmentation->getStride ();
446  }
447#endif
448#if H_3D_DIM_RBC
449  if( isRbcMode )
450  {
451    biSegPattern  = pcCU->getEdgePartition( uiAbsPartIdx );
452    patternStride = iWidth;
453  }
454#endif
455
456  // get predicted partition values
457  assert( biSegPattern );
458  Int* piMask = NULL;
459  if( isDmmMode ) piMask = pcCU->getPattern()->getAdiOrgBuf( iWidth, iHeight, m_piYuvExt ); // no filtering for DMM
460  else            piMask = pcCU->getPattern()->getPredictorPtr( 0, g_aucConvertToBit[ iWidth ] + 2, m_piYuvExt );
461  assert( piMask );
462  Int maskStride = 2*iWidth + 1; 
463  Int* ptrSrc = piMask+maskStride+1;
464  Pel predDC1 = 0; Pel predDC2 = 0;
465  xPredBiSegDCs( ptrSrc, maskStride, biSegPattern, patternStride, predDC1, predDC2 );
466
467  // set segment values with deltaDC offsets
468  Pel segDC1 = 0;
469  Pel segDC2 = 0;
470  if( dimDeltaDC )
471  {
472    Pel deltaDC1 = pcCU->getDimDeltaDC( dimType, 0, uiAbsPartIdx );
473    Pel deltaDC2 = pcCU->getDimDeltaDC( dimType, 1, uiAbsPartIdx );
474#if H_3D_DIM_DMM
475    if( isDmmMode )
476    {
477#if H_3D_DIM_DLT
478      segDC1 = pcCU->getSlice()->getVPS()->idx2DepthValue( pcCU->getSlice()->getLayerIdInVps(), pcCU->getSlice()->getVPS()->depthValue2idx( pcCU->getSlice()->getLayerIdInVps(), predDC1 ) + deltaDC1 );
479      segDC2 = pcCU->getSlice()->getVPS()->idx2DepthValue( pcCU->getSlice()->getLayerIdInVps(), pcCU->getSlice()->getVPS()->depthValue2idx( pcCU->getSlice()->getLayerIdInVps(), predDC2 ) + deltaDC2 );
480#else
481      segDC1 = ClipY( predDC1 + deltaDC1 );
482      segDC2 = ClipY( predDC2 + deltaDC2 );
483#endif
484    }
485#endif
486#if H_3D_DIM_RBC
487    if( isRbcMode )
488    {
489      xDeltaDCQuantScaleUp( pcCU, deltaDC1 );
490      xDeltaDCQuantScaleUp( pcCU, deltaDC2 );
491      segDC1 = ClipY( predDC1 + deltaDC1 );
492      segDC2 = ClipY( predDC2 + deltaDC2 );
493    }
494#endif
495  }
496  else
497  {
498    segDC1 = predDC1;
499    segDC2 = predDC2;
500  }
501
502  // set prediction signal
503  Pel* pDst = piPred;
504  xAssignBiSegDCs( pDst, uiStride, biSegPattern, patternStride, segDC1, segDC2 );
505
506#if H_3D_DIM_DMM
507  if( dimType == DMM4_IDX ) { dmmSegmentation->destroy(); delete dmmSegmentation; }
508#endif
509}
510#endif
511
512/** Function for checking identical motion.
513 * \param TComDataCU* pcCU
514 * \param UInt PartAddr
515 */
516Bool TComPrediction::xCheckIdenticalMotion ( TComDataCU* pcCU, UInt PartAddr )
517{
518  if( pcCU->getSlice()->isInterB() && !pcCU->getSlice()->getPPS()->getWPBiPred() )
519  {
520    if( pcCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(PartAddr) >= 0 && pcCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(PartAddr) >= 0)
521    {
522      Int RefPOCL0 = pcCU->getSlice()->getRefPic(REF_PIC_LIST_0, pcCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(PartAddr))->getPOC();
523      Int RefPOCL1 = pcCU->getSlice()->getRefPic(REF_PIC_LIST_1, pcCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(PartAddr))->getPOC();
524      if(RefPOCL0 == RefPOCL1 && pcCU->getCUMvField(REF_PIC_LIST_0)->getMv(PartAddr) == pcCU->getCUMvField(REF_PIC_LIST_1)->getMv(PartAddr))
525      {
526        return true;
527      }
528    }
529  }
530  return false;
531}
532
533
534Void TComPrediction::motionCompensation ( TComDataCU* pcCU, TComYuv* pcYuvPred, RefPicList eRefPicList, Int iPartIdx )
535{
536  Int         iWidth;
537  Int         iHeight;
538  UInt        uiPartAddr;
539
540  if ( iPartIdx >= 0 )
541  {
542    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
543    if ( eRefPicList != REF_PIC_LIST_X )
544    {
545      if( pcCU->getSlice()->getPPS()->getUseWP())
546      {
547        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, true );
548      }
549      else
550      {
551        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
552      }
553      if ( pcCU->getSlice()->getPPS()->getUseWP() )
554      {
555        xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
556      }
557    }
558    else
559    {
560      if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
561      {
562        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
563      }
564      else
565      {
566        xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );
567      }
568    }
569    return;
570  }
571
572  for ( iPartIdx = 0; iPartIdx < pcCU->getNumPartInter(); iPartIdx++ )
573  {
574    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
575
576    if ( eRefPicList != REF_PIC_LIST_X )
577    {
578      if( pcCU->getSlice()->getPPS()->getUseWP())
579      {
580        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, true );
581      }
582      else
583      {
584        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
585      }
586      if ( pcCU->getSlice()->getPPS()->getUseWP() )
587      {
588        xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
589      }
590    }
591    else
592    {
593      if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
594      {
595        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
596      }
597      else
598      {
599        xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );
600      }
601    }
602  }
603  return;
604}
605
606Void TComPrediction::xPredInterUni ( TComDataCU* pcCU, UInt uiPartAddr, Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Bool bi )
607{
608  Int         iRefIdx     = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );           assert (iRefIdx >= 0);
609  TComMv      cMv         = pcCU->getCUMvField( eRefPicList )->getMv( uiPartAddr );
610  pcCU->clipMv(cMv);
611  xPredInterLumaBlk  ( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi );
612  xPredInterChromaBlk( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi );
613}
614
615Void TComPrediction::xPredInterBi ( TComDataCU* pcCU, UInt uiPartAddr, Int iWidth, Int iHeight, TComYuv*& rpcYuvPred )
616{
617  TComYuv* pcMbYuv;
618  Int      iRefIdx[2] = {-1, -1};
619
620  for ( Int iRefList = 0; iRefList < 2; iRefList++ )
621  {
622    RefPicList eRefPicList = (iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0);
623    iRefIdx[iRefList] = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );
624
625    if ( iRefIdx[iRefList] < 0 )
626    {
627      continue;
628    }
629
630    assert( iRefIdx[iRefList] < pcCU->getSlice()->getNumRefIdx(eRefPicList) );
631
632    pcMbYuv = &m_acYuvPred[iRefList];
633    if( pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiPartAddr ) >= 0 && pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiPartAddr ) >= 0 )
634    {
635      xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv, true );
636    }
637    else
638    {
639      if ( ( pcCU->getSlice()->getPPS()->getUseWP()       && pcCU->getSlice()->getSliceType() == P_SLICE ) || 
640           ( pcCU->getSlice()->getPPS()->getWPBiPred() && pcCU->getSlice()->getSliceType() == B_SLICE ) )
641      {
642        xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv, true );
643      }
644      else
645      {
646        xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv );
647      }
648    }
649  }
650
651  if ( pcCU->getSlice()->getPPS()->getWPBiPred() && pcCU->getSlice()->getSliceType() == B_SLICE  )
652  {
653    xWeightedPredictionBi( pcCU, &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred );
654  } 
655  else if ( pcCU->getSlice()->getPPS()->getUseWP() && pcCU->getSlice()->getSliceType() == P_SLICE )
656  {
657    xWeightedPredictionUni( pcCU, &m_acYuvPred[0], uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, rpcYuvPred ); 
658  }
659  else
660  {
661    xWeightedAverage( &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred );
662  }
663}
664
665/**
666 * \brief Generate motion-compensated luma block
667 *
668 * \param cu       Pointer to current CU
669 * \param refPic   Pointer to reference picture
670 * \param partAddr Address of block within CU
671 * \param mv       Motion vector
672 * \param width    Width of block
673 * \param height   Height of block
674 * \param dstPic   Pointer to destination picture
675 * \param bi       Flag indicating whether bipred is used
676 */
677Void TComPrediction::xPredInterLumaBlk( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi )
678{
679  Int refStride = refPic->getStride(); 
680  Int refOffset = ( mv->getHor() >> 2 ) + ( mv->getVer() >> 2 ) * refStride;
681  Pel *ref      = refPic->getLumaAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
682 
683  Int dstStride = dstPic->getStride();
684  Pel *dst      = dstPic->getLumaAddr( partAddr );
685 
686  Int xFrac = mv->getHor() & 0x3;
687  Int yFrac = mv->getVer() & 0x3;
688
689  if ( yFrac == 0 )
690  {
691    m_if.filterHorLuma( ref, refStride, dst, dstStride, width, height, xFrac,       !bi );
692  }
693  else if ( xFrac == 0 )
694  {
695    m_if.filterVerLuma( ref, refStride, dst, dstStride, width, height, yFrac, true, !bi );
696  }
697  else
698  {
699    Int tmpStride = m_filteredBlockTmp[0].getStride();
700    Short *tmp    = m_filteredBlockTmp[0].getLumaAddr();
701
702    Int filterSize = NTAPS_LUMA;
703    Int halfFilterSize = ( filterSize >> 1 );
704
705    m_if.filterHorLuma(ref - (halfFilterSize-1)*refStride, refStride, tmp, tmpStride, width, height+filterSize-1, xFrac, false     );
706    m_if.filterVerLuma(tmp + (halfFilterSize-1)*tmpStride, tmpStride, dst, dstStride, width, height,              yFrac, false, !bi);   
707  }
708}
709
710/**
711 * \brief Generate motion-compensated chroma block
712 *
713 * \param cu       Pointer to current CU
714 * \param refPic   Pointer to reference picture
715 * \param partAddr Address of block within CU
716 * \param mv       Motion vector
717 * \param width    Width of block
718 * \param height   Height of block
719 * \param dstPic   Pointer to destination picture
720 * \param bi       Flag indicating whether bipred is used
721 */
722Void TComPrediction::xPredInterChromaBlk( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi )
723{
724  Int     refStride  = refPic->getCStride();
725  Int     dstStride  = dstPic->getCStride();
726 
727  Int     refOffset  = (mv->getHor() >> 3) + (mv->getVer() >> 3) * refStride;
728 
729  Pel*    refCb     = refPic->getCbAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
730  Pel*    refCr     = refPic->getCrAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
731 
732  Pel* dstCb = dstPic->getCbAddr( partAddr );
733  Pel* dstCr = dstPic->getCrAddr( partAddr );
734 
735  Int     xFrac  = mv->getHor() & 0x7;
736  Int     yFrac  = mv->getVer() & 0x7;
737  UInt    cxWidth  = width  >> 1;
738  UInt    cxHeight = height >> 1;
739 
740  Int     extStride = m_filteredBlockTmp[0].getStride();
741  Short*  extY      = m_filteredBlockTmp[0].getLumaAddr();
742 
743  Int filterSize = NTAPS_CHROMA;
744 
745  Int halfFilterSize = (filterSize>>1);
746 
747  if ( yFrac == 0 )
748  {
749    m_if.filterHorChroma(refCb, refStride, dstCb,  dstStride, cxWidth, cxHeight, xFrac, !bi);   
750    m_if.filterHorChroma(refCr, refStride, dstCr,  dstStride, cxWidth, cxHeight, xFrac, !bi);   
751  }
752  else if ( xFrac == 0 )
753  {
754    m_if.filterVerChroma(refCb, refStride, dstCb, dstStride, cxWidth, cxHeight, yFrac, true, !bi);   
755    m_if.filterVerChroma(refCr, refStride, dstCr, dstStride, cxWidth, cxHeight, yFrac, true, !bi);   
756  }
757  else
758  {
759    m_if.filterHorChroma(refCb - (halfFilterSize-1)*refStride, refStride, extY,  extStride, cxWidth, cxHeight+filterSize-1, xFrac, false);
760    m_if.filterVerChroma(extY  + (halfFilterSize-1)*extStride, extStride, dstCb, dstStride, cxWidth, cxHeight  , yFrac, false, !bi);
761   
762    m_if.filterHorChroma(refCr - (halfFilterSize-1)*refStride, refStride, extY,  extStride, cxWidth, cxHeight+filterSize-1, xFrac, false);
763    m_if.filterVerChroma(extY  + (halfFilterSize-1)*extStride, extStride, dstCr, dstStride, cxWidth, cxHeight  , yFrac, false, !bi);   
764  }
765}
766
767Void TComPrediction::xWeightedAverage( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartIdx, Int iWidth, Int iHeight, TComYuv*& rpcYuvDst )
768{
769  if( iRefIdx0 >= 0 && iRefIdx1 >= 0 )
770  {
771    rpcYuvDst->addAvg( pcYuvSrc0, pcYuvSrc1, uiPartIdx, iWidth, iHeight );
772  }
773  else if ( iRefIdx0 >= 0 && iRefIdx1 <  0 )
774  {
775    pcYuvSrc0->copyPartToPartYuv( rpcYuvDst, uiPartIdx, iWidth, iHeight );
776  }
777  else if ( iRefIdx0 <  0 && iRefIdx1 >= 0 )
778  {
779    pcYuvSrc1->copyPartToPartYuv( rpcYuvDst, uiPartIdx, iWidth, iHeight );
780  }
781}
782
783// AMVP
784Void TComPrediction::getMvPredAMVP( TComDataCU* pcCU, UInt uiPartIdx, UInt uiPartAddr, RefPicList eRefPicList, TComMv& rcMvPred )
785{
786  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
787  if( pcAMVPInfo->iN <= 1 )
788  {
789    rcMvPred = pcAMVPInfo->m_acMvCand[0];
790
791    pcCU->setMVPIdxSubParts( 0, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
792    pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
793    return;
794  }
795
796  assert(pcCU->getMVPIdx(eRefPicList,uiPartAddr) >= 0);
797  rcMvPred = pcAMVPInfo->m_acMvCand[pcCU->getMVPIdx(eRefPicList,uiPartAddr)];
798  return;
799}
800
801/** Function for deriving planar intra prediction.
802 * \param pSrc pointer to reconstructed sample array
803 * \param srcStride the stride of the reconstructed sample array
804 * \param rpDst reference to pointer for the prediction sample array
805 * \param dstStride the stride of the prediction sample array
806 * \param width the width of the block
807 * \param height the height of the block
808 *
809 * This function derives the prediction samples for planar mode (intra coding).
810 */
811Void TComPrediction::xPredIntraPlanar( Int* pSrc, Int srcStride, Pel* rpDst, Int dstStride, UInt width, UInt height )
812{
813  assert(width == height);
814
815  Int k, l, bottomLeft, topRight;
816  Int horPred;
817  Int leftColumn[MAX_CU_SIZE], topRow[MAX_CU_SIZE], bottomRow[MAX_CU_SIZE], rightColumn[MAX_CU_SIZE];
818  UInt blkSize = width;
819  UInt offset2D = width;
820  UInt shift1D = g_aucConvertToBit[ width ] + 2;
821  UInt shift2D = shift1D + 1;
822
823  // Get left and above reference column and row
824  for(k=0;k<blkSize+1;k++)
825  {
826    topRow[k] = pSrc[k-srcStride];
827    leftColumn[k] = pSrc[k*srcStride-1];
828  }
829
830  // Prepare intermediate variables used in interpolation
831  bottomLeft = leftColumn[blkSize];
832  topRight   = topRow[blkSize];
833  for (k=0;k<blkSize;k++)
834  {
835    bottomRow[k]   = bottomLeft - topRow[k];
836    rightColumn[k] = topRight   - leftColumn[k];
837    topRow[k]      <<= shift1D;
838    leftColumn[k]  <<= shift1D;
839  }
840
841  // Generate prediction signal
842  for (k=0;k<blkSize;k++)
843  {
844    horPred = leftColumn[k] + offset2D;
845    for (l=0;l<blkSize;l++)
846    {
847      horPred += rightColumn[k];
848      topRow[l] += bottomRow[l];
849      rpDst[k*dstStride+l] = ( (horPred + topRow[l]) >> shift2D );
850    }
851  }
852}
853
854/** Function for filtering intra DC predictor.
855 * \param pSrc pointer to reconstructed sample array
856 * \param iSrcStride the stride of the reconstructed sample array
857 * \param rpDst reference to pointer for the prediction sample array
858 * \param iDstStride the stride of the prediction sample array
859 * \param iWidth the width of the block
860 * \param iHeight the height of the block
861 *
862 * This function performs filtering left and top edges of the prediction samples for DC mode (intra coding).
863 */
864Void TComPrediction::xDCPredFiltering( Int* pSrc, Int iSrcStride, Pel*& rpDst, Int iDstStride, Int iWidth, Int iHeight )
865{
866  Pel* pDst = rpDst;
867  Int x, y, iDstStride2, iSrcStride2;
868
869  // boundary pixels processing
870  pDst[0] = (Pel)((pSrc[-iSrcStride] + pSrc[-1] + 2 * pDst[0] + 2) >> 2);
871
872  for ( x = 1; x < iWidth; x++ )
873  {
874    pDst[x] = (Pel)((pSrc[x - iSrcStride] +  3 * pDst[x] + 2) >> 2);
875  }
876
877  for ( y = 1, iDstStride2 = iDstStride, iSrcStride2 = iSrcStride-1; y < iHeight; y++, iDstStride2+=iDstStride, iSrcStride2+=iSrcStride )
878  {
879    pDst[iDstStride2] = (Pel)((pSrc[iSrcStride2] + 3 * pDst[iDstStride2] + 2) >> 2);
880  }
881
882  return;
883}
884
885#if H_3D_DIM
886Void TComPrediction::xPredBiSegDCs( Int* ptrSrc, UInt srcStride, Bool* biSegPattern, Int patternStride, Pel& predDC1, Pel& predDC2 )
887{
888  Int  refDC1, refDC2;
889  const Int  iTR = (   patternStride - 1        ) - srcStride;
890  const Int  iTM = ( ( patternStride - 1 ) >> 1 ) - srcStride;
891  const Int  iLB = (   patternStride - 1        ) * srcStride - 1;
892  const Int  iLM = ( ( patternStride - 1 ) >> 1 ) * srcStride - 1;
893
894  Bool bL = ( biSegPattern[0] != biSegPattern[(patternStride-1)*patternStride] );
895  Bool bT = ( biSegPattern[0] != biSegPattern[(patternStride-1)]               );
896
897  if( bL == bT )
898  {
899    refDC1 = bL ? ( ptrSrc[iTR] + ptrSrc[iLB] )>>1 : 1<<( g_bitDepthY - 1 );
900    refDC2 =      ( ptrSrc[ -1] + ptrSrc[-(Int)srcStride] )>>1;
901  }
902  else
903  {
904    refDC1 = bL ? ptrSrc[iLB] : ptrSrc[iTR];
905    refDC2 = bL ? ptrSrc[iTM] : ptrSrc[iLM];
906  }
907
908  predDC1 = biSegPattern[0] ? refDC1 : refDC2;
909  predDC2 = biSegPattern[0] ? refDC2 : refDC1;
910}
911
912Void TComPrediction::xAssignBiSegDCs( Pel* ptrDst, UInt dstStride, Bool* biSegPattern, Int patternStride, Pel valDC1, Pel valDC2 )
913{
914  if( dstStride == patternStride )
915  {
916    for( UInt k = 0; k < (patternStride * patternStride); k++ )
917    {
918      if( true == biSegPattern[k] ) { ptrDst[k] = valDC2; }
919      else                          { ptrDst[k] = valDC1; }
920    }
921  }
922  else
923  {
924    Pel* piTemp = ptrDst;
925    for( UInt uiY = 0; uiY < patternStride; uiY++ )
926    {
927      for( UInt uiX = 0; uiX < patternStride; uiX++ )
928      {
929        if( true == biSegPattern[uiX] ) { piTemp[uiX] = valDC2; }
930        else                            { piTemp[uiX] = valDC1; }
931      }
932      piTemp       += dstStride;
933      biSegPattern += patternStride;
934    }
935  }
936}
937
938#if H_3D_DIM_DMM
939UInt TComPrediction::xPredWedgeFromIntra( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, Int iDeltaEnd )
940{
941  UInt uiThisBlockSize = uiWidth;
942
943  TComDataCU* pcTempCU;
944  UInt        uiTempPartIdx;
945  // 1st: try continue above wedgelet
946  pcTempCU = pcCU->getPUAbove( uiTempPartIdx, pcCU->getZorderIdxInCU() + uiAbsPartIdx );
947  if( pcTempCU && isDimMode( pcTempCU->getLumaIntraDir( uiTempPartIdx ) ) )
948  {
949    UInt dimType =  getDimType( pcTempCU->getLumaIntraDir( uiTempPartIdx ) );
950    if( DMM1_IDX == dimType || DMM2_IDX == dimType || DMM3_IDX == dimType )
951    {
952      // get offset between current and reference block
953      UInt uiOffsetX = 0, uiOffsetY = 0;
954      xGetBlockOffset( pcCU, uiAbsPartIdx, pcTempCU, uiTempPartIdx, uiOffsetX, uiOffsetY );
955
956      // get reference wedgelet
957      WedgeList* pacWedgeList = &g_dmmWedgeLists[(g_aucConvertToBit[(pcTempCU->getWidth( uiTempPartIdx )>>((pcTempCU->getPartitionSize( uiTempPartIdx ) == SIZE_NxN) ? 1 : 0))])];
958      TComWedgelet* pcRefWedgelet = &(pacWedgeList->at( pcTempCU->getDmmWedgeTabIdx( dimType, uiTempPartIdx ) ) );
959
960      // find wedgelet, if direction is suitable for continue wedge
961      if( pcRefWedgelet->checkPredDirAbovePossible( uiThisBlockSize, uiOffsetX ) )
962      {
963        UChar uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye;
964        pcRefWedgelet->getPredDirStartEndAbove( uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye, uiThisBlockSize, uiOffsetX, iDeltaEnd );
965        return xGetWedgePatternIdx( uiThisBlockSize, uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye );
966      }
967    }
968  }
969
970  // 2nd: try continue left wedglelet
971  pcTempCU = pcCU->getPULeft( uiTempPartIdx, pcCU->getZorderIdxInCU() + uiAbsPartIdx );
972  if( pcTempCU && isDimMode( pcTempCU->getLumaIntraDir( uiTempPartIdx ) ) )
973  {
974    UInt dimType = getDimType( pcTempCU->getLumaIntraDir( uiTempPartIdx ) );
975    if( DMM1_IDX == dimType || DMM2_IDX == dimType || DMM3_IDX == dimType )
976    {
977      // get offset between current and reference block
978      UInt uiOffsetX = 0, uiOffsetY = 0;
979      xGetBlockOffset( pcCU, uiAbsPartIdx, pcTempCU, uiTempPartIdx, uiOffsetX, uiOffsetY );
980
981      // get reference wedgelet
982      WedgeList* pacWedgeList = &g_dmmWedgeLists[(g_aucConvertToBit[(pcTempCU->getWidth( uiTempPartIdx )>>((pcTempCU->getPartitionSize( uiTempPartIdx ) == SIZE_NxN) ? 1 : 0))])];
983      TComWedgelet* pcRefWedgelet = &(pacWedgeList->at( pcTempCU->getDmmWedgeTabIdx( dimType, uiTempPartIdx ) ) );
984
985      // find wedgelet, if direction is suitable for continue wedge
986      if( pcRefWedgelet->checkPredDirLeftPossible( uiThisBlockSize, uiOffsetY ) )
987      {
988        UChar uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye;
989        pcRefWedgelet->getPredDirStartEndLeft( uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye, uiThisBlockSize, uiOffsetY, iDeltaEnd );
990        return xGetWedgePatternIdx( uiThisBlockSize, uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye );
991      }
992    }
993  }
994
995  // 3rd: (default) make wedglet from intra dir and max slope point
996  Int iSlopeX = 0, iSlopeY = 0;
997  UInt uiStartPosX = 0, uiStartPosY = 0;
998  if( xGetWedgeIntraDirPredData( pcCU, uiAbsPartIdx, uiThisBlockSize, iSlopeX, iSlopeY, uiStartPosX, uiStartPosY ) )
999  {
1000    UChar uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye;
1001    xGetWedgeIntraDirStartEnd( pcCU, uiAbsPartIdx, uiThisBlockSize, iSlopeX, iSlopeY, uiStartPosX, uiStartPosY, uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye, iDeltaEnd );
1002    return xGetWedgePatternIdx( uiThisBlockSize, uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye );
1003  }
1004
1005  return 0;
1006}
1007
1008UInt TComPrediction::xPredWedgeFromTex( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, UInt intraTabIdx )
1009{
1010  TComPic*      pcPicTex = pcCU->getSlice()->getPicLists()->getPic( pcCU->getSlice()->getViewIndex(), false, pcCU->getSlice()->getPOC() );
1011  assert( pcPicTex != NULL );
1012  TComDataCU*   pcColTexCU = pcPicTex->getCU(pcCU->getAddr());
1013  UInt          uiTexPartIdx = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
1014  Int           uiColTexIntraDir = pcColTexCU->isIntra( uiTexPartIdx ) ? pcColTexCU->getLumaIntraDir( uiTexPartIdx ) : 255;
1015
1016  if( uiColTexIntraDir > DC_IDX && uiColTexIntraDir < 35 ) { return g_aauiWdgLstM3[g_aucConvertToBit[uiWidth]][uiColTexIntraDir-2].at(intraTabIdx); }
1017  else                                                     { return g_dmmWedgeNodeLists[(g_aucConvertToBit[uiWidth])].at(intraTabIdx).getPatternIdx(); }
1018}
1019
1020Void TComPrediction::xPredContourFromTex( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, TComWedgelet* pcContourWedge )
1021{
1022  pcContourWedge->clear();
1023
1024  // get copy of co-located texture luma block
1025  TComYuv cTempYuv;
1026  cTempYuv.create( uiWidth, uiHeight ); 
1027  cTempYuv.clear();
1028  Pel* piRefBlkY = cTempYuv.getLumaAddr();
1029  xCopyTextureLumaBlock( pcCU, uiAbsPartIdx, piRefBlkY, uiWidth, uiHeight );
1030  piRefBlkY = cTempYuv.getLumaAddr();
1031
1032  // find contour for texture luma block
1033  UInt iDC = 0;
1034  for( UInt k = 0; k < (uiWidth*uiHeight); k++ ) 
1035  { 
1036    iDC += piRefBlkY[k]; 
1037  }
1038  iDC /= (uiWidth*uiHeight);
1039  piRefBlkY = cTempYuv.getLumaAddr();
1040
1041  Bool* pabContourPattern = pcContourWedge->getPattern();
1042  for( UInt k = 0; k < (uiWidth*uiHeight); k++ ) 
1043  { 
1044    pabContourPattern[k] = (piRefBlkY[k] > iDC) ? true : false;
1045  }
1046
1047  cTempYuv.destroy();
1048}
1049
1050
1051Void TComPrediction::xCopyTextureLumaBlock( TComDataCU* pcCU, UInt uiAbsPartIdx, Pel* piDestBlockY, UInt uiWidth, UInt uiHeight )
1052{
1053  TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getPicLists()->getPic( pcCU->getSlice()->getViewIndex(), false, pcCU->getSlice()->getPOC() )->getPicYuvRec();
1054  assert( pcPicYuvRef != NULL );
1055  Int         iRefStride = pcPicYuvRef->getStride();
1056  Pel*        piRefY = pcPicYuvRef->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiAbsPartIdx );
1057
1058  for ( Int y = 0; y < uiHeight; y++ )
1059  {
1060    ::memcpy(piDestBlockY, piRefY, sizeof(Pel)*uiWidth);
1061    piDestBlockY += uiWidth;
1062    piRefY += iRefStride;
1063  }
1064}
1065
1066Void TComPrediction::xGetBlockOffset( TComDataCU* pcCU, UInt uiAbsPartIdx, TComDataCU* pcRefCU, UInt uiRefAbsPartIdx, UInt& ruiOffsetX, UInt& ruiOffsetY )
1067{
1068  ruiOffsetX = 0;
1069  ruiOffsetY = 0;
1070
1071  // get offset between current and above/left block
1072  UInt uiThisOriginX = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
1073  UInt uiThisOriginY = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
1074
1075  UInt uiNumPartInRefCU = pcRefCU->getTotalNumPart();
1076  UInt uiMaxDepthRefCU = 0;
1077  while( uiNumPartInRefCU > 1 )
1078  {
1079    uiNumPartInRefCU >>= 2;
1080    uiMaxDepthRefCU++;
1081  }
1082
1083  UInt uiDepthRefPU = (pcRefCU->getDepth(uiRefAbsPartIdx)) + (pcRefCU->getPartitionSize(uiRefAbsPartIdx) == SIZE_2Nx2N ? 0 : 1);
1084  UInt uiShifts = (uiMaxDepthRefCU - uiDepthRefPU)*2;
1085  UInt uiRefBlockOriginPartIdx = (uiRefAbsPartIdx>>uiShifts)<<uiShifts;
1086
1087  UInt uiRefOriginX = pcRefCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiRefBlockOriginPartIdx] ];
1088  UInt uiRefOriginY = pcRefCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiRefBlockOriginPartIdx] ];
1089
1090  if( (uiThisOriginX - uiRefOriginX) > 0 ) { ruiOffsetX = (UInt)(uiThisOriginX - uiRefOriginX); }
1091  if( (uiThisOriginY - uiRefOriginY) > 0 ) { ruiOffsetY = (UInt)(uiThisOriginY - uiRefOriginY); }
1092}
1093
1094Bool TComPrediction::xGetWedgeIntraDirPredData( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiBlockSize, Int& riSlopeX, Int& riSlopeY, UInt& ruiStartPosX, UInt& ruiStartPosY )
1095{
1096  riSlopeX = 0, riSlopeY = 0, ruiStartPosX = 0, ruiStartPosY = 0;
1097
1098  // 1st step: get wedge start point (max. slope)
1099  Int* piSource = pcCU->getPattern()->getAdiOrgBuf( uiBlockSize, uiBlockSize, m_piYuvExt );
1100  Int iSourceStride = ( uiBlockSize<<1 ) + 1;
1101
1102  UInt uiSlopeMaxAbove = 0, uiPosSlopeMaxAbove = 0;
1103  for( UInt uiPosHor = 0; uiPosHor < (uiBlockSize-1); uiPosHor++ )
1104  {
1105    if( abs( piSource[uiPosHor+1] - piSource[uiPosHor] ) > uiSlopeMaxAbove )
1106    {
1107      uiSlopeMaxAbove = abs( piSource[uiPosHor+1] - piSource[uiPosHor] );
1108      uiPosSlopeMaxAbove = uiPosHor;
1109    }
1110  }
1111
1112  UInt uiSlopeMaxLeft = 0, uiPosSlopeMaxLeft = 0;
1113  for( UInt uiPosVer = 0; uiPosVer < (uiBlockSize-1); uiPosVer++ )
1114  {
1115    if( abs( piSource[(uiPosVer+1)*iSourceStride] - piSource[uiPosVer*iSourceStride] ) > uiSlopeMaxLeft )
1116    {
1117      uiSlopeMaxLeft = abs( piSource[(uiPosVer+1)*iSourceStride] - piSource[uiPosVer*iSourceStride] );
1118      uiPosSlopeMaxLeft = uiPosVer;
1119    }
1120  }
1121
1122  if( uiSlopeMaxAbove == 0 && uiSlopeMaxLeft == 0 ) 
1123  { 
1124    return false; 
1125  }
1126
1127  ruiStartPosX = ( uiSlopeMaxAbove >  uiSlopeMaxLeft  ) ? uiPosSlopeMaxAbove : 0;
1128  ruiStartPosY = ( uiSlopeMaxLeft  >= uiSlopeMaxAbove ) ? uiPosSlopeMaxLeft  : 0;
1129
1130  // 2nd step: derive wedge direction
1131  Int uiPreds[3] = {-1, -1, -1};
1132  Int iMode = -1;
1133  Int iPredNum = pcCU->getIntraDirLumaPredictor( uiAbsPartIdx, uiPreds, &iMode ); 
1134
1135  UInt uiDirMode = 0;
1136  if( iMode >= 0 ) { iPredNum = iMode; }
1137  if( iPredNum == 1 ) { uiDirMode = uiPreds[0]; }
1138  if( iPredNum == 2 ) { uiDirMode = uiPreds[1]; }
1139
1140  if( uiDirMode < 2 ) { return false; } // no planar & DC
1141
1142  Bool modeHor       = (uiDirMode < 18);
1143  Bool modeVer       = !modeHor;
1144  Int intraPredAngle = modeVer ? (Int)uiDirMode - VER_IDX : modeHor ? -((Int)uiDirMode - HOR_IDX) : 0;
1145  Int absAng         = abs(intraPredAngle);
1146  Int signAng        = intraPredAngle < 0 ? -1 : 1;
1147  Int angTable[9]    = {0,2,5,9,13,17,21,26,32};
1148  absAng             = angTable[absAng];
1149  intraPredAngle     = signAng * absAng;
1150
1151  // 3rd step: set slope for direction
1152  if( modeHor )
1153  {
1154    riSlopeX = ( intraPredAngle > 0 ) ?            -32 :              32;
1155    riSlopeY = ( intraPredAngle > 0 ) ? intraPredAngle : -intraPredAngle;
1156  }
1157  else if( modeVer )
1158  {
1159    riSlopeX = ( intraPredAngle > 0 ) ? intraPredAngle : -intraPredAngle;
1160    riSlopeY = ( intraPredAngle > 0 ) ?            -32 :              32;
1161  }
1162
1163  return true;
1164}
1165
1166Void TComPrediction::xGetWedgeIntraDirStartEnd( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiBlockSize, Int iDeltaX, Int iDeltaY, UInt uiPMSPosX, UInt uiPMSPosY, UChar& ruhXs, UChar& ruhYs, UChar& ruhXe, UChar& ruhYe, Int iDeltaEnd )
1167{
1168  ruhXs = 0;
1169  ruhYs = 0;
1170  ruhXe = 0;
1171  ruhYe = 0;
1172
1173  // scaling of start pos and block size to wedge resolution
1174  UInt uiScaledStartPosX = 0;
1175  UInt uiScaledStartPosY = 0;
1176  UInt uiScaledBlockSize = 0;
1177  WedgeResolution eWedgeRes = g_dmmWedgeResolution[(UInt)g_aucConvertToBit[uiBlockSize]];
1178  switch( eWedgeRes )
1179  {
1180  case( DOUBLE_PEL ): { uiScaledStartPosX = (uiPMSPosX>>1); uiScaledStartPosY = (uiPMSPosY>>1); uiScaledBlockSize = (uiBlockSize>>1); break; }
1181  case(   FULL_PEL ): { uiScaledStartPosX =  uiPMSPosX;     uiScaledStartPosY =  uiPMSPosY;     uiScaledBlockSize =  uiBlockSize;     break; }
1182  case(   HALF_PEL ): { uiScaledStartPosX = (uiPMSPosX<<1); uiScaledStartPosY = (uiPMSPosY<<1); uiScaledBlockSize = (uiBlockSize<<1); break; }
1183  }
1184  Int iMaxPos = (Int)uiScaledBlockSize - 1;
1185
1186  // case above
1187  if( uiScaledStartPosX > 0 && uiScaledStartPosY == 0 )
1188  {
1189    ruhXs = (UChar)uiScaledStartPosX;
1190    ruhYs = 0;
1191
1192    if( iDeltaY == 0 )
1193    {
1194      if( iDeltaX < 0 )
1195      {
1196        ruhXe = 0;
1197        ruhYe = (UChar)std::min( std::max( iDeltaEnd, 0 ), iMaxPos );
1198        return;
1199      }
1200      else
1201      {
1202        ruhXe = (UChar)iMaxPos;
1203        ruhYe = (UChar)std::min( std::max( -iDeltaEnd, 0 ), iMaxPos );
1204        std::swap( ruhXs, ruhXe );
1205        std::swap( ruhYs, ruhYe );
1206        return;
1207      }
1208    }
1209
1210    // regular case
1211    Int iVirtualEndX = (Int)ruhXs + roftoi( (Double)iMaxPos * ((Double)iDeltaX / (Double)iDeltaY) );
1212
1213    if( iVirtualEndX < 0 )
1214    {
1215      Int iYe = roftoi( (Double)(0 - (Int)ruhXs) * ((Double)iDeltaY / (Double)iDeltaX) ) + iDeltaEnd;
1216      if( iYe < (Int)uiScaledBlockSize )
1217      {
1218        ruhXe = 0;
1219        ruhYe = (UChar)std::max( iYe, 0 );
1220        return;
1221      }
1222      else
1223      {
1224        ruhXe = (UChar)std::min( (iYe - iMaxPos), iMaxPos );
1225        ruhYe = (UChar)iMaxPos;
1226        return;
1227      }
1228    }
1229    else if( iVirtualEndX > iMaxPos )
1230    {
1231      Int iYe = roftoi( (Double)(iMaxPos - (Int)ruhXs) * ((Double)iDeltaY / (Double)iDeltaX) ) - iDeltaEnd;
1232      if( iYe < (Int)uiScaledBlockSize )
1233      {
1234        ruhXe = (UChar)iMaxPos;
1235        ruhYe = (UChar)std::max( iYe, 0 );
1236        std::swap( ruhXs, ruhXe );
1237        std::swap( ruhYs, ruhYe );
1238        return;
1239      }
1240      else
1241      {
1242        ruhXe = (UChar)std::max( (iMaxPos - (iYe - iMaxPos)), 0 );
1243        ruhYe = (UChar)iMaxPos;
1244        return;
1245      }
1246    }
1247    else
1248    {
1249      Int iXe = iVirtualEndX + iDeltaEnd;
1250      if( iXe < 0 )
1251      {
1252        ruhXe = 0;
1253        ruhYe = (UChar)std::max( (iMaxPos + iXe), 0 );
1254        return;
1255      }
1256      else if( iXe > iMaxPos )
1257      {
1258        ruhXe = (UChar)iMaxPos;
1259        ruhYe = (UChar)std::max( (iMaxPos - (iXe - iMaxPos)), 0 );
1260        std::swap( ruhXs, ruhXe );
1261        std::swap( ruhYs, ruhYe );
1262        return;
1263      }
1264      else
1265      {
1266        ruhXe = (UChar)iXe;
1267        ruhYe = (UChar)iMaxPos;
1268        return;
1269      }
1270    }
1271  }
1272
1273  // case left
1274  if( uiScaledStartPosY > 0 && uiScaledStartPosX == 0 )
1275  {
1276    ruhXs = 0;
1277    ruhYs = (UChar)uiScaledStartPosY;
1278
1279    if( iDeltaX == 0 )
1280    {
1281      if( iDeltaY < 0 )
1282      {
1283        ruhXe = (UChar)std::min( std::max( -iDeltaEnd, 0 ), iMaxPos );
1284        ruhYe = 0;
1285        std::swap( ruhXs, ruhXe );
1286        std::swap( ruhYs, ruhYe );
1287        return;
1288      }
1289      else
1290      {
1291        ruhXe = (UChar)std::min( std::max( iDeltaEnd, 0 ), iMaxPos );
1292        ruhYe = (UChar)iMaxPos;
1293        return; 
1294      }
1295    }
1296
1297    // regular case
1298    Int iVirtualEndY = (Int)ruhYs + roftoi( (Double)iMaxPos * ((Double)iDeltaY / (Double)iDeltaX) );
1299
1300    if( iVirtualEndY < 0 )
1301    {
1302      Int iXe = roftoi( (Double)(0 - (Int)ruhYs ) * ((Double)iDeltaX / (Double)iDeltaY) ) - iDeltaEnd;
1303      if( iXe < (Int)uiScaledBlockSize )
1304      {
1305        ruhXe = (UChar)std::max( iXe, 0 );
1306        ruhYe = 0;
1307        std::swap( ruhXs, ruhXe );
1308        std::swap( ruhYs, ruhYe );
1309        return;
1310      }
1311      else
1312      {
1313        ruhXe = (UChar)iMaxPos;
1314        ruhYe = (UChar)std::min( (iXe - iMaxPos), iMaxPos );
1315        std::swap( ruhXs, ruhXe );
1316        std::swap( ruhYs, ruhYe );
1317        return;
1318      }
1319    }
1320    else if( iVirtualEndY > (uiScaledBlockSize-1) )
1321    {
1322      Int iXe = roftoi( (Double)((Int)(uiScaledBlockSize-1) - (Int)ruhYs ) * ((Double)iDeltaX / (Double)iDeltaY) ) + iDeltaEnd;
1323      if( iXe < (Int)uiScaledBlockSize )
1324      {
1325        ruhXe = (UChar)std::max( iXe, 0 );
1326        ruhYe = (UChar)(uiScaledBlockSize-1);
1327        return;
1328      }
1329      else
1330      {
1331        ruhXe = (UChar)iMaxPos;
1332        ruhYe = (UChar)std::max( (iMaxPos - (iXe - iMaxPos)), 0 );
1333        std::swap( ruhXs, ruhXe );
1334        std::swap( ruhYs, ruhYe );
1335        return;
1336      }
1337    }
1338    else
1339    {
1340      Int iYe = iVirtualEndY - iDeltaEnd;
1341      if( iYe < 0 )
1342      {
1343        ruhXe = (UChar)std::max( (iMaxPos + iYe), 0 );
1344        ruhYe = 0;
1345        std::swap( ruhXs, ruhXe );
1346        std::swap( ruhYs, ruhYe );
1347        return;
1348      }
1349      else if( iYe > iMaxPos )
1350      {
1351        ruhXe = (UChar)std::max( (iMaxPos - (iYe - iMaxPos)), 0 );
1352        ruhYe = (UChar)iMaxPos;
1353        return;
1354      }
1355      else
1356      {
1357        ruhXe = (UChar)iMaxPos;
1358        ruhYe = (UChar)iYe;
1359        std::swap( ruhXs, ruhXe );
1360        std::swap( ruhYs, ruhYe );
1361        return;
1362      }
1363    }
1364  }
1365
1366  // case origin
1367  if( uiScaledStartPosX == 0 && uiScaledStartPosY == 0 )
1368  {
1369    if( iDeltaX*iDeltaY < 0 )
1370    {
1371      return;
1372    }
1373
1374    ruhXs = 0;
1375    ruhYs = 0;
1376
1377    if( iDeltaY == 0 )
1378    {
1379      ruhXe = (UChar)iMaxPos;
1380      ruhYe = 0;
1381      std::swap( ruhXs, ruhXe );
1382      std::swap( ruhYs, ruhYe );
1383      return;
1384    }
1385
1386    if( iDeltaX == 0 )
1387    {
1388      ruhXe = 0;
1389      ruhYe = (UChar)iMaxPos;
1390      return;
1391    }
1392
1393    Int iVirtualEndX = (Int)ruhXs + roftoi( (Double)iMaxPos * ((Double)iDeltaX / (Double)iDeltaY) );
1394
1395    if( iVirtualEndX > iMaxPos )
1396    {
1397      Int iYe = roftoi( (Double)((Int)iMaxPos - (Int)ruhXs) * ((Double)iDeltaY / (Double)iDeltaX) ) - iDeltaEnd;
1398      if( iYe < (Int)uiScaledBlockSize )
1399      {
1400        ruhXe = (UChar)(uiScaledBlockSize-1);
1401        ruhYe = (UChar)std::max( iYe, 0 );
1402        std::swap( ruhXs, ruhXe );
1403        std::swap( ruhYs, ruhYe );
1404        return;
1405      }
1406      else
1407      {
1408        ruhXe = (UChar)std::max( (iMaxPos - (iYe - iMaxPos)), 0 );
1409        ruhYe = (UChar)(uiScaledBlockSize-1);
1410        return;
1411      }
1412    }
1413    else
1414    {
1415      Int iXe = iVirtualEndX + iDeltaEnd;
1416      if( iXe < 0 )
1417      {
1418        ruhXe = 0;
1419        ruhYe = (UChar)std::max( (iMaxPos + iXe), 0 );
1420        return;
1421      }
1422      else if( iXe > iMaxPos )
1423      {
1424        ruhXe = (UChar)(uiScaledBlockSize-1);
1425        ruhYe = (UChar)std::max( (iMaxPos - (iXe - iMaxPos)), 0 );
1426        std::swap( ruhXs, ruhXe );
1427        std::swap( ruhYs, ruhYe );
1428        return;
1429      }
1430      else
1431      {
1432        ruhXe = (UChar)iXe;
1433        ruhYe = (UChar)(uiScaledBlockSize-1);
1434        return;
1435      }
1436    }
1437  }
1438}
1439
1440UInt TComPrediction::xGetWedgePatternIdx( UInt uiBlockSize, UChar uhXs, UChar uhYs, UChar uhXe, UChar uhYe )
1441{
1442  WedgeRefList* pcWedgeRefList = &g_dmmWedgeRefLists[(g_aucConvertToBit[uiBlockSize])];
1443  for( UInt uiIdx = 0; uiIdx < pcWedgeRefList->size(); uiIdx++ )
1444  {
1445    TComWedgeRef* pcTestWedgeRef = &(pcWedgeRefList->at(uiIdx));
1446    if( pcTestWedgeRef->getStartX() == uhXs && pcTestWedgeRef->getStartY() == uhYs && pcTestWedgeRef->getEndX() == uhXe && pcTestWedgeRef->getEndY() == uhYe )
1447    {
1448      return pcTestWedgeRef->getRefIdx();
1449    }
1450  }
1451  return 0;
1452}
1453#endif
1454#if H_3D_DIM_RBC
1455Void TComPrediction::xDeltaDCQuantScaleUp( TComDataCU* pcCU, Pel& rDeltaDC )
1456{
1457  Int  iSign  = rDeltaDC < 0 ? -1 : 1;
1458  UInt uiAbs  = abs( rDeltaDC );
1459
1460  Int iQp = pcCU->getQP(0);
1461  Double dMax = (Double)( 1<<( g_bitDepthY - 1 ) );
1462  Double dStepSize = Clip3( 1.0, dMax, pow( 2.0, iQp/10.0 - 2.0 ) );
1463
1464  rDeltaDC = iSign * roftoi( uiAbs * dStepSize );
1465  return;
1466}
1467
1468Void TComPrediction::xDeltaDCQuantScaleDown( TComDataCU*  pcCU, Pel& rDeltaDC )
1469{
1470  Int  iSign  = rDeltaDC < 0 ? -1 : 1;
1471  UInt uiAbs  = abs( rDeltaDC );
1472
1473  Int iQp = pcCU->getQP(0);
1474  Double dMax = (Double)( 1<<( g_bitDepthY - 1 ) );
1475  Double dStepSize = Clip3( 1.0, dMax, pow( 2.0, iQp/10.0 - 2.0 ) );
1476
1477  rDeltaDC = iSign * roftoi( uiAbs / dStepSize );
1478  return;
1479}
1480#endif
1481#if H_3D_DIM_SDC
1482Void TComPrediction::analyzeSegmentsSDC( Pel* pOrig, UInt uiStride, UInt uiSize, Pel* rpSegMeans, UInt uiNumSegments, Bool* pMask, UInt uiMaskStride )
1483{
1484  Int iSumDepth[2];
1485  memset(iSumDepth, 0, sizeof(Int)*2);
1486  Int iSumPix[2];
1487  memset(iSumPix, 0, sizeof(Int)*2);
1488 
1489  Int subSamplePix;
1490  if ( uiSize == 64 || uiSize == 32 )
1491  {
1492    subSamplePix = 2;
1493  }
1494  else
1495  {
1496    subSamplePix = 1;
1497  }
1498  for (Int y=0; y<uiSize; y+=subSamplePix)
1499  {
1500    for (Int x=0; x<uiSize; x+=subSamplePix)
1501    {
1502      UChar ucSegment = pMask?(UChar)pMask[x]:0;
1503      assert( ucSegment < uiNumSegments );
1504     
1505      iSumDepth[ucSegment] += pOrig[x];
1506      iSumPix[ucSegment]   += 1;
1507    }
1508   
1509    pOrig  += uiStride*subSamplePix;
1510    pMask  += uiMaskStride*subSamplePix;
1511  }
1512 
1513  // compute mean for each segment
1514  for( UChar ucSeg = 0; ucSeg < uiNumSegments; ucSeg++ )
1515  {
1516    if( iSumPix[ucSeg] > 0 )
1517      rpSegMeans[ucSeg] = iSumDepth[ucSeg] / iSumPix[ucSeg];
1518    else
1519      rpSegMeans[ucSeg] = 0;  // this happens for zero-segments
1520  }
1521}
1522#endif // H_3D_DIM_SDC
1523#endif
1524//! \}
Note: See TracBrowser for help on using the repository browser.