source: 3DVCSoftware/trunk/source/Lib/TLibCommon/TComLoopFilter.cpp @ 21

Last change on this file since 21 was 5, checked in by hhi, 13 years ago

Clean version with cfg-files

  • Property svn:eol-style set to native
File size: 33.7 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2011, 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 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
35
36/** \file     TComLoopFilter.cpp
37    \brief    deblocking filter
38*/
39
40#include "TComLoopFilter.h"
41#include "TComSlice.h"
42#include "TComMv.h"
43
44// ====================================================================================================================
45// Constants
46// ====================================================================================================================
47
48#define   EDGE_VER    0
49#define   EDGE_HOR    1
50#define   QpUV(iQpY)  ( g_aucChromaScale[ Max( Min( (iQpY), MAX_QP ), MIN_QP ) ] )
51
52
53#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
54#define   DECIDE_FILTER                0
55#define   EXECUTE_FILTER               1
56#define   DECIDE_AND_EXECUTE_FILTER    2
57#endif
58
59
60
61// ====================================================================================================================
62// Tables
63// ====================================================================================================================
64
65const UChar tctable_8x8[56] =
66{
67  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
68};
69
70const UChar betatable_8x8[52] =
71{
72  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
73};
74
75// ====================================================================================================================
76// Constructor / destructor / create / destroy
77// ====================================================================================================================
78
79TComLoopFilter::TComLoopFilter()
80: m_uiNumPartitions( 0 )
81{
82  m_uiDisableDeblockingFilterIdc = 0;
83}
84
85TComLoopFilter::~TComLoopFilter()
86{
87}
88
89// ====================================================================================================================
90// Public member functions
91// ====================================================================================================================
92
93Void TComLoopFilter::setCfg( UInt uiDisableDblkIdc, Int iAlphaOffset, Int iBetaOffset)
94{
95  m_uiDisableDeblockingFilterIdc  = uiDisableDblkIdc;
96}
97
98Void TComLoopFilter::create( UInt uiMaxCUDepth )
99{
100  m_uiNumPartitions = 1 << ( uiMaxCUDepth<<1 );
101  for( UInt uiDir = 0; uiDir < 2; uiDir++ )
102  {
103    for( UInt uiPlane = 0; uiPlane < 3; uiPlane++ )
104    {
105      m_aapucBS       [uiDir][uiPlane] = new UChar[m_uiNumPartitions];
106      m_aapbEdgeFilter[uiDir][uiPlane] = new Bool [m_uiNumPartitions];
107    }
108  }
109}
110
111Void TComLoopFilter::destroy()
112{
113  for( UInt uiDir = 0; uiDir < 2; uiDir++ )
114  {
115    for( UInt uiPlane = 0; uiPlane < 3; uiPlane++ )
116    {
117      delete [] m_aapucBS       [uiDir][uiPlane];
118      delete [] m_aapbEdgeFilter[uiDir][uiPlane];
119    }
120  }
121}
122
123/**
124 - call deblocking function for every CU
125 .
126 \param  pcPic   picture class (TComPic) pointer
127 */
128Void TComLoopFilter::loopFilterPic( TComPic* pcPic )
129{
130  if (m_uiDisableDeblockingFilterIdc == 1)
131    return;
132 
133#if PARALLEL_MERGED_DEBLK
134  // add extra buffer and copy pic
135  pcPic->addDeblockBuffer();
136  pcPic->getPicYuvRec()->copyToPicLuma(pcPic->getPicYuvDeblkBuf());
137
138  // Horizontal filtering
139  for ( UInt uiCUAddr = 0; uiCUAddr < pcPic->getNumCUsInFrame(); uiCUAddr++ )
140  {
141    TComDataCU* pcCU = pcPic->getCU( uiCUAddr );
142
143    for( Int iPlane = 0; iPlane < 3; iPlane++ )
144    {
145      ::memset( m_aapucBS       [EDGE_VER][iPlane], 0, sizeof( UChar ) * m_uiNumPartitions );
146      assert( 0 == false );
147      ::memset( m_aapbEdgeFilter[EDGE_VER][iPlane], 0, sizeof( bool  ) * m_uiNumPartitions );
148    }
149
150    // CU-based deblocking
151    xDeblockCU( pcCU, 0, 0, EDGE_VER );
152  }
153
154  // Vertical filtering
155  for ( UInt uiCUAddr = 0; uiCUAddr < pcPic->getNumCUsInFrame(); uiCUAddr++ )
156  {
157    TComDataCU* pcCU = pcPic->getCU( uiCUAddr );
158
159    for( Int iPlane = 0; iPlane < 3; iPlane++ )
160    {
161      ::memset( m_aapucBS       [EDGE_HOR][iPlane], 0, sizeof( UChar ) * m_uiNumPartitions );
162      assert( 0 == false );
163      ::memset( m_aapbEdgeFilter[EDGE_HOR][iPlane], 0, sizeof( bool  ) * m_uiNumPartitions );
164    }
165
166    // CU-based deblocking
167    xDeblockCU( pcCU, 0, 0, EDGE_HOR );
168  }
169
170  // remove extra pic buffer
171  pcPic->removeDeblockBuffer();
172#else
173  // for every CU
174  for ( UInt uiCUAddr = 0; uiCUAddr < pcPic->getNumCUsInFrame(); uiCUAddr++ )
175  {
176    TComDataCU* pcCU = pcPic->getCU( uiCUAddr );
177   
178    for( Int iDir = EDGE_VER; iDir <= EDGE_HOR; iDir++ )
179    {
180      for( Int iPlane = 0; iPlane < 3; iPlane++ )
181      {
182        ::memset( m_aapucBS       [iDir][iPlane], 0, sizeof( UChar ) * m_uiNumPartitions );
183        assert( 0 == false );
184        ::memset( m_aapbEdgeFilter[iDir][iPlane], 0, sizeof( bool  ) * m_uiNumPartitions );
185      }
186    }
187    // CU-based deblocking
188    xDeblockCU( pcCU, 0, 0 );
189  }
190#endif
191}
192
193
194// ====================================================================================================================
195// Protected member functions
196// ====================================================================================================================
197
198#if PARALLEL_MERGED_DEBLK
199/**
200 - Deblocking filter process in CU-based (the same function as conventional's)
201 .
202 \param Edge          the direction of the edge in block boundary (horizonta/vertical), which is added newly
203*/
204Void TComLoopFilter::xDeblockCU( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int Edge )
205#else
206Void TComLoopFilter::xDeblockCU( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth )
207#endif
208{
209  TComPic* pcPic     = pcCU->getPic();
210  UInt uiCurNumParts = pcPic->getNumPartInCU() >> (uiDepth<<1);
211  UInt uiQNumParts   = uiCurNumParts>>2;
212 
213  if( pcCU->getDepth(uiAbsZorderIdx) > uiDepth )
214  {
215    for ( UInt uiPartIdx = 0; uiPartIdx < 4; uiPartIdx++, uiAbsZorderIdx+=uiQNumParts )
216    {
217      UInt uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsZorderIdx] ];
218      UInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsZorderIdx] ];
219      if( ( uiLPelX < pcCU->getSlice()->getSPS()->getWidth() ) && ( uiTPelY < pcCU->getSlice()->getSPS()->getHeight() ) )
220#if PARALLEL_MERGED_DEBLK
221        xDeblockCU( pcCU, uiAbsZorderIdx, uiDepth+1, Edge );
222#else
223        xDeblockCU( pcCU, uiAbsZorderIdx, uiDepth+1 );
224#endif
225    }
226    return;
227  }
228 
229  xSetLoopfilterParam( pcCU, uiAbsZorderIdx );
230 
231  xSetEdgefilterTU   ( pcCU, uiAbsZorderIdx, uiDepth );
232  xSetEdgefilterPU   ( pcCU, uiAbsZorderIdx );
233 
234#if PARALLEL_MERGED_DEBLK
235  Int iDir = Edge;
236#else
237  for ( Int iDir = EDGE_VER; iDir <= EDGE_HOR; iDir++ )
238#endif
239  {
240    for( UInt uiPartIdx = uiAbsZorderIdx; uiPartIdx < uiAbsZorderIdx + uiCurNumParts; uiPartIdx++ )
241    {
242      if ( m_aapbEdgeFilter[iDir][0][uiPartIdx] )
243      {
244        xGetBoundaryStrengthSingle ( pcCU, uiAbsZorderIdx, iDir, uiPartIdx );
245      }
246    }
247  }
248 
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#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
255  for ( UInt iEdge = 0; iEdge < uiSizeInPU ; iEdge+=PartIdxIncr)
256  {
257    xEdgeFilterLuma     ( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, iEdge, DECIDE_FILTER);//Decide horizontal filter
258  }
259  for ( UInt iEdge = 0; iEdge < uiSizeInPU ; iEdge+=PartIdxIncr)
260  {
261    xEdgeFilterLuma     ( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, iEdge, DECIDE_AND_EXECUTE_FILTER);//Decide vertical filter
262    if ( (iEdge % ( (DEBLOCK_SMALLEST_BLOCK<<1)/uiPelsInPart ) ) == 0 )
263    {
264      xEdgeFilterChroma   ( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, iEdge );
265    }
266  } 
267  for ( UInt iEdge = 0; iEdge < uiSizeInPU ; iEdge+=PartIdxIncr)
268  {
269    xEdgeFilterLuma     ( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, iEdge, EXECUTE_FILTER );//Execute horizontal filter
270    if ( (iEdge % ( (DEBLOCK_SMALLEST_BLOCK<<1)/uiPelsInPart ) ) == 0 )
271    {
272      xEdgeFilterChroma   ( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, iEdge );
273    }
274  } 
275#else 
276#if !PARALLEL_MERGED_DEBLK
277  for ( Int iDir = EDGE_VER; iDir <= EDGE_HOR; iDir++ )
278#endif
279  {
280    for ( UInt iEdge = 0; iEdge < uiSizeInPU ; iEdge+=PartIdxIncr)
281    {
282      xEdgeFilterLuma     ( pcCU, uiAbsZorderIdx, uiDepth, iDir, iEdge );
283      if ( (iEdge % ( (DEBLOCK_SMALLEST_BLOCK<<1)/uiPelsInPart ) ) == 0 )
284        xEdgeFilterChroma   ( pcCU, uiAbsZorderIdx, uiDepth, iDir, iEdge );
285    }
286  }
287#endif 
288}
289
290Void TComLoopFilter::xSetEdgefilterMultiple( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdgeIdx, Bool bValue )
291{
292  const UInt uiWidthInBaseUnits  = pcCU->getPic()->getNumPartInWidth () >> uiDepth;
293  const UInt uiHeightInBaseUnits = pcCU->getPic()->getNumPartInHeight() >> uiDepth;
294  const UInt uiNumElem = iDir == 0 ? uiHeightInBaseUnits : uiWidthInBaseUnits;
295  assert( uiNumElem > 0 );
296  for( UInt ui = 0; ui < uiNumElem; ui++ )
297  {
298    const UInt uiBsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, iDir, iEdgeIdx, ui );
299    m_aapbEdgeFilter[iDir][0][uiBsIdx] = bValue;
300    m_aapbEdgeFilter[iDir][1][uiBsIdx] = bValue;
301    m_aapbEdgeFilter[iDir][2][uiBsIdx] = bValue;
302  }
303}
304
305Void TComLoopFilter::xSetEdgefilterTU( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth )
306{
307  if( pcCU->getTransformIdx( uiAbsZorderIdx ) + pcCU->getDepth( uiAbsZorderIdx) > uiDepth )
308  {
309    const UInt uiCurNumParts = pcCU->getPic()->getNumPartInCU() >> (uiDepth<<1);
310    const UInt uiQNumParts   = uiCurNumParts>>2;
311    for ( UInt uiPartIdx = 0; uiPartIdx < 4; uiPartIdx++, uiAbsZorderIdx+=uiQNumParts )
312    {
313      xSetEdgefilterTU( pcCU, uiAbsZorderIdx, uiDepth+1 );
314    }
315    return;
316  }
317  xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, 0, m_stLFCUParam.bInternalEdge );
318  xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, 0, m_stLFCUParam.bInternalEdge );
319}
320
321Void TComLoopFilter::xSetEdgefilterPU( TComDataCU* pcCU, UInt uiAbsZorderIdx )
322{
323  const UInt uiDepth = pcCU->getDepth( uiAbsZorderIdx );
324  const UInt uiWidthInBaseUnits  = pcCU->getPic()->getNumPartInWidth () >> uiDepth;
325  const UInt uiHeightInBaseUnits = pcCU->getPic()->getNumPartInHeight() >> uiDepth;
326  const UInt uiHWidthInBaseUnits  = uiWidthInBaseUnits  >> 1;
327  const UInt uiHHeightInBaseUnits = uiHeightInBaseUnits >> 1;
328 
329  xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, 0, m_stLFCUParam.bLeftEdge );
330  xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, 0, m_stLFCUParam.bTopEdge );
331 
332  switch ( pcCU->getPartitionSize( uiAbsZorderIdx ) )
333  {
334    case SIZE_2Nx2N:
335    {
336      break;
337    }
338    case SIZE_2NxN:
339    {
340      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
341      break;
342    }
343    case SIZE_Nx2N:
344    {
345      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiHWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
346      break;
347    }
348    case SIZE_NxN:
349    {
350      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiHWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
351      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
352      break;
353    }
354    default:
355    {
356      assert(0);
357      break;
358    }
359  }
360}
361
362
363Void TComLoopFilter::xSetLoopfilterParam( TComDataCU* pcCU, UInt uiAbsZorderIdx )
364{
365  UInt uiX           = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsZorderIdx ] ];
366  UInt uiY           = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsZorderIdx ] ];
367 
368#if MTK_NONCROSS_INLOOP_FILTER
369  TComDataCU* pcTempCU;
370  UInt        uiTempPartIdx;
371#endif
372
373  m_stLFCUParam.bInternalEdge = m_uiDisableDeblockingFilterIdc ? false : true ;
374 
375  if ( (uiX == 0) || (m_uiDisableDeblockingFilterIdc == 1) )
376    m_stLFCUParam.bLeftEdge = false;
377  else
378    m_stLFCUParam.bLeftEdge = true;
379#if MTK_NONCROSS_INLOOP_FILTER
380  if ( m_stLFCUParam.bLeftEdge )
381  {
382    pcTempCU = pcCU->getPULeft( uiTempPartIdx, uiAbsZorderIdx, !pcCU->getSlice()->getSPS()->getLFCrossSliceBoundaryFlag(), false );
383    if ( pcTempCU )
384      m_stLFCUParam.bLeftEdge = true;
385    else
386      m_stLFCUParam.bLeftEdge = false;
387  }
388#endif
389 
390  if ( (uiY == 0 ) || (m_uiDisableDeblockingFilterIdc == 1) )
391    m_stLFCUParam.bTopEdge = false;
392  else
393    m_stLFCUParam.bTopEdge = true;
394#if MTK_NONCROSS_INLOOP_FILTER
395  if ( m_stLFCUParam.bTopEdge )
396  {
397    pcTempCU = pcCU->getPUAbove( uiTempPartIdx, uiAbsZorderIdx, !pcCU->getSlice()->getSPS()->getLFCrossSliceBoundaryFlag(), false );
398    if ( pcTempCU )
399      m_stLFCUParam.bTopEdge = true;
400    else
401      m_stLFCUParam.bTopEdge = false;
402  }
403#endif
404}
405
406Void TComLoopFilter::xGetBoundaryStrengthSingle ( TComDataCU* pcCU, UInt uiAbsZorderIdx, Int iDir, UInt uiAbsPartIdx )
407{
408  const UInt uiHWidth  = pcCU->getWidth( uiAbsZorderIdx ) >> 1;
409  const UInt uiHHeight = pcCU->getHeight( uiAbsZorderIdx ) >> 1;
410  const bool bAtCUBoundary = iDir == EDGE_VER ? g_auiRasterToPelX[g_auiZscanToRaster[uiAbsZorderIdx]] == g_auiRasterToPelX[g_auiZscanToRaster[uiAbsPartIdx]]
411  : g_auiRasterToPelY[g_auiZscanToRaster[uiAbsZorderIdx]] == g_auiRasterToPelY[g_auiZscanToRaster[uiAbsPartIdx]];
412  const bool bAtCUHalf     = iDir == EDGE_VER ? ( g_auiRasterToPelX[g_auiZscanToRaster[uiAbsZorderIdx]] + uiHWidth ) == g_auiRasterToPelX[g_auiZscanToRaster[uiAbsPartIdx]]
413  : ( g_auiRasterToPelY[g_auiZscanToRaster[uiAbsZorderIdx]] + uiHHeight ) == g_auiRasterToPelY[g_auiZscanToRaster[uiAbsPartIdx]];
414  TComSlice* const pcSlice = pcCU->getSlice();
415 
416  const UInt uiPartQ = uiAbsPartIdx;
417  TComDataCU* const pcCUQ = pcCU;
418 
419  UInt uiPartP;
420  TComDataCU* pcCUP;
421  UInt uiBs;
422 
423#if MTK_NONCROSS_INLOOP_FILTER
424  //-- Calculate Block Index
425  if (iDir == EDGE_VER)
426  {
427    pcCUP = pcCUQ->getPULeft(uiPartP, uiPartQ, !pcCU->getSlice()->getSPS()->getLFCrossSliceBoundaryFlag(), false);
428  }
429  else  // (iDir == EDGE_HOR)
430  {
431    pcCUP = pcCUQ->getPUAbove(uiPartP, uiPartQ, !pcCU->getSlice()->getSPS()->getLFCrossSliceBoundaryFlag(), false);
432  }
433#else
434  //-- Calculate Block Index
435  if (iDir == EDGE_VER)
436  {
437    pcCUP = pcCUQ->getPULeft(uiPartP, uiPartQ, false, false);
438  }
439  else  // (iDir == EDGE_HOR)
440  {
441    pcCUP = pcCUQ->getPUAbove(uiPartP, uiPartQ, false, false);
442  }
443#endif
444 
445  //-- Set BS for Intra MB : BS = 4 or 3
446  if ( pcCUP->isIntra(uiPartP) || pcCUQ->isIntra(uiPartQ) )
447  {
448    uiBs = bAtCUBoundary ? 4 : 3;   // Intra MB && MB boundary
449  }
450 
451  //-- Set BS for not Intra MB : BS = 2 or 1 or 0
452  if ( !pcCUP->isIntra(uiPartP) && !pcCUQ->isIntra(uiPartQ) )
453  {
454    if ( pcCUQ->getCbf( uiPartQ, TEXT_LUMA, pcCUQ->getTransformIdx(uiPartQ)) != 0 || pcCUP->getCbf( uiPartP, TEXT_LUMA, pcCUP->getTransformIdx(uiPartP) ) != 0)
455    {
456      uiBs = 2;
457    }
458    else
459    {
460      if (pcSlice->isInterB())
461      {
462        Int iRefIdx;
463        Int *piRefP0, *piRefP1, *piRefQ0, *piRefQ1;
464        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
465        piRefP0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
466        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartP);
467        piRefP1 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx);
468        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
469        piRefQ0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
470        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartQ);
471        piRefQ1 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx);
472       
473       
474        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
475        TComMv pcMvP1 = pcCUP->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartP);
476        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
477        TComMv pcMvQ1 = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartQ);
478       
479        if ( ((piRefP0==piRefQ0)&&(piRefP1==piRefQ1)) || ((piRefP0==piRefQ1)&&(piRefP1==piRefQ0)) )
480        {
481          uiBs = 0;
482          if ( piRefP0 != piRefP1 )   // Different L0 & L1
483          {
484            if ( piRefP0 == piRefQ0 )
485            {
486              pcMvP0 -= pcMvQ0;   pcMvP1 -= pcMvQ1;
487              uiBs = (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
488              (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4);
489            }
490            else
491            {
492              pcMvP0 -= pcMvQ1;   pcMvP1 -= pcMvQ0;
493              uiBs = (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
494              (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4);
495            }
496          }
497          else    // Same L0 & L1
498          {
499            TComMv pcMvSub0 = pcMvP0 - pcMvQ0;
500            TComMv pcMvSub1 = pcMvP1 - pcMvQ1;
501            pcMvP0 -= pcMvQ1;   pcMvP1 -= pcMvQ0;
502            uiBs = ( (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
503                    (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4) ) &&
504            ( (pcMvSub0.getAbsHor() >= 4) | (pcMvSub0.getAbsVer() >= 4) |
505             (pcMvSub1.getAbsHor() >= 4) | (pcMvSub1.getAbsVer() >= 4) );
506          }
507        }
508        else // for all different Ref_Idx
509        {
510          uiBs = 1;
511        }
512      }
513      else  // pcSlice->isInterP()
514      {
515        Int iRefIdx;
516        Int *piRefP0, *piRefQ0;
517        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
518        piRefP0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
519        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
520        piRefQ0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
521        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
522        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
523       
524        pcMvP0 -= pcMvQ0;
525        uiBs = (piRefP0 != piRefQ0) | (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4);
526      }
527    }   // enf of "if( one of BCBP == 0 )"
528  }   // enf of "if( not Intra )"
529 
530  m_aapucBS[iDir][0][uiAbsPartIdx] = uiBs;
531  if ( bAtCUBoundary || bAtCUHalf )
532  {
533    m_aapucBS[iDir][1][uiAbsPartIdx] = uiBs;
534    m_aapucBS[iDir][2][uiAbsPartIdx] = uiBs;
535  }
536}
537
538
539#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
540Void TComLoopFilter::xEdgeFilterLuma( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdge, Int iDecideExecute )
541#else
542Void TComLoopFilter::xEdgeFilterLuma( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdge  )
543#endif
544{
545  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
546  Pel* piSrc    = pcPicYuvRec->getLumaAddr( pcCU->getAddr(), uiAbsZorderIdx );
547  Pel* piTmpSrc = piSrc;
548#if PARALLEL_MERGED_DEBLK
549  TComPicYuv* pcPicYuvJudge = pcCU->getPic()->getPicYuvDeblkBuf();
550  Pel* piSrcJudge    = pcPicYuvJudge->getLumaAddr( pcCU->getAddr(), uiAbsZorderIdx );
551  Pel* piTmpSrcJudge = piSrcJudge;
552#endif
553
554  Int  iStride = pcPicYuvRec->getStride();
555  Int  iQP = pcCU->getQP( uiAbsZorderIdx );
556  UInt uiNumParts = pcCU->getPic()->getNumPartInWidth()>>uiDepth;
557 
558  UInt  uiPelsInPart = g_uiMaxCUWidth >> g_uiMaxCUDepth;
559  UInt  PartIdxIncr = DEBLOCK_SMALLEST_BLOCK / uiPelsInPart ? DEBLOCK_SMALLEST_BLOCK / uiPelsInPart : 1;
560  UInt  uiBlocksInPart = uiPelsInPart / DEBLOCK_SMALLEST_BLOCK ? uiPelsInPart / DEBLOCK_SMALLEST_BLOCK : 1;
561  UInt  uiBsAbsIdx, uiBs;
562  Int   iOffset, iSrcStep;
563#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
564  Pel*  piTmpSrc1;
565  UInt* piDecisions_D;
566  UInt* piDecisions_Sample;
567#endif 
568  if (iDir == EDGE_VER)
569  {
570    iOffset = 1;
571    iSrcStep = iStride;
572    piTmpSrc += iEdge*uiPelsInPart;
573#if PARALLEL_MERGED_DEBLK
574    piTmpSrcJudge += iEdge*uiPelsInPart;
575#endif
576  }
577  else  // (iDir == EDGE_HOR)
578  {
579    iOffset = iStride;
580    iSrcStep = 1;
581    piTmpSrc += iEdge*uiPelsInPart*iStride;
582#if PARALLEL_MERGED_DEBLK
583    piTmpSrcJudge += iEdge*uiPelsInPart*iStride;
584#endif
585  }
586 
587  for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx+=PartIdxIncr )
588  {
589   
590    uiBs = 0;
591    for (UInt iIdxInside = 0; iIdxInside<PartIdxIncr; iIdxInside++)
592    {
593      uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, iDir, iEdge, iIdx+iIdxInside);
594      if (uiBs < m_aapucBS[iDir][0][uiBsAbsIdx])
595      {
596        uiBs = m_aapucBS[iDir][0][uiBsAbsIdx];
597      }
598    }
599   
600    Int iBitdepthScale = (1<<(g_uiBitIncrement+g_uiBitDepth-8));
601   
602    UInt uiTcOffset = (uiBs>2)?4:0;
603   
604    Int iIndexTC = Clip3(0, MAX_QP+4, iQP + uiTcOffset );
605    Int iIndexB = Clip3(0, MAX_QP, iQP );
606   
607    Int iTc =  tctable_8x8[iIndexTC]*iBitdepthScale;
608#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
609    if (iDecideExecute==DECIDE_AND_EXECUTE_FILTER && uiBs)
610    {
611      Int iBeta = betatable_8x8[iIndexB]*iBitdepthScale;
612     
613      for (UInt iBlkIdx = 0; iBlkIdx< uiBlocksInPart; iBlkIdx ++)
614      {
615        Int iTmp=iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK;
616        Int iD = xCalcD( piTmpSrc+iSrcStep*(iTmp+2), iOffset) + xCalcD( piTmpSrc+iSrcStep*(iTmp+5), iOffset);
617       
618        if (iD < iBeta)
619        {
620          for ( UInt i = 0; i < DEBLOCK_SMALLEST_BLOCK; i++)
621          {
622            xPelFilterLuma( piTmpSrc+iSrcStep*(iTmp+i), iOffset, iD, iBeta, iTc);
623          }
624        }
625      }     
626    }
627    else if (iDecideExecute==DECIDE_FILTER && uiBs)
628    {
629      Int iBeta = betatable_8x8[iIndexB]*iBitdepthScale;
630     
631      piDecisions_D      = (iIdx*uiPelsInPart)/DEBLOCK_SMALLEST_BLOCK + m_decisions_D     [(iEdge*uiPelsInPart)/DEBLOCK_SMALLEST_BLOCK];
632      piDecisions_Sample =  iIdx*uiPelsInPart                         + m_decisions_Sample[(iEdge*uiPelsInPart)/DEBLOCK_SMALLEST_BLOCK];
633     
634      for (UInt iBlkIdx = 0; iBlkIdx< uiBlocksInPart; iBlkIdx ++)
635      {
636        Int iTmp=iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK;
637        Int iD = xCalcD( piTmpSrc+(iTmp+2), iOffset) + xCalcD( piTmpSrc+(iTmp+5), iOffset);
638        piTmpSrc1 = piTmpSrc+iTmp;
639       
640        if (iD < iBeta)
641        {
642          *piDecisions_D++=1;
643          for ( UInt i = 0; i < DEBLOCK_SMALLEST_BLOCK; i++)
644          {
645            *piDecisions_Sample++ = xPelFilterLumaDecision( piTmpSrc1++, iOffset, iD, iBeta, iTc);
646          }
647        }
648        else
649        {
650          *piDecisions_D++=0;
651          piDecisions_Sample+=DEBLOCK_SMALLEST_BLOCK;
652        }
653      }
654    }
655    else if ( uiBs ) // EXECUTE_FILTER
656    {
657      piDecisions_D      = (iIdx*uiPelsInPart)/DEBLOCK_SMALLEST_BLOCK + m_decisions_D     [(iEdge*uiPelsInPart)/DEBLOCK_SMALLEST_BLOCK];
658      piDecisions_Sample =  iIdx*uiPelsInPart                         + m_decisions_Sample[(iEdge*uiPelsInPart)/DEBLOCK_SMALLEST_BLOCK];
659      piTmpSrc1          = piTmpSrc+iIdx*uiPelsInPart;
660     
661      for (UInt iBlkIdx = 0; iBlkIdx< uiBlocksInPart; iBlkIdx ++)
662      {
663        if ( *piDecisions_D++ )
664        {
665          for ( UInt i = 0; i < DEBLOCK_SMALLEST_BLOCK; i++)
666          {
667            xPelFilterLumaExecution( piTmpSrc1++, iOffset, iTc, *piDecisions_Sample++  );
668          }
669        }
670        else
671        {
672          piDecisions_Sample+=DEBLOCK_SMALLEST_BLOCK;
673          piTmpSrc1+=DEBLOCK_SMALLEST_BLOCK;
674        }
675      }
676    }
677#else
678    Int iBeta = betatable_8x8[iIndexB]*iBitdepthScale;
679   
680   
681    for (UInt iBlkIdx = 0; iBlkIdx< uiBlocksInPart; iBlkIdx ++)
682    {
683      if ( uiBs )
684      {
685#if PARALLEL_MERGED_DEBLK
686        Int iD = xCalcD( piTmpSrcJudge+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+2), iOffset) + xCalcD( piTmpSrcJudge+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+5), iOffset);
687#else 
688        Int iD = xCalcD( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+2), iOffset) + xCalcD( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+5), iOffset);
689#endif
690        if (iD < iBeta)
691        {
692          for ( UInt i = 0; i < DEBLOCK_SMALLEST_BLOCK; i++)
693          {
694#if PARALLEL_MERGED_DEBLK
695            xPelFilterLuma( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+i), iOffset, iD, iBeta, iTc , piTmpSrcJudge+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+i));
696#else           
697            xPelFilterLuma( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+i), iOffset, iD, iBeta, iTc );
698#endif
699          }
700        }
701      }
702    }
703#endif
704  }
705}
706
707
708Void TComLoopFilter::xEdgeFilterChroma( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdge )
709{
710  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
711  Int         iStride     = pcPicYuvRec->getCStride();
712  Pel*        piSrcCb     = pcPicYuvRec->getCbAddr( pcCU->getAddr(), uiAbsZorderIdx );
713  Pel*        piSrcCr     = pcPicYuvRec->getCrAddr( pcCU->getAddr(), uiAbsZorderIdx );
714 
715  Int   iQP = QpUV((Int) pcCU->getQP( uiAbsZorderIdx ));
716  UInt  uiPelsInPartChroma = g_uiMaxCUWidth >> (g_uiMaxCUDepth+1);
717 
718  Int   iOffset, iSrcStep;
719 
720  const UInt uiLCUWidthInBaseUnits = pcCU->getPic()->getNumPartInWidth();
721 
722  // Vertical Position
723  UInt uiEdgeNumInLCUVert = g_auiZscanToRaster[uiAbsZorderIdx]%uiLCUWidthInBaseUnits + iEdge;
724  UInt uiEdgeNumInLCUHor = g_auiZscanToRaster[uiAbsZorderIdx]/uiLCUWidthInBaseUnits + iEdge;
725 
726  if ( ( (uiEdgeNumInLCUVert%(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChroma))&&(iDir==0) ) || ( (uiEdgeNumInLCUHor%(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChroma))&& iDir ) )
727  {
728    return;
729  }
730 
731  UInt  uiNumParts = pcCU->getPic()->getNumPartInWidth()>>uiDepth;
732 
733  UInt  uiBsAbsIdx;
734  UChar ucBs;
735 
736  Pel* piTmpSrcCb = piSrcCb;
737  Pel* piTmpSrcCr = piSrcCr;
738 
739 
740  if (iDir == EDGE_VER)
741  {
742    iOffset   = 1;
743    iSrcStep  = iStride;
744    piTmpSrcCb += iEdge*uiPelsInPartChroma;
745    piTmpSrcCr += iEdge*uiPelsInPartChroma;
746  }
747  else  // (iDir == EDGE_HOR)
748  {
749    iOffset   = iStride;
750    iSrcStep  = 1;
751    piTmpSrcCb += iEdge*iStride*uiPelsInPartChroma;
752    piTmpSrcCr += iEdge*iStride*uiPelsInPartChroma;
753  }
754 
755  for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx++ )
756  {
757    ucBs = 0;
758   
759    uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, iDir, iEdge, iIdx);
760    ucBs = m_aapucBS[iDir][0][uiBsAbsIdx];
761   
762    Int iBitdepthScale = (1<<(g_uiBitIncrement+g_uiBitDepth-8));
763   
764    UInt uiTcOffset = (ucBs>2)?4:0;
765   
766    Int iIndexTC = Clip3(0, MAX_QP+4, iQP + uiTcOffset );
767   
768    Int iTc =  tctable_8x8[iIndexTC]*iBitdepthScale;
769   
770    if ( ucBs > 2)
771    {
772      for ( UInt uiStep = 0; uiStep < uiPelsInPartChroma; uiStep++ )
773      {
774        xPelFilterChroma( piTmpSrcCb + iSrcStep*(uiStep+iIdx*uiPelsInPartChroma), iOffset, iTc );
775        xPelFilterChroma( piTmpSrcCr + iSrcStep*(uiStep+iIdx*uiPelsInPartChroma), iOffset, iTc );
776      }
777    }
778  }
779}
780
781#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
782/**
783 - Decision for one line/column for the luminance component to use strong or weak deblocking
784 .
785 \param piSrc         pointer to picture data
786 \param iOffset       offset value for picture data
787 \param d             d value
788 \param beta          beta value
789 \param tc            tc value
790
791 \returns decision to use strong or weak deblocking
792 */
793__inline Int TComLoopFilter::xPelFilterLumaDecision( Pel* piSrc, Int iOffset, Int d, Int beta, Int tc)
794{
795  Pel m4  = piSrc[0];
796  Pel m3  = piSrc[-iOffset];
797 
798  if ( ((abs(piSrc[-iOffset*4]-m3) + abs(piSrc[ iOffset*3]-m4)) < (beta>>3)) && (d<(beta>>2)) && ( abs(m3-m4) < ((tc*5+1)>>1)) ) //strong filtering
799  {
800    return 1;
801  }
802  else //weak filtering
803  {
804    return 0;
805  }
806}
807
808
809/**
810 - Strong deblocking of one line/column for the luminance component
811 .
812 \param piSrc         pointer to picture data
813 \param iOffset       offset value for picture data
814 \param m0            sample value
815 \param m1            sample value
816 \param m2            sample value
817 \param m3            sample value
818 \param m4            sample value
819 \param m5            sample value
820 \param m6            sample value
821 \param m7            sample value
822 */
823__inline Void TComLoopFilter::xPelFilterLumaStrong(Pel* piSrc, Int iOffset, Pel m0, Pel m1, Pel m2, Pel m3, Pel m4, Pel m5, Pel m6, Pel m7)
824{
825  piSrc[-iOffset] = Clip(( m1 + 2*m2 + 2*m3 + 2*m4 + m5 + 4) >> 3 );
826  piSrc[0] = Clip(( m2 + 2*m3 + 2*m4 + 2*m5 + m6 + 4) >> 3 );
827
828  piSrc[-iOffset*2] = Clip(( m1 + m2 + m3 + m4 + 2)>>2);
829  piSrc[ iOffset] = Clip(( m3 + m4 + m5 + m6 + 2)>>2);
830
831  piSrc[-iOffset*3] = Clip(( 2*m0 + 3*m1 + m2 + m3 + m4 + 4 )>>3);
832  piSrc[ iOffset*2] = Clip(( m3 + m4 + m5 + 3*m6 + 2*m7 +4 )>>3); 
833}
834
835/**
836 - Weak deblocking of one line/column for the luminance component
837 .
838 \param piSrc         pointer to picture data
839 \param iOffset       offset value for picture data
840 \param tc            tc value
841 \param m1            sample value
842 \param m2            sample value
843 \param m3            sample value
844 \param m4            sample value
845 \param m5            sample value
846 \param m6            sample value
847 */
848__inline Void TComLoopFilter::xPelFilterLumaWeak(Pel* piSrc, Int iOffset, Int tc, Pel m1, Pel m2, Pel m3, Pel m4, Pel m5, Pel m6)
849{
850  Int delta = Clip3(-tc, tc, ((13*(m4-m3) + 4*(m5-m2) - 5*(m6-m1)+16)>>5) );
851
852  piSrc[-iOffset] = Clip(m3+delta);
853  piSrc[0] = Clip(m4-delta);
854  piSrc[-iOffset*2] = Clip(m2+delta/2);
855  piSrc[ iOffset] = Clip(m5-delta/2);
856}
857#endif
858
859#if PARALLEL_MERGED_DEBLK
860/**
861 - Deblocking for the luminance component with strong or weak filter
862 .
863 \param piSrcJudge    pointer to picture data for decision
864*/
865__inline Void TComLoopFilter::xPelFilterLuma( Pel* piSrc, Int iOffset, Int d, Int beta, Int tc , Pel* piSrcJudge)
866#else
867__inline Void TComLoopFilter::xPelFilterLuma( Pel* piSrc, Int iOffset, Int d, Int beta, Int tc )
868#endif
869{
870#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
871  Int d_strong;
872#else 
873  Int d_strong, delta;
874#endif
875 
876  Pel m4  = piSrc[0];
877  Pel m3  = piSrc[-iOffset];
878  Pel m5  = piSrc[ iOffset];
879  Pel m2  = piSrc[-iOffset*2];
880  Pel m6  = piSrc[ iOffset*2];
881  Pel m1  = piSrc[-iOffset*3];
882  Pel m7  = piSrc[ iOffset*3];
883  Pel m0  = piSrc[-iOffset*4];
884#if PARALLEL_MERGED_DEBLK
885  Pel m4j  = piSrcJudge[0];
886  Pel m3j  = piSrcJudge[-iOffset];
887  Pel m7j  = piSrcJudge[ iOffset*3];
888  Pel m0j  = piSrcJudge[-iOffset*4];
889
890  d_strong = abs(m0j-m3j) + abs(m7j-m4j);
891
892  if ( (d_strong < (beta>>3)) && (d<(beta>>2)) && ( abs(m3j-m4j) < ((tc*5+1)>>1)) ) //strong filtering
893#else
894  d_strong = abs(m0-m3) + abs(m7-m4);
895 
896  if ( (d_strong < (beta>>3)) && (d<(beta>>2)) && ( abs(m3-m4) < ((tc*5+1)>>1)) ) //strong filtering
897#endif
898  {
899#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
900    xPelFilterLumaStrong(piSrc, iOffset, m0, m1, m2, m3, m4, m5, m6, m7);
901#else 
902    piSrc[-iOffset] = Clip(( m1 + 2*m2 + 2*m3 + 2*m4 + m5 + 4) >> 3 );
903    piSrc[0] = Clip(( m2 + 2*m3 + 2*m4 + 2*m5 + m6 + 4) >> 3 );
904   
905    piSrc[-iOffset*2] = Clip(( m1 + m2 + m3 + m4 + 2)>>2);
906    piSrc[ iOffset] = Clip(( m3 + m4 + m5 + m6 + 2)>>2);
907   
908    piSrc[-iOffset*3] = Clip(( 2*m0 + 3*m1 + m2 + m3 + m4 + 4 )>>3);
909    piSrc[ iOffset*2] = Clip(( m3 + m4 + m5 + 3*m6 + 2*m7 +4 )>>3);
910#endif
911  }
912  else
913  {
914#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
915    xPelFilterLumaWeak(piSrc, iOffset, tc, m1, m2, m3, m4, m5, m6);
916#else   
917    /* Weak filter */
918    delta = Clip3(-tc, tc, ((13*(m4-m3) + 4*(m5-m2) - 5*(m6-m1)+16)>>5) );
919   
920    piSrc[-iOffset] = Clip(m3+delta);
921    piSrc[0] = Clip(m4-delta);
922    piSrc[-iOffset*2] = Clip(m2+delta/2);
923    piSrc[ iOffset] = Clip(m5-delta/2);
924#endif
925  }
926}
927
928#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
929/**
930 - Deblocking of one line/column for the luminance component
931 .
932 \param piSrc         pointer to picture data
933 \param iOffset       offset value for picture data
934 \param tc            tc value
935 \param strongFilter  indicator to use either strong or weak filter     
936 */
937__inline Void TComLoopFilter::xPelFilterLumaExecution( Pel* piSrc, Int iOffset, Int tc, Int strongFilter)
938{ 
939  if (strongFilter) //strong filtering
940  {
941    xPelFilterLumaStrong(piSrc, iOffset, piSrc[-iOffset*4], piSrc[-iOffset*3], piSrc[-iOffset*2], piSrc[-iOffset], piSrc[0], piSrc[ iOffset], piSrc[ iOffset*2], piSrc[ iOffset*3]);
942  }
943  else //weak filtering
944  {
945    xPelFilterLumaWeak(piSrc, iOffset, tc, piSrc[-iOffset*3], piSrc[-iOffset*2], piSrc[-iOffset], piSrc[0], piSrc[ iOffset], piSrc[ iOffset*2]);
946  }
947}
948#endif
949
950__inline Void TComLoopFilter::xPelFilterChroma( Pel* piSrc, Int iOffset, Int tc )
951{
952  int delta;
953 
954  Pel m4  = piSrc[0];
955  Pel m3  = piSrc[-iOffset];
956  Pel m5  = piSrc[ iOffset];
957  Pel m2  = piSrc[-iOffset*2];
958 
959  delta = Clip3(-tc,tc, (((( m4 - m3 ) << 2 ) + m2 - m5 + 4 ) >> 3) );
960  piSrc[-iOffset] = Clip(m3+delta);
961  piSrc[0] = Clip(m4-delta);
962}
963
964
965__inline Int TComLoopFilter::xCalcD( Pel* piSrc, Int iOffset)
966{
967  return abs( piSrc[-iOffset*3] - 2*piSrc[-iOffset*2] + piSrc[-iOffset] ) + abs( piSrc[0] - 2*piSrc[iOffset] + piSrc[iOffset*2] );
968}
Note: See TracBrowser for help on using the repository browser.