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

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

Merge Dev2.a to Dev2 and simulation results updated

  • Property svn:eol-style set to native
File size: 38.9 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6 * Copyright (c) 2010-2013, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TComPrediction.cpp
35    \brief    prediction class
36*/
37
38#include <memory.h>
39#include "TComPrediction.h"
40
41//! \ingroup TLibCommon
42//! \{
43
44// ====================================================================================================================
45// Constructor / destructor / initialize
46// ====================================================================================================================
47
48TComPrediction::TComPrediction()
49: m_pLumaRecBuffer(0)
50, m_iLumaRecStride(0)
51{
52  m_piYuvExt = NULL;
53}
54
55TComPrediction::~TComPrediction()
56{
57 
58  delete[] m_piYuvExt;
59
60  m_acYuvPred[0].destroy();
61  m_acYuvPred[1].destroy();
62
63  m_cYuvPredTemp.destroy();
64
65#if H_3D_ARP
66  m_acYuvPredBase[0].destroy();
67  m_acYuvPredBase[1].destroy();
68#endif
69
70  if( m_pLumaRecBuffer )
71  {
72    delete [] m_pLumaRecBuffer;
73  }
74 
75  Int i, j;
76  for (i = 0; i < 4; i++)
77  {
78    for (j = 0; j < 4; j++)
79    {
80      m_filteredBlock[i][j].destroy();
81    }
82    m_filteredBlockTmp[i].destroy();
83  }
84}
85
86Void TComPrediction::initTempBuff()
87{
88  if( m_piYuvExt == NULL )
89  {
90    Int extWidth  = MAX_CU_SIZE + 16; 
91    Int extHeight = MAX_CU_SIZE + 1;
92    Int i, j;
93    for (i = 0; i < 4; i++)
94    {
95      m_filteredBlockTmp[i].create(extWidth, extHeight + 7);
96      for (j = 0; j < 4; j++)
97      {
98        m_filteredBlock[i][j].create(extWidth, extHeight);
99      }
100    }
101    m_iYuvExtHeight  = ((MAX_CU_SIZE + 2) << 4);
102    m_iYuvExtStride = ((MAX_CU_SIZE  + 8) << 4);
103    m_piYuvExt = new Int[ m_iYuvExtStride * m_iYuvExtHeight ];
104
105    // new structure
106    m_acYuvPred[0] .create( MAX_CU_SIZE, MAX_CU_SIZE );
107    m_acYuvPred[1] .create( MAX_CU_SIZE, MAX_CU_SIZE );
108
109    m_cYuvPredTemp.create( MAX_CU_SIZE, MAX_CU_SIZE );
110#if H_3D_ARP
111    m_acYuvPredBase[0] .create( g_uiMaxCUWidth, g_uiMaxCUHeight );
112    m_acYuvPredBase[1] .create( g_uiMaxCUWidth, g_uiMaxCUHeight );
113#endif
114  }
115
116  if (m_iLumaRecStride != (MAX_CU_SIZE>>1) + 1)
117  {
118    m_iLumaRecStride =  (MAX_CU_SIZE>>1) + 1;
119    if (!m_pLumaRecBuffer)
120    {
121      m_pLumaRecBuffer = new Pel[ m_iLumaRecStride * m_iLumaRecStride ];
122    }
123  }
124#if H_3D_IC
125  for( Int i = 1; i < 64; i++ )
126  {
127    m_uiaShift[i-1] = ( (1 << 15) + i/2 ) / i;
128  }
129#endif
130}
131
132// ====================================================================================================================
133// Public member functions
134// ====================================================================================================================
135
136// Function for calculating DC value of the reference samples used in Intra prediction
137Pel TComPrediction::predIntraGetPredValDC( Int* pSrc, Int iSrcStride, UInt iWidth, UInt iHeight, Bool bAbove, Bool bLeft )
138{
139  Int iInd, iSum = 0;
140  Pel pDcVal;
141
142  if (bAbove)
143  {
144    for (iInd = 0;iInd < iWidth;iInd++)
145    {
146      iSum += pSrc[iInd-iSrcStride];
147    }
148  }
149  if (bLeft)
150  {
151    for (iInd = 0;iInd < iHeight;iInd++)
152    {
153      iSum += pSrc[iInd*iSrcStride-1];
154    }
155  }
156
157  if (bAbove && bLeft)
158  {
159    pDcVal = (iSum + iWidth) / (iWidth + iHeight);
160  }
161  else if (bAbove)
162  {
163    pDcVal = (iSum + iWidth/2) / iWidth;
164  }
165  else if (bLeft)
166  {
167    pDcVal = (iSum + iHeight/2) / iHeight;
168  }
169  else
170  {
171    pDcVal = pSrc[-1]; // Default DC value already calculated and placed in the prediction array if no neighbors are available
172  }
173 
174  return pDcVal;
175}
176
177// Function for deriving the angular Intra predictions
178
179/** Function for deriving the simplified angular intra predictions.
180 * \param pSrc pointer to reconstructed sample array
181 * \param srcStride the stride of the reconstructed sample array
182 * \param rpDst reference to pointer for the prediction sample array
183 * \param dstStride the stride of the prediction sample array
184 * \param width the width of the block
185 * \param height the height of the block
186 * \param dirMode the intra prediction mode index
187 * \param blkAboveAvailable boolean indication if the block above is available
188 * \param blkLeftAvailable boolean indication if the block to the left is available
189 *
190 * This function derives the prediction samples for the angular mode based on the prediction direction indicated by
191 * the prediction mode index. The prediction direction is given by the displacement of the bottom row of the block and
192 * the reference row above the block in the case of vertical prediction or displacement of the rightmost column
193 * of the block and reference column left from the block in the case of the horizontal prediction. The displacement
194 * is signalled at 1/32 pixel accuracy. When projection of the predicted pixel falls inbetween reference samples,
195 * the predicted value for the pixel is linearly interpolated from the reference samples. All reference samples are taken
196 * from the extended main reference.
197 */
198Void TComPrediction::xPredIntraAng(Int bitDepth, Int* pSrc, Int srcStride, Pel*& rpDst, Int dstStride, UInt width, UInt height, UInt dirMode, Bool blkAboveAvailable, Bool blkLeftAvailable, Bool bFilter )
199{
200  Int k,l;
201  Int blkSize        = width;
202  Pel* pDst          = rpDst;
203
204  // Map the mode index to main prediction direction and angle
205  assert( dirMode > 0 ); //no planar
206  Bool modeDC        = dirMode < 2;
207  Bool modeHor       = !modeDC && (dirMode < 18);
208  Bool modeVer       = !modeDC && !modeHor;
209  Int intraPredAngle = modeVer ? (Int)dirMode - VER_IDX : modeHor ? -((Int)dirMode - HOR_IDX) : 0;
210  Int absAng         = abs(intraPredAngle);
211  Int signAng        = intraPredAngle < 0 ? -1 : 1;
212
213  // Set bitshifts and scale the angle parameter to block size
214  Int angTable[9]    = {0,    2,    5,   9,  13,  17,  21,  26,  32};
215  Int invAngTable[9] = {0, 4096, 1638, 910, 630, 482, 390, 315, 256}; // (256 * 32) / Angle
216  Int invAngle       = invAngTable[absAng];
217  absAng             = angTable[absAng];
218  intraPredAngle     = signAng * absAng;
219
220  // Do the DC prediction
221  if (modeDC)
222  {
223    Pel dcval = predIntraGetPredValDC(pSrc, srcStride, width, height, blkAboveAvailable, blkLeftAvailable);
224
225    for (k=0;k<blkSize;k++)
226    {
227      for (l=0;l<blkSize;l++)
228      {
229        pDst[k*dstStride+l] = dcval;
230      }
231    }
232  }
233
234  // Do angular predictions
235  else
236  {
237    Pel* refMain;
238    Pel* refSide;
239    Pel  refAbove[2*MAX_CU_SIZE+1];
240    Pel  refLeft[2*MAX_CU_SIZE+1];
241
242    // Initialise the Main and Left reference array.
243    if (intraPredAngle < 0)
244    {
245      for (k=0;k<blkSize+1;k++)
246      {
247        refAbove[k+blkSize-1] = pSrc[k-srcStride-1];
248      }
249      for (k=0;k<blkSize+1;k++)
250      {
251        refLeft[k+blkSize-1] = pSrc[(k-1)*srcStride-1];
252      }
253      refMain = (modeVer ? refAbove : refLeft) + (blkSize-1);
254      refSide = (modeVer ? refLeft : refAbove) + (blkSize-1);
255
256      // Extend the Main reference to the left.
257      Int invAngleSum    = 128;       // rounding for (shift by 8)
258      for (k=-1; k>blkSize*intraPredAngle>>5; k--)
259      {
260        invAngleSum += invAngle;
261        refMain[k] = refSide[invAngleSum>>8];
262      }
263    }
264    else
265    {
266      for (k=0;k<2*blkSize+1;k++)
267      {
268        refAbove[k] = pSrc[k-srcStride-1];
269      }
270      for (k=0;k<2*blkSize+1;k++)
271      {
272        refLeft[k] = pSrc[(k-1)*srcStride-1];
273      }
274      refMain = modeVer ? refAbove : refLeft;
275      refSide = modeVer ? refLeft  : refAbove;
276    }
277
278    if (intraPredAngle == 0)
279    {
280      for (k=0;k<blkSize;k++)
281      {
282        for (l=0;l<blkSize;l++)
283        {
284          pDst[k*dstStride+l] = refMain[l+1];
285        }
286      }
287
288      if ( bFilter )
289      {
290        for (k=0;k<blkSize;k++)
291        {
292          pDst[k*dstStride] = Clip3(0, (1<<bitDepth)-1, pDst[k*dstStride] + (( refSide[k+1] - refSide[0] ) >> 1) );
293        }
294      }
295    }
296    else
297    {
298      Int deltaPos=0;
299      Int deltaInt;
300      Int deltaFract;
301      Int refMainIndex;
302
303      for (k=0;k<blkSize;k++)
304      {
305        deltaPos += intraPredAngle;
306        deltaInt   = deltaPos >> 5;
307        deltaFract = deltaPos & (32 - 1);
308
309        if (deltaFract)
310        {
311          // Do linear filtering
312          for (l=0;l<blkSize;l++)
313          {
314            refMainIndex        = l+deltaInt+1;
315            pDst[k*dstStride+l] = (Pel) ( ((32-deltaFract)*refMain[refMainIndex]+deltaFract*refMain[refMainIndex+1]+16) >> 5 );
316          }
317        }
318        else
319        {
320          // Just copy the integer samples
321          for (l=0;l<blkSize;l++)
322          {
323            pDst[k*dstStride+l] = refMain[l+deltaInt+1];
324          }
325        }
326      }
327    }
328
329    // Flip the block if this is the horizontal mode
330    if (modeHor)
331    {
332      Pel  tmp;
333      for (k=0;k<blkSize-1;k++)
334      {
335        for (l=k+1;l<blkSize;l++)
336        {
337          tmp                 = pDst[k*dstStride+l];
338          pDst[k*dstStride+l] = pDst[l*dstStride+k];
339          pDst[l*dstStride+k] = tmp;
340        }
341      }
342    }
343  }
344}
345
346Void TComPrediction::predIntraLumaAng(TComPattern* pcTComPattern, UInt uiDirMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, Bool bAbove, Bool bLeft )
347{
348  Pel *pDst = piPred;
349  Int *ptrSrc;
350
351  assert( g_aucConvertToBit[ iWidth ] >= 0 ); //   4x  4
352  assert( g_aucConvertToBit[ iWidth ] <= 5 ); // 128x128
353  assert( iWidth == iHeight  );
354
355  ptrSrc = pcTComPattern->getPredictorPtr( uiDirMode, g_aucConvertToBit[ iWidth ] + 2, m_piYuvExt );
356
357  // get starting pixel in block
358  Int sw = 2 * iWidth + 1;
359
360  // Create the prediction
361  if ( uiDirMode == PLANAR_IDX )
362  {
363    xPredIntraPlanar( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight );
364  }
365  else
366  {
367    if ( (iWidth > 16) || (iHeight > 16) )
368    {
369      xPredIntraAng(g_bitDepthY, ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode, bAbove, bLeft, false );
370    }
371    else
372    {
373      xPredIntraAng(g_bitDepthY, ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode, bAbove, bLeft, true );
374
375      if( (uiDirMode == DC_IDX ) && bAbove && bLeft )
376      {
377        xDCPredFiltering( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight);
378      }
379    }
380  }
381}
382
383// Angular chroma
384Void TComPrediction::predIntraChromaAng( Int* piSrc, UInt uiDirMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, Bool bAbove, Bool bLeft )
385{
386  Pel *pDst = piPred;
387  Int *ptrSrc = piSrc;
388
389  // get starting pixel in block
390  Int sw = 2 * iWidth + 1;
391
392  if ( uiDirMode == PLANAR_IDX )
393  {
394    xPredIntraPlanar( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight );
395  }
396  else
397  {
398    // Create the prediction
399    xPredIntraAng(g_bitDepthC, ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode, bAbove, bLeft, false );
400  }
401}
402
403/** Function for checking identical motion.
404 * \param TComDataCU* pcCU
405 * \param UInt PartAddr
406 */
407Bool TComPrediction::xCheckIdenticalMotion ( TComDataCU* pcCU, UInt PartAddr )
408{
409  if( pcCU->getSlice()->isInterB() && !pcCU->getSlice()->getPPS()->getWPBiPred() )
410  {
411    if( pcCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(PartAddr) >= 0 && pcCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(PartAddr) >= 0)
412    {
413      Int RefPOCL0 = pcCU->getSlice()->getRefPic(REF_PIC_LIST_0, pcCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(PartAddr))->getPOC();
414      Int RefPOCL1 = pcCU->getSlice()->getRefPic(REF_PIC_LIST_1, pcCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(PartAddr))->getPOC();
415      if(RefPOCL0 == RefPOCL1 && pcCU->getCUMvField(REF_PIC_LIST_0)->getMv(PartAddr) == pcCU->getCUMvField(REF_PIC_LIST_1)->getMv(PartAddr))
416      {
417        return true;
418      }
419    }
420  }
421  return false;
422}
423
424
425Void TComPrediction::motionCompensation ( TComDataCU* pcCU, TComYuv* pcYuvPred, RefPicList eRefPicList, Int iPartIdx )
426{
427  Int         iWidth;
428  Int         iHeight;
429  UInt        uiPartAddr;
430
431  if ( iPartIdx >= 0 )
432  {
433    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
434    if ( eRefPicList != REF_PIC_LIST_X )
435    {
436      if( pcCU->getSlice()->getPPS()->getUseWP())
437      {
438        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, true );
439      }
440      else
441      {
442        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
443      }
444      if ( pcCU->getSlice()->getPPS()->getUseWP() )
445      {
446        xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
447      }
448    }
449    else
450    {
451      if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
452      {
453        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
454      }
455      else
456      {
457        xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );
458      }
459    }
460    return;
461  }
462
463  for ( iPartIdx = 0; iPartIdx < pcCU->getNumPartInter(); iPartIdx++ )
464  {
465    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
466
467    if ( eRefPicList != REF_PIC_LIST_X )
468    {
469      if( pcCU->getSlice()->getPPS()->getUseWP())
470      {
471        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, true );
472      }
473      else
474      {
475        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
476      }
477      if ( pcCU->getSlice()->getPPS()->getUseWP() )
478      {
479        xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
480      }
481    }
482    else
483    {
484      if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
485      {
486        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
487      }
488      else
489      {
490        xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );
491      }
492    }
493  }
494  return;
495}
496
497Void TComPrediction::xPredInterUni ( TComDataCU* pcCU, UInt uiPartAddr, Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Bool bi )
498{
499  Int         iRefIdx     = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );           assert (iRefIdx >= 0);
500  TComMv      cMv         = pcCU->getCUMvField( eRefPicList )->getMv( uiPartAddr );
501  pcCU->clipMv(cMv);
502#if H_3D_ARP
503  if(  pcCU->getARPW( uiPartAddr ) > 0 
504    && pcCU->getPartitionSize(uiPartAddr)==SIZE_2Nx2N
505    && pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPOC()!= pcCU->getSlice()->getPOC() 
506    )
507  {
508    xPredInterUniARP( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, rpcYuvPred, bi );
509  }
510  else
511  {
512#endif
513#if H_3D_IC
514    Bool bICFlag = pcCU->getICFlag( uiPartAddr ) && ( pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getViewIndex() != pcCU->getSlice()->getViewIndex() );
515    xPredInterLumaBlk  ( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi
516#if H_3D_ARP
517      , false
518#endif
519      , bICFlag );
520    xPredInterChromaBlk( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi
521#if H_3D_ARP
522      , false
523#endif
524      , bICFlag );
525#else
526  xPredInterLumaBlk  ( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi );
527  xPredInterChromaBlk( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi );
528#endif
529#if H_3D_ARP
530  }
531#endif
532}
533
534#if H_3D_ARP
535Void TComPrediction::xPredInterUniARP( TComDataCU* pcCU, UInt uiPartAddr, Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Bool bi, TComMvField * pNewMvFiled )
536{
537  Int         iRefIdx      = pNewMvFiled ? pNewMvFiled->getRefIdx() : pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );           
538  TComMv      cMv          = pNewMvFiled ? pNewMvFiled->getMv()     : pcCU->getCUMvField( eRefPicList )->getMv( uiPartAddr );
539  Bool        bTobeScaled  = false;
540  TComPic* pcPicYuvBaseCol = NULL;
541  TComPic* pcPicYuvBaseRef = NULL;
542
543#if H_3D_NBDV
544  DisInfo cDistparity;
545  cDistparity.bDV           = pcCU->getDvInfo(uiPartAddr).bDV;
546  if( cDistparity.bDV )
547  {
548    cDistparity.m_acNBDV = pcCU->getDvInfo(0).m_acNBDV;
549    assert(pcCU->getDvInfo(uiPartAddr).bDV ==  pcCU->getDvInfo(0).bDV);
550    cDistparity.m_aVIdxCan = pcCU->getDvInfo(uiPartAddr).m_aVIdxCan;
551  }
552#else
553  assert(0); // ARP can be applied only when a DV is available
554#endif
555
556  UChar dW = cDistparity.bDV ? pcCU->getARPW ( uiPartAddr ) : 0;
557
558  if( cDistparity.bDV ) 
559  {
560    if( dW > 0 && pcCU->getSlice()->getRefPic( eRefPicList, 0 )->getPOC()!= pcCU->getSlice()->getPOC() )
561    {
562      bTobeScaled = true;
563    }
564
565    pcPicYuvBaseCol =  pcCU->getSlice()->getBaseViewRefPic( pcCU->getSlice()->getPOC(),                              cDistparity.m_aVIdxCan );
566    pcPicYuvBaseRef =  pcCU->getSlice()->getBaseViewRefPic( pcCU->getSlice()->getRefPic( eRefPicList, 0 )->getPOC(), cDistparity.m_aVIdxCan );
567   
568    if( ( !pcPicYuvBaseCol || pcPicYuvBaseCol->getPOC() != pcCU->getSlice()->getPOC() ) || ( !pcPicYuvBaseRef || pcPicYuvBaseRef->getPOC() != pcCU->getSlice()->getRefPic( eRefPicList, 0 )->getPOC() ) )
569    {
570      dW = 0;
571      bTobeScaled = false;
572    }
573    else
574    {
575      assert( pcPicYuvBaseCol->getPOC() == pcCU->getSlice()->getPOC() && pcPicYuvBaseRef->getPOC() == pcCU->getSlice()->getRefPic( eRefPicList, 0 )->getPOC() );
576    }
577
578    if(bTobeScaled)
579    {     
580      Int iCurrPOC    = pcCU->getSlice()->getPOC();
581      Int iColRefPOC  = pcCU->getSlice()->getRefPOC( eRefPicList, iRefIdx );
582      Int iCurrRefPOC = pcCU->getSlice()->getRefPOC( eRefPicList,  0);
583      Int iScale = pcCU-> xGetDistScaleFactor(iCurrPOC, iCurrRefPOC, iCurrPOC, iColRefPOC);
584      if ( iScale != 4096 )
585      {
586        cMv = cMv.scaleMv( iScale );
587      }
588      iRefIdx = 0;
589    }
590  }
591
592  pcCU->clipMv(cMv);
593  TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec();
594  xPredInterLumaBlk  ( pcCU, pcPicYuvRef, uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi, true );
595  xPredInterChromaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi, true );
596
597  if( dW > 0 )
598  {
599    TComYuv * pYuvB0 = &m_acYuvPredBase[0];
600    TComYuv * pYuvB1  = &m_acYuvPredBase[1];
601
602    TComMv cMVwithDisparity = cMv + cDistparity.m_acNBDV;
603    pcCU->clipMv(cMVwithDisparity);
604
605    assert ( cDistparity.bDV );
606
607    pcPicYuvRef = pcPicYuvBaseCol->getPicYuvRec();
608    xPredInterLumaBlk  ( pcCU, pcPicYuvRef, uiPartAddr, &cDistparity.m_acNBDV, iWidth, iHeight, pYuvB0, bi, true );
609    xPredInterChromaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cDistparity.m_acNBDV, iWidth, iHeight, pYuvB0, bi, true );
610   
611    pcPicYuvRef = pcPicYuvBaseRef->getPicYuvRec();
612    xPredInterLumaBlk  ( pcCU, pcPicYuvRef, uiPartAddr, &cMVwithDisparity, iWidth, iHeight, pYuvB1, bi, true );
613    xPredInterChromaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMVwithDisparity, iWidth, iHeight, pYuvB1, bi, true );
614
615    pYuvB0->subtractARP( pYuvB0 , pYuvB1 , uiPartAddr , iWidth , iHeight );
616
617    if( 2 == dW )
618    {
619      pYuvB0->multiplyARP( uiPartAddr , iWidth , iHeight , dW );
620    }
621
622    rpcYuvPred->addARP( rpcYuvPred , pYuvB0 , uiPartAddr , iWidth , iHeight , !bi );
623  }
624}
625#endif
626
627Void TComPrediction::xPredInterBi ( TComDataCU* pcCU, UInt uiPartAddr, Int iWidth, Int iHeight, TComYuv*& rpcYuvPred )
628{
629  TComYuv* pcMbYuv;
630  Int      iRefIdx[2] = {-1, -1};
631
632  for ( Int iRefList = 0; iRefList < 2; iRefList++ )
633  {
634    RefPicList eRefPicList = (iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0);
635    iRefIdx[iRefList] = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );
636
637    if ( iRefIdx[iRefList] < 0 )
638    {
639      continue;
640    }
641
642    assert( iRefIdx[iRefList] < pcCU->getSlice()->getNumRefIdx(eRefPicList) );
643
644    pcMbYuv = &m_acYuvPred[iRefList];
645    if( pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiPartAddr ) >= 0 && pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiPartAddr ) >= 0 )
646    {
647      xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv, true );
648    }
649    else
650    {
651      if ( ( pcCU->getSlice()->getPPS()->getUseWP()       && pcCU->getSlice()->getSliceType() == P_SLICE ) || 
652           ( pcCU->getSlice()->getPPS()->getWPBiPred() && pcCU->getSlice()->getSliceType() == B_SLICE ) )
653      {
654        xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv, true );
655      }
656      else
657      {
658        xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv );
659      }
660    }
661  }
662
663  if ( pcCU->getSlice()->getPPS()->getWPBiPred() && pcCU->getSlice()->getSliceType() == B_SLICE  )
664  {
665    xWeightedPredictionBi( pcCU, &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred );
666  } 
667  else if ( pcCU->getSlice()->getPPS()->getUseWP() && pcCU->getSlice()->getSliceType() == P_SLICE )
668  {
669    xWeightedPredictionUni( pcCU, &m_acYuvPred[0], uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, rpcYuvPred ); 
670  }
671  else
672  {
673    xWeightedAverage( &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred );
674  }
675}
676
677/**
678 * \brief Generate motion-compensated luma block
679 *
680 * \param cu       Pointer to current CU
681 * \param refPic   Pointer to reference picture
682 * \param partAddr Address of block within CU
683 * \param mv       Motion vector
684 * \param width    Width of block
685 * \param height   Height of block
686 * \param dstPic   Pointer to destination picture
687 * \param bi       Flag indicating whether bipred is used
688 */
689Void TComPrediction::xPredInterLumaBlk( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi
690#if H_3D_ARP
691    , Bool filterType
692#endif
693#if H_3D_IC
694    , Bool bICFlag
695#endif
696  )
697{
698  Int refStride = refPic->getStride(); 
699  Int refOffset = ( mv->getHor() >> 2 ) + ( mv->getVer() >> 2 ) * refStride;
700  Pel *ref      = refPic->getLumaAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
701 
702  Int dstStride = dstPic->getStride();
703  Pel *dst      = dstPic->getLumaAddr( partAddr );
704 
705  Int xFrac = mv->getHor() & 0x3;
706  Int yFrac = mv->getVer() & 0x3;
707
708#if H_3D_IC
709  if( cu->getSlice()->getIsDepth() )
710  {
711    refOffset = mv->getHor() + mv->getVer() * refStride;
712    ref       = refPic->getLumaAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
713    xFrac     = 0;
714    yFrac     = 0;
715  }
716#endif
717
718  if ( yFrac == 0 )
719  {
720    m_if.filterHorLuma( ref, refStride, dst, dstStride, width, height, xFrac,       !bi
721#if H_3D_ARP
722    , filterType
723#endif
724      );
725  }
726  else if ( xFrac == 0 )
727  {
728    m_if.filterVerLuma( ref, refStride, dst, dstStride, width, height, yFrac, true, !bi
729#if H_3D_ARP
730    , filterType
731#endif
732      );
733  }
734  else
735  {
736    Int tmpStride = m_filteredBlockTmp[0].getStride();
737    Short *tmp    = m_filteredBlockTmp[0].getLumaAddr();
738
739    Int filterSize = NTAPS_LUMA;
740    Int halfFilterSize = ( filterSize >> 1 );
741
742    m_if.filterHorLuma(ref - (halfFilterSize-1)*refStride, refStride, tmp, tmpStride, width, height+filterSize-1, xFrac, false     
743#if H_3D_ARP
744    , filterType
745#endif
746      );
747    m_if.filterVerLuma(tmp + (halfFilterSize-1)*tmpStride, tmpStride, dst, dstStride, width, height,              yFrac, false, !bi
748#if H_3D_ARP
749    , filterType
750#endif
751      );   
752  }
753
754#if H_3D_IC
755  if( bICFlag )
756  {
757    Int a, b, iShift, i, j;
758
759    xGetLLSICPrediction( cu, mv, refPic, a, b, iShift, TEXT_LUMA );
760
761    for ( i = 0; i < height; i++ )
762    {
763      for ( j = 0; j < width; j++ )
764      {
765        if( bi )
766        {
767          Int iIFshift = IF_INTERNAL_PREC - g_bitDepthY;
768          dst[j] = ( ( a*dst[j] + a*IF_INTERNAL_OFFS ) >> iShift ) + b*( 1 << iIFshift ) - IF_INTERNAL_OFFS;
769        }
770        else
771          dst[j] = Clip3( 0, ( 1 << g_bitDepthY ) - 1, ( ( a*dst[j] ) >> iShift ) + b );
772      }
773      dst += dstStride;
774    }
775  }
776#endif
777}
778
779/**
780 * \brief Generate motion-compensated chroma block
781 *
782 * \param cu       Pointer to current CU
783 * \param refPic   Pointer to reference picture
784 * \param partAddr Address of block within CU
785 * \param mv       Motion vector
786 * \param width    Width of block
787 * \param height   Height of block
788 * \param dstPic   Pointer to destination picture
789 * \param bi       Flag indicating whether bipred is used
790 */
791Void TComPrediction::xPredInterChromaBlk( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi
792#if H_3D_ARP
793    , Bool filterType
794#endif
795#if H_3D_IC
796    , Bool bICFlag
797#endif
798  )
799{
800  Int     refStride  = refPic->getCStride();
801  Int     dstStride  = dstPic->getCStride();
802 
803  Int     refOffset  = (mv->getHor() >> 3) + (mv->getVer() >> 3) * refStride;
804 
805  Pel*    refCb     = refPic->getCbAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
806  Pel*    refCr     = refPic->getCrAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
807 
808  Pel* dstCb = dstPic->getCbAddr( partAddr );
809  Pel* dstCr = dstPic->getCrAddr( partAddr );
810 
811  Int     xFrac  = mv->getHor() & 0x7;
812  Int     yFrac  = mv->getVer() & 0x7;
813  UInt    cxWidth  = width  >> 1;
814  UInt    cxHeight = height >> 1;
815 
816  Int     extStride = m_filteredBlockTmp[0].getStride();
817  Short*  extY      = m_filteredBlockTmp[0].getLumaAddr();
818 
819  Int filterSize = NTAPS_CHROMA;
820 
821  Int halfFilterSize = (filterSize>>1);
822 
823  if ( yFrac == 0 )
824  {
825    m_if.filterHorChroma(refCb, refStride, dstCb,  dstStride, cxWidth, cxHeight, xFrac, !bi
826#if H_3D_ARP
827    , filterType
828#endif
829    );   
830    m_if.filterHorChroma(refCr, refStride, dstCr,  dstStride, cxWidth, cxHeight, xFrac, !bi
831#if H_3D_ARP
832    , filterType
833#endif
834    );
835  }
836  else if ( xFrac == 0 )
837  {
838    m_if.filterVerChroma(refCb, refStride, dstCb, dstStride, cxWidth, cxHeight, yFrac, true, !bi
839#if H_3D_ARP
840    , filterType
841#endif
842    );
843    m_if.filterVerChroma(refCr, refStride, dstCr, dstStride, cxWidth, cxHeight, yFrac, true, !bi
844#if H_3D_ARP
845    , filterType
846#endif
847    );
848  }
849  else
850  {
851    m_if.filterHorChroma(refCb - (halfFilterSize-1)*refStride, refStride, extY,  extStride, cxWidth, cxHeight+filterSize-1, xFrac, false
852#if H_3D_ARP
853    , filterType
854#endif 
855      );
856    m_if.filterVerChroma(extY  + (halfFilterSize-1)*extStride, extStride, dstCb, dstStride, cxWidth, cxHeight  , yFrac, false, !bi
857#if H_3D_ARP
858    , filterType
859#endif
860      );
861   
862    m_if.filterHorChroma(refCr - (halfFilterSize-1)*refStride, refStride, extY,  extStride, cxWidth, cxHeight+filterSize-1, xFrac, false
863#if H_3D_ARP
864    , filterType
865#endif
866      );
867    m_if.filterVerChroma(extY  + (halfFilterSize-1)*extStride, extStride, dstCr, dstStride, cxWidth, cxHeight  , yFrac, false, !bi
868#if H_3D_ARP
869    , filterType
870#endif
871      );   
872  }
873
874#if H_3D_IC
875  if( bICFlag )
876  {
877    Int a, b, iShift, i, j;
878    xGetLLSICPrediction( cu, mv, refPic, a, b, iShift, TEXT_CHROMA_U ); // Cb
879    for ( i = 0; i < cxHeight; i++ )
880    {
881      for ( j = 0; j < cxWidth; j++ )
882      {
883        if( bi )
884        {
885          Int iIFshift = IF_INTERNAL_PREC - g_bitDepthC;
886          dstCb[j] = ( ( a*dstCb[j] + a*IF_INTERNAL_OFFS ) >> iShift ) + b*( 1<<iIFshift ) - IF_INTERNAL_OFFS;
887        }
888        else
889          dstCb[j] = Clip3(  0, ( 1 << g_bitDepthC ) - 1, ( ( a*dstCb[j] ) >> iShift ) + b );
890      }
891      dstCb += dstStride;
892    }
893    xGetLLSICPrediction( cu, mv, refPic, a, b, iShift, TEXT_CHROMA_V ); // Cr
894    for ( i = 0; i < cxHeight; i++ )
895    {
896      for ( j = 0; j < cxWidth; j++ )
897      {
898        if( bi )
899        {
900          Int iIFshift = IF_INTERNAL_PREC - g_bitDepthC;
901          dstCr[j] = ( ( a*dstCr[j] + a*IF_INTERNAL_OFFS ) >> iShift ) + b*( 1<<iIFshift ) - IF_INTERNAL_OFFS;
902        }
903        else
904          dstCr[j] = Clip3( 0, ( 1 << g_bitDepthC ) - 1, ( ( a*dstCr[j] ) >> iShift ) + b );
905      }
906      dstCr += dstStride;
907    }
908  }
909#endif
910}
911
912Void TComPrediction::xWeightedAverage( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartIdx, Int iWidth, Int iHeight, TComYuv*& rpcYuvDst )
913{
914  if( iRefIdx0 >= 0 && iRefIdx1 >= 0 )
915  {
916    rpcYuvDst->addAvg( pcYuvSrc0, pcYuvSrc1, uiPartIdx, iWidth, iHeight );
917  }
918  else if ( iRefIdx0 >= 0 && iRefIdx1 <  0 )
919  {
920    pcYuvSrc0->copyPartToPartYuv( rpcYuvDst, uiPartIdx, iWidth, iHeight );
921  }
922  else if ( iRefIdx0 <  0 && iRefIdx1 >= 0 )
923  {
924    pcYuvSrc1->copyPartToPartYuv( rpcYuvDst, uiPartIdx, iWidth, iHeight );
925  }
926}
927
928// AMVP
929Void TComPrediction::getMvPredAMVP( TComDataCU* pcCU, UInt uiPartIdx, UInt uiPartAddr, RefPicList eRefPicList, TComMv& rcMvPred )
930{
931  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
932  if( pcAMVPInfo->iN <= 1 )
933  {
934    rcMvPred = pcAMVPInfo->m_acMvCand[0];
935
936    pcCU->setMVPIdxSubParts( 0, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
937    pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
938    return;
939  }
940
941  assert(pcCU->getMVPIdx(eRefPicList,uiPartAddr) >= 0);
942  rcMvPred = pcAMVPInfo->m_acMvCand[pcCU->getMVPIdx(eRefPicList,uiPartAddr)];
943  return;
944}
945
946/** Function for deriving planar intra prediction.
947 * \param pSrc pointer to reconstructed sample array
948 * \param srcStride the stride of the reconstructed sample array
949 * \param rpDst reference to pointer for the prediction sample array
950 * \param dstStride the stride of the prediction sample array
951 * \param width the width of the block
952 * \param height the height of the block
953 *
954 * This function derives the prediction samples for planar mode (intra coding).
955 */
956Void TComPrediction::xPredIntraPlanar( Int* pSrc, Int srcStride, Pel* rpDst, Int dstStride, UInt width, UInt height )
957{
958  assert(width == height);
959
960  Int k, l, bottomLeft, topRight;
961  Int horPred;
962  Int leftColumn[MAX_CU_SIZE], topRow[MAX_CU_SIZE], bottomRow[MAX_CU_SIZE], rightColumn[MAX_CU_SIZE];
963  UInt blkSize = width;
964  UInt offset2D = width;
965  UInt shift1D = g_aucConvertToBit[ width ] + 2;
966  UInt shift2D = shift1D + 1;
967
968  // Get left and above reference column and row
969  for(k=0;k<blkSize+1;k++)
970  {
971    topRow[k] = pSrc[k-srcStride];
972    leftColumn[k] = pSrc[k*srcStride-1];
973  }
974
975  // Prepare intermediate variables used in interpolation
976  bottomLeft = leftColumn[blkSize];
977  topRight   = topRow[blkSize];
978  for (k=0;k<blkSize;k++)
979  {
980    bottomRow[k]   = bottomLeft - topRow[k];
981    rightColumn[k] = topRight   - leftColumn[k];
982    topRow[k]      <<= shift1D;
983    leftColumn[k]  <<= shift1D;
984  }
985
986  // Generate prediction signal
987  for (k=0;k<blkSize;k++)
988  {
989    horPred = leftColumn[k] + offset2D;
990    for (l=0;l<blkSize;l++)
991    {
992      horPred += rightColumn[k];
993      topRow[l] += bottomRow[l];
994      rpDst[k*dstStride+l] = ( (horPred + topRow[l]) >> shift2D );
995    }
996  }
997}
998
999/** Function for filtering intra DC predictor.
1000 * \param pSrc pointer to reconstructed sample array
1001 * \param iSrcStride the stride of the reconstructed sample array
1002 * \param rpDst reference to pointer for the prediction sample array
1003 * \param iDstStride the stride of the prediction sample array
1004 * \param iWidth the width of the block
1005 * \param iHeight the height of the block
1006 *
1007 * This function performs filtering left and top edges of the prediction samples for DC mode (intra coding).
1008 */
1009Void TComPrediction::xDCPredFiltering( Int* pSrc, Int iSrcStride, Pel*& rpDst, Int iDstStride, Int iWidth, Int iHeight )
1010{
1011  Pel* pDst = rpDst;
1012  Int x, y, iDstStride2, iSrcStride2;
1013
1014  // boundary pixels processing
1015  pDst[0] = (Pel)((pSrc[-iSrcStride] + pSrc[-1] + 2 * pDst[0] + 2) >> 2);
1016
1017  for ( x = 1; x < iWidth; x++ )
1018  {
1019    pDst[x] = (Pel)((pSrc[x - iSrcStride] +  3 * pDst[x] + 2) >> 2);
1020  }
1021
1022  for ( y = 1, iDstStride2 = iDstStride, iSrcStride2 = iSrcStride-1; y < iHeight; y++, iDstStride2+=iDstStride, iSrcStride2+=iSrcStride )
1023  {
1024    pDst[iDstStride2] = (Pel)((pSrc[iSrcStride2] + 3 * pDst[iDstStride2] + 2) >> 2);
1025  }
1026
1027  return;
1028}
1029
1030#if H_3D_IC
1031/** Function for deriving the position of first non-zero binary bit of a value
1032 * \param x input value
1033 *
1034 * This function derives the position of first non-zero binary bit of a value
1035 */
1036Int GetMSB( UInt x )
1037{
1038  Int iMSB = 0, bits = ( sizeof( Int ) << 3 ), y = 1;
1039
1040  while( x > 1 )
1041  {
1042    bits >>= 1;
1043    y = x >> bits;
1044
1045    if( y )
1046    {
1047      x = y;
1048      iMSB += bits;
1049    }
1050  }
1051
1052  iMSB+=y;
1053
1054  return iMSB;
1055}
1056
1057/** Function for counting leading number of zeros/ones
1058 * \param x input value
1059 \ This function counts leading number of zeros for positive numbers and
1060 \ leading number of ones for negative numbers. This can be implemented in
1061 \ single instructure cycle on many processors.
1062 */
1063
1064Short CountLeadingZerosOnes (Short x)
1065{
1066  Short clz;
1067  Short i;
1068
1069  if(x == 0)
1070  {
1071    clz = 0;
1072  }
1073  else
1074  {
1075    if (x == -1)
1076    {
1077      clz = 15;
1078    }
1079    else
1080    {
1081      if(x < 0)
1082      {
1083        x = ~x;
1084      }
1085      clz = 15;
1086      for(i = 0;i < 15;++i)
1087      {
1088        if(x) 
1089        {
1090          clz --;
1091        }
1092        x = x >> 1;
1093      }
1094    }
1095  }
1096  return clz;
1097}
1098
1099/** Function for deriving LM illumination compensation.
1100 */
1101Void TComPrediction::xGetLLSICPrediction( TComDataCU* pcCU, TComMv *pMv, TComPicYuv *pRefPic, Int &a, Int &b, Int &iShift, TextType eType )
1102{
1103  TComPicYuv *pRecPic = pcCU->getPic()->getPicYuvRec();
1104  Pel *pRec = NULL, *pRef = NULL;
1105  UInt uiWidth, uiHeight, uiTmpPartIdx;
1106  Int iRecStride = ( eType == TEXT_LUMA ) ? pRecPic->getStride() : pRecPic->getCStride();
1107  Int iRefStride = ( eType == TEXT_LUMA ) ? pRefPic->getStride() : pRefPic->getCStride();
1108  Int iCUPelX, iCUPelY, iRefX, iRefY, iRefOffset, iHor, iVer;
1109
1110  iCUPelX = pcCU->getCUPelX() + g_auiRasterToPelX[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]];
1111  iCUPelY = pcCU->getCUPelY() + g_auiRasterToPelY[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]];
1112  iHor = pcCU->getSlice()->getIsDepth() ? pMv->getHor() : ( ( pMv->getHor() + 2 ) >> 2 );
1113  iVer = pcCU->getSlice()->getIsDepth() ? pMv->getVer() : ( ( pMv->getVer() + 2 ) >> 2 );
1114  iRefX   = iCUPelX + iHor;
1115  iRefY   = iCUPelY + iVer;
1116  if( eType != TEXT_LUMA )
1117  {
1118    iHor = pcCU->getSlice()->getIsDepth() ? ( ( pMv->getHor() + 1 ) >> 1 ) : ( ( pMv->getHor() + 4 ) >> 3 );
1119    iVer = pcCU->getSlice()->getIsDepth() ? ( ( pMv->getVer() + 1 ) >> 1 ) : ( ( pMv->getVer() + 4 ) >> 3 );
1120  }
1121  uiWidth  = ( eType == TEXT_LUMA ) ? pcCU->getWidth( 0 )  : ( pcCU->getWidth( 0 )  >> 1 );
1122  uiHeight = ( eType == TEXT_LUMA ) ? pcCU->getHeight( 0 ) : ( pcCU->getHeight( 0 ) >> 1 );
1123
1124  Int i, j, iCountShift = 0;
1125
1126  // LLS parameters estimation -->
1127
1128  Int x = 0, y = 0, xx = 0, xy = 0;
1129
1130  if( pcCU->getPUAbove( uiTmpPartIdx, pcCU->getZorderIdxInCU() ) && iCUPelY > 0 && iRefY > 0 )
1131  {
1132    iRefOffset = iHor + iVer * iRefStride - iRefStride;
1133    if( eType == TEXT_LUMA )
1134    {
1135      pRef = pRefPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
1136      pRec = pRecPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - iRecStride;
1137    }
1138    else if( eType == TEXT_CHROMA_U )
1139    {
1140      pRef = pRefPic->getCbAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
1141      pRec = pRecPic->getCbAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - iRecStride;
1142    }
1143    else
1144    {
1145      assert( eType == TEXT_CHROMA_V );
1146      pRef = pRefPic->getCrAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
1147      pRec = pRecPic->getCrAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - iRecStride;
1148    }
1149
1150    for( j = 0; j < uiWidth; j++ )
1151    {
1152      x += pRef[j];
1153      y += pRec[j];
1154      xx += pRef[j] * pRef[j];
1155      xy += pRef[j] * pRec[j];
1156    }
1157    iCountShift += g_aucConvertToBit[ uiWidth ] + 2;
1158  }
1159
1160
1161  if( pcCU->getPULeft( uiTmpPartIdx, pcCU->getZorderIdxInCU() ) && iCUPelX > 0 && iRefX > 0 )
1162  {
1163    iRefOffset = iHor + iVer * iRefStride - 1;
1164    if( eType == TEXT_LUMA )
1165    {
1166      pRef = pRefPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
1167      pRec = pRecPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - 1;
1168    }
1169    else if( eType == TEXT_CHROMA_U )
1170    {
1171      pRef = pRefPic->getCbAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
1172      pRec = pRecPic->getCbAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - 1;
1173    }
1174    else
1175    {
1176      assert( eType == TEXT_CHROMA_V );
1177      pRef = pRefPic->getCrAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
1178      pRec = pRecPic->getCrAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - 1;
1179    }
1180
1181    for( i = 0; i < uiHeight; i++ )
1182    {
1183      x += pRef[0];
1184      y += pRec[0];
1185      xx += pRef[0] * pRef[0];
1186      xy += pRef[0] * pRec[0];
1187
1188      pRef += iRefStride;
1189      pRec += iRecStride;
1190    }
1191    iCountShift += iCountShift > 0 ? 1 : ( g_aucConvertToBit[ uiWidth ] + 2 );
1192  }
1193
1194  Int iTempShift = ( ( eType == TEXT_LUMA ) ? g_bitDepthY : g_bitDepthC ) + g_aucConvertToBit[ uiWidth ] + 3 - 15;
1195
1196  if( iTempShift > 0 )
1197  {
1198    x  = ( x +  ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
1199    y  = ( y +  ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
1200    xx = ( xx + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
1201    xy = ( xy + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
1202    iCountShift -= iTempShift;
1203  }
1204
1205  iShift = 13;
1206
1207  if( iCountShift == 0 )
1208  {
1209    a = 1;
1210    b = 0;
1211    iShift = 0;
1212  }
1213  else
1214  {
1215    Int a1 = ( xy << iCountShift ) - y * x;
1216    Int a2 = ( xx << iCountShift ) - x * x;             
1217
1218    {
1219      const Int iShiftA2 = 6;
1220      const Int iShiftA1 = 15;
1221      const Int iAccuracyShift = 15;
1222
1223      Int iScaleShiftA2 = 0;
1224      Int iScaleShiftA1 = 0;
1225      Int a1s = a1;
1226      Int a2s = a2;
1227
1228      iScaleShiftA1 = GetMSB( abs( a1 ) ) - iShiftA1;
1229      iScaleShiftA2 = GetMSB( abs( a2 ) ) - iShiftA2; 
1230
1231      if( iScaleShiftA1 < 0 )
1232      {
1233        iScaleShiftA1 = 0;
1234      }
1235
1236      if( iScaleShiftA2 < 0 )
1237      {
1238        iScaleShiftA2 = 0;
1239      }
1240
1241      Int iScaleShiftA = iScaleShiftA2 + iAccuracyShift - iShift - iScaleShiftA1;
1242
1243      a2s = a2 >> iScaleShiftA2;
1244
1245      a1s = a1 >> iScaleShiftA1;
1246
1247      if (a2s >= 1)
1248      {
1249        a = a1s * m_uiaShift[ a2s - 1];
1250      }
1251      else
1252      {
1253        a = 0;
1254      }
1255
1256      if( iScaleShiftA < 0 )
1257      {
1258        a = a << -iScaleShiftA;
1259      }
1260      else
1261      {
1262        a = a >> iScaleShiftA;
1263      }
1264
1265      a = Clip3( -( 1 << 15 ), ( 1 << 15 ) - 1, a ); 
1266
1267      Int minA = -(1 << (6));
1268      Int maxA = (1 << 6) - 1;
1269      if( a <= maxA && a >= minA )
1270      {
1271        // do nothing
1272      }
1273      else
1274      {
1275        Short n = CountLeadingZerosOnes( a );
1276        a = a >> (9-n);
1277        iShift -= (9-n);
1278      }
1279
1280      b = (  y - ( ( a * x ) >> iShift ) + ( 1 << ( iCountShift - 1 ) ) ) >> iCountShift;
1281    }
1282  }   
1283}
1284#endif
1285//! \}
Note: See TracBrowser for help on using the repository browser.