source: 3DVCSoftware/branches/HTM-4.0.1-VSP-dev0/source/Lib/TLibCommon/TComLoopFilter.cpp @ 166

Last change on this file since 166 was 166, checked in by mitsubishi-htm, 12 years ago

Initial integration of VSP into HTM 4.0.1. The version used for JCT3V-B0102 at Shanghai meeting.

  • VC9 project/solution files updated. Other Visual C++ project/solution files are not updated.
  • Linux make file updated.

TODO

  • A second release is expected to include some bug fix and improvements on the interface, e.g. to move switches from macro definition to the configuration file.
  • A third release is expected after being integrated within HTM 5.x, which is to be used for CE1.h anchor.
  • Property svn:eol-style set to native
File size: 35.6 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-2012, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TComLoopFilter.cpp
35    \brief    deblocking filter
36*/
37
38#include "TComLoopFilter.h"
39#include "TComSlice.h"
40#include "TComMv.h"
41
42//! \ingroup TLibCommon
43//! \{
44
45// ====================================================================================================================
46// Constants
47// ====================================================================================================================
48
49#define   EDGE_VER    0
50#define   EDGE_HOR    1
51#define   QpUV(iQpY)  ( g_aucChromaScale[ max( min( (iQpY), MAX_QP ), MIN_QP ) ] )
52
53#define DEFAULT_INTRA_TC_OFFSET 2 ///< Default intra TC offset
54
55// ====================================================================================================================
56// Tables
57// ====================================================================================================================
58
59const UChar tctable_8x8[56] =
60{
61  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
62};
63
64const UChar betatable_8x8[52] =
65{
66  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
67};
68
69// ====================================================================================================================
70// Constructor / destructor / create / destroy
71// ====================================================================================================================
72
73TComLoopFilter::TComLoopFilter()
74: m_uiNumPartitions( 0 )
75{
76  m_uiDisableDeblockingFilterIdc = 0;
77  m_bLFCrossTileBoundary = true;
78}
79
80TComLoopFilter::~TComLoopFilter()
81{
82}
83
84// ====================================================================================================================
85// Public member functions
86// ====================================================================================================================
87#if DBL_CONTROL
88Void TComLoopFilter::setCfg( Bool DeblockingFilterControlPresent, UInt uiDisableDblkIdc, Int iBetaOffset_div2, Int iTcOffset_div2, Bool bLFCrossTileBoundary)
89#else
90Void TComLoopFilter::setCfg( UInt uiDisableDblkIdc, Int iBetaOffset_div2, Int iTcOffset_div2, Bool bLFCrossTileBoundary)
91#endif
92{
93#if !DBL_CONTROL
94  m_uiDisableDeblockingFilterIdc  = uiDisableDblkIdc;
95#endif
96  m_bLFCrossTileBoundary = bLFCrossTileBoundary;
97
98#if DBL_CONTROL
99  if (DeblockingFilterControlPresent)
100  {
101    m_uiDisableDeblockingFilterIdc  = uiDisableDblkIdc;
102    m_betaOffsetDiv2 = iBetaOffset_div2;
103    m_tcOffsetDiv2 = iTcOffset_div2;
104  } 
105  else // use default values
106  {
107    m_uiDisableDeblockingFilterIdc = 0;
108    m_betaOffsetDiv2 = 0;
109    m_tcOffsetDiv2 = 0;
110  }
111#else
112  m_betaOffsetDiv2 = iBetaOffset_div2;
113  m_tcOffsetDiv2 = iTcOffset_div2;
114#endif
115}
116
117Void TComLoopFilter::create( UInt uiMaxCUDepth )
118{
119  m_uiNumPartitions = 1 << ( uiMaxCUDepth<<1 );
120  for( UInt uiDir = 0; uiDir < 2; uiDir++ )
121  {
122    m_aapucBS       [uiDir] = new UChar[m_uiNumPartitions];
123    for( UInt uiPlane = 0; uiPlane < 3; uiPlane++ )
124    {
125      m_aapbEdgeFilter[uiDir][uiPlane] = new Bool [m_uiNumPartitions];
126    }
127  }
128}
129
130Void TComLoopFilter::destroy()
131{
132  for( UInt uiDir = 0; uiDir < 2; uiDir++ )
133  {
134    delete [] m_aapucBS       [uiDir];
135    for( UInt uiPlane = 0; uiPlane < 3; uiPlane++ )
136    {
137      delete [] m_aapbEdgeFilter[uiDir][uiPlane];
138    }
139  }
140}
141
142/**
143 - call deblocking function for every CU
144 .
145 \param  pcPic   picture class (TComPic) pointer
146 */
147Void TComLoopFilter::loopFilterPic( TComPic* pcPic )
148{
149  if (m_uiDisableDeblockingFilterIdc == 1)
150  {
151    return;
152  }
153 
154  // Horizontal filtering
155  for ( UInt uiCUAddr = 0; uiCUAddr < pcPic->getNumCUsInFrame(); uiCUAddr++ )
156  {
157    TComDataCU* pcCU = pcPic->getCU( uiCUAddr );
158
159    ::memset( m_aapucBS       [EDGE_VER], 0, sizeof( UChar ) * m_uiNumPartitions );
160    for( Int iPlane = 0; iPlane < 3; iPlane++ )
161    {
162      ::memset( m_aapbEdgeFilter[EDGE_VER][iPlane], 0, sizeof( bool  ) * m_uiNumPartitions );
163    }
164
165    // CU-based deblocking
166    xDeblockCU( pcCU, 0, 0, EDGE_VER );
167  }
168
169  // Vertical filtering
170  for ( UInt uiCUAddr = 0; uiCUAddr < pcPic->getNumCUsInFrame(); uiCUAddr++ )
171  {
172    TComDataCU* pcCU = pcPic->getCU( uiCUAddr );
173
174      ::memset( m_aapucBS       [EDGE_HOR], 0, sizeof( UChar ) * m_uiNumPartitions );
175    for( Int iPlane = 0; iPlane < 3; iPlane++ )
176    {
177      ::memset( m_aapbEdgeFilter[EDGE_HOR][iPlane], 0, sizeof( bool  ) * m_uiNumPartitions );
178    }
179
180    // CU-based deblocking
181    xDeblockCU( pcCU, 0, 0, EDGE_HOR );
182  }
183}
184
185
186// ====================================================================================================================
187// Protected member functions
188// ====================================================================================================================
189
190/**
191 - Deblocking filter process in CU-based (the same function as conventional's)
192 .
193 \param Edge          the direction of the edge in block boundary (horizonta/vertical), which is added newly
194*/
195Void TComLoopFilter::xDeblockCU( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int Edge )
196{
197  if(pcCU->getPic()==0||pcCU->getPartitionSize(uiAbsZorderIdx)==SIZE_NONE)
198  {
199    return;
200  }
201  TComPic* pcPic     = pcCU->getPic();
202  UInt uiCurNumParts = pcPic->getNumPartInCU() >> (uiDepth<<1);
203  UInt uiQNumParts   = uiCurNumParts>>2;
204 
205  if( pcCU->getDepth(uiAbsZorderIdx) > uiDepth )
206  {
207    for ( UInt uiPartIdx = 0; uiPartIdx < 4; uiPartIdx++, uiAbsZorderIdx+=uiQNumParts )
208    {
209      UInt uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsZorderIdx] ];
210      UInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsZorderIdx] ];
211      if( ( uiLPelX < pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() ) && ( uiTPelY < pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() ) )
212      {
213        xDeblockCU( pcCU, uiAbsZorderIdx, uiDepth+1, Edge );
214      }
215    }
216    return;
217  }
218 
219  xSetLoopfilterParam( pcCU, uiAbsZorderIdx );
220 
221  xSetEdgefilterTU   ( pcCU, uiAbsZorderIdx , uiAbsZorderIdx, uiDepth );
222  xSetEdgefilterPU   ( pcCU, uiAbsZorderIdx );
223 
224  Int iDir = Edge;
225  for( UInt uiPartIdx = uiAbsZorderIdx; uiPartIdx < uiAbsZorderIdx + uiCurNumParts; uiPartIdx++ )
226  {
227    UInt uiBSCheck = ((iDir == EDGE_VER && uiPartIdx%2 == 0) || (iDir == EDGE_HOR && (uiPartIdx-((uiPartIdx>>2)<<2))/2 == 0));
228    if ( m_aapbEdgeFilter[iDir][0][uiPartIdx] && uiBSCheck )
229    {
230      xGetBoundaryStrengthSingle ( pcCU, uiAbsZorderIdx, iDir, uiPartIdx );
231    }
232  }
233 
234  UInt uiPelsInPart = g_uiMaxCUWidth >> g_uiMaxCUDepth;
235  UInt PartIdxIncr = DEBLOCK_SMALLEST_BLOCK / uiPelsInPart ? DEBLOCK_SMALLEST_BLOCK / uiPelsInPart : 1 ;
236 
237  UInt uiSizeInPU = pcPic->getNumPartInWidth()>>(uiDepth);
238 
239  for ( UInt iEdge = 0; iEdge < uiSizeInPU ; iEdge+=PartIdxIncr)
240  {
241    xEdgeFilterLuma     ( pcCU, uiAbsZorderIdx, uiDepth, iDir, iEdge );
242    if ( (iEdge % ( (DEBLOCK_SMALLEST_BLOCK<<1)/uiPelsInPart ) ) == 0 )
243    {
244      xEdgeFilterChroma   ( pcCU, uiAbsZorderIdx, uiDepth, iDir, iEdge );
245    }
246  }
247}
248
249Void TComLoopFilter::xSetEdgefilterMultiple( TComDataCU* pcCU, UInt uiScanIdx, UInt uiDepth, Int iDir, Int iEdgeIdx, Bool bValue,UInt uiWidthInBaseUnits, UInt uiHeightInBaseUnits, Bool nonSquare )
250{ 
251  if ( uiWidthInBaseUnits == 0 )
252  {
253    uiWidthInBaseUnits  = pcCU->getPic()->getNumPartInWidth () >> uiDepth;
254  }
255  if ( uiHeightInBaseUnits == 0 )
256  {
257    uiHeightInBaseUnits = pcCU->getPic()->getNumPartInHeight() >> uiDepth;
258  }
259  const UInt uiNumElem = iDir == 0 ? uiHeightInBaseUnits : uiWidthInBaseUnits;
260  assert( uiNumElem > 0 );
261  assert( uiWidthInBaseUnits > 0 );
262  assert( uiHeightInBaseUnits > 0 );
263  for( UInt ui = 0; ui < uiNumElem; ui++ )
264  {
265    const UInt uiBsIdx = xCalcBsIdx( pcCU, uiScanIdx, 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    if (iEdgeIdx == 0)
270    {
271      m_aapucBS[iDir][uiBsIdx] = bValue;
272    }
273  }
274}
275
276Void TComLoopFilter::xSetEdgefilterTU( TComDataCU* pcCU, UInt absTUPartIdx, UInt uiAbsZorderIdx, UInt uiDepth )
277{
278  if( pcCU->getTransformIdx( uiAbsZorderIdx ) + pcCU->getDepth( uiAbsZorderIdx) > uiDepth )
279  {
280    const UInt uiCurNumParts = pcCU->getPic()->getNumPartInCU() >> (uiDepth<<1);
281    const UInt uiQNumParts   = uiCurNumParts>>2;
282    const UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiDepth ] + 2;
283    for ( UInt uiPartIdx = 0; uiPartIdx < 4; uiPartIdx++, uiAbsZorderIdx+=uiQNumParts )
284    {
285      UInt nsAddr = 0;
286      nsAddr = pcCU->getNSAbsPartIdx( uiLog2TrSize - 1, uiAbsZorderIdx, absTUPartIdx, uiPartIdx, uiDepth + 1 - pcCU->getDepth( uiAbsZorderIdx ) );
287      xSetEdgefilterTU( pcCU,nsAddr, uiAbsZorderIdx, uiDepth + 1 );
288    }
289    return;
290  }
291
292  Int trWidth  = pcCU->getWidth( uiAbsZorderIdx ) >> pcCU->getTransformIdx( uiAbsZorderIdx );
293  Int trHeight = pcCU->getHeight( uiAbsZorderIdx ) >> pcCU->getTransformIdx( uiAbsZorderIdx );
294  pcCU->getNSQTSize( uiDepth - pcCU->getDepth( uiAbsZorderIdx ), uiAbsZorderIdx, trWidth, trHeight );
295
296  UInt uiWidthInBaseUnits  = trWidth >> 2;
297  UInt uiHeightInBaseUnits = trHeight >> 2;
298
299  xSetEdgefilterMultiple( pcCU, absTUPartIdx, uiDepth, EDGE_VER, 0, m_stLFCUParam.bInternalEdge, uiWidthInBaseUnits, uiHeightInBaseUnits );
300  xSetEdgefilterMultiple( pcCU, absTUPartIdx, uiDepth, EDGE_HOR, 0, m_stLFCUParam.bInternalEdge, uiWidthInBaseUnits, uiHeightInBaseUnits );
301}
302
303Void TComLoopFilter::xSetEdgefilterPU( TComDataCU* pcCU, UInt uiAbsZorderIdx )
304{
305  const UInt uiDepth = pcCU->getDepth( uiAbsZorderIdx );
306  const UInt uiWidthInBaseUnits  = pcCU->getPic()->getNumPartInWidth () >> uiDepth;
307  const UInt uiHeightInBaseUnits = pcCU->getPic()->getNumPartInHeight() >> uiDepth;
308  const UInt uiHWidthInBaseUnits  = uiWidthInBaseUnits  >> 1;
309  const UInt uiHHeightInBaseUnits = uiHeightInBaseUnits >> 1;
310  const UInt uiQWidthInBaseUnits  = uiWidthInBaseUnits  >> 2;
311  const UInt uiQHeightInBaseUnits = uiHeightInBaseUnits >> 2;
312 
313  xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, 0, m_stLFCUParam.bLeftEdge );
314  xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, 0, m_stLFCUParam.bTopEdge );
315 
316  switch ( pcCU->getPartitionSize( uiAbsZorderIdx ) )
317  {
318    case SIZE_2Nx2N:
319    {
320      break;
321    }
322    case SIZE_2NxN:
323    {
324      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
325      break;
326    }
327    case SIZE_Nx2N:
328    {
329      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiHWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
330      break;
331    }
332    case SIZE_NxN:
333    {
334      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiHWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
335      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
336      break;
337    }
338    case SIZE_2NxnU:
339    {
340      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiQHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
341      break;
342    }
343    case SIZE_2NxnD:
344    {
345      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHeightInBaseUnits - uiQHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
346      break;
347    }
348    case SIZE_nLx2N:
349    {
350      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiQWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
351      break;
352    }
353    case SIZE_nRx2N:
354    {
355      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiWidthInBaseUnits - uiQWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
356      break;
357    }
358    default:
359    {
360      break;
361    }
362  }
363}
364
365
366Void TComLoopFilter::xSetLoopfilterParam( TComDataCU* pcCU, UInt uiAbsZorderIdx )
367{
368  UInt uiX           = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsZorderIdx ] ];
369  UInt uiY           = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsZorderIdx ] ];
370 
371  TComDataCU* pcTempCU;
372  UInt        uiTempPartIdx;
373
374  m_stLFCUParam.bInternalEdge = m_uiDisableDeblockingFilterIdc ? false : true ;
375 
376  if ( (uiX == 0) || (m_uiDisableDeblockingFilterIdc == 1) )
377  {
378    m_stLFCUParam.bLeftEdge = false;
379  }
380  else
381  {
382    m_stLFCUParam.bLeftEdge = true;
383  }
384  if ( m_stLFCUParam.bLeftEdge )
385  {
386    pcTempCU = pcCU->getPULeft( uiTempPartIdx, uiAbsZorderIdx, !pcCU->getSlice()->getSPS()->getLFCrossSliceBoundaryFlag(), false, !m_bLFCrossTileBoundary);
387    if ( pcTempCU )
388    {
389      m_stLFCUParam.bLeftEdge = true;
390    }
391    else
392    {
393      m_stLFCUParam.bLeftEdge = false;
394    }
395  }
396 
397  if ( (uiY == 0 ) || (m_uiDisableDeblockingFilterIdc == 1) )
398  {
399    m_stLFCUParam.bTopEdge = false;
400  }
401  else
402  {
403    m_stLFCUParam.bTopEdge = true;
404  }
405  if ( m_stLFCUParam.bTopEdge )
406  {
407    pcTempCU = pcCU->getPUAbove( uiTempPartIdx, uiAbsZorderIdx, !pcCU->getSlice()->getSPS()->getLFCrossSliceBoundaryFlag(), false , false, false, !m_bLFCrossTileBoundary);
408    if ( pcTempCU )
409    {
410      m_stLFCUParam.bTopEdge = true;
411    }
412    else
413    {
414      m_stLFCUParam.bTopEdge = false;
415    }
416  }
417}
418
419Void TComLoopFilter::xGetBoundaryStrengthSingle ( TComDataCU* pcCU, UInt uiAbsZorderIdx, Int iDir, UInt uiAbsPartIdx )
420{
421  TComSlice* const pcSlice = pcCU->getSlice();
422 
423  const UInt uiPartQ = uiAbsPartIdx;
424  TComDataCU* const pcCUQ = pcCU;
425 
426  UInt uiPartP;
427  TComDataCU* pcCUP;
428  UInt uiBs = 0;
429 
430  //-- Calculate Block Index
431  if (iDir == EDGE_VER)
432  {
433    pcCUP = pcCUQ->getPULeft(uiPartP, uiPartQ, !pcCU->getSlice()->getSPS()->getLFCrossSliceBoundaryFlag(), false, !m_bLFCrossTileBoundary);
434  }
435  else  // (iDir == EDGE_HOR)
436  {
437    pcCUP = pcCUQ->getPUAbove(uiPartP, uiPartQ, !pcCU->getSlice()->getSPS()->getLFCrossSliceBoundaryFlag(), false, false, false, !m_bLFCrossTileBoundary);
438  }
439 
440  //-- Set BS for Intra MB : BS = 4 or 3
441  if ( pcCUP->isIntra(uiPartP) || pcCUQ->isIntra(uiPartQ) 
442#if FORCE_REF_VSP==1
443    || pcCUP->isVspMode(uiPartP) || pcCUQ->isVspMode(uiPartQ) 
444#endif
445  )
446  {
447    uiBs = 2;
448  }
449 
450  //-- Set BS for not Intra MB : BS = 2 or 1 or 0
451  if ( !pcCUP->isIntra(uiPartP) && !pcCUQ->isIntra(uiPartQ) 
452#if FORCE_REF_VSP==1
453    && !pcCUP->isVspMode(uiPartP) && !pcCUQ->isVspMode(uiPartQ) 
454#endif
455  )
456  {
457#if NSQT_LFFIX
458    UInt nsPartQ = uiPartQ;
459    UInt nsPartP = uiPartP;
460    if(pcCUQ->getPredictionMode(uiPartQ) == MODE_INTER && pcCUQ->useNonSquarePU(uiPartQ))
461    {
462      nsPartQ = pcCUQ->getNSQTPartIdx( uiAbsPartIdx );
463    }
464    if(pcCUP->getPredictionMode(uiPartP) == MODE_INTER && pcCUP->useNonSquarePU(uiPartP))
465    {
466      nsPartP = pcCUP->getNSQTPartIdx( uiPartP );
467    }
468
469    if ( m_aapucBS[iDir][uiAbsPartIdx] && (pcCUQ->getCbf( nsPartQ, TEXT_LUMA, pcCUQ->getTransformIdx(nsPartQ)) != 0 || pcCUP->getCbf( nsPartP, TEXT_LUMA, pcCUP->getTransformIdx(nsPartP) ) != 0) )
470#else
471    if ( m_aapucBS[iDir][uiAbsPartIdx] && (pcCUQ->getCbf( uiPartQ, TEXT_LUMA, pcCUQ->getTransformIdx(uiPartQ)) != 0 || pcCUP->getCbf( uiPartP, TEXT_LUMA, pcCUP->getTransformIdx(uiPartP) ) != 0) )
472#endif
473    {
474      uiBs = 1;
475    }
476    else
477    {
478      if (iDir == EDGE_HOR)
479      {
480        pcCUP = pcCUQ->getPUAbove(uiPartP, uiPartQ, !pcCU->getSlice()->getSPS()->getLFCrossSliceBoundaryFlag(), false, true, false, !m_bLFCrossTileBoundary);
481      }
482      if (pcSlice->isInterB())
483      {
484        Int iRefIdx;
485        Int *piRefP0, *piRefP1, *piRefQ0, *piRefQ1;
486        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
487        piRefP0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
488        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartP);
489        piRefP1 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx);
490        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
491        piRefQ0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
492        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartQ);
493        piRefQ1 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx);
494       
495       
496        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
497        TComMv pcMvP1 = pcCUP->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartP);
498        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
499        TComMv pcMvQ1 = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartQ);
500       
501        if ( ((piRefP0==piRefQ0)&&(piRefP1==piRefQ1)) || ((piRefP0==piRefQ1)&&(piRefP1==piRefQ0)) )
502        {
503          uiBs = 0;
504          if ( piRefP0 != piRefP1 )   // Different L0 & L1
505          {
506            if ( piRefP0 == piRefQ0 )
507            {
508              pcMvP0 -= pcMvQ0;   pcMvP1 -= pcMvQ1;
509              uiBs = (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
510              (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4);
511            }
512            else
513            {
514              pcMvP0 -= pcMvQ1;   pcMvP1 -= pcMvQ0;
515              uiBs = (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
516              (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4);
517            }
518          }
519          else    // Same L0 & L1
520          {
521            TComMv pcMvSub0 = pcMvP0 - pcMvQ0;
522            TComMv pcMvSub1 = pcMvP1 - pcMvQ1;
523            pcMvP0 -= pcMvQ1;   pcMvP1 -= pcMvQ0;
524            uiBs = ( (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4) |
525                    (pcMvP1.getAbsHor() >= 4) | (pcMvP1.getAbsVer() >= 4) ) &&
526            ( (pcMvSub0.getAbsHor() >= 4) | (pcMvSub0.getAbsVer() >= 4) |
527             (pcMvSub1.getAbsHor() >= 4) | (pcMvSub1.getAbsVer() >= 4) );
528          }
529        }
530        else // for all different Ref_Idx
531        {
532          uiBs = 1;
533        }
534      }
535      else  // pcSlice->isInterP()
536      {
537        Int iRefIdx;
538        Int *piRefP0, *piRefQ0;
539        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
540        piRefP0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
541        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
542        piRefQ0 = (iRefIdx < 0) ? NULL :  (Int*) pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
543        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
544        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
545       
546        pcMvP0 -= pcMvQ0;
547        uiBs = (piRefP0 != piRefQ0) | (pcMvP0.getAbsHor() >= 4) | (pcMvP0.getAbsVer() >= 4);
548      }
549    }   // enf of "if( one of BCBP == 0 )"
550  }   // enf of "if( not Intra )"
551 
552#if FORCE_REF_VSP==1
553  if ( pcCUP->isVspMode(uiPartP) || pcCUQ->isVspMode(uiPartQ))
554  {
555    uiBs = 0;
556  }
557#endif
558
559  m_aapucBS[iDir][uiAbsPartIdx] = uiBs;
560}
561
562
563Void TComLoopFilter::xEdgeFilterLuma( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdge  )
564{
565  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
566  Pel* piSrc    = pcPicYuvRec->getLumaAddr( pcCU->getAddr(), uiAbsZorderIdx );
567  Pel* piTmpSrc = piSrc;
568 
569  Int  iStride = pcPicYuvRec->getStride();
570  Int iQP = 0;
571  Int iQP_P = 0;
572  Int iQP_Q = 0;
573  UInt uiNumParts = pcCU->getPic()->getNumPartInWidth()>>uiDepth;
574 
575  UInt  uiPelsInPart = g_uiMaxCUWidth >> g_uiMaxCUDepth;
576#if !DBL_H0473_PART_1
577  UInt  PartIdxIncr = DEBLOCK_SMALLEST_BLOCK / uiPelsInPart ? DEBLOCK_SMALLEST_BLOCK / uiPelsInPart : 1;
578  UInt  uiBlocksInPart = uiPelsInPart / DEBLOCK_SMALLEST_BLOCK ? uiPelsInPart / DEBLOCK_SMALLEST_BLOCK : 1;
579#endif
580  UInt  uiBsAbsIdx = 0, uiBs = 0;
581  Int   iOffset, iSrcStep;
582 
583  Bool  bPCMFilter = (pcCU->getSlice()->getSPS()->getUsePCM() && pcCU->getSlice()->getSPS()->getPCMFilterDisableFlag())? true : false;
584  Bool  bPartPNoFilter = false;
585  Bool  bPartQNoFilter = false; 
586  UInt  uiPartPIdx = 0;
587  UInt  uiPartQIdx = 0;
588  TComDataCU* pcCUP = pcCU; 
589  TComDataCU* pcCUQ = pcCU;
590 
591  if (iDir == EDGE_VER)
592  {
593    iOffset = 1;
594    iSrcStep = iStride;
595    piTmpSrc += iEdge*uiPelsInPart;
596  }
597  else  // (iDir == EDGE_HOR)
598  {
599    iOffset = iStride;
600    iSrcStep = 1;
601    piTmpSrc += iEdge*uiPelsInPart*iStride;
602  }
603 
604#if !DBL_H0473_PART_1
605  for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx+=PartIdxIncr )
606  {
607    uiBs = 0;
608    for (UInt iIdxInside = 0; iIdxInside<PartIdxIncr; iIdxInside++)
609    {
610      uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, iDir, iEdge, iIdx+iIdxInside);
611      if (uiBs < m_aapucBS[iDir][uiBsAbsIdx])
612      {
613        uiBs = m_aapucBS[iDir][uiBsAbsIdx];
614      }
615    }
616   
617#else
618  for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx++ )
619  {
620    uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, iDir, iEdge, iIdx);
621    uiBs = m_aapucBS[iDir][uiBsAbsIdx];
622#endif
623    if ( uiBs )
624    {
625      iQP_Q = pcCU->getQP( uiBsAbsIdx );
626      uiPartQIdx = uiBsAbsIdx;
627      // Derive neighboring PU index
628      if (iDir == EDGE_VER)
629      {
630        pcCUP = pcCUQ->getPULeft (uiPartPIdx, uiPartQIdx,!pcCU->getSlice()->getSPS()->getLFCrossSliceBoundaryFlag(), false, !m_bLFCrossTileBoundary);
631      }
632      else  // (iDir == EDGE_HOR)
633      {
634        pcCUP = pcCUQ->getPUAbove(uiPartPIdx, uiPartQIdx,!pcCU->getSlice()->getSPS()->getLFCrossSliceBoundaryFlag(), false, false, false, !m_bLFCrossTileBoundary);
635      }
636
637      iQP_P = pcCUP->getQP(uiPartPIdx);
638     
639      if(pcCU->getIPCMFlag(uiPartQIdx)) 
640      {
641        iQP_Q = 0; 
642      }
643      if(pcCUP->getIPCMFlag(uiPartPIdx)) 
644      {
645        iQP_P = 0; 
646      }
647     
648      iQP = (iQP_P + iQP_Q + 1) >> 1;
649      Int iBitdepthScale = (1<<(g_uiBitIncrement+g_uiBitDepth-8));
650     
651      Int iIndexTC = Clip3(0, MAX_QP+DEFAULT_INTRA_TC_OFFSET, Int(iQP + DEFAULT_INTRA_TC_OFFSET*(uiBs-1) + (m_tcOffsetDiv2 << 1)));
652      Int iIndexB = Clip3(0, MAX_QP, iQP + (m_betaOffsetDiv2 << 1));
653     
654      Int iTc =  tctable_8x8[iIndexTC]*iBitdepthScale;
655      Int iBeta = betatable_8x8[iIndexB]*iBitdepthScale;
656      Int iSideThreshold = (iBeta+(iBeta>>1))>>3;
657      Int iThrCut = iTc*10;
658     
659     
660#if !DBL_H0473_PART_1     
661      for (UInt iBlkIdx = 0; iBlkIdx< uiBlocksInPart; iBlkIdx ++)
662      {
663        Int dp0 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+0), iOffset);
664        Int dq0 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+0), iOffset);
665        Int dp3 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+3), iOffset);
666        Int dq3 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+3), iOffset);
667        Int d0 = dp0 + dq0;
668        Int d3 = dp3 + dq3;
669       
670        Int dp4 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+4), iOffset);
671        Int dq4 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+4), iOffset);
672        Int dp7 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+7), iOffset);
673        Int dq7 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+7), iOffset);
674        Int d4 = dp4 + dq4;
675        Int d7 = dp7 + dq7;
676#else
677        Int dp0 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+0), iOffset);
678        Int dq0 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+0), iOffset);
679        Int dp3 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+3), iOffset);
680        Int dq3 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+3), iOffset);
681        Int d0 = dp0 + dq0;
682        Int d3 = dp3 + dq3;
683
684        Int dp = dp0 + dp3;
685        Int dq = dq0 + dq3;
686        Int d =  d0 + d3;
687#endif
688       
689        if (bPCMFilter)
690        {
691          // Check if each of PUs is I_PCM
692          bPartPNoFilter = (pcCUP->getIPCMFlag(uiPartPIdx));
693          bPartQNoFilter = (pcCUQ->getIPCMFlag(uiPartQIdx));
694        }
695#if LOSSLESS_CODING
696        // check if each of PUs is lossless coded
697        bPartPNoFilter = bPartPNoFilter || (pcCU->isLosslessCoded(uiAbsZorderIdx) );
698        bPartQNoFilter = bPartQNoFilter || (pcCU->isLosslessCoded(uiAbsZorderIdx) );
699#endif
700#if !DBL_H0473_PART_1         
701        if (d0+d3 < iBeta)
702        {
703          Bool bFilterP = (dp0+dp3 < iSideThreshold);
704          Bool bFilterQ = (dq0+dq3 < iSideThreshold);
705         
706          Bool sw =  xUseStrongFiltering( iOffset, 2*d0, iBeta, iTc , piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+0))
707          && xUseStrongFiltering( iOffset, 2*d3, iBeta, iTc , piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+3));
708         
709#else
710        if (d < iBeta)
711        { 
712          Bool bFilterP = (dp < iSideThreshold);
713          Bool bFilterQ = (dq < iSideThreshold);
714
715          Bool sw =  xUseStrongFiltering( iOffset, 2*d0, iBeta, iTc, piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+0))
716                  && xUseStrongFiltering( iOffset, 2*d3, iBeta, iTc, piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+3));
717#endif
718
719          for ( Int i = 0; i < DEBLOCK_SMALLEST_BLOCK/2; i++)
720          {
721#if !DBL_H0473_PART_1         
722            xPelFilterLuma( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+i), iOffset, d0+d3, iBeta, iTc, sw, bPartPNoFilter, bPartQNoFilter, iThrCut, bFilterP, bFilterQ);
723#else
724            xPelFilterLuma( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+i), iOffset, d, iBeta, iTc, sw, bPartPNoFilter, bPartQNoFilter, iThrCut, bFilterP, bFilterQ);
725#endif
726
727          }
728        }
729#if !DBL_H0473_PART_1             
730        if (d4+d7 < iBeta)
731        {
732          Bool bFilterP = (dp4+dp7 < iSideThreshold);
733          Bool bFilterQ = (dq4+dq7 < iSideThreshold);
734         
735          Bool sw =  xUseStrongFiltering( iOffset, 2*d4, iBeta, iTc , piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+4))
736          && xUseStrongFiltering( iOffset, 2*d7, iBeta, iTc , piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+7));
737          for ( Int i = DEBLOCK_SMALLEST_BLOCK/2; i < DEBLOCK_SMALLEST_BLOCK; i++)
738          {
739            xPelFilterLuma( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*DEBLOCK_SMALLEST_BLOCK+i), iOffset, d4+d7, iBeta, iTc, sw, bPartPNoFilter, bPartQNoFilter, iThrCut, bFilterP, bFilterQ);
740          }
741        }
742      }
743#endif
744    }
745  }
746}
747
748
749Void TComLoopFilter::xEdgeFilterChroma( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdge )
750{
751  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
752  Int         iStride     = pcPicYuvRec->getCStride();
753  Pel*        piSrcCb     = pcPicYuvRec->getCbAddr( pcCU->getAddr(), uiAbsZorderIdx );
754  Pel*        piSrcCr     = pcPicYuvRec->getCrAddr( pcCU->getAddr(), uiAbsZorderIdx );
755  Int iQP = 0;
756  Int iQP_P = 0;
757  Int iQP_Q = 0;
758 
759  UInt  uiPelsInPartChroma = g_uiMaxCUWidth >> (g_uiMaxCUDepth+1);
760 
761  Int   iOffset, iSrcStep;
762 
763  const UInt uiLCUWidthInBaseUnits = pcCU->getPic()->getNumPartInWidth();
764 
765  Bool  bPCMFilter = (pcCU->getSlice()->getSPS()->getUsePCM() && pcCU->getSlice()->getSPS()->getPCMFilterDisableFlag())? true : false;
766  Bool  bPartPNoFilter = false;
767  Bool  bPartQNoFilter = false; 
768  UInt  uiPartPIdx;
769  UInt  uiPartQIdx;
770  TComDataCU* pcCUP; 
771  TComDataCU* pcCUQ = pcCU;
772 
773  // Vertical Position
774  UInt uiEdgeNumInLCUVert = g_auiZscanToRaster[uiAbsZorderIdx]%uiLCUWidthInBaseUnits + iEdge;
775  UInt uiEdgeNumInLCUHor = g_auiZscanToRaster[uiAbsZorderIdx]/uiLCUWidthInBaseUnits + iEdge;
776 
777  if ( ( (uiEdgeNumInLCUVert%(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChroma))&&(iDir==0) ) || ( (uiEdgeNumInLCUHor%(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChroma))&& iDir ) )
778  {
779    return;
780  }
781 
782  UInt  uiNumParts = pcCU->getPic()->getNumPartInWidth()>>uiDepth;
783 
784  UInt  uiBsAbsIdx;
785  UChar ucBs;
786 
787  Pel* piTmpSrcCb = piSrcCb;
788  Pel* piTmpSrcCr = piSrcCr;
789 
790 
791  if (iDir == EDGE_VER)
792  {
793    iOffset   = 1;
794    iSrcStep  = iStride;
795    piTmpSrcCb += iEdge*uiPelsInPartChroma;
796    piTmpSrcCr += iEdge*uiPelsInPartChroma;
797  }
798  else  // (iDir == EDGE_HOR)
799  {
800    iOffset   = iStride;
801    iSrcStep  = 1;
802    piTmpSrcCb += iEdge*iStride*uiPelsInPartChroma;
803    piTmpSrcCr += iEdge*iStride*uiPelsInPartChroma;
804  }
805 
806  for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx++ )
807  {
808    ucBs = 0;
809   
810    uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, iDir, iEdge, iIdx);
811    ucBs = m_aapucBS[iDir][uiBsAbsIdx];
812   
813    if ( ucBs > 1)
814    {
815      iQP_Q = pcCU->getQP( uiBsAbsIdx );
816      uiPartQIdx = uiBsAbsIdx;
817      // Derive neighboring PU index
818      if (iDir == EDGE_VER)
819      {
820        pcCUP = pcCUQ->getPULeft (uiPartPIdx, uiPartQIdx,!pcCU->getSlice()->getSPS()->getLFCrossSliceBoundaryFlag(), false, !m_bLFCrossTileBoundary);
821      }
822      else  // (iDir == EDGE_HOR)
823      {
824        pcCUP = pcCUQ->getPUAbove(uiPartPIdx, uiPartQIdx,!pcCU->getSlice()->getSPS()->getLFCrossSliceBoundaryFlag(), false, false, false, !m_bLFCrossTileBoundary);
825      }
826
827      iQP_P = pcCUP->getQP(uiPartPIdx);
828     
829      if(pcCU->getIPCMFlag(uiPartQIdx)) 
830      {
831        iQP_Q = 0; 
832      }
833      if(pcCUP->getIPCMFlag(uiPartPIdx)) 
834      {
835        iQP_P = 0; 
836      }
837     
838      iQP = QpUV((iQP_P + iQP_Q + 1) >> 1);
839      Int iBitdepthScale = (1<<(g_uiBitIncrement+g_uiBitDepth-8));
840     
841      Int iIndexTC = Clip3(0, MAX_QP+DEFAULT_INTRA_TC_OFFSET, iQP + DEFAULT_INTRA_TC_OFFSET*(ucBs - 1) + (m_tcOffsetDiv2 << 1));
842      Int iTc =  tctable_8x8[iIndexTC]*iBitdepthScale;
843     
844      if(bPCMFilter)
845      {
846        // Check if each of PUs is IPCM
847        bPartPNoFilter = (pcCUP->getIPCMFlag(uiPartPIdx));
848        bPartQNoFilter = (pcCUQ->getIPCMFlag(uiPartQIdx));
849      }
850     
851#if LOSSLESS_CODING
852      // check if each of PUs is lossless coded
853      bPartPNoFilter = bPartPNoFilter || (pcCU->isLosslessCoded(uiAbsZorderIdx) );
854      bPartQNoFilter = bPartQNoFilter || (pcCU->isLosslessCoded(uiAbsZorderIdx) );
855#endif
856      for ( UInt uiStep = 0; uiStep < uiPelsInPartChroma; uiStep++ )
857      {
858        xPelFilterChroma( piTmpSrcCb + iSrcStep*(uiStep+iIdx*uiPelsInPartChroma), iOffset, iTc , bPartPNoFilter, bPartQNoFilter);
859        xPelFilterChroma( piTmpSrcCr + iSrcStep*(uiStep+iIdx*uiPelsInPartChroma), iOffset, iTc , bPartPNoFilter, bPartQNoFilter);
860      }
861    }
862  }
863}
864
865/**
866 - Deblocking for the luminance component with strong or weak filter
867 .
868 \param piSrc           pointer to picture data
869 \param iOffset         offset value for picture data
870 \param d               d value
871 \param beta            beta value
872 \param tc              tc value
873 \param sw              decision strong/weak filter
874 \param bPartPNoFilter  indicator to disable filtering on partP
875 \param bPartQNoFilter  indicator to disable filtering on partQ
876 \param iThrCut         threshold value for weak filter decision
877 \param bFilterSecondP  decision weak filter/no filter for partP
878 \param bFilterSecondQ  decision weak filter/no filter for partQ
879*/
880__inline Void TComLoopFilter::xPelFilterLuma( Pel* piSrc, Int iOffset, Int d, Int beta, Int tc , Bool sw, Bool bPartPNoFilter, Bool bPartQNoFilter, Int iThrCut, Bool bFilterSecondP, Bool bFilterSecondQ)
881{
882  Int delta;
883 
884  Pel m4  = piSrc[0];
885  Pel m3  = piSrc[-iOffset];
886  Pel m5  = piSrc[ iOffset];
887  Pel m2  = piSrc[-iOffset*2];
888  Pel m6  = piSrc[ iOffset*2];
889  Pel m1  = piSrc[-iOffset*3];
890  Pel m7  = piSrc[ iOffset*3];
891  Pel m0  = piSrc[-iOffset*4];
892
893  if (sw)
894  {
895#if DBL_STRONG_FILTER_CLIP
896    piSrc[-iOffset]   = Clip3(m3-2*tc, m3+2*tc, ((m1 + 2*m2 + 2*m3 + 2*m4 + m5 + 4) >> 3));
897    piSrc[0]          = Clip3(m4-2*tc, m4+2*tc, ((m2 + 2*m3 + 2*m4 + 2*m5 + m6 + 4) >> 3));
898    piSrc[-iOffset*2] = Clip3(m2-2*tc, m2+2*tc, ((m1 + m2 + m3 + m4 + 2)>>2));
899    piSrc[ iOffset]   = Clip3(m5-2*tc, m5+2*tc, ((m3 + m4 + m5 + m6 + 2)>>2));
900    piSrc[-iOffset*3] = Clip3(m1-2*tc, m1+2*tc, ((2*m0 + 3*m1 + m2 + m3 + m4 + 4 )>>3));
901    piSrc[ iOffset*2] = Clip3(m6-2*tc, m6+2*tc, ((m3 + m4 + m5 + 3*m6 + 2*m7 +4 )>>3));
902#else
903    piSrc[-iOffset] = ( m1 + 2*m2 + 2*m3 + 2*m4 + m5 + 4) >> 3;
904    piSrc[0] = ( m2 + 2*m3 + 2*m4 + 2*m5 + m6 + 4) >> 3;
905   
906    piSrc[-iOffset*2] = ( m1 + m2 + m3 + m4 + 2)>>2;
907    piSrc[ iOffset] = ( m3 + m4 + m5 + m6 + 2)>>2;
908   
909    piSrc[-iOffset*3] = ( 2*m0 + 3*m1 + m2 + m3 + m4 + 4 )>>3;
910    piSrc[ iOffset*2] = ( m3 + m4 + m5 + 3*m6 + 2*m7 +4 )>>3;
911#endif
912  }
913  else
914  {
915    /* Weak filter */
916    delta = (9*(m4-m3) -3*(m5-m2) + 8)>>4 ;
917
918    if ( abs(delta) < iThrCut )
919    {
920      delta = Clip3(-tc, tc, delta);       
921      piSrc[-iOffset] = Clip((m3+delta));
922      piSrc[0] = Clip((m4-delta));
923
924      Int tc2 = tc>>1;
925      if(bFilterSecondP)
926      {
927        Int delta1 = Clip3(-tc2, tc2, (( ((m1+m3+1)>>1)- m2+delta)>>1));
928        piSrc[-iOffset*2] = Clip((m2+delta1));
929      }
930      if(bFilterSecondQ)
931      {
932        Int delta2 = Clip3(-tc2, tc2, (( ((m6+m4+1)>>1)- m5-delta)>>1));
933        piSrc[ iOffset] = Clip((m5+delta2));
934      }
935    }
936  }
937
938  if(bPartPNoFilter)
939  {
940    piSrc[-iOffset] = m3;
941    piSrc[-iOffset*2] = m2;
942    piSrc[-iOffset*3] = m1;
943  }
944  if(bPartQNoFilter)
945  {
946    piSrc[0] = m4;
947    piSrc[ iOffset] = m5;
948    piSrc[ iOffset*2] = m6;
949  }
950}
951
952/**
953 - Deblocking of one line/column for the chrominance component
954 .
955 \param piSrc           pointer to picture data
956 \param iOffset         offset value for picture data
957 \param tc              tc value
958 \param bPartPNoFilter  indicator to disable filtering on partP
959 \param bPartQNoFilter  indicator to disable filtering on partQ
960 */
961__inline Void TComLoopFilter::xPelFilterChroma( Pel* piSrc, Int iOffset, Int tc, Bool bPartPNoFilter, Bool bPartQNoFilter)
962{
963  int delta;
964 
965  Pel m4  = piSrc[0];
966  Pel m3  = piSrc[-iOffset];
967  Pel m5  = piSrc[ iOffset];
968  Pel m2  = piSrc[-iOffset*2];
969 
970  delta = Clip3(-tc,tc, (((( m4 - m3 ) << 2 ) + m2 - m5 + 4 ) >> 3) );
971  piSrc[-iOffset] = Clip(m3+delta);
972  piSrc[0] = Clip(m4-delta);
973
974  if(bPartPNoFilter)
975  {
976    piSrc[-iOffset] = m3;
977  }
978  if(bPartQNoFilter)
979  {
980    piSrc[0] = m4;
981  }
982}
983
984/**
985 - Decision between strong and weak filter
986 .
987 \param offset         offset value for picture data
988 \param d               d value
989 \param beta            beta value
990 \param tc              tc value
991 \param piSrc           pointer to picture data
992 */
993__inline Bool TComLoopFilter::xUseStrongFiltering( Int offset, Int d, Int beta, Int tc, Pel* piSrc)
994{
995  Pel m4  = piSrc[0];
996  Pel m3  = piSrc[-offset];
997  Pel m7  = piSrc[ offset*3];
998  Pel m0  = piSrc[-offset*4];
999
1000  Int d_strong = abs(m0-m3) + abs(m7-m4);
1001
1002  return ( (d_strong < (beta>>3)) && (d<(beta>>2)) && ( abs(m3-m4) < ((tc*5+1)>>1)) );
1003}
1004
1005__inline Int TComLoopFilter::xCalcDP( Pel* piSrc, Int iOffset)
1006{
1007  return abs( piSrc[-iOffset*3] - 2*piSrc[-iOffset*2] + piSrc[-iOffset] ) ;
1008}
1009 
1010__inline Int TComLoopFilter::xCalcDQ( Pel* piSrc, Int iOffset)
1011{
1012  return abs( piSrc[0] - 2*piSrc[iOffset] + piSrc[iOffset*2] );
1013}
1014//! \}
Note: See TracBrowser for help on using the repository browser.