source: 3DVCSoftware/branches/0.2-poznan-univ/source/Lib/TLibCommon/TComLoopFilter.cpp @ 11

Last change on this file since 11 was 11, checked in by poznan-univ, 12 years ago

Poznan disocclusion coding - CU Skip

  • Property svn:eol-style set to native
File size: 34.1 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#if POZNAN_ENCODE_ONLY_DISOCCLUDED_CU
448     || pcCUP->isCUSkiped(uiPartP) || pcCUQ->isCUSkiped(uiPartQ) 
449#endif
450  )
451  {
452    uiBs = bAtCUBoundary ? 4 : 3;   // Intra MB && MB boundary
453  }
454
455  //-- Set BS for not Intra MB : BS = 2 or 1 or 0
456  if ( !pcCUP->isIntra(uiPartP) && !pcCUQ->isIntra(uiPartQ) 
457#if POZNAN_ENCODE_ONLY_DISOCCLUDED_CU
458     && !pcCUP->isCUSkiped(uiPartP) && !pcCUQ->isCUSkiped(uiPartQ) 
459#endif
460  )
461  {
462    if ( pcCUQ->getCbf( uiPartQ, TEXT_LUMA, pcCUQ->getTransformIdx(uiPartQ)) != 0 || pcCUP->getCbf( uiPartP, TEXT_LUMA, pcCUP->getTransformIdx(uiPartP) ) != 0)
463    {
464      uiBs = 2;
465    }
466    else
467    {
468      if (pcSlice->isInterB())
469      {
470        Int iRefIdx;
471        Int *piRefP0, *piRefP1, *piRefQ0, *piRefQ1;
472        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
473        piRefP0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
474        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartP);
475        piRefP1 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx);
476        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
477        piRefQ0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
478        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartQ);
479        piRefQ1 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx);
480       
481       
482        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
483        TComMv pcMvP1 = pcCUP->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartP);
484        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
485        TComMv pcMvQ1 = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartQ);
486       
487        if ( ((piRefP0==piRefQ0)&&(piRefP1==piRefQ1)) || ((piRefP0==piRefQ1)&&(piRefP1==piRefQ0)) )
488        {
489          uiBs = 0;
490          if ( piRefP0 != piRefP1 )   // Different L0 & L1
491          {
492            if ( piRefP0 == piRefQ0 )
493            {
494              pcMvP0 -= pcMvQ0;   pcMvP1 -= pcMvQ1;
495              uiBs = (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
496              (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4);
497            }
498            else
499            {
500              pcMvP0 -= pcMvQ1;   pcMvP1 -= pcMvQ0;
501              uiBs = (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
502              (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4);
503            }
504          }
505          else    // Same L0 & L1
506          {
507            TComMv pcMvSub0 = pcMvP0 - pcMvQ0;
508            TComMv pcMvSub1 = pcMvP1 - pcMvQ1;
509            pcMvP0 -= pcMvQ1;   pcMvP1 -= pcMvQ0;
510            uiBs = ( (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
511                    (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4) ) &&
512            ( (pcMvSub0.getAbsHor() >= 4) | (pcMvSub0.getAbsVer() >= 4) |
513             (pcMvSub1.getAbsHor() >= 4) | (pcMvSub1.getAbsVer() >= 4) );
514          }
515        }
516        else // for all different Ref_Idx
517        {
518          uiBs = 1;
519        }
520      }
521      else  // pcSlice->isInterP()
522      {
523        Int iRefIdx;
524        Int *piRefP0, *piRefQ0;
525        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
526        piRefP0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
527        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
528        piRefQ0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
529        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
530        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
531       
532        pcMvP0 -= pcMvQ0;
533        uiBs = (piRefP0 != piRefQ0) | (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4);
534      }
535    }   // enf of "if( one of BCBP == 0 )"
536  }   // enf of "if( not Intra )"
537
538#if POZNAN_ENCODE_ONLY_DISOCCLUDED_CU //if one of the block is CUSkipped dont use loop filter
539  if ( pcCUP->isCUSkiped(uiPartP) || pcCUQ->isCUSkiped(uiPartQ))
540  {
541    uiBs = 0;
542  }
543#endif
544
545  m_aapucBS[iDir][0][uiAbsPartIdx] = uiBs;
546  if ( bAtCUBoundary || bAtCUHalf )
547  {
548    m_aapucBS[iDir][1][uiAbsPartIdx] = uiBs;
549    m_aapucBS[iDir][2][uiAbsPartIdx] = uiBs;
550  }
551}
552
553
554#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
555Void TComLoopFilter::xEdgeFilterLuma( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdge, Int iDecideExecute )
556#else
557Void TComLoopFilter::xEdgeFilterLuma( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdge  )
558#endif
559{
560  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
561  Pel* piSrc    = pcPicYuvRec->getLumaAddr( pcCU->getAddr(), uiAbsZorderIdx );
562  Pel* piTmpSrc = piSrc;
563#if PARALLEL_MERGED_DEBLK
564  TComPicYuv* pcPicYuvJudge = pcCU->getPic()->getPicYuvDeblkBuf();
565  Pel* piSrcJudge    = pcPicYuvJudge->getLumaAddr( pcCU->getAddr(), uiAbsZorderIdx );
566  Pel* piTmpSrcJudge = piSrcJudge;
567#endif
568
569  Int  iStride = pcPicYuvRec->getStride();
570  Int  iQP = pcCU->getQP( uiAbsZorderIdx );
571  UInt uiNumParts = pcCU->getPic()->getNumPartInWidth()>>uiDepth;
572 
573  UInt  uiPelsInPart = g_uiMaxCUWidth >> g_uiMaxCUDepth;
574  UInt  PartIdxIncr = DEBLOCK_SMALLEST_BLOCK / uiPelsInPart ? DEBLOCK_SMALLEST_BLOCK / uiPelsInPart : 1;
575  UInt  uiBlocksInPart = uiPelsInPart / DEBLOCK_SMALLEST_BLOCK ? uiPelsInPart / DEBLOCK_SMALLEST_BLOCK : 1;
576  UInt  uiBsAbsIdx, uiBs;
577  Int   iOffset, iSrcStep;
578#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
579  Pel*  piTmpSrc1;
580  UInt* piDecisions_D;
581  UInt* piDecisions_Sample;
582#endif 
583  if (iDir == EDGE_VER)
584  {
585    iOffset = 1;
586    iSrcStep = iStride;
587    piTmpSrc += iEdge*uiPelsInPart;
588#if PARALLEL_MERGED_DEBLK
589    piTmpSrcJudge += iEdge*uiPelsInPart;
590#endif
591  }
592  else  // (iDir == EDGE_HOR)
593  {
594    iOffset = iStride;
595    iSrcStep = 1;
596    piTmpSrc += iEdge*uiPelsInPart*iStride;
597#if PARALLEL_MERGED_DEBLK
598    piTmpSrcJudge += iEdge*uiPelsInPart*iStride;
599#endif
600  }
601 
602  for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx+=PartIdxIncr )
603  {
604   
605    uiBs = 0;
606    for (UInt iIdxInside = 0; iIdxInside<PartIdxIncr; iIdxInside++)
607    {
608      uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, iDir, iEdge, iIdx+iIdxInside);
609      if (uiBs < m_aapucBS[iDir][0][uiBsAbsIdx])
610      {
611        uiBs = m_aapucBS[iDir][0][uiBsAbsIdx];
612      }
613    }
614   
615    Int iBitdepthScale = (1<<(g_uiBitIncrement+g_uiBitDepth-8));
616   
617    UInt uiTcOffset = (uiBs>2)?4:0;
618   
619    Int iIndexTC = Clip3(0, MAX_QP+4, iQP + uiTcOffset );
620    Int iIndexB = Clip3(0, MAX_QP, iQP );
621   
622    Int iTc =  tctable_8x8[iIndexTC]*iBitdepthScale;
623#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
624    if (iDecideExecute==DECIDE_AND_EXECUTE_FILTER && uiBs)
625    {
626      Int iBeta = betatable_8x8[iIndexB]*iBitdepthScale;
627     
628      for (UInt iBlkIdx = 0; iBlkIdx< uiBlocksInPart; iBlkIdx ++)
629      {
630        Int iTmp=iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK;
631        Int iD = xCalcD( piTmpSrc+iSrcStep*(iTmp+2), iOffset) + xCalcD( piTmpSrc+iSrcStep*(iTmp+5), iOffset);
632       
633        if (iD < iBeta)
634        {
635          for ( UInt i = 0; i < DEBLOCK_SMALLEST_BLOCK; i++)
636          {
637            xPelFilterLuma( piTmpSrc+iSrcStep*(iTmp+i), iOffset, iD, iBeta, iTc);
638          }
639        }
640      }     
641    }
642    else if (iDecideExecute==DECIDE_FILTER && uiBs)
643    {
644      Int iBeta = betatable_8x8[iIndexB]*iBitdepthScale;
645     
646      piDecisions_D      = (iIdx*uiPelsInPart)/DEBLOCK_SMALLEST_BLOCK + m_decisions_D     [(iEdge*uiPelsInPart)/DEBLOCK_SMALLEST_BLOCK];
647      piDecisions_Sample =  iIdx*uiPelsInPart                         + m_decisions_Sample[(iEdge*uiPelsInPart)/DEBLOCK_SMALLEST_BLOCK];
648     
649      for (UInt iBlkIdx = 0; iBlkIdx< uiBlocksInPart; iBlkIdx ++)
650      {
651        Int iTmp=iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK;
652        Int iD = xCalcD( piTmpSrc+(iTmp+2), iOffset) + xCalcD( piTmpSrc+(iTmp+5), iOffset);
653        piTmpSrc1 = piTmpSrc+iTmp;
654       
655        if (iD < iBeta)
656        {
657          *piDecisions_D++=1;
658          for ( UInt i = 0; i < DEBLOCK_SMALLEST_BLOCK; i++)
659          {
660            *piDecisions_Sample++ = xPelFilterLumaDecision( piTmpSrc1++, iOffset, iD, iBeta, iTc);
661          }
662        }
663        else
664        {
665          *piDecisions_D++=0;
666          piDecisions_Sample+=DEBLOCK_SMALLEST_BLOCK;
667        }
668      }
669    }
670    else if ( uiBs ) // EXECUTE_FILTER
671    {
672      piDecisions_D      = (iIdx*uiPelsInPart)/DEBLOCK_SMALLEST_BLOCK + m_decisions_D     [(iEdge*uiPelsInPart)/DEBLOCK_SMALLEST_BLOCK];
673      piDecisions_Sample =  iIdx*uiPelsInPart                         + m_decisions_Sample[(iEdge*uiPelsInPart)/DEBLOCK_SMALLEST_BLOCK];
674      piTmpSrc1          = piTmpSrc+iIdx*uiPelsInPart;
675     
676      for (UInt iBlkIdx = 0; iBlkIdx< uiBlocksInPart; iBlkIdx ++)
677      {
678        if ( *piDecisions_D++ )
679        {
680          for ( UInt i = 0; i < DEBLOCK_SMALLEST_BLOCK; i++)
681          {
682            xPelFilterLumaExecution( piTmpSrc1++, iOffset, iTc, *piDecisions_Sample++  );
683          }
684        }
685        else
686        {
687          piDecisions_Sample+=DEBLOCK_SMALLEST_BLOCK;
688          piTmpSrc1+=DEBLOCK_SMALLEST_BLOCK;
689        }
690      }
691    }
692#else
693    Int iBeta = betatable_8x8[iIndexB]*iBitdepthScale;
694   
695   
696    for (UInt iBlkIdx = 0; iBlkIdx< uiBlocksInPart; iBlkIdx ++)
697    {
698      if ( uiBs )
699      {
700#if PARALLEL_MERGED_DEBLK
701        Int iD = xCalcD( piTmpSrcJudge+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+2), iOffset) + xCalcD( piTmpSrcJudge+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+5), iOffset);
702#else 
703        Int iD = xCalcD( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+2), iOffset) + xCalcD( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+5), iOffset);
704#endif
705        if (iD < iBeta)
706        {
707          for ( UInt i = 0; i < DEBLOCK_SMALLEST_BLOCK; i++)
708          {
709#if PARALLEL_MERGED_DEBLK
710            xPelFilterLuma( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+i), iOffset, iD, iBeta, iTc , piTmpSrcJudge+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+i));
711#else           
712            xPelFilterLuma( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+i), iOffset, iD, iBeta, iTc );
713#endif
714          }
715        }
716      }
717    }
718#endif
719  }
720}
721
722
723Void TComLoopFilter::xEdgeFilterChroma( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdge )
724{
725  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
726  Int         iStride     = pcPicYuvRec->getCStride();
727  Pel*        piSrcCb     = pcPicYuvRec->getCbAddr( pcCU->getAddr(), uiAbsZorderIdx );
728  Pel*        piSrcCr     = pcPicYuvRec->getCrAddr( pcCU->getAddr(), uiAbsZorderIdx );
729 
730  Int   iQP = QpUV((Int) pcCU->getQP( uiAbsZorderIdx ));
731  UInt  uiPelsInPartChroma = g_uiMaxCUWidth >> (g_uiMaxCUDepth+1);
732 
733  Int   iOffset, iSrcStep;
734 
735  const UInt uiLCUWidthInBaseUnits = pcCU->getPic()->getNumPartInWidth();
736 
737  // Vertical Position
738  UInt uiEdgeNumInLCUVert = g_auiZscanToRaster[uiAbsZorderIdx]%uiLCUWidthInBaseUnits + iEdge;
739  UInt uiEdgeNumInLCUHor = g_auiZscanToRaster[uiAbsZorderIdx]/uiLCUWidthInBaseUnits + iEdge;
740 
741  if ( ( (uiEdgeNumInLCUVert%(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChroma))&&(iDir==0) ) || ( (uiEdgeNumInLCUHor%(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChroma))&& iDir ) )
742  {
743    return;
744  }
745 
746  UInt  uiNumParts = pcCU->getPic()->getNumPartInWidth()>>uiDepth;
747 
748  UInt  uiBsAbsIdx;
749  UChar ucBs;
750 
751  Pel* piTmpSrcCb = piSrcCb;
752  Pel* piTmpSrcCr = piSrcCr;
753 
754 
755  if (iDir == EDGE_VER)
756  {
757    iOffset   = 1;
758    iSrcStep  = iStride;
759    piTmpSrcCb += iEdge*uiPelsInPartChroma;
760    piTmpSrcCr += iEdge*uiPelsInPartChroma;
761  }
762  else  // (iDir == EDGE_HOR)
763  {
764    iOffset   = iStride;
765    iSrcStep  = 1;
766    piTmpSrcCb += iEdge*iStride*uiPelsInPartChroma;
767    piTmpSrcCr += iEdge*iStride*uiPelsInPartChroma;
768  }
769 
770  for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx++ )
771  {
772    ucBs = 0;
773   
774    uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, iDir, iEdge, iIdx);
775    ucBs = m_aapucBS[iDir][0][uiBsAbsIdx];
776   
777    Int iBitdepthScale = (1<<(g_uiBitIncrement+g_uiBitDepth-8));
778   
779    UInt uiTcOffset = (ucBs>2)?4:0;
780   
781    Int iIndexTC = Clip3(0, MAX_QP+4, iQP + uiTcOffset );
782   
783    Int iTc =  tctable_8x8[iIndexTC]*iBitdepthScale;
784   
785    if ( ucBs > 2)
786    {
787      for ( UInt uiStep = 0; uiStep < uiPelsInPartChroma; uiStep++ )
788      {
789        xPelFilterChroma( piTmpSrcCb + iSrcStep*(uiStep+iIdx*uiPelsInPartChroma), iOffset, iTc );
790        xPelFilterChroma( piTmpSrcCr + iSrcStep*(uiStep+iIdx*uiPelsInPartChroma), iOffset, iTc );
791      }
792    }
793  }
794}
795
796#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
797/**
798 - Decision for one line/column for the luminance component to use strong or weak deblocking
799 .
800 \param piSrc         pointer to picture data
801 \param iOffset       offset value for picture data
802 \param d             d value
803 \param beta          beta value
804 \param tc            tc value
805
806 \returns decision to use strong or weak deblocking
807 */
808__inline Int TComLoopFilter::xPelFilterLumaDecision( Pel* piSrc, Int iOffset, Int d, Int beta, Int tc)
809{
810  Pel m4  = piSrc[0];
811  Pel m3  = piSrc[-iOffset];
812 
813  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
814  {
815    return 1;
816  }
817  else //weak filtering
818  {
819    return 0;
820  }
821}
822
823
824/**
825 - Strong deblocking of one line/column for the luminance component
826 .
827 \param piSrc         pointer to picture data
828 \param iOffset       offset value for picture data
829 \param m0            sample value
830 \param m1            sample value
831 \param m2            sample value
832 \param m3            sample value
833 \param m4            sample value
834 \param m5            sample value
835 \param m6            sample value
836 \param m7            sample value
837 */
838__inline Void TComLoopFilter::xPelFilterLumaStrong(Pel* piSrc, Int iOffset, Pel m0, Pel m1, Pel m2, Pel m3, Pel m4, Pel m5, Pel m6, Pel m7)
839{
840  piSrc[-iOffset] = Clip(( m1 + 2*m2 + 2*m3 + 2*m4 + m5 + 4) >> 3 );
841  piSrc[0] = Clip(( m2 + 2*m3 + 2*m4 + 2*m5 + m6 + 4) >> 3 );
842
843  piSrc[-iOffset*2] = Clip(( m1 + m2 + m3 + m4 + 2)>>2);
844  piSrc[ iOffset] = Clip(( m3 + m4 + m5 + m6 + 2)>>2);
845
846  piSrc[-iOffset*3] = Clip(( 2*m0 + 3*m1 + m2 + m3 + m4 + 4 )>>3);
847  piSrc[ iOffset*2] = Clip(( m3 + m4 + m5 + 3*m6 + 2*m7 +4 )>>3); 
848}
849
850/**
851 - Weak deblocking of one line/column for the luminance component
852 .
853 \param piSrc         pointer to picture data
854 \param iOffset       offset value for picture data
855 \param tc            tc value
856 \param m1            sample value
857 \param m2            sample value
858 \param m3            sample value
859 \param m4            sample value
860 \param m5            sample value
861 \param m6            sample value
862 */
863__inline Void TComLoopFilter::xPelFilterLumaWeak(Pel* piSrc, Int iOffset, Int tc, Pel m1, Pel m2, Pel m3, Pel m4, Pel m5, Pel m6)
864{
865  Int delta = Clip3(-tc, tc, ((13*(m4-m3) + 4*(m5-m2) - 5*(m6-m1)+16)>>5) );
866
867  piSrc[-iOffset] = Clip(m3+delta);
868  piSrc[0] = Clip(m4-delta);
869  piSrc[-iOffset*2] = Clip(m2+delta/2);
870  piSrc[ iOffset] = Clip(m5-delta/2);
871}
872#endif
873
874#if PARALLEL_MERGED_DEBLK
875/**
876 - Deblocking for the luminance component with strong or weak filter
877 .
878 \param piSrcJudge    pointer to picture data for decision
879*/
880__inline Void TComLoopFilter::xPelFilterLuma( Pel* piSrc, Int iOffset, Int d, Int beta, Int tc , Pel* piSrcJudge)
881#else
882__inline Void TComLoopFilter::xPelFilterLuma( Pel* piSrc, Int iOffset, Int d, Int beta, Int tc )
883#endif
884{
885#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
886  Int d_strong;
887#else 
888  Int d_strong, delta;
889#endif
890 
891  Pel m4  = piSrc[0];
892  Pel m3  = piSrc[-iOffset];
893  Pel m5  = piSrc[ iOffset];
894  Pel m2  = piSrc[-iOffset*2];
895  Pel m6  = piSrc[ iOffset*2];
896  Pel m1  = piSrc[-iOffset*3];
897  Pel m7  = piSrc[ iOffset*3];
898  Pel m0  = piSrc[-iOffset*4];
899#if PARALLEL_MERGED_DEBLK
900  Pel m4j  = piSrcJudge[0];
901  Pel m3j  = piSrcJudge[-iOffset];
902  Pel m7j  = piSrcJudge[ iOffset*3];
903  Pel m0j  = piSrcJudge[-iOffset*4];
904
905  d_strong = abs(m0j-m3j) + abs(m7j-m4j);
906
907  if ( (d_strong < (beta>>3)) && (d<(beta>>2)) && ( abs(m3j-m4j) < ((tc*5+1)>>1)) ) //strong filtering
908#else
909  d_strong = abs(m0-m3) + abs(m7-m4);
910 
911  if ( (d_strong < (beta>>3)) && (d<(beta>>2)) && ( abs(m3-m4) < ((tc*5+1)>>1)) ) //strong filtering
912#endif
913  {
914#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
915    xPelFilterLumaStrong(piSrc, iOffset, m0, m1, m2, m3, m4, m5, m6, m7);
916#else 
917    piSrc[-iOffset] = Clip(( m1 + 2*m2 + 2*m3 + 2*m4 + m5 + 4) >> 3 );
918    piSrc[0] = Clip(( m2 + 2*m3 + 2*m4 + 2*m5 + m6 + 4) >> 3 );
919   
920    piSrc[-iOffset*2] = Clip(( m1 + m2 + m3 + m4 + 2)>>2);
921    piSrc[ iOffset] = Clip(( m3 + m4 + m5 + m6 + 2)>>2);
922   
923    piSrc[-iOffset*3] = Clip(( 2*m0 + 3*m1 + m2 + m3 + m4 + 4 )>>3);
924    piSrc[ iOffset*2] = Clip(( m3 + m4 + m5 + 3*m6 + 2*m7 +4 )>>3);
925#endif
926  }
927  else
928  {
929#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
930    xPelFilterLumaWeak(piSrc, iOffset, tc, m1, m2, m3, m4, m5, m6);
931#else   
932    /* Weak filter */
933    delta = Clip3(-tc, tc, ((13*(m4-m3) + 4*(m5-m2) - 5*(m6-m1)+16)>>5) );
934   
935    piSrc[-iOffset] = Clip(m3+delta);
936    piSrc[0] = Clip(m4-delta);
937    piSrc[-iOffset*2] = Clip(m2+delta/2);
938    piSrc[ iOffset] = Clip(m5-delta/2);
939#endif
940  }
941}
942
943#if (PARALLEL_DEBLK_DECISION && !PARALLEL_MERGED_DEBLK)
944/**
945 - Deblocking of one line/column for the luminance component
946 .
947 \param piSrc         pointer to picture data
948 \param iOffset       offset value for picture data
949 \param tc            tc value
950 \param strongFilter  indicator to use either strong or weak filter     
951 */
952__inline Void TComLoopFilter::xPelFilterLumaExecution( Pel* piSrc, Int iOffset, Int tc, Int strongFilter)
953{ 
954  if (strongFilter) //strong filtering
955  {
956    xPelFilterLumaStrong(piSrc, iOffset, piSrc[-iOffset*4], piSrc[-iOffset*3], piSrc[-iOffset*2], piSrc[-iOffset], piSrc[0], piSrc[ iOffset], piSrc[ iOffset*2], piSrc[ iOffset*3]);
957  }
958  else //weak filtering
959  {
960    xPelFilterLumaWeak(piSrc, iOffset, tc, piSrc[-iOffset*3], piSrc[-iOffset*2], piSrc[-iOffset], piSrc[0], piSrc[ iOffset], piSrc[ iOffset*2]);
961  }
962}
963#endif
964
965__inline Void TComLoopFilter::xPelFilterChroma( Pel* piSrc, Int iOffset, Int tc )
966{
967  int delta;
968 
969  Pel m4  = piSrc[0];
970  Pel m3  = piSrc[-iOffset];
971  Pel m5  = piSrc[ iOffset];
972  Pel m2  = piSrc[-iOffset*2];
973 
974  delta = Clip3(-tc,tc, (((( m4 - m3 ) << 2 ) + m2 - m5 + 4 ) >> 3) );
975  piSrc[-iOffset] = Clip(m3+delta);
976  piSrc[0] = Clip(m4-delta);
977}
978
979
980__inline Int TComLoopFilter::xCalcD( Pel* piSrc, Int iOffset)
981{
982  return abs( piSrc[-iOffset*3] - 2*piSrc[-iOffset*2] + piSrc[-iOffset] ) + abs( piSrc[0] - 2*piSrc[iOffset] + piSrc[iOffset*2] );
983}
Note: See TracBrowser for help on using the repository browser.