Ticket #119: TComLoopFilter.cpp

File TComLoopFilter.cpp, 61.6 KB (added by andreyn, 13 years ago)

Bugfix. (To activate, set #define BUGFIX_119 1)

Line 
1/* ====================================================================================================================
2
3  The copyright in this software is being made available under the License included below.
4  This software may be subject to other third party and   contributor rights, including patent rights, and no such
5  rights are granted under this license.
6
7  Copyright (c) 2010, SAMSUNG ELECTRONICS CO., LTD. and BRITISH BROADCASTING CORPORATION
8  All rights reserved.
9
10  Redistribution and use in source and binary forms, with or without modification, are permitted only for
11  the purpose of developing standards within the Joint Collaborative Team on Video Coding and for testing and
12  promoting such standards. The following conditions are required to be met:
13
14    * Redistributions of source code must retain the above copyright notice, this list of conditions and
15      the following disclaimer.
16    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
17      the following disclaimer in the documentation and/or other materials provided with the distribution.
18    * Neither the name of SAMSUNG ELECTRONICS CO., LTD. nor the name of the BRITISH BROADCASTING CORPORATION
19      may be used to endorse or promote products derived from this software without specific prior written permission.
20
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
22  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 * ====================================================================================================================
30*/
31
32/** \file     TComLoopFilter.cpp
33    \brief    deblocking filter
34*/
35
36#include "TComLoopFilter.h"
37#include "TComSlice.h"
38#include "TComMv.h"
39
40// ====================================================================================================================
41// Constants
42// ====================================================================================================================
43
44#define   EDGE_VER    0
45#define   EDGE_HOR    1
46#define   QpUV(iQpY)  ( g_aucChromaScale[ Max( Min( (iQpY), MAX_QP ), MIN_QP ) ] )
47
48// ====================================================================================================================
49// Tables
50// ====================================================================================================================
51
52#if TENTM_DEBLOCKING_FILTER
53
54const UChar tctable_8x8[56] =
55{
56  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,5,5,6,6,7,8,9,9,10,10,11,11,12,12,13,13,14,14
57};
58
59const UChar betatable_8x8[52] =
60{
61  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64
62};
63
64#else
65const UChar ALPHA_TABLE[52]  = {0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,4,4,5,6,  7,8,9,10,12,13,15,17,  20,22,25,28,32,36,40,45,  50,56,63,71,80,90,101,113,  127,144,162,182,203,226,255,255} ;
66const UChar  BETA_TABLE[52]  = {0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,2,2,2,3,  3,3,3, 4, 4, 4, 6, 6,   7, 7, 8, 8, 9, 9,10,10,  11,11,12,12,13,13, 14, 14,   15, 15, 16, 16, 17, 17, 18, 18} ;
67const UChar CLIP_TAB[52][5]  =
68{
69  { 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},
70  { 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},
71  { 0, 0, 0, 0, 0},{ 0, 0, 0, 1, 1},{ 0, 0, 0, 1, 1},{ 0, 0, 0, 1, 1},{ 0, 0, 0, 1, 1},{ 0, 0, 1, 1, 1},{ 0, 0, 1, 1, 1},{ 0, 1, 1, 1, 1},
72  { 0, 1, 1, 1, 1},{ 0, 1, 1, 1, 1},{ 0, 1, 1, 1, 1},{ 0, 1, 1, 2, 2},{ 0, 1, 1, 2, 2},{ 0, 1, 1, 2, 2},{ 0, 1, 1, 2, 2},{ 0, 1, 2, 3, 3},
73  { 0, 1, 2, 3, 3},{ 0, 2, 2, 3, 3},{ 0, 2, 2, 4, 4},{ 0, 2, 3, 4, 4},{ 0, 2, 3, 4, 4},{ 0, 3, 3, 5, 5},{ 0, 3, 4, 6, 6},{ 0, 3, 4, 6, 6},
74  { 0, 4, 5, 7, 7},{ 0, 4, 5, 8, 8},{ 0, 4, 6, 9, 9},{ 0, 5, 7,10,10},{ 0, 6, 8,11,11},{ 0, 6, 8,13,13},{ 0, 7,10,14,14},{ 0, 8,11,16,16},
75  { 0, 9,12,18,18},{ 0,10,13,20,20},{ 0,11,15,23,23},{ 0,13,17,25,25}
76};
77#endif
78
79// ====================================================================================================================
80// Constructor / destructor / create / destroy
81// ====================================================================================================================
82
83TComLoopFilter::TComLoopFilter()
84#if HHI_DEBLOCKING_FILTER || TENTM_DEBLOCKING_FILTER
85: m_uiNumPartitions( 0 )
86#endif
87{
88  m_uiDisableDeblockingFilterIdc = 0;
89}
90
91TComLoopFilter::~TComLoopFilter()
92{
93}
94
95// ====================================================================================================================
96// Public member functions
97// ====================================================================================================================
98
99Void TComLoopFilter::setCfg( UInt uiDisableDblkIdc, Int iAlphaOffset, Int iBetaOffset)
100{
101  m_uiDisableDeblockingFilterIdc  = uiDisableDblkIdc;
102#if !TENTM_DEBLOCKING_FILTER
103  m_iAlphaOffset                  = iAlphaOffset;
104  m_iBetaOffset                   = iBetaOffset;
105#endif
106}
107
108#if HHI_DEBLOCKING_FILTER || TENTM_DEBLOCKING_FILTER
109Void TComLoopFilter::create( UInt uiMaxCUDepth )
110{
111  m_uiNumPartitions = 1 << ( uiMaxCUDepth<<1 );
112  for( UInt uiDir = 0; uiDir < 2; uiDir++ )
113    for( UInt uiPlane = 0; uiPlane < 3; uiPlane++ )
114    {
115      m_aapucBS       [uiDir][uiPlane] = new UChar[m_uiNumPartitions];
116      m_aapbEdgeFilter[uiDir][uiPlane] = new Bool [m_uiNumPartitions];
117    }
118}
119
120Void TComLoopFilter::destroy()
121{
122  for( UInt uiDir = 0; uiDir < 2; uiDir++ )
123    for( UInt uiPlane = 0; uiPlane < 3; uiPlane++ )
124    {
125      delete [] m_aapucBS       [uiDir][uiPlane];
126      delete [] m_aapbEdgeFilter[uiDir][uiPlane];
127    }
128}
129#endif
130
131/**
132    - call deblocking function for every CU
133    .
134    \param  pcPic   picture class (TComPic) pointer
135 */
136Void TComLoopFilter::loopFilterPic( TComPic* pcPic )
137{
138  if (m_uiDisableDeblockingFilterIdc == 1)
139    return;
140
141  // for every CU
142  for ( UInt uiCUAddr = 0; uiCUAddr < pcPic->getNumCUsInFrame(); uiCUAddr++ )
143  {
144    TComDataCU* pcCU = pcPic->getCU( uiCUAddr );
145
146#if HHI_DEBLOCKING_FILTER || TENTM_DEBLOCKING_FILTER
147    for( Int iDir = EDGE_VER; iDir <= EDGE_HOR; iDir++ )
148      for( Int iPlane = 0; iPlane < 3; iPlane++ )
149      {
150        ::memset( m_aapucBS       [iDir][iPlane], 0, sizeof( UChar ) * m_uiNumPartitions );
151        assert( 0 == false );
152        ::memset( m_aapbEdgeFilter[iDir][iPlane], 0, sizeof( bool  ) * m_uiNumPartitions );
153      }
154#endif
155    // CU-based deblocking
156    xDeblockCU( pcCU, 0, 0 );
157  }
158}
159
160// ====================================================================================================================
161// Protected member functions
162// ====================================================================================================================
163
164Void TComLoopFilter::xDeblockCU( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth )
165{
166  TComPic* pcPic     = pcCU->getPic();
167  UInt uiCurNumParts = pcPic->getNumPartInCU() >> (uiDepth<<1);
168  UInt uiQNumParts   = uiCurNumParts>>2;
169
170  if( pcCU->getDepth(uiAbsZorderIdx) > uiDepth )
171  {
172    for ( UInt uiPartIdx = 0; uiPartIdx < 4; uiPartIdx++, uiAbsZorderIdx+=uiQNumParts )
173    {
174      UInt uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsZorderIdx] ];
175      UInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsZorderIdx] ];
176      if( ( uiLPelX < pcCU->getSlice()->getSPS()->getWidth() ) && ( uiTPelY < pcCU->getSlice()->getSPS()->getHeight() ) )
177        xDeblockCU( pcCU, uiAbsZorderIdx, uiDepth+1 );
178    }
179    return;
180  }
181
182  xSetLoopfilterParam( pcCU, uiAbsZorderIdx );
183
184#if PLANAR_INTRA
185  Bool bVerDone = false;
186  Bool bHorDone = false;
187
188  if ( pcCU->getPlanarInfo( uiAbsZorderIdx, PLANAR_FLAG) )
189  {
190    // Check the vertical (left) border
191    if (m_stLFCUParam.bLeftEdge )
192    {
193      UInt        uiPartP;
194      TComDataCU* pcCUP = pcCU->getPULeft(uiPartP, uiAbsZorderIdx);
195
196      if ( pcCUP->getPlanarInfo( uiPartP, PLANAR_FLAG) && (pcCU->getHeight(uiAbsZorderIdx) == pcCUP->getHeight(uiPartP) ) )
197      {
198        xEdgeFilterPlanarIntra( pcCU, uiAbsZorderIdx, EDGE_VER );
199        bVerDone = true;
200      }
201    }
202
203    // Check the horizontal (top) border
204    if (m_stLFCUParam.bTopEdge )
205    {
206      UInt        uiPartP;
207      TComDataCU* pcCUP = pcCU->getPUAbove(uiPartP, uiAbsZorderIdx);
208
209      if ( pcCUP->getPlanarInfo( uiPartP, PLANAR_FLAG)  && (pcCU->getWidth(uiAbsZorderIdx) == pcCUP->getWidth(uiPartP) ))
210      {
211        xEdgeFilterPlanarIntra( pcCU, uiAbsZorderIdx, EDGE_HOR );
212        bHorDone = true;
213      }
214    }
215  }
216
217  if ( bVerDone && bHorDone )
218    return;
219#endif
220
221#if HHI_DEBLOCKING_FILTER || TENTM_DEBLOCKING_FILTER
222  xSetEdgefilterTU   ( pcCU, uiAbsZorderIdx, uiDepth );
223  xSetEdgefilterPU   ( pcCU, uiAbsZorderIdx );
224
225  for ( Int iDir = EDGE_VER; iDir <= EDGE_HOR; iDir++ )
226  {
227    for( UInt uiPartIdx = uiAbsZorderIdx; uiPartIdx < uiAbsZorderIdx + uiCurNumParts; uiPartIdx++ )
228    {
229      if ( m_aapbEdgeFilter[iDir][0][uiPartIdx] )
230      {
231        xGetBoundaryStrengthSingle ( pcCU, uiAbsZorderIdx, iDir, uiPartIdx );
232      }
233    }
234  }
235#endif
236
237#if HHI_DEBLOCKING_FILTER
238  for( Int iDir = EDGE_VER; iDir <= EDGE_HOR; iDir++ )
239  for( UInt uiPartIdx = uiAbsZorderIdx; uiPartIdx < uiAbsZorderIdx + uiCurNumParts; uiPartIdx++ )
240  {
241#if PLANAR_INTRA
242    if ( ( iDir == EDGE_VER && bVerDone ) || ( iDir == EDGE_HOR && bHorDone ) )
243      continue;
244#endif
245    xEdgeFilterLumaSingle  ( pcCU, uiPartIdx, iDir );
246    xEdgeFilterChromaSingle( pcCU, uiPartIdx, iDir );
247  }
248#elif TENTM_DEBLOCKING_FILTER
249  UInt uiPelsInPart = g_uiMaxCUWidth >> g_uiMaxCUDepth;
250  UInt PartIdxIncr = DEBLOCK_SMALLEST_BLOCK / uiPelsInPart ? DEBLOCK_SMALLEST_BLOCK / uiPelsInPart : 1 ;
251
252  UInt uiSizeInPU = pcPic->getNumPartInWidth()>>(uiDepth);
253
254  for ( Int iDir = EDGE_VER; iDir <= EDGE_HOR; iDir++ )
255  {
256#if PLANAR_INTRA
257    if ( ( iDir == EDGE_VER && bVerDone ) || ( iDir == EDGE_HOR && bHorDone ) )
258      continue;
259#endif
260    for ( Int iEdge = 0; iEdge < uiSizeInPU ; iEdge+=PartIdxIncr)
261    {
262      xEdgeFilterLuma     ( pcCU, uiAbsZorderIdx, uiDepth, iDir, iEdge );
263      if ( (iEdge % ( (DEBLOCK_SMALLEST_BLOCK<<1)/uiPelsInPart ) ) == 0 )
264        xEdgeFilterChroma   ( pcCU, uiAbsZorderIdx, uiDepth, iDir, iEdge );
265    }
266  }
267#else
268  xSetEdgefilter     ( pcCU, uiAbsZorderIdx );
269
270  for ( Int iDir = EDGE_VER; iDir <= EDGE_HOR; iDir++ )
271  {
272#if PLANAR_INTRA
273    if ( ( iDir == EDGE_VER && bVerDone ) || ( iDir == EDGE_HOR && bHorDone ) )
274      continue;
275#endif
276    for ( Int iEdge = 0; iEdge < 4; iEdge++ )
277    {
278      if ( m_stLFCUParam.bLumaEdgeFilter[iDir][iEdge] )
279      {
280        xGetBoundaryStrength ( pcCU, uiAbsZorderIdx, iDir, iEdge, uiDepth );
281        if (m_stLFCUParam.iBsEdgeSum[iDir][iEdge] != 0)
282        {
283          xEdgeFilterLuma     ( pcCU, uiAbsZorderIdx, iDir, iEdge );
284          xEdgeFilterChroma   ( pcCU, uiAbsZorderIdx, iDir, iEdge );
285        }
286      }
287    }
288  }
289#endif
290}
291
292#if HHI_DEBLOCKING_FILTER || TENTM_DEBLOCKING_FILTER
293Void TComLoopFilter::xSetEdgefilterMultiple( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdgeIdx, Bool bValue )
294{
295  const UInt uiWidthInBaseUnits  = pcCU->getPic()->getNumPartInWidth () >> uiDepth;
296  const UInt uiHeightInBaseUnits = pcCU->getPic()->getNumPartInHeight() >> uiDepth;
297  const UInt uiNumElem = iDir == 0 ? uiHeightInBaseUnits : uiWidthInBaseUnits;
298  assert( uiNumElem > 0 );
299  for( UInt ui = 0; ui < uiNumElem; ui++ )
300  {
301    const UInt uiBsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, iDir, iEdgeIdx, ui );
302    m_aapbEdgeFilter[iDir][0][uiBsIdx] = bValue;
303    m_aapbEdgeFilter[iDir][1][uiBsIdx] = bValue;
304    m_aapbEdgeFilter[iDir][2][uiBsIdx] = bValue;
305  }
306}
307
308Void TComLoopFilter::xSetEdgefilterTU( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth )
309{
310  if( pcCU->getTransformIdx( uiAbsZorderIdx ) + pcCU->getDepth( uiAbsZorderIdx) > uiDepth )
311  {
312    const UInt uiCurNumParts = pcCU->getPic()->getNumPartInCU() >> (uiDepth<<1);
313    const UInt uiQNumParts   = uiCurNumParts>>2;
314    for ( UInt uiPartIdx = 0; uiPartIdx < 4; uiPartIdx++, uiAbsZorderIdx+=uiQNumParts )
315    {
316      xSetEdgefilterTU( pcCU, uiAbsZorderIdx, uiDepth+1 );
317    }
318    return;
319  }
320  xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, 0, m_stLFCUParam.bInternalEdge );
321  xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, 0, m_stLFCUParam.bInternalEdge );
322}
323
324Void TComLoopFilter::xSetEdgefilterPU( TComDataCU* pcCU, UInt uiAbsZorderIdx )
325{
326  const UInt uiDepth = pcCU->getDepth( uiAbsZorderIdx );
327  const UInt uiWidthInBaseUnits  = pcCU->getPic()->getNumPartInWidth () >> uiDepth;
328  const UInt uiHeightInBaseUnits = pcCU->getPic()->getNumPartInHeight() >> uiDepth;
329  const UInt uiHWidthInBaseUnits  = uiWidthInBaseUnits  >> 1;
330  const UInt uiHHeightInBaseUnits = uiHeightInBaseUnits >> 1;
331  const UInt uiQWidthInBaseUnits  = uiWidthInBaseUnits  >> 2;
332  const UInt uiQHeightInBaseUnits = uiHeightInBaseUnits >> 2;
333
334  xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, 0, m_stLFCUParam.bLeftEdge );
335  xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, 0, m_stLFCUParam.bTopEdge );
336
337  switch ( pcCU->getPartitionSize( uiAbsZorderIdx ) )
338  {
339  case SIZE_2Nx2N:
340    {
341      break;
342    }
343  case SIZE_2NxN:
344    {
345      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
346      break;
347    }
348  case SIZE_Nx2N:
349    {
350      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiHWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
351      break;
352    }
353  case SIZE_NxN:
354    {
355      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiHWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
356      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
357      break;
358    }
359  case SIZE_2NxnU:
360    {
361      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiQHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
362      break;
363    }
364  case SIZE_2NxnD:
365    {
366      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHeightInBaseUnits - uiQHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
367      break;
368    }
369  case SIZE_nLx2N:
370    {
371      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiQWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
372      break;
373    }
374  case SIZE_nRx2N:
375    {
376      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiWidthInBaseUnits - uiQWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
377      break;
378    }
379  default:
380    {
381      assert(0);
382      break;
383    }
384}
385}
386#endif
387
388#if PLANAR_INTRA
389Void TComLoopFilter::xPelFilterPlanarIntra( Pel* piSrc, Int iOffset, Int iBlkSize )
390{
391  Int a1,a2,bitShift;
392  Int blkSizeHalf    = iBlkSize >> 1;
393  Int blkSizeQuarter = iBlkSize >> 2;
394  Int k;
395
396  switch (iBlkSize)
397  {
398  case 2:   return;
399  case 4:   bitShift = 1; break;
400  case 8:   bitShift = 2; break;
401  case 16:  bitShift = 3; break;
402  case 32:  bitShift = 4; break;
403  case 64:  bitShift = 5; break;
404  case 128: bitShift = 6; break;
405  default: assert( iBlkSize ); break;
406  }
407
408  a1 = piSrc[-blkSizeQuarter*iOffset];
409  a2 = piSrc[ blkSizeQuarter*iOffset];
410
411  for(k=1;k<blkSizeHalf;k++)
412  {
413      piSrc[(-blkSizeQuarter+k)*iOffset] = (a1*(blkSizeHalf-k) + a2*k + blkSizeQuarter) >> bitShift;
414  }
415}
416
417Void TComLoopFilter::xEdgeFilterPlanarIntra( TComDataCU* pcCU, UInt uiAbsZorderIdx, Int iDir )
418{
419  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
420  Pel*        piSrc       = pcPicYuvRec->getLumaAddr( pcCU->getAddr(), uiAbsZorderIdx );
421
422  Int   iStride   = pcPicYuvRec->getStride();
423  Int   iOffset, iSrcStep;
424  Int   iNumStep;
425
426  // Luminance parameters
427  if (iDir == EDGE_VER)
428  {
429    iOffset  = 1;
430    iSrcStep = iStride;
431    iNumStep = pcCU->getHeight(uiAbsZorderIdx);
432  }
433  else
434  {
435    iOffset  = iStride;
436    iSrcStep = 1;
437    iNumStep = pcCU->getWidth(uiAbsZorderIdx);
438  }
439
440  // Filter Y component
441  for ( UInt uiStep = 0; uiStep < iNumStep; uiStep++ )
442  {
443    xPelFilterPlanarIntra( piSrc+iSrcStep*uiStep, iOffset, iNumStep );
444  }
445
446  // Chrominance parameters
447  iStride = pcPicYuvRec->getCStride();
448
449  if (iDir == EDGE_VER)
450  {
451    iOffset  = 1;
452    iSrcStep = iStride;
453    iNumStep = pcCU->getHeight(uiAbsZorderIdx) >> 1;
454  }
455  else
456  {
457    iOffset  = iStride;
458    iSrcStep = 1;
459    iNumStep = pcCU->getWidth(uiAbsZorderIdx) >> 1;
460  }
461
462  // Filter U component
463  piSrc = pcPicYuvRec->getCbAddr( pcCU->getAddr(), uiAbsZorderIdx );
464
465  for ( UInt uiStep = 0; uiStep < iNumStep; uiStep++ )
466  {
467    xPelFilterPlanarIntra( piSrc + iSrcStep*uiStep, iOffset, iNumStep );
468  }
469
470  // Filter V component
471  piSrc = pcPicYuvRec->getCrAddr( pcCU->getAddr(), uiAbsZorderIdx );
472
473  for ( UInt uiStep = 0; uiStep < iNumStep; uiStep++ )
474  {
475    xPelFilterPlanarIntra( piSrc + iSrcStep*uiStep, iOffset, iNumStep );
476  }
477}
478#endif
479
480#if !HHI_DEBLOCKING_FILTER && !TENTM_DEBLOCKING_FILTER
481Void TComLoopFilter::xSetEdgefilter( TComDataCU* pcCU, UInt uiAbsZorderIdx )
482{
483  switch ( pcCU->getPartitionSize( uiAbsZorderIdx ) )
484  {
485  case SIZE_2Nx2N:
486    {
487      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][0] = m_stLFCUParam.bLeftEdge;
488      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][1] = false;
489      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][2] = false;
490      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][3] = false;
491
492      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][0] = m_stLFCUParam.bTopEdge;
493      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][1] = false;
494      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][2] = false;
495      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][3] = false;
496      break;
497    }
498  case SIZE_2NxN:
499    {
500      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][0] = m_stLFCUParam.bLeftEdge;
501      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][1] = false;
502      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][2] = false;
503      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][3] = false;
504
505      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][0] = m_stLFCUParam.bTopEdge;
506      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][1] = false;
507      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][2] = m_stLFCUParam.bInternalEdge;
508      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][3] = false;
509      break;
510    }
511  case SIZE_Nx2N:
512    {
513      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][0] = m_stLFCUParam.bLeftEdge;
514      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][1] = false;
515      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][2] = m_stLFCUParam.bInternalEdge;
516      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][3] = false;
517
518      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][0] = m_stLFCUParam.bTopEdge;
519      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][1] = false;
520      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][2] = false;
521      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][3] = false;
522      break;
523    }
524  case SIZE_NxN:
525    {
526      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][0] = m_stLFCUParam.bLeftEdge;
527      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][1] = false;
528      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][2] = m_stLFCUParam.bInternalEdge;
529      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][3] = false;
530
531      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][0] = m_stLFCUParam.bTopEdge;
532      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][1] = false;
533      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][2] = m_stLFCUParam.bInternalEdge;
534      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][3] = false;
535      break;
536    }
537  case SIZE_2NxnU:
538    {
539      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][0] = m_stLFCUParam.bLeftEdge;
540      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][1] = false;
541      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][2] = false;
542      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][3] = false;
543
544      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][0] = m_stLFCUParam.bTopEdge;
545      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][1] = m_stLFCUParam.bInternalEdge;
546      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][2] = false;
547      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][3] = false;
548      break;
549    }
550  case SIZE_2NxnD:
551    {
552      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][0] = m_stLFCUParam.bLeftEdge;
553      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][1] = false;
554      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][2] = false;
555      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][3] = false;
556
557      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][0] = m_stLFCUParam.bTopEdge;
558      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][1] = false;
559      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][2] = false;
560      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][3] = m_stLFCUParam.bInternalEdge;
561      break;
562    }
563  case SIZE_nLx2N:
564    {
565      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][0] = m_stLFCUParam.bLeftEdge;
566      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][1] = m_stLFCUParam.bInternalEdge;
567      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][2] = false;
568      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][3] = false;
569
570      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][0] = m_stLFCUParam.bTopEdge;
571      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][1] = false;
572      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][2] = false;
573      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][3] = false;
574      break;
575    }
576  case SIZE_nRx2N:
577    {
578      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][0] = m_stLFCUParam.bLeftEdge;
579      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][1] = false;
580      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][2] = false;
581      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][3] = m_stLFCUParam.bInternalEdge;
582
583      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][0] = m_stLFCUParam.bTopEdge;
584      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][1] = false;
585      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][2] = false;
586      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][3] = false;
587      break;
588    }
589  default:
590    {
591      assert(0);
592      break;
593    }
594  }
595
596  switch ( pcCU->getTransformIdx( uiAbsZorderIdx ) )
597  {
598  case 0:
599    {
600      //follows to prediction boundary??
601      break;
602    }
603  case 1:
604    {
605      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][2] = m_stLFCUParam.bInternalEdge;
606      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][2] = m_stLFCUParam.bInternalEdge;
607      break;
608    }
609  case 2:
610    {
611      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][1] = m_stLFCUParam.bInternalEdge;
612      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][2] = m_stLFCUParam.bInternalEdge;
613      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][3] = m_stLFCUParam.bInternalEdge;
614
615      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][1] = m_stLFCUParam.bInternalEdge;
616      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][2] = m_stLFCUParam.bInternalEdge;
617      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][3] = m_stLFCUParam.bInternalEdge;
618      break;
619    }
620  default:
621    {
622      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][1] = m_stLFCUParam.bInternalEdge;
623      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][2] = m_stLFCUParam.bInternalEdge;
624      m_stLFCUParam.bLumaEdgeFilter[EDGE_VER][3] = m_stLFCUParam.bInternalEdge;
625
626      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][1] = m_stLFCUParam.bInternalEdge;
627      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][2] = m_stLFCUParam.bInternalEdge;
628      m_stLFCUParam.bLumaEdgeFilter[EDGE_HOR][3] = m_stLFCUParam.bInternalEdge;
629      break;
630    }
631  }
632}
633#endif
634
635Void TComLoopFilter::xSetLoopfilterParam( TComDataCU* pcCU, UInt uiAbsZorderIdx )
636{
637  UInt uiX           = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsZorderIdx ] ];
638  UInt uiY           = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsZorderIdx ] ];
639
640  m_stLFCUParam.bInternalEdge = m_uiDisableDeblockingFilterIdc ? false : true ;
641
642  if ( (uiX == 0) || (m_uiDisableDeblockingFilterIdc == 1) )
643    m_stLFCUParam.bLeftEdge = false;
644  else
645    m_stLFCUParam.bLeftEdge = true;
646
647  if ( (uiY == 0 ) || (m_uiDisableDeblockingFilterIdc == 1) )
648    m_stLFCUParam.bTopEdge = false;
649  else
650    m_stLFCUParam.bTopEdge = true;
651}
652
653#if HHI_DEBLOCKING_FILTER || TENTM_DEBLOCKING_FILTER
654Void TComLoopFilter::xGetBoundaryStrengthSingle ( TComDataCU* pcCU, UInt uiAbsZorderIdx, Int iDir, UInt uiAbsPartIdx )
655{
656  const UInt uiHWidth  = pcCU->getWidth( uiAbsZorderIdx ) >> 1;
657  const UInt uiHHeight = pcCU->getHeight( uiAbsZorderIdx ) >> 1;
658  const bool bAtCUBoundary = iDir == EDGE_VER ? g_auiRasterToPelX[g_auiZscanToRaster[uiAbsZorderIdx]] == g_auiRasterToPelX[g_auiZscanToRaster[uiAbsPartIdx]]
659                                              : g_auiRasterToPelY[g_auiZscanToRaster[uiAbsZorderIdx]] == g_auiRasterToPelY[g_auiZscanToRaster[uiAbsPartIdx]];
660  const bool bAtCUHalf     = iDir == EDGE_VER ? ( g_auiRasterToPelX[g_auiZscanToRaster[uiAbsZorderIdx]] + uiHWidth ) == g_auiRasterToPelX[g_auiZscanToRaster[uiAbsPartIdx]]
661                                              : ( g_auiRasterToPelY[g_auiZscanToRaster[uiAbsZorderIdx]] + uiHHeight ) == g_auiRasterToPelY[g_auiZscanToRaster[uiAbsPartIdx]];
662  TComSlice* const pcSlice = pcCU->getSlice();
663 
664  const UInt uiPartQ = uiAbsPartIdx;
665  TComDataCU* const pcCUQ = pcCU;
666
667  UInt uiPartP;
668  TComDataCU* pcCUP;
669#ifdef QC_AMVRES
670  UInt mvlimit= 4<<(Int)(pcCU->getSlice()->getSPS()->getUseAMVRes());
671#endif
672  UInt uiBs;
673
674  //-- Calculate Block Index
675  if (iDir == EDGE_VER)
676  {
677    pcCUP = pcCUQ->getPULeft(uiPartP, uiPartQ);
678  }
679  else  // (iDir == EDGE_HOR)
680  {
681    pcCUP = pcCUQ->getPUAbove(uiPartP, uiPartQ);
682  }
683
684  //-- Set BS for Intra MB : BS = 4 or 3
685  if ( pcCUP->isIntra(uiPartP) || pcCUQ->isIntra(uiPartQ) )
686  {
687    uiBs = bAtCUBoundary ? 4 : 3;   // Intra MB && MB boundary
688  }
689
690  //-- Set BS for not Intra MB : BS = 2 or 1 or 0
691  if ( !pcCUP->isIntra(uiPartP) && !pcCUQ->isIntra(uiPartQ) )
692  {
693    if ( pcCUQ->getCbf( uiPartQ, TEXT_LUMA, pcCUQ->getTransformIdx(uiPartQ)) != 0 || pcCUP->getCbf( uiPartP, TEXT_LUMA, pcCUP->getTransformIdx(uiPartP) ) != 0)
694    {
695      uiBs = 2;
696    }
697    else
698    {
699      if (pcSlice->isInterB())
700      {
701        Int iRefIdx;
702        Int *piRefP0, *piRefP1, *piRefQ0, *piRefQ1;
703        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
704        piRefP0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
705        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartP);
706        piRefP1 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx);
707        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
708        piRefQ0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
709        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartQ);
710        piRefQ1 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx);
711
712
713        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
714        TComMv pcMvP1 = pcCUP->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartP);
715        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
716        TComMv pcMvQ1 = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartQ);
717#ifdef DCM_PBIC
718        TComIc pcIcP  = pcCUP->getCUIcField()->getIc(uiPartP);
719        TComIc pcIcQ  = pcCUQ->getCUIcField()->getIc(uiPartQ);
720#endif
721
722        if ( ((piRefP0==piRefQ0)&&(piRefP1==piRefQ1)) || ((piRefP0==piRefQ1)&&(piRefP1==piRefQ0)) )
723        {
724          uiBs = 0;
725#ifdef QC_AMVRES
726          if ( piRefP0 != piRefP1 )   // Different L0 & L1
727          {
728            if ( piRefP0 == piRefQ0 )
729            {
730              pcMvP0 -= pcMvQ0;   pcMvP1 -= pcMvQ1;
731#ifdef DCM_PBIC
732              uiBs = (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit) |
733                     (pcMvP1.getAbsHor() >= mvlimit) | (pcMvP1.getAbsVer() >= mvlimit) |
734                     !(pcIcP.isequalIcParam(pcIcQ));
735#else
736              uiBs = (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit) |
737                     (pcMvP1.getAbsHor() >= mvlimit) | (pcMvP1.getAbsVer() >= mvlimit);
738#endif
739            }
740            else
741            {
742              pcMvP0 -= pcMvQ1;   pcMvP1 -= pcMvQ0;
743#ifdef DCM_PBIC
744              Int iParam0, iParam1, iParam2;
745              pcIcP.getIcParam( iParam0, iParam1, iParam2 );
746              pcIcP.setIcParam( iParam0,-iParam1, iParam2 );
747              uiBs = (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit) |
748                     (pcMvP1.getAbsHor() >= mvlimit) | (pcMvP1.getAbsVer() >= mvlimit) |
749                     !(pcIcP.isequalIcParam(pcIcQ));
750#else
751              uiBs = (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit) |
752                     (pcMvP1.getAbsHor() >= mvlimit) | (pcMvP1.getAbsVer() >= mvlimit);
753#endif
754            }
755          }
756          else    // Same L0 & L1
757          {
758            TComMv pcMvSub0 = pcMvP0 - pcMvQ0;
759            TComMv pcMvSub1 = pcMvP1 - pcMvQ1;
760            pcMvP0 -= pcMvQ1;   pcMvP1 -= pcMvQ0;
761#ifdef DCM_PBIC
762            uiBs = (pcMvSub0.getAbsHor() >= mvlimit) | (pcMvSub0.getAbsVer() >= mvlimit) |
763                   (pcMvSub1.getAbsHor() >= mvlimit) | (pcMvSub1.getAbsVer() >= mvlimit) |
764                   !(pcIcP.isequalIcParam(pcIcQ));
765            Int iParam0, iParam1, iParam2;
766            pcIcP.getIcParam( iParam0, iParam1, iParam2 );
767            pcIcP.setIcParam( iParam0,-iParam1, iParam2 );
768            uiBs = uiBs && 
769                   ( (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit) |
770                     (pcMvP1.getAbsHor() >= mvlimit) | (pcMvP1.getAbsVer() >= mvlimit) |
771                     !(pcIcP.isequalIcParam(pcIcQ)) );
772#else
773            uiBs = ( (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit) |
774                     (pcMvP1.getAbsHor() >= mvlimit) | (pcMvP1.getAbsVer() >= mvlimit) ) &&
775                   ( (pcMvSub0.getAbsHor() >= mvlimit) | (pcMvSub0.getAbsVer() >= mvlimit) |
776                     (pcMvSub1.getAbsHor() >= mvlimit) | (pcMvSub1.getAbsVer() >= mvlimit) );
777#endif
778          }
779#else
780          if ( piRefP0 != piRefP1 )   // Different L0 & L1
781          {
782            if ( piRefP0 == piRefQ0 )
783            {
784              pcMvP0 -= pcMvQ0;   pcMvP1 -= pcMvQ1;
785#ifdef DCM_PBIC
786              uiBs = (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
787                     (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4) |
788                     !(pcIcP.isequalIcParam(pcIcQ));
789#else
790              uiBs = (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
791                     (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4);
792#endif
793            }
794            else
795            {
796              pcMvP0 -= pcMvQ1;   pcMvP1 -= pcMvQ0;
797#ifdef DCM_PBIC
798              Int iParam0, iParam1, iParam2;
799              pcIcP.getIcParam( iParam0, iParam1, iParam2 );
800              pcIcP.setIcParam( iParam0,-iParam1, iParam2 );
801              uiBs = (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
802                     (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4) |
803                     !(pcIcP.isequalIcParam(pcIcQ));
804#else
805              uiBs = (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
806                     (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4);
807#endif
808            }
809          }
810          else    // Same L0 & L1
811          {
812            TComMv pcMvSub0 = pcMvP0 - pcMvQ0;
813            TComMv pcMvSub1 = pcMvP1 - pcMvQ1;
814            pcMvP0 -= pcMvQ1;   pcMvP1 -= pcMvQ0;
815#ifdef DCM_PBIC
816            uiBs = (pcMvSub0.getAbsHor() >= 4) | (pcMvSub0.getAbsVer() >= 4) |
817                   (pcMvSub1.getAbsHor() >= 4) | (pcMvSub1.getAbsVer() >= 4) |
818                   !(pcIcP.isequalIcParam(pcIcQ));
819            Int iParam0, iParam1, iParam2;
820            pcIcP.getIcParam( iParam0, iParam1, iParam2 );
821            pcIcP.setIcParam( iParam0,-iParam1, iParam2 );
822            uiBs = uiBs && 
823                   ( (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
824                     (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4) |
825                     !(pcIcP.isequalIcParam(pcIcQ)) );
826#else
827            uiBs = ( (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
828                     (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4) ) &&
829                   ( (pcMvSub0.getAbsHor() >= 4) | (pcMvSub0.getAbsVer() >= 4) |
830                     (pcMvSub1.getAbsHor() >= 4) | (pcMvSub1.getAbsVer() >= 4) );
831#endif
832          }
833#endif
834        }
835        else // for all different Ref_Idx
836        {
837          uiBs = 1;
838        }
839      }
840      else  // pcSlice->isInterP()
841      {
842        Int iRefIdx;
843        Int *piRefP0, *piRefQ0;
844        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
845        piRefP0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
846        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
847        piRefQ0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
848        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
849        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
850#ifdef DCM_PBIC
851        TComIc pcIcP  = pcCUP->getCUIcField()->getIc(uiPartP);
852        TComIc pcIcQ  = pcCUQ->getCUIcField()->getIc(uiPartQ);
853#endif
854
855        pcMvP0 -= pcMvQ0;
856#ifdef QC_AMVRES
857#ifdef DCM_PBIC
858        uiBs = (piRefP0 != piRefQ0) | (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit) | !(pcIcP.isequalIcParam(pcIcQ));
859#else
860        uiBs = (piRefP0 != piRefQ0) | (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit);
861#endif
862#else
863#ifdef DCM_PBIC
864        uiBs = (piRefP0 != piRefQ0) | (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) | !(pcIcP.isequalIcParam(pcIcQ));
865#else
866        uiBs = (piRefP0 != piRefQ0) | (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4);
867#endif
868#endif
869      }
870    }   // enf of "if( one of BCBP == 0 )"
871  }   // enf of "if( not Intra )"
872
873  m_aapucBS[iDir][0][uiAbsPartIdx] = uiBs;
874  if ( bAtCUBoundary || bAtCUHalf )
875  {
876    m_aapucBS[iDir][1][uiAbsPartIdx] = uiBs;
877    m_aapucBS[iDir][2][uiAbsPartIdx] = uiBs;
878  }
879}
880#endif
881
882#if HHI_DEBLOCKING_FILTER
883Void TComLoopFilter::xEdgeFilterLumaSingle( TComDataCU* pcCU, UInt uiAbsZorderIdx, Int iDir )
884{
885  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
886  Pel*        piSrc       = pcPicYuvRec->getLumaAddr( pcCU->getAddr(), uiAbsZorderIdx );
887
888  Int   iStride   = pcPicYuvRec->getStride();
889  Int   iQP = pcCU->getQP( uiAbsZorderIdx );
890  Int   iOffset, iSrcStep;
891  UInt  uiNumStep;
892
893  if (iDir == EDGE_VER)
894  {
895    iOffset = 1;
896    iSrcStep = iStride;
897    uiNumStep = g_uiMaxCUHeight >> g_uiMaxCUDepth;
898  }
899  else  // (iDir == EDGE_HOR)
900  {
901    iOffset = iStride;
902    iSrcStep = 1;
903    uiNumStep = g_uiMaxCUWidth >> g_uiMaxCUDepth;
904  }
905
906  const UChar ucBs = m_aapucBS[iDir][0][uiAbsZorderIdx];
907
908  if ( ucBs )
909  {
910    for ( UInt uiStep = 0; uiStep < uiNumStep; uiStep++ )
911    {
912      xPelFilterLuma( piSrc+iSrcStep*uiStep, iOffset, ucBs, iQP );
913    }
914  }
915}
916
917Void TComLoopFilter::xEdgeFilterChromaSingle( TComDataCU* pcCU, UInt uiAbsZorderIdx, Int iDir )
918{
919  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
920  Int         iStride     = pcPicYuvRec->getCStride();
921  Pel*        piSrcCb     = pcPicYuvRec->getCbAddr( pcCU->getAddr(), uiAbsZorderIdx );
922  Pel*        piSrcCr     = pcPicYuvRec->getCrAddr( pcCU->getAddr(), uiAbsZorderIdx );
923
924  Int   iQP       = QpUV((Int) pcCU->getQP( uiAbsZorderIdx ));
925
926  UInt  uiNumStep;
927  Int   iOffset, iSrcStep;
928
929  if (iDir == EDGE_VER)
930  {
931    iOffset   = 1;
932    iSrcStep  = iStride;
933    uiNumStep = g_uiMaxCUHeight >> ( 1 + g_uiMaxCUDepth );
934  }
935  else  // (iDir == EDGE_HOR)
936  {
937    iOffset   = iStride;
938    iSrcStep  = 1;
939    uiNumStep = g_uiMaxCUWidth >> ( 1 + g_uiMaxCUDepth );
940  }
941
942  const UChar ucBsCb = m_aapucBS[iDir][1][uiAbsZorderIdx];
943  const UChar ucBsCr = m_aapucBS[iDir][2][uiAbsZorderIdx];
944
945  if ( ucBsCb )
946  {
947    for ( UInt uiStep = 0; uiStep < uiNumStep; uiStep++ )
948    {
949      xPelFilterChroma( piSrcCb + iSrcStep*uiStep, iOffset, ucBsCb, iQP );
950    }
951  }
952
953  if ( ucBsCr )
954  {
955    for ( UInt uiStep = 0; uiStep < uiNumStep; uiStep++ )
956    {
957      xPelFilterChroma( piSrcCr + iSrcStep*uiStep, iOffset, ucBsCr, iQP );
958    }
959  }
960}
961
962#elif TENTM_DEBLOCKING_FILTER
963Void TComLoopFilter::xEdgeFilterLuma( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdge  )
964{
965  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
966  Pel* piSrc    = pcPicYuvRec->getLumaAddr( pcCU->getAddr(), uiAbsZorderIdx );
967  Pel* piTmpSrc = piSrc;
968
969  Int  iStride = pcPicYuvRec->getStride();
970  Int  iQP = pcCU->getQP( uiAbsZorderIdx );
971  UInt uiNumParts = pcCU->getPic()->getNumPartInWidth()>>uiDepth;
972
973  UInt  uiPelsInPart = g_uiMaxCUWidth >> g_uiMaxCUDepth;
974  UInt  PartIdxIncr = DEBLOCK_SMALLEST_BLOCK / uiPelsInPart ? DEBLOCK_SMALLEST_BLOCK / uiPelsInPart : 1;
975  UInt  uiBlocksInPart = uiPelsInPart / DEBLOCK_SMALLEST_BLOCK ? uiPelsInPart / DEBLOCK_SMALLEST_BLOCK : 1;
976  UInt  uiBsAbsIdx, uiBs;
977  Int   iOffset, iSrcStep;
978
979  if (iDir == EDGE_VER)
980  {
981    iOffset = 1;
982    iSrcStep = iStride;
983    piTmpSrc += iEdge*uiPelsInPart;
984  }
985  else  // (iDir == EDGE_HOR)
986  {
987    iOffset = iStride;
988    iSrcStep = 1;
989    piTmpSrc += iEdge*uiPelsInPart*iStride;
990  }
991
992  for ( Int iIdx = 0; iIdx < uiNumParts; iIdx+=PartIdxIncr )
993  {
994
995    uiBs = 0;
996    for (Int iIdxInside = 0; iIdxInside<PartIdxIncr; iIdxInside++)
997    {
998      uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, iDir, iEdge, iIdx+iIdxInside);
999      if (uiBs < m_aapucBS[iDir][0][uiBsAbsIdx])
1000      {
1001        uiBs = m_aapucBS[iDir][0][uiBsAbsIdx];
1002      }
1003    }
1004
1005    Int iBitdepthScale = (1<<g_uiBitIncrement);
1006
1007    UInt uiTcOffset = (uiBs>2)?4:0;
1008
1009    Int iIndexTC = Clip3(0, MAX_QP+4, iQP + uiTcOffset );
1010    Int iIndexB = Clip3(0, MAX_QP, iQP );
1011
1012    Int iTc =  tctable_8x8[iIndexTC]*iBitdepthScale;
1013    Int iBeta = betatable_8x8[iIndexB]*iBitdepthScale;
1014
1015    for (Int iBlkIdx = 0; iBlkIdx< uiBlocksInPart; iBlkIdx ++)
1016    {
1017      if ( uiBs )
1018      {
1019        Int iD = xCalcD( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+2), iOffset) + xCalcD( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+5), iOffset);
1020        if (iD < iBeta)
1021        {
1022          for ( UInt i = 0; i < DEBLOCK_SMALLEST_BLOCK; i++)
1023          {
1024            xPelFilterLuma( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+i), iOffset, iD, iBeta, iTc );
1025          }
1026        }
1027      }
1028    }
1029  }
1030}
1031
1032
1033Void TComLoopFilter::xEdgeFilterChroma( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdge )
1034{
1035  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
1036  Int         iStride     = pcPicYuvRec->getCStride();
1037  Pel*        piSrcCb     = pcPicYuvRec->getCbAddr( pcCU->getAddr(), uiAbsZorderIdx );
1038  Pel*        piSrcCr     = pcPicYuvRec->getCrAddr( pcCU->getAddr(), uiAbsZorderIdx );
1039
1040  Int   iQP = QpUV((Int) pcCU->getQP( uiAbsZorderIdx ));
1041  UInt  uiPelsInPartChroma = g_uiMaxCUWidth >> (g_uiMaxCUDepth+1);
1042#if !BUGFIX_119
1043  UInt  uiBlocksInPart = uiPelsInPartChroma / DEBLOCK_SMALLEST_BLOCK ? uiPelsInPartChroma / DEBLOCK_SMALLEST_BLOCK : 1;
1044#endif
1045  Int   iOffset, iSrcStep;
1046
1047  const UInt uiLCUWidthInBaseUnits = pcCU->getPic()->getNumPartInWidth();
1048
1049// Vertical Position
1050  UInt uiEdgeNumInLCUVert = g_auiZscanToRaster[uiAbsZorderIdx]%uiLCUWidthInBaseUnits + iEdge;
1051  UInt uiEdgeNumInLCUHor = g_auiZscanToRaster[uiAbsZorderIdx]/uiLCUWidthInBaseUnits + iEdge;
1052#if BUGFIX_119
1053  if ( (uiEdgeNumInLCUVert%(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChroma))&&(iDir==0) || (uiEdgeNumInLCUHor%(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChroma))&& iDir  )
1054#else
1055  if ( (uiEdgeNumInLCUVert%(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChroma)) || (uiEdgeNumInLCUHor%(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChroma)) )
1056#endif
1057    return;
1058
1059  UInt  uiNumParts = pcCU->getPic()->getNumPartInWidth()>>uiDepth;
1060
1061#if !BUGFIX_119
1062  UInt  PartIdxIncr = DEBLOCK_SMALLEST_BLOCK / uiPelsInPartChroma ? DEBLOCK_SMALLEST_BLOCK / uiPelsInPartChroma : 1;
1063#endif
1064  UInt  uiBsAbsIdx;
1065  UChar ucBs;
1066
1067  Pel* piTmpSrcCb = piSrcCb;
1068  Pel* piTmpSrcCr = piSrcCr;
1069
1070
1071  if (iDir == EDGE_VER)
1072  {
1073    iOffset   = 1;
1074    iSrcStep  = iStride;
1075    piTmpSrcCb += iEdge*uiPelsInPartChroma;
1076    piTmpSrcCr += iEdge*uiPelsInPartChroma;
1077  }
1078  else  // (iDir == EDGE_HOR)
1079  {
1080    iOffset   = iStride;
1081    iSrcStep  = 1;
1082    piTmpSrcCb += iEdge*iStride*uiPelsInPartChroma;
1083    piTmpSrcCr += iEdge*iStride*uiPelsInPartChroma;
1084  }
1085
1086#if BUGFIX_119
1087  for ( Int iIdx = 0; iIdx < uiNumParts; iIdx++ )
1088#else
1089  for ( Int iIdx = 0; iIdx < uiNumParts; iIdx+=PartIdxIncr )
1090#endif
1091  {
1092    ucBs = 0;
1093
1094#if BUGFIX_119
1095    uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, iDir, iEdge, iIdx);
1096    ucBs = m_aapucBS[iDir][0][uiBsAbsIdx];
1097#else
1098    for (Int iIdxInside = 0; iIdxInside<PartIdxIncr; iIdxInside++)
1099    {
1100      uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, iDir, iEdge, iIdx+iIdxInside);
1101      if (ucBs < m_aapucBS[iDir][0][uiBsAbsIdx])
1102      {
1103        ucBs = m_aapucBS[iDir][0][uiBsAbsIdx];
1104      }
1105    }
1106#endif
1107    Int iBitdepthScale = (1<<g_uiBitIncrement);
1108
1109    UInt uiTcOffset = (ucBs>2)?4:0;
1110
1111    Int iIndexTC = Clip3(0, MAX_QP+4, iQP + uiTcOffset );
1112
1113    Int iTc =  tctable_8x8[iIndexTC]*iBitdepthScale;
1114
1115#if BUGFIX_119
1116    if ( ucBs > 2)
1117    {
1118      for ( UInt uiStep = 0; uiStep < uiPelsInPartChroma; uiStep++ )
1119      {
1120        xPelFilterChroma( piTmpSrcCb + iSrcStep*(uiStep+iIdx*uiPelsInPartChroma), iOffset, iTc );
1121        xPelFilterChroma( piTmpSrcCr + iSrcStep*(uiStep+iIdx*uiPelsInPartChroma), iOffset, iTc );
1122#else
1123    for (Int iBlkIdx = 0; iBlkIdx < uiBlocksInPart; iBlkIdx ++)
1124    {
1125
1126      if ( ucBs > 2)
1127      {
1128        for ( UInt uiStep = 0; uiStep < DEBLOCK_SMALLEST_BLOCK; uiStep++ )
1129        {
1130          xPelFilterChroma( piTmpSrcCb + iSrcStep*(uiStep+iIdx*uiPelsInPartChroma+iBlkIdx*DEBLOCK_SMALLEST_BLOCK), iOffset, iTc );
1131          xPelFilterChroma( piTmpSrcCr + iSrcStep*(uiStep+iIdx*uiPelsInPartChroma+iBlkIdx*DEBLOCK_SMALLEST_BLOCK), iOffset, iTc );
1132        }
1133#endif
1134      }
1135    }
1136  }
1137}
1138
1139
1140__inline Void TComLoopFilter::xPelFilterLuma( Pel* piSrc, Int iOffset, Int d, Int beta, Int tc )
1141{
1142
1143  Int d_strong, delta;
1144
1145  Pel m4  = piSrc[0];
1146  Pel m3  = piSrc[-iOffset];
1147  Pel m5  = piSrc[ iOffset];
1148  Pel m2  = piSrc[-iOffset*2];
1149  Pel m6  = piSrc[ iOffset*2];
1150  Pel m1  = piSrc[-iOffset*3];
1151  Pel m7  = piSrc[ iOffset*3];
1152  Pel m0  = piSrc[-iOffset*4];
1153
1154  d_strong = abs(m0-m3) + abs(m7-m4);
1155
1156  if ( (d_strong < (beta>>3)) && (d<(beta>>2)) && ( abs(m3-m4) < ((tc*5+1)>>1)) ) //strong filtering
1157  {
1158
1159    piSrc[-iOffset] = Clip(( m1 + 2*m2 + 2*m3 + 2*m4 + m5 + 4) >> 3 );
1160    piSrc[0] = Clip(( m2 + 2*m3 + 2*m4 + 2*m5 + m6 + 4) >> 3 );
1161
1162    piSrc[-iOffset*2] = Clip(( m1 + m2 + m3 + m4 + 2)>>2);
1163    piSrc[ iOffset] = Clip(( m3 + m4 + m5 + m6 + 2)>>2);
1164
1165    piSrc[-iOffset*3] = Clip(( 2*m0 + 3*m1 + m2 + m3 + m4 + 4 )>>3);
1166    piSrc[ iOffset*2] = Clip(( m3 + m4 + m5 + 3*m6 + 2*m7 +4 )>>3);
1167
1168  }
1169  else
1170  {
1171    /* Weak filter */
1172
1173    delta = Clip3(-tc, tc, ((13*(m4-m3) + 4*(m5-m2) - 5*(m6-m1)+16)>>5) );
1174
1175    piSrc[-iOffset] = Clip(m3+delta);
1176    piSrc[0] = Clip(m4-delta);
1177    piSrc[-iOffset*2] = Clip(m2+delta/2);
1178    piSrc[ iOffset] = Clip(m5-delta/2);
1179  }
1180}
1181
1182__inline Void TComLoopFilter::xPelFilterChroma( Pel* piSrc, Int iOffset, Int tc )
1183{
1184  int delta;
1185
1186  Pel m4  = piSrc[0];
1187  Pel m3  = piSrc[-iOffset];
1188  Pel m5  = piSrc[ iOffset];
1189  Pel m2  = piSrc[-iOffset*2];
1190
1191  delta = Clip3(-tc,tc, (((( m4 - m3 ) << 2 ) + m2 - m5 + 4 ) >> 3) );
1192  piSrc[-iOffset] = Clip(m3+delta);
1193  piSrc[0] = Clip(m4-delta);
1194}
1195
1196
1197__inline Int TComLoopFilter::xCalcD( Pel* piSrc, Int iOffset)
1198{
1199  return abs( piSrc[-iOffset*3] - 2*piSrc[-iOffset*2] + piSrc[-iOffset] ) + abs( piSrc[0] - 2*piSrc[iOffset] + piSrc[iOffset*2] );
1200}
1201#else
1202
1203Void TComLoopFilter::xGetBoundaryStrength( TComDataCU* pcCU, UInt uiAbsZorderIdx, Int iDir, Int iEdge, UInt uiDepth )
1204{
1205  TComPic* pcPic = pcCU->getPic();
1206  UInt uiCurNumParts    = pcPic->getNumPartInCU() >> (uiDepth<<1);
1207  UInt uiHNumParts      = uiCurNumParts>>1;
1208  UInt uiQNumParts      = uiCurNumParts>>2;
1209
1210  UInt uiPartP, uiPartQ;
1211  UInt uiBsIdx; //index to store Bs for each transform boundary
1212
1213  TComSlice* pcSlice = pcCU->getSlice();
1214  TComDataCU* pcCUQ = pcCU;
1215  TComDataCU* pcCUP;
1216#ifdef QC_AMVRES
1217  UInt mvlimit= 4<<(Int)(pcCU->getSlice()->getSPS()->getUseAMVRes());
1218#endif
1219  m_stLFCUParam.iBsEdgeSum[iDir][iEdge] = 0;
1220
1221  for ( Int iIdx = 0; iIdx < 4; iIdx++ )
1222  {
1223    //-- Calculate Block Index
1224    if (iDir == EDGE_VER)
1225    {
1226      uiBsIdx = iEdge + (iIdx*4);
1227
1228      uiPartQ = uiAbsZorderIdx;
1229      if (iEdge >> 1)
1230        uiPartQ += uiQNumParts;
1231      if (iIdx >> 1)
1232        uiPartQ += uiHNumParts;
1233
1234      if (iEdge %2)
1235      {
1236        uiPartP = uiPartQ;
1237        pcCUP = pcCUQ;
1238      }
1239      else
1240      {
1241        pcCUP = pcCUQ->getPULeft(uiPartP, uiPartQ);
1242      }
1243    }
1244    else  // (iDir == EDGE_HOR)
1245    {
1246      uiBsIdx = iIdx + (iEdge*4);
1247
1248      uiPartQ = uiAbsZorderIdx;
1249      if (iIdx >> 1)
1250        uiPartQ += uiQNumParts;
1251      if (iEdge >> 1)
1252        uiPartQ += uiHNumParts;
1253
1254      if (iEdge %2)
1255      {
1256        uiPartP = uiPartQ;
1257        pcCUP = pcCUQ;
1258      }
1259      else
1260      {
1261        pcCUP = pcCUQ->getPUAbove(uiPartP, uiPartQ);
1262      }
1263    }
1264
1265    //-- Set BS for Intra MB : BS = 4 or 3
1266    if ( pcCUP->isIntra(uiPartP) || pcCUQ->isIntra(uiPartQ) )
1267    {
1268      m_aaucBS[iDir][uiBsIdx] = (iEdge == 0) ? 4 : 3;   // Intra MB && MB boundary
1269    }
1270
1271    //-- Set BS for not Intra MB : BS = 2 or 1 or 0
1272    if ( !pcCUP->isIntra(uiPartP) && !pcCUQ->isIntra(uiPartQ) )
1273    {
1274      if ( pcCUQ->getCbf( uiPartQ, TEXT_LUMA, pcCUQ->getTransformIdx(uiPartQ)) != 0 || pcCUP->getCbf( uiPartP, TEXT_LUMA, pcCUP->getTransformIdx(uiPartP) ) != 0)
1275      {
1276        m_aaucBS[iDir][uiBsIdx] = 2;
1277      }
1278      else
1279      {
1280        if (pcSlice->isInterB())
1281        {
1282          Int iRefIdx;
1283          Int *piRefP0, *piRefP1, *piRefQ0, *piRefQ1;
1284          iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
1285          piRefP0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
1286          iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartP);
1287          piRefP1 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx);
1288          iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
1289          piRefQ0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
1290          iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartQ);
1291          piRefQ1 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx);
1292
1293
1294          TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
1295          TComMv pcMvP1 = pcCUP->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartP);
1296          TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
1297          TComMv pcMvQ1 = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartQ);
1298#ifdef DCM_PBIC
1299          TComIc pcIcP  = pcCUP->getCUIcField()->getIc(uiPartP);
1300          TComIc pcIcQ  = pcCUQ->getCUIcField()->getIc(uiPartQ);
1301#endif
1302
1303          if ( ((piRefP0==piRefQ0)&&(piRefP1==piRefQ1)) || ((piRefP0==piRefQ1)&&(piRefP1==piRefQ0)) )
1304          {
1305            m_aaucBS[iDir][uiBsIdx] = 0;
1306
1307            if ( piRefP0 != piRefP1 )   // Different L0 & L1
1308            {
1309              if ( piRefP0 == piRefQ0 )
1310              {
1311                pcMvP0 -= pcMvQ0;   pcMvP1 -= pcMvQ1;
1312#ifdef QC_AMVRES
1313#ifdef DCM_PBIC
1314                m_aaucBS[iDir][uiBsIdx] = (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit) |
1315                                          (pcMvP1.getAbsHor() >= mvlimit) | (pcMvP1.getAbsVer() >= mvlimit) |
1316                                          !(pcIcP.isequalIcParam(pcIcQ));
1317#else
1318                m_aaucBS[iDir][uiBsIdx] = (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit) |
1319                                          (pcMvP1.getAbsHor() >= mvlimit) | (pcMvP1.getAbsVer() >= mvlimit);
1320#endif
1321#else
1322#ifdef DCM_PBIC
1323                m_aaucBS[iDir][uiBsIdx] = (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
1324                                          (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4) |
1325                                          !(pcIcP.isequalIcParam(pcIcQ));
1326#else
1327                m_aaucBS[iDir][uiBsIdx] = (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
1328                                        (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4);
1329#endif
1330#endif             
1331              }
1332              else
1333              {
1334                pcMvP0 -= pcMvQ1;   pcMvP1 -= pcMvQ0;
1335#ifdef QC_AMVRES
1336#ifdef DCM_PBIC
1337                Int iParam0, iParam1, iParam2;
1338                pcIcP.getIcParam( iParam0, iParam1, iParam2 );
1339                pcIcP.setIcParam( iParam0,-iParam1, iParam2 );
1340                m_aaucBS[iDir][uiBsIdx] = (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit) |
1341                                          (pcMvP1.getAbsHor() >= mvlimit) | (pcMvP1.getAbsVer() >= mvlimit) |
1342                                          !(pcIcP.isequalIcParam(pcIcQ));
1343#else
1344                m_aaucBS[iDir][uiBsIdx] = (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit) |
1345                                        (pcMvP1.getAbsHor() >= mvlimit) | (pcMvP1.getAbsVer() >= mvlimit);
1346#endif
1347#else
1348#ifdef DCM_PBIC
1349                Int iParam0, iParam1, iParam2;
1350                pcIcP.getIcParam( iParam0, iParam1, iParam2 );
1351                pcIcP.setIcParam( iParam0,-iParam1, iParam2 );
1352                m_aaucBS[iDir][uiBsIdx] = (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
1353                                          (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4) |
1354                                          !(pcIcP.isequalIcParam(pcIcQ));
1355#else
1356                m_aaucBS[iDir][uiBsIdx] = (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
1357                                        (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4);
1358#endif
1359#endif
1360              }
1361            }
1362            else    // Same L0 & L1
1363            {
1364              TComMv pcMvSub0 = pcMvP0 - pcMvQ0;
1365              TComMv pcMvSub1 = pcMvP1 - pcMvQ1;
1366              pcMvP0 -= pcMvQ1;   pcMvP1 -= pcMvQ0;
1367#ifdef QC_AMVRES
1368#ifdef DCM_PBIC
1369              m_aaucBS[iDir][uiBsIdx] = (pcMvSub0.getAbsHor() >= mvlimit) | (pcMvSub0.getAbsVer() >= mvlimit) |
1370                                        (pcMvSub1.getAbsHor() >= mvlimit) | (pcMvSub1.getAbsVer() >= mvlimit) |
1371                                        !(pcIcP.isequalIcParam(pcIcQ));
1372              Int iParam0, iParam1, iParam2;
1373              pcIcP.getIcParam( iParam0, iParam1, iParam2 );
1374              pcIcP.setIcParam( iParam0,-iParam1, iParam2 );
1375              m_aaucBS[iDir][uiBsIdx] = m_aaucBS[iDir][uiBsIdx] && 
1376                                        ( (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit) |
1377                                          (pcMvP1.getAbsHor() >= mvlimit) | (pcMvP1.getAbsVer() >= mvlimit) |
1378                                          !(pcIcP.isequalIcParam(pcIcQ)) );
1379#else
1380              m_aaucBS[iDir][uiBsIdx] = ( (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit) |
1381                                        (pcMvP1.getAbsHor() >= mvlimit) | (pcMvP1.getAbsVer() >= mvlimit) ) &&
1382                                      ( (pcMvSub0.getAbsHor() >= mvlimit) | (pcMvSub0.getAbsVer() >= mvlimit) |
1383                                        (pcMvSub1.getAbsHor() >= mvlimit) | (pcMvSub1.getAbsVer() >= mvlimit) );
1384#endif
1385#else
1386#ifdef DCM_PBIC
1387              m_aaucBS[iDir][uiBsIdx] = (pcMvSub0.getAbsHor() >= 4) | (pcMvSub0.getAbsVer() >= 4) |
1388                                        (pcMvSub1.getAbsHor() >= 4) | (pcMvSub1.getAbsVer() >= 4) |
1389                                        !(pcIcP.isequalIcParam(pcIcQ));
1390              Int iParam0, iParam1, iParam2;
1391              pcIcP.getIcParam( iParam0, iParam1, iParam2 );
1392              pcIcP.setIcParam( iParam0,-iParam1, iParam2 );
1393              m_aaucBS[iDir][uiBsIdx] = m_aaucBS[iDir][uiBsIdx] && 
1394                                        ( (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
1395                                          (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4) |
1396                                          !(pcIcP.isequalIcParam(pcIcQ)) );
1397#else
1398              m_aaucBS[iDir][uiBsIdx] = ( (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
1399                                        (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4) ) &&
1400                                      ( (pcMvSub0.getAbsHor() >= 4) | (pcMvSub0.getAbsVer() >= 4) |
1401                                        (pcMvSub1.getAbsHor() >= 4) | (pcMvSub1.getAbsVer() >= 4) );
1402#endif
1403#endif
1404            }
1405          }
1406          else // for all different Ref_Idx
1407          {
1408            m_aaucBS[iDir][uiBsIdx] = 1;
1409          }
1410        }
1411        else  // pcSlice->isInterP()
1412        {
1413          Int iRefIdx;
1414          Int *piRefP0, *piRefQ0;
1415          iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
1416          piRefP0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
1417          iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
1418          piRefQ0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
1419          TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
1420          TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
1421#ifdef DCM_PBIC
1422          TComIc pcIcP  = pcCUP->getCUIcField()->getIc(uiPartP);
1423          TComIc pcIcQ  = pcCUQ->getCUIcField()->getIc(uiPartQ);
1424#endif
1425
1426          pcMvP0 -= pcMvQ0;
1427#ifdef QC_AMVRES
1428#ifdef DCM_PBIC
1429          m_aaucBS[iDir][uiBsIdx] = (piRefP0 != piRefQ0) | (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit) | !(pcIcP.isequalIcParam(pcIcQ));
1430#else
1431          m_aaucBS[iDir][uiBsIdx] = (piRefP0 != piRefQ0) | (pcMvP0.getAbsHor() >= mvlimit) | (pcMvP0.getAbsVer() >= mvlimit);
1432#endif
1433#else
1434#ifdef DCM_PBIC
1435          m_aaucBS[iDir][uiBsIdx] = (piRefP0 != piRefQ0) | (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) | !(pcIcP.isequalIcParam(pcIcQ));
1436#else
1437          m_aaucBS[iDir][uiBsIdx] = (piRefP0 != piRefQ0) | (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4);
1438#endif
1439#endif
1440        }
1441      }   // enf of "if( one of BCBP == 0 )"
1442    }   // enf of "if( not Intra )"
1443
1444    m_stLFCUParam.iBsEdgeSum[iDir][iEdge] += m_aaucBS[iDir][uiBsIdx];
1445  }   // end of "for( iIdx<4 )"
1446}
1447
1448Void TComLoopFilter::xEdgeFilterLuma( TComDataCU* pcCU, UInt uiAbsZorderIdx, Int iDir, Int iEdge )
1449{
1450  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
1451  Pel*        piSrc       = pcPicYuvRec->getLumaAddr( pcCU->getAddr(), uiAbsZorderIdx );
1452
1453  Int   iStride   = pcPicYuvRec->getStride();
1454  Int   iQWidth   = pcCU->getWidth(uiAbsZorderIdx)>>2;
1455  Int   iQHeight  = pcCU->getHeight(uiAbsZorderIdx)>>2;
1456  Int   iQP = pcCU->getQP( uiAbsZorderIdx );
1457  UInt  uiBsIdx;
1458  Int   iOffset, iSrcStep;
1459  UInt  uiNumStep;
1460
1461  for ( Int iIdx = 0; iIdx < 4; iIdx++ )
1462  {
1463    Pel* piTmpSrc = piSrc;
1464
1465    if (iDir == EDGE_VER)
1466    {
1467      uiBsIdx = iEdge + (iIdx*4);
1468      iOffset = 1;
1469      iSrcStep = iStride;
1470      piTmpSrc += iEdge*iQWidth + iIdx*iQHeight*iStride;
1471      uiNumStep = iQHeight;
1472    }
1473    else  // (iDir == EDGE_HOR)
1474    {
1475      uiBsIdx = iIdx + (iEdge*4);
1476      iOffset = iStride;
1477      iSrcStep = 1;
1478      piTmpSrc += iIdx*iQWidth + iEdge*iQHeight*iStride;
1479      uiNumStep = iQWidth;
1480    }
1481
1482    UChar ucBs = m_aaucBS[iDir][uiBsIdx];
1483
1484    if ( ucBs )
1485    {
1486      for ( UInt uiStep = 0; uiStep < uiNumStep; uiStep++ )
1487      {
1488        xPelFilterLuma( piTmpSrc+iSrcStep*uiStep, iOffset, ucBs, iQP );
1489      }
1490    }
1491  }  // end of for (PelNum)
1492}
1493
1494Void TComLoopFilter::xEdgeFilterChroma( TComDataCU* pcCU, UInt uiAbsZorderIdx, Int iDir, Int iEdge )
1495{
1496  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
1497  Int         iStride     = pcPicYuvRec->getCStride();
1498  Pel*        piSrcCb     = pcPicYuvRec->getCbAddr( pcCU->getAddr(), uiAbsZorderIdx );
1499  Pel*        piSrcCr     = pcPicYuvRec->getCrAddr( pcCU->getAddr(), uiAbsZorderIdx );
1500
1501  Int   iQWidth   = pcCU->getWidth(uiAbsZorderIdx)>>3;
1502  Int   iQHeight  = pcCU->getHeight(uiAbsZorderIdx)>>3;
1503  Int   iQStride  = iQHeight*iStride;
1504  Int   iQP       = QpUV((Int) pcCU->getQP( uiAbsZorderIdx ));
1505
1506  UInt  uiNumStep;
1507  UInt  uiBsIdx;
1508  Int   iOffset, iSrcStep;
1509
1510  if ( iEdge % 2 != 0 )
1511    return;
1512
1513  for ( Int iIdx = 0; iIdx < 4; iIdx++ )
1514  {
1515    Pel* piTmpSrcCb = piSrcCb;
1516    Pel* piTmpSrcCr = piSrcCr;
1517
1518    //-- Calculate Block Index
1519    if (iDir == EDGE_VER)
1520    {
1521      uiBsIdx  = iEdge + (iIdx*4);
1522      iOffset   = 1;
1523      iSrcStep  = iStride;
1524      piTmpSrcCb += iEdge*iQWidth + iIdx*iQStride;
1525      piTmpSrcCr += iEdge*iQWidth + iIdx*iQStride;
1526      uiNumStep = iQHeight;
1527    }
1528    else  // (iDir == EDGE_HOR)
1529    {
1530      uiBsIdx  = iIdx + (iEdge*4);
1531      iOffset   = iStride;
1532      iSrcStep  = 1;
1533      piTmpSrcCb += iIdx*iQWidth + iEdge*iQStride;
1534      piTmpSrcCr += iIdx*iQWidth + iEdge*iQStride;
1535      uiNumStep = iQWidth;
1536    }
1537
1538    UChar ucBs = m_aaucBS[iDir][uiBsIdx];
1539
1540    if ( ucBs )
1541    {
1542      for ( UInt uiStep = 0; uiStep < uiNumStep; uiStep++ )
1543      {
1544        xPelFilterChroma( piTmpSrcCb + iSrcStep*uiStep, iOffset, ucBs, iQP );
1545        xPelFilterChroma( piTmpSrcCr + iSrcStep*uiStep, iOffset, ucBs, iQP );
1546      }
1547    }
1548  }  // end of for (iBlkIdx)
1549}
1550
1551#endif
1552
1553#if !TENTM_DEBLOCKING_FILTER
1554__inline Void TComLoopFilter::xPelFilterLuma( Pel* piSrc, Int iOffset, UChar ucBs, Int iQP )
1555{
1556  Int iBitdepthScale = (1<<g_uiBitIncrement);
1557
1558  Int iIndexA = Clip3(0, MAX_QP, iQP + m_iAlphaOffset);
1559  Int iIndexB = Clip3(0, MAX_QP, iQP + m_iBetaOffset);
1560
1561  UInt    uiAlpha = ALPHA_TABLE[iIndexA] * iBitdepthScale;
1562  UInt    uiBeta  =  BETA_TABLE[iIndexB] * iBitdepthScale;
1563  const UChar* pucClipTab = CLIP_TAB[iIndexA];
1564
1565  Pel Q0  = piSrc[0];
1566  Pel P0  = piSrc[-iOffset];
1567  Pel Q1  = piSrc[ iOffset];
1568  Pel P1  = piSrc[-iOffset*2];
1569  Pel Q2  = piSrc[ iOffset*2];
1570  Pel P2  = piSrc[-iOffset*3];
1571  Pel Q3  = piSrc[ iOffset*3];
1572  Pel P3  = piSrc[-iOffset*4];
1573
1574  Int aQ = 0;
1575  Int aP = 0;
1576
1577  UInt uiAbsDelta = abs(Q0 - P0);
1578
1579  if ( uiAbsDelta < uiAlpha )
1580  {
1581    Int C0 = pucClipTab[ucBs] * iBitdepthScale;
1582    if ( ((UInt)abs(Q0 - Q1) < uiBeta) && ((UInt)abs(P0 - P1) < uiBeta ) )   // filterSampleFlag
1583    {
1584      aQ = ( (UInt)abs(Q2 - Q0) < uiBeta ) ? 1 : 0;
1585      aP = ( (UInt)abs(P2 - P0) < uiBeta ) ? 1 : 0;
1586
1587      if (ucBs == 4)    // for Intra strong filtering
1588      {
1589        UInt uiSmallGap = (uiAbsDelta < ((uiAlpha>>2) + 2));
1590        aQ &= uiSmallGap;
1591        aP &= uiSmallGap;
1592        piSrc[0]        = aQ ? ( P1 + ((Q1+ Q0 + P0) << 1) + Q2 + 4) >> 3 : ((Q1<<1) + Q0 + P1 + 2) >> 2;
1593        piSrc[-iOffset] = aP ? ( Q1 + ((P1+ P0 + Q0) << 1) + P2 + 4) >> 3 : ((P1<<1) + P0 + Q1 + 2) >> 2;
1594
1595        piSrc[ iOffset  ] = aQ ? ( Q2 + Q1 + Q0 + P0 + 2) >> 2 : Q1;
1596        piSrc[-iOffset*2] = aP ? ( P2 + P1 + P0 + Q0 + 2) >> 2 : P1;
1597
1598        piSrc[ iOffset*2] = aQ ? (((Q3 + Q2) << 1) + Q2 + Q1 + Q0 + P0 + 4) >> 3 : Q2;
1599        piSrc[-iOffset*3] = aP ? (((P3 + P2) << 1) + P2 + P1 + P0 + Q0 + 4) >> 3 : P2;
1600      }
1601      else    // normal filtering ( BS < 4)
1602      {
1603        Short tC     = (C0 + aP + aQ);
1604        Pel iDif  = Clip3(-tC, tC, (( ((Q0-P0) << 2) + (P1-Q1) + 4 ) >> 3) );
1605        piSrc[0]        = Clip( Q0 - iDif );
1606        piSrc[-iOffset] = Clip( P0 + iDif );
1607
1608        if (aP)
1609          piSrc[-iOffset*2] += Clip3(-C0, C0, ( (P2 + ((P0 + Q0 + 1) >> 1) - ( P1 << 1) ) >> 1) );
1610        if (aQ)
1611          piSrc[ iOffset  ] += Clip3(-C0, C0, ( (Q2 + ((P0 + Q0 + 1) >> 1) - ( Q1 << 1) ) >> 1) );
1612      }
1613    }  // end of if ( filterSampleFlag )
1614  } // end of if ( uiAbsDelta < uiAlpha )
1615}
1616
1617__inline Void TComLoopFilter::xPelFilterChroma( Pel* piSrc, Int iOffset, UChar ucBs, Int iQP )
1618{
1619  Int iBitdepthScale = (1<<g_uiBitIncrement);
1620
1621  Int iIndexA = Clip3(0, MAX_QP, iQP + m_iAlphaOffset);
1622  Int iIndexB = Clip3(0, MAX_QP, iQP + m_iBetaOffset);
1623
1624  UInt    uiAlpha = ALPHA_TABLE[iIndexA] * iBitdepthScale;
1625  UInt    uiBeta  =  BETA_TABLE[iIndexB] * iBitdepthScale;
1626  const UChar* pucClipTab = CLIP_TAB[iIndexA];
1627
1628  Pel Q0  = piSrc[0];
1629  Pel P0  = piSrc[-iOffset];
1630  Pel Q1  = piSrc[ iOffset];
1631  Pel P1  = piSrc[-iOffset*2];
1632
1633  UInt uiAbsDelta = abs(Q0 - P0);
1634
1635  if ( uiAbsDelta < uiAlpha )
1636  {
1637    Int C0 = pucClipTab[ucBs] * iBitdepthScale;
1638    if ( ((UInt)abs(Q0 - Q1) < uiBeta) && ((UInt)abs(P0 - P1) < uiBeta ) )  // filterSampleFlag
1639    {
1640      if (ucBs == 4)    // for Intra strong filtering
1641      {
1642        piSrc[0]        = ((Q1 <<1) + Q0 + P1 + 2) >> 2;
1643        piSrc[-iOffset] = ((P1 <<1) + P0 + Q1 + 2) >> 2;
1644      }
1645      else    // normal filtering ( BS < 4)
1646      {
1647        Short tC     = (C0 + 1);
1648        Pel iDelta  = Clip3(-tC, tC, (( ((Q0-P0) << 2) + (P1-Q1) + 4 ) >> 3) );
1649        piSrc[0]        = Clip( Q0 - iDelta );
1650        piSrc[-iOffset] = Clip( P0 + iDelta );
1651      }
1652    }  // end of if ( filterSampleFlag )
1653  } // end of if ( uiAbsDelta < uiAlpha )
1654}
1655#endif