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

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

inital import

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