source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibCommon/TComLoopFilter.cpp @ 1465

Last change on this file since 1465 was 1465, checked in by seregin, 9 years ago

port rev 4597

  • Property svn:eol-style set to native
File size: 34.3 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-2015, 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#include "TComTU.h"
42
43//! \ingroup TLibCommon
44//! \{
45
46// ====================================================================================================================
47// Constants
48// ====================================================================================================================
49
50//#define   EDGE_VER    0
51//#define   EDGE_HOR    1
52
53#define DEFAULT_INTRA_TC_OFFSET 2 ///< Default intra TC offset
54
55// ====================================================================================================================
56// Tables
57// ====================================================================================================================
58
59const UChar TComLoopFilter::sm_tcTable[MAX_QP + 1 + DEFAULT_INTRA_TC_OFFSET] =
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,10,11,13,14,16,18,20,22,24
62};
63
64const UChar TComLoopFilter::sm_betaTable[MAX_QP + 1] =
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, m_bLFCrossTileBoundary(true)
76{
77  for( Int edgeDir = 0; edgeDir < NUM_EDGE_DIR; edgeDir++ )
78  {
79    m_aapucBS       [edgeDir] = NULL;
80    m_aapbEdgeFilter[edgeDir] = NULL;
81  }
82}
83
84TComLoopFilter::~TComLoopFilter()
85{
86}
87
88// ====================================================================================================================
89// Public member functions
90// ====================================================================================================================
91Void TComLoopFilter::setCfg( Bool bLFCrossTileBoundary )
92{
93  m_bLFCrossTileBoundary = bLFCrossTileBoundary;
94}
95
96Void TComLoopFilter::create( UInt uiMaxCUDepth )
97{
98  destroy();
99  m_uiNumPartitions = 1 << ( uiMaxCUDepth<<1 );
100  for( Int edgeDir = 0; edgeDir < NUM_EDGE_DIR; edgeDir++ )
101  {
102    m_aapucBS       [edgeDir] = new UChar[m_uiNumPartitions];
103    m_aapbEdgeFilter[edgeDir] = new Bool [m_uiNumPartitions];
104  }
105}
106
107Void TComLoopFilter::destroy()
108{
109  for( Int edgeDir = 0; edgeDir < NUM_EDGE_DIR; edgeDir++ )
110  {
111    if (m_aapucBS[edgeDir] != NULL)
112    {
113      delete [] m_aapucBS[edgeDir];
114      m_aapucBS[edgeDir] = NULL;
115    }
116
117    if (m_aapbEdgeFilter[edgeDir])
118    {
119      delete [] m_aapbEdgeFilter[edgeDir];
120      m_aapbEdgeFilter[edgeDir] = NULL;
121    }
122  }
123}
124
125/**
126 - call deblocking function for every CU
127 .
128 \param  pcPic   picture class (TComPic) pointer
129 */
130Void TComLoopFilter::loopFilterPic( TComPic* pcPic )
131{
132  // Horizontal filtering
133  for ( UInt ctuRsAddr = 0; ctuRsAddr < pcPic->getNumberOfCtusInFrame(); ctuRsAddr++ )
134  {
135    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
136
137    ::memset( m_aapucBS       [EDGE_VER], 0, sizeof( UChar ) * m_uiNumPartitions );
138    ::memset( m_aapbEdgeFilter[EDGE_VER], 0, sizeof( Bool  ) * m_uiNumPartitions );
139
140    // CU-based deblocking
141    xDeblockCU( pCtu, 0, 0, EDGE_VER );
142  }
143
144  // Vertical filtering
145  for ( UInt ctuRsAddr = 0; ctuRsAddr < pcPic->getNumberOfCtusInFrame(); ctuRsAddr++ )
146  {
147    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
148
149    ::memset( m_aapucBS       [EDGE_HOR], 0, sizeof( UChar ) * m_uiNumPartitions );
150    ::memset( m_aapbEdgeFilter[EDGE_HOR], 0, sizeof( Bool  ) * m_uiNumPartitions );
151
152    // CU-based deblocking
153    xDeblockCU( pCtu, 0, 0, EDGE_HOR );
154  }
155}
156
157
158// ====================================================================================================================
159// Protected member functions
160// ====================================================================================================================
161
162/**
163 Deblocking filter process in CU-based (the same function as conventional's)
164
165 \param pcCU             Pointer to CTU/CU structure
166 \param uiAbsZorderIdx   Position in CU
167 \param uiDepth          Depth in CU
168 \param edgeDir          the direction of the edge in block boundary (horizontal/vertical), which is added newly
169*/
170Void TComLoopFilter::xDeblockCU( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, DeblockEdgeDir edgeDir )
171{
172  if(pcCU->getPic()==0||pcCU->getPartitionSize(uiAbsZorderIdx)==NUMBER_OF_PART_SIZES)
173  {
174    return;
175  }
176  TComPic* pcPic     = pcCU->getPic();
177  UInt uiCurNumParts = pcPic->getNumPartitionsInCtu() >> (uiDepth<<1);
178  UInt uiQNumParts   = uiCurNumParts>>2;
179  const TComSPS &sps = *(pcCU->getSlice()->getSPS());
180
181  if( pcCU->getDepth(uiAbsZorderIdx) > uiDepth )
182  {
183    for ( UInt uiPartIdx = 0; uiPartIdx < 4; uiPartIdx++, uiAbsZorderIdx+=uiQNumParts )
184    {
185      UInt uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsZorderIdx] ];
186      UInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsZorderIdx] ];
187#if SVC_EXTENSION
188      if( ( uiLPelX < pcCU->getSlice()->getPicWidthInLumaSamples() ) && ( uiTPelY < pcCU->getSlice()->getPicHeightInLumaSamples() ) )
189#else
190      if( ( uiLPelX < sps.getPicWidthInLumaSamples() ) && ( uiTPelY < sps.getPicHeightInLumaSamples() ) )
191#endif
192      {
193        xDeblockCU( pcCU, uiAbsZorderIdx, uiDepth+1, edgeDir );
194      }
195    }
196    return;
197  }
198
199  xSetLoopfilterParam( pcCU, uiAbsZorderIdx );
200  TComTURecurse tuRecurse(pcCU, uiAbsZorderIdx);
201  xSetEdgefilterTU   ( tuRecurse );
202  xSetEdgefilterPU   ( pcCU, uiAbsZorderIdx );
203
204  const UInt uiPelsInPart = sps.getMaxCUWidth() >> sps.getMaxTotalCUDepth();
205
206  for( UInt uiPartIdx = uiAbsZorderIdx; uiPartIdx < uiAbsZorderIdx + uiCurNumParts; uiPartIdx++ )
207  {
208    UInt uiBSCheck;
209    if( uiPelsInPart == 4 )
210    {
211      uiBSCheck = (edgeDir == EDGE_VER && uiPartIdx%2 == 0) || (edgeDir == EDGE_HOR && (uiPartIdx-((uiPartIdx>>2)<<2))/2 == 0);
212    }
213    else
214    {
215      uiBSCheck = 1;
216    }
217
218    if ( m_aapbEdgeFilter[edgeDir][uiPartIdx] && uiBSCheck )
219    {
220      xGetBoundaryStrengthSingle ( pcCU, edgeDir, uiPartIdx );
221    }
222  }
223
224  UInt PartIdxIncr = DEBLOCK_SMALLEST_BLOCK / uiPelsInPart ? DEBLOCK_SMALLEST_BLOCK / uiPelsInPart : 1 ;
225
226  UInt uiSizeInPU = pcPic->getNumPartInCtuWidth()>>(uiDepth);
227  const ChromaFormat chFmt=pcPic->getChromaFormat();
228  const UInt shiftFactor  = edgeDir == EDGE_VER ? pcPic->getComponentScaleX(COMPONENT_Cb) : pcPic->getComponentScaleY(COMPONENT_Cb);
229  const Bool bAlwaysDoChroma=chFmt==CHROMA_444;
230
231  for ( Int iEdge = 0; iEdge < uiSizeInPU ; iEdge+=PartIdxIncr)
232  {
233    xEdgeFilterLuma     ( pcCU, uiAbsZorderIdx, uiDepth, edgeDir, iEdge );
234    if ( chFmt!=CHROMA_400 && (bAlwaysDoChroma ||
235                               (uiPelsInPart>DEBLOCK_SMALLEST_BLOCK) ||
236                               (iEdge % ( (DEBLOCK_SMALLEST_BLOCK<<shiftFactor)/uiPelsInPart ) ) == 0
237                              )
238       )
239    {
240      xEdgeFilterChroma   ( pcCU, uiAbsZorderIdx, uiDepth, edgeDir, iEdge );
241    }
242  }
243}
244
245Void TComLoopFilter::xSetEdgefilterMultiple( TComDataCU*    pcCU,
246                                             UInt           uiAbsZorderIdx,
247                                             UInt           uiDepth,
248                                             DeblockEdgeDir edgeDir,
249                                             Int            iEdgeIdx,
250                                             Bool           bValue,
251                                             UInt           uiWidthInBaseUnits,
252                                             UInt           uiHeightInBaseUnits,
253                                             const TComRectangle *rect)
254{
255  if ( uiWidthInBaseUnits == 0 )
256  {
257    uiWidthInBaseUnits  = pcCU->getPic()->getNumPartInCtuWidth () >> uiDepth;
258  }
259  if ( uiHeightInBaseUnits == 0 )
260  {
261    uiHeightInBaseUnits = pcCU->getPic()->getNumPartInCtuHeight() >> uiDepth;
262  }
263  const UInt uiNumElem = edgeDir == EDGE_VER ? uiHeightInBaseUnits : uiWidthInBaseUnits;
264  assert( uiNumElem > 0 );
265  assert( uiWidthInBaseUnits > 0 );
266  assert( uiHeightInBaseUnits > 0 );
267  for( UInt ui = 0; ui < uiNumElem; ui++ )
268  {
269    const UInt uiBsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, edgeDir, iEdgeIdx, ui, rect );
270    m_aapbEdgeFilter[edgeDir][uiBsIdx] = bValue;
271    if (iEdgeIdx == 0)
272    {
273      m_aapucBS[edgeDir][uiBsIdx] = bValue;
274    }
275  }
276}
277
278Void TComLoopFilter::xSetEdgefilterTU(  TComTU &rTu )
279{
280  TComDataCU* pcCU  = rTu.getCU();
281  UInt uiTransDepthTotal = rTu.GetTransformDepthTotal();
282
283  if( pcCU->getTransformIdx( rTu.GetAbsPartIdxTU() ) + pcCU->getDepth( rTu.GetAbsPartIdxTU()) > uiTransDepthTotal )
284  {
285    TComTURecurse tuChild(rTu, false);
286    do
287    {
288      xSetEdgefilterTU( tuChild );
289    } while (tuChild.nextSection(rTu));
290    return;
291  }
292
293  const TComRectangle &rect = rTu.getRect(COMPONENT_Y);
294  const TComSPS &sps=*(pcCU->getSlice()->getSPS());
295
296  const UInt uiWidthInBaseUnits  = rect.width  / (sps.getMaxCUWidth()  >> sps.getMaxTotalCUDepth());
297  const UInt uiHeightInBaseUnits = rect.height / (sps.getMaxCUHeight() >> sps.getMaxTotalCUDepth());
298
299  xSetEdgefilterMultiple( pcCU, rTu.GetAbsPartIdxCU(), uiTransDepthTotal, EDGE_VER, 0, m_stLFCUParam.bInternalEdge, uiWidthInBaseUnits, uiHeightInBaseUnits, &rect );
300  xSetEdgefilterMultiple( pcCU, rTu.GetAbsPartIdxCU(), uiTransDepthTotal, EDGE_HOR, 0, m_stLFCUParam.bInternalEdge, uiWidthInBaseUnits, uiHeightInBaseUnits, &rect );
301}
302
303Void TComLoopFilter::xSetEdgefilterPU( TComDataCU* pcCU, UInt uiAbsZorderIdx )
304{
305  const UInt uiDepth = pcCU->getDepth( uiAbsZorderIdx );
306  const UInt uiWidthInBaseUnits  = pcCU->getPic()->getNumPartInCtuWidth () >> uiDepth;
307  const UInt uiHeightInBaseUnits = pcCU->getPic()->getNumPartInCtuHeight() >> 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  UInt        uiTempPartIdx;
372
373  m_stLFCUParam.bInternalEdge = ! pcCU->getSlice()->getDeblockingFilterDisable();
374
375  if ( (uiX == 0) || pcCU->getSlice()->getDeblockingFilterDisable() )
376  {
377    m_stLFCUParam.bLeftEdge = false;
378  }
379  else
380  {
381    m_stLFCUParam.bLeftEdge = true;
382  }
383  if ( m_stLFCUParam.bLeftEdge )
384  {
385    const TComDataCU* pcTempCU = pcCU->getPULeft( uiTempPartIdx, uiAbsZorderIdx, !pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), !m_bLFCrossTileBoundary);
386
387    if ( pcTempCU != NULL )
388    {
389      m_stLFCUParam.bLeftEdge = true;
390    }
391    else
392    {
393      m_stLFCUParam.bLeftEdge = false;
394    }
395  }
396
397  if ( (uiY == 0 ) || pcCU->getSlice()->getDeblockingFilterDisable() )
398  {
399    m_stLFCUParam.bTopEdge = false;
400  }
401  else
402  {
403    m_stLFCUParam.bTopEdge = true;
404  }
405  if ( m_stLFCUParam.bTopEdge )
406  {
407    const TComDataCU* pcTempCU = pcCU->getPUAbove( uiTempPartIdx, uiAbsZorderIdx, !pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), false, !m_bLFCrossTileBoundary);
408
409    if ( pcTempCU != NULL )
410    {
411      m_stLFCUParam.bTopEdge = true;
412    }
413    else
414    {
415      m_stLFCUParam.bTopEdge = false;
416    }
417  }
418}
419
420Void TComLoopFilter::xGetBoundaryStrengthSingle ( TComDataCU* pCtu, DeblockEdgeDir edgeDir, UInt uiAbsPartIdx4x4BlockWithinCtu )
421{
422  TComSlice * const pcSlice = pCtu->getSlice();
423
424  const Bool lfCrossSliceBoundaryFlag=pCtu->getSlice()->getLFCrossSliceBoundaryFlag();
425
426  const UInt uiPartQ = uiAbsPartIdx4x4BlockWithinCtu;
427  TComDataCU* const pcCUQ = pCtu;
428
429  UInt uiPartP;
430  const TComDataCU* pcCUP;
431  UInt uiBs = 0;
432
433  //-- Calculate Block Index
434  if (edgeDir == EDGE_VER)
435  {
436    pcCUP = pcCUQ->getPULeft(uiPartP, uiPartQ, !lfCrossSliceBoundaryFlag, !m_bLFCrossTileBoundary);
437  }
438  else  // (edgeDir == EDGE_HOR)
439  {
440    pcCUP = pcCUQ->getPUAbove(uiPartP, uiPartQ, !pCtu->getSlice()->getLFCrossSliceBoundaryFlag(), false, !m_bLFCrossTileBoundary);
441  }
442
443  //-- Set BS for Intra MB : BS = 4 or 3
444  if ( pcCUP->isIntra(uiPartP) || pcCUQ->isIntra(uiPartQ) )
445  {
446    uiBs = 2;
447  }
448
449  //-- Set BS for not Intra MB : BS = 2 or 1 or 0
450  if ( !pcCUP->isIntra(uiPartP) && !pcCUQ->isIntra(uiPartQ) )
451  {
452    UInt nsPartQ = uiPartQ;
453    UInt nsPartP = uiPartP;
454
455    if ( m_aapucBS[edgeDir][uiAbsPartIdx4x4BlockWithinCtu] && (pcCUQ->getCbf( nsPartQ, COMPONENT_Y, pcCUQ->getTransformIdx(nsPartQ)) != 0 || pcCUP->getCbf( nsPartP, COMPONENT_Y, pcCUP->getTransformIdx(nsPartP) ) != 0) )
456    {
457      uiBs = 1;
458    }
459    else
460    {
461      if (pcSlice->isInterB() || pcCUP->getSlice()->isInterB())
462      {
463        Int iRefIdx;
464        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
465        const TComPic *piRefP0 = (iRefIdx < 0) ? NULL : pcCUP->getSlice()->getRefPic(REF_PIC_LIST_0, iRefIdx);
466        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartP);
467        const TComPic *piRefP1 = (iRefIdx < 0) ? NULL : pcCUP->getSlice()->getRefPic(REF_PIC_LIST_1, iRefIdx);
468        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
469        const TComPic *piRefQ0 = (iRefIdx < 0) ? NULL : pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
470        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartQ);
471        const TComPic *piRefQ1 = (iRefIdx < 0) ? NULL : pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx);
472
473        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
474        TComMv pcMvP1 = pcCUP->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartP);
475        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
476        TComMv pcMvQ1 = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartQ);
477
478        if (piRefP0 == NULL)
479        {
480          pcMvP0.setZero();
481        }
482        if (piRefP1 == NULL)
483        {
484          pcMvP1.setZero();
485        }
486        if (piRefQ0 == NULL)
487        {
488          pcMvQ0.setZero();
489        }
490        if (piRefQ1 == NULL)
491        {
492          pcMvQ1.setZero();
493        }
494
495        if ( ((piRefP0==piRefQ0)&&(piRefP1==piRefQ1)) || ((piRefP0==piRefQ1)&&(piRefP1==piRefQ0)) )
496        {
497          if ( piRefP0 != piRefP1 )   // Different L0 & L1
498          {
499            if ( piRefP0 == piRefQ0 )
500            {
501              uiBs  = ((abs(pcMvQ0.getHor() - pcMvP0.getHor()) >= 4) ||
502                       (abs(pcMvQ0.getVer() - pcMvP0.getVer()) >= 4) ||
503                       (abs(pcMvQ1.getHor() - pcMvP1.getHor()) >= 4) ||
504                       (abs(pcMvQ1.getVer() - pcMvP1.getVer()) >= 4)) ? 1 : 0;
505            }
506            else
507            {
508              uiBs  = ((abs(pcMvQ1.getHor() - pcMvP0.getHor()) >= 4) ||
509                       (abs(pcMvQ1.getVer() - pcMvP0.getVer()) >= 4) ||
510                       (abs(pcMvQ0.getHor() - pcMvP1.getHor()) >= 4) ||
511                       (abs(pcMvQ0.getVer() - pcMvP1.getVer()) >= 4)) ? 1 : 0;
512            }
513          }
514          else    // Same L0 & L1
515          {
516            uiBs  = ((abs(pcMvQ0.getHor() - pcMvP0.getHor()) >= 4) ||
517                     (abs(pcMvQ0.getVer() - pcMvP0.getVer()) >= 4) ||
518                     (abs(pcMvQ1.getHor() - pcMvP1.getHor()) >= 4) ||
519                     (abs(pcMvQ1.getVer() - pcMvP1.getVer()) >= 4)) &&
520                    ((abs(pcMvQ1.getHor() - pcMvP0.getHor()) >= 4) ||
521                     (abs(pcMvQ1.getVer() - pcMvP0.getVer()) >= 4) ||
522                     (abs(pcMvQ0.getHor() - pcMvP1.getHor()) >= 4) ||
523                     (abs(pcMvQ0.getVer() - pcMvP1.getVer()) >= 4)) ? 1 : 0;
524          }
525        }
526        else // for all different Ref_Idx
527        {
528          uiBs = 1;
529        }
530      }
531      else  // pcSlice->isInterP()
532      {
533        Int iRefIdx;
534        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
535        const TComPic *piRefP0 = (iRefIdx < 0) ? NULL : pcCUP->getSlice()->getRefPic(REF_PIC_LIST_0, iRefIdx);
536        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
537        const TComPic *piRefQ0 = (iRefIdx < 0) ? NULL : pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
538        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
539        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
540
541        if (piRefP0 == NULL)
542        {
543          pcMvP0.setZero();
544        }
545        if (piRefQ0 == NULL)
546        {
547          pcMvQ0.setZero();
548        }
549
550        uiBs  = ((piRefP0 != piRefQ0) ||
551                 (abs(pcMvQ0.getHor() - pcMvP0.getHor()) >= 4) ||
552                 (abs(pcMvQ0.getVer() - pcMvP0.getVer()) >= 4)) ? 1 : 0;
553      }
554    }   // enf of "if( one of BCBP == 0 )"
555  }   // enf of "if( not Intra )"
556
557  m_aapucBS[edgeDir][uiAbsPartIdx4x4BlockWithinCtu] = uiBs;
558}
559
560
561Void TComLoopFilter::xEdgeFilterLuma( TComDataCU* const pcCU, const UInt uiAbsZorderIdx, const UInt uiDepth, const DeblockEdgeDir edgeDir, const Int iEdge  )
562{
563        TComPicYuv *pcPicYuvRec                   = pcCU->getPic()->getPicYuvRec();
564        Pel        *piSrc                         = pcPicYuvRec->getAddr(COMPONENT_Y, pcCU->getCtuRsAddr(), uiAbsZorderIdx );
565        Pel        *piTmpSrc                      = piSrc;
566  const TComSPS    &sps                           = *(pcCU->getSlice()->getSPS());
567  const Bool        ppsTransquantBypassEnableFlag = pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag();
568
569#if SVC_EXTENSION
570  const Int bitDepthLuma                          = pcCU->getSlice()->getBitDepth(CHANNEL_TYPE_LUMA);
571#else
572  const Int         bitDepthLuma                  = sps.getBitDepth(CHANNEL_TYPE_LUMA);
573#endif
574
575  const Bool        lfCrossSliceBoundaryFlag      = pcCU->getSlice()->getLFCrossSliceBoundaryFlag();
576
577  Int  iStride = pcPicYuvRec->getStride(COMPONENT_Y);
578  Int iQP = 0;
579  Int iQP_P = 0;
580  Int iQP_Q = 0;
581  UInt uiNumParts = pcCU->getPic()->getNumPartInCtuWidth()>>uiDepth;
582
583  UInt  uiPelsInPart = sps.getMaxCUWidth() >> sps.getMaxTotalCUDepth();
584  UInt  uiBsAbsIdx = 0, uiBs = 0;
585  Int   iOffset, iSrcStep;
586
587  Bool  bPCMFilter = (sps.getUsePCM() && sps.getPCMFilterDisableFlag())? true : false;
588  Bool  bPartPNoFilter = false;
589  Bool  bPartQNoFilter = false;
590  UInt  uiPartPIdx = 0;
591  UInt  uiPartQIdx = 0;
592  const TComDataCU* pcCUP = pcCU;
593  TComDataCU* pcCUQ = pcCU;
594  Int  betaOffsetDiv2 = pcCUQ->getSlice()->getDeblockingFilterBetaOffsetDiv2();
595  Int  tcOffsetDiv2 = pcCUQ->getSlice()->getDeblockingFilterTcOffsetDiv2();
596
597  if (edgeDir == EDGE_VER)
598  {
599    iOffset = 1;
600    iSrcStep = iStride;
601    piTmpSrc += iEdge*uiPelsInPart;
602  }
603  else  // (edgeDir == EDGE_HOR)
604  {
605    iOffset = iStride;
606    iSrcStep = 1;
607    piTmpSrc += iEdge*uiPelsInPart*iStride;
608  }
609
610  const Int iBitdepthScale = 1 << (bitDepthLuma-8);
611
612  for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx++ )
613  {
614    uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, edgeDir, iEdge, iIdx);
615    uiBs = m_aapucBS[edgeDir][uiBsAbsIdx];
616    if ( uiBs )
617    {
618      iQP_Q = pcCU->getQP( uiBsAbsIdx );
619      uiPartQIdx = uiBsAbsIdx;
620      // Derive neighboring PU index
621      if (edgeDir == EDGE_VER)
622      {
623        pcCUP = pcCUQ->getPULeft (uiPartPIdx, uiPartQIdx,!lfCrossSliceBoundaryFlag, !m_bLFCrossTileBoundary);
624      }
625      else  // (iDir == EDGE_HOR)
626      {
627        pcCUP = pcCUQ->getPUAbove(uiPartPIdx, uiPartQIdx,!lfCrossSliceBoundaryFlag, false, !m_bLFCrossTileBoundary);
628      }
629
630      iQP_P = pcCUP->getQP(uiPartPIdx);
631      iQP = (iQP_P + iQP_Q + 1) >> 1;
632
633      Int iIndexTC = Clip3(0, MAX_QP+DEFAULT_INTRA_TC_OFFSET, Int(iQP + DEFAULT_INTRA_TC_OFFSET*(uiBs-1) + (tcOffsetDiv2 << 1)));
634      Int iIndexB = Clip3(0, MAX_QP, iQP + (betaOffsetDiv2 << 1));
635
636      Int iTc =  sm_tcTable[iIndexTC]*iBitdepthScale;
637      Int iBeta = sm_betaTable[iIndexB]*iBitdepthScale;
638      Int iSideThreshold = (iBeta+(iBeta>>1))>>3;
639      Int iThrCut = iTc*10;
640
641
642      UInt  uiBlocksInPart = uiPelsInPart / 4 ? uiPelsInPart / 4 : 1;
643      for (UInt iBlkIdx = 0; iBlkIdx<uiBlocksInPart; iBlkIdx ++)
644      {
645        Int dp0 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0), iOffset);
646        Int dq0 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0), iOffset);
647        Int dp3 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3), iOffset);
648        Int dq3 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3), iOffset);
649        Int d0 = dp0 + dq0;
650        Int d3 = dp3 + dq3;
651
652        Int dp = dp0 + dp3;
653        Int dq = dq0 + dq3;
654        Int d =  d0 + d3;
655
656        if (bPCMFilter || ppsTransquantBypassEnableFlag)
657        {
658          // Check if each of PUs is I_PCM with LF disabling
659          bPartPNoFilter = (bPCMFilter && pcCUP->getIPCMFlag(uiPartPIdx));
660          bPartQNoFilter = (bPCMFilter && pcCUQ->getIPCMFlag(uiPartQIdx));
661
662          // check if each of PUs is lossless coded
663          bPartPNoFilter = bPartPNoFilter || (pcCUP->isLosslessCoded(uiPartPIdx) );
664          bPartQNoFilter = bPartQNoFilter || (pcCUQ->isLosslessCoded(uiPartQIdx) );
665        }
666
667        if (d < iBeta)
668        {
669          Bool bFilterP = (dp < iSideThreshold);
670          Bool bFilterQ = (dq < iSideThreshold);
671
672          Bool sw =  xUseStrongFiltering( iOffset, 2*d0, iBeta, iTc, piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0))
673          && xUseStrongFiltering( iOffset, 2*d3, iBeta, iTc, piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3));
674
675          for ( Int i = 0; i < DEBLOCK_SMALLEST_BLOCK/2; i++)
676          {
677            xPelFilterLuma( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+i), iOffset, iTc, sw, bPartPNoFilter, bPartQNoFilter, iThrCut, bFilterP, bFilterQ, bitDepthLuma);
678          }
679        }
680      }
681    }
682  }
683}
684
685
686Void TComLoopFilter::xEdgeFilterChroma( TComDataCU* const pcCU, const UInt uiAbsZorderIdx, const UInt uiDepth, const DeblockEdgeDir edgeDir, const Int iEdge )
687{
688        TComPicYuv *pcPicYuvRec    = pcCU->getPic()->getPicYuvRec();
689        Int         iStride        = pcPicYuvRec->getStride(COMPONENT_Cb);
690        Pel        *piSrcCb        = pcPicYuvRec->getAddr( COMPONENT_Cb, pcCU->getCtuRsAddr(), uiAbsZorderIdx );
691        Pel        *piSrcCr        = pcPicYuvRec->getAddr( COMPONENT_Cr, pcCU->getCtuRsAddr(), uiAbsZorderIdx );
692  const TComSPS    &sps            = *(pcCU->getSlice()->getSPS());
693#if SVC_EXTENSION
694  const Int         bitDepthChroma = pcCU->getSlice()->getBitDepth(CHANNEL_TYPE_CHROMA);
695#else 
696  const Int         bitDepthChroma = sps.getBitDepth(CHANNEL_TYPE_CHROMA);
697#endif
698
699  const UInt  uiPelsInPartChromaH = sps.getMaxCUWidth() >> (sps.getMaxTotalCUDepth()+pcPicYuvRec->getComponentScaleX(COMPONENT_Cb));
700  const UInt  uiPelsInPartChromaV = sps.getMaxCUHeight() >> (sps.getMaxTotalCUDepth()+pcPicYuvRec->getComponentScaleY(COMPONENT_Cb));
701
702  Int iQP = 0;
703  Int iQP_P = 0;
704  Int iQP_Q = 0;
705
706  Int   iOffset, iSrcStep;
707  UInt  uiLoopLength;
708
709  const UInt uiCtuWidthInBaseUnits = pcCU->getPic()->getNumPartInCtuWidth();
710
711  Bool  bPCMFilter = (pcCU->getSlice()->getSPS()->getUsePCM() && pcCU->getSlice()->getSPS()->getPCMFilterDisableFlag())? true : false;
712  Bool  bPartPNoFilter = false;
713  Bool  bPartQNoFilter = false;
714  TComDataCU* pcCUQ = pcCU;
715  Int tcOffsetDiv2 = pcCU->getSlice()->getDeblockingFilterTcOffsetDiv2();
716
717  // Vertical Position
718  UInt uiEdgeNumInCtuVert = g_auiZscanToRaster[uiAbsZorderIdx]%uiCtuWidthInBaseUnits + iEdge;
719  UInt uiEdgeNumInCtuHor = g_auiZscanToRaster[uiAbsZorderIdx]/uiCtuWidthInBaseUnits + iEdge;
720
721  if ( (uiPelsInPartChromaH < DEBLOCK_SMALLEST_BLOCK) && (uiPelsInPartChromaV < DEBLOCK_SMALLEST_BLOCK) &&
722       (
723         ( (uiEdgeNumInCtuVert%(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChromaH)) && (edgeDir==EDGE_VER) ) ||
724         ( (uiEdgeNumInCtuHor %(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChromaV)) && (edgeDir==EDGE_HOR) )
725       )
726     )
727  {
728    return;
729  }
730
731
732  const Bool lfCrossSliceBoundaryFlag=pcCU->getSlice()->getLFCrossSliceBoundaryFlag();
733
734  UInt  uiNumParts = pcCU->getPic()->getNumPartInCtuWidth()>>uiDepth;
735
736  UInt  uiBsAbsIdx;
737  UChar ucBs;
738
739  Pel* piTmpSrcCb = piSrcCb;
740  Pel* piTmpSrcCr = piSrcCr;
741
742  if (edgeDir == EDGE_VER)
743  {
744    iOffset   = 1;
745    iSrcStep  = iStride;
746    piTmpSrcCb += iEdge*uiPelsInPartChromaH;
747    piTmpSrcCr += iEdge*uiPelsInPartChromaH;
748    uiLoopLength=uiPelsInPartChromaV;
749  }
750  else  // (edgeDir == EDGE_HOR)
751  {
752    iOffset   = iStride;
753    iSrcStep  = 1;
754    piTmpSrcCb += iEdge*iStride*uiPelsInPartChromaV;
755    piTmpSrcCr += iEdge*iStride*uiPelsInPartChromaV;
756    uiLoopLength=uiPelsInPartChromaH;
757  }
758
759#if SVC_EXTENSION
760  const Int iBitdepthScale = 1 << (pcCU->getSlice()->getBitDepth(CHANNEL_TYPE_CHROMA)-8);
761#else
762  const Int iBitdepthScale = 1 << (pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_CHROMA)-8);
763#endif
764
765  for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx++ )
766  {
767    uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, edgeDir, iEdge, iIdx);
768    ucBs = m_aapucBS[edgeDir][uiBsAbsIdx];
769
770    if ( ucBs > 1)
771    {
772      iQP_Q = pcCU->getQP( uiBsAbsIdx );
773      UInt  uiPartQIdx = uiBsAbsIdx;
774      // Derive neighboring PU index
775      const TComDataCU* pcCUP;
776      UInt  uiPartPIdx;
777
778      if (edgeDir == EDGE_VER)
779      {
780        pcCUP = pcCUQ->getPULeft (uiPartPIdx, uiPartQIdx,!lfCrossSliceBoundaryFlag, !m_bLFCrossTileBoundary);
781      }
782      else  // (edgeDir == EDGE_HOR)
783      {
784        pcCUP = pcCUQ->getPUAbove(uiPartPIdx, uiPartQIdx,!lfCrossSliceBoundaryFlag, false, !m_bLFCrossTileBoundary);
785      }
786
787      iQP_P = pcCUP->getQP(uiPartPIdx);
788
789      if (bPCMFilter || pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
790      {
791        // Check if each of PUs is I_PCM with LF disabling
792        bPartPNoFilter = (bPCMFilter && pcCUP->getIPCMFlag(uiPartPIdx));
793        bPartQNoFilter = (bPCMFilter && pcCUQ->getIPCMFlag(uiPartQIdx));
794
795        // check if each of PUs is lossless coded
796        bPartPNoFilter = bPartPNoFilter || (pcCUP->isLosslessCoded(uiPartPIdx));
797        bPartQNoFilter = bPartQNoFilter || (pcCUQ->isLosslessCoded(uiPartQIdx));
798      }
799
800      for ( UInt chromaIdx = 0; chromaIdx < 2; chromaIdx++ )
801      {
802        Int chromaQPOffset  = pcCU->getSlice()->getPPS()->getQpOffset(ComponentID(chromaIdx + 1));
803        Pel* piTmpSrcChroma = (chromaIdx == 0) ? piTmpSrcCb : piTmpSrcCr;
804
805        iQP = ((iQP_P + iQP_Q + 1) >> 1) + chromaQPOffset;
806        if (iQP >= chromaQPMappingTableSize)
807        {
808          if (pcPicYuvRec->getChromaFormat()==CHROMA_420)
809          {
810            iQP -=6;
811          }
812          else if (iQP>51)
813          {
814            iQP=51;
815          }
816        }
817        else if (iQP >= 0 )
818        {
819          iQP = getScaledChromaQP(iQP, pcPicYuvRec->getChromaFormat());
820        }
821
822        Int iIndexTC = Clip3(0, MAX_QP+DEFAULT_INTRA_TC_OFFSET, iQP + DEFAULT_INTRA_TC_OFFSET*(ucBs - 1) + (tcOffsetDiv2 << 1));
823        Int iTc =  sm_tcTable[iIndexTC]*iBitdepthScale;
824
825        for ( UInt uiStep = 0; uiStep < uiLoopLength; uiStep++ )
826        {
827          xPelFilterChroma( piTmpSrcChroma + iSrcStep*(uiStep+iIdx*uiLoopLength), iOffset, iTc , bPartPNoFilter, bPartQNoFilter, bitDepthChroma);
828        }
829      }
830    }
831  }
832}
833
834/**
835 - Deblocking for the luminance component with strong or weak filter
836 .
837 \param piSrc           pointer to picture data
838 \param iOffset         offset value for picture data
839 \param tc              tc value
840 \param sw              decision strong/weak filter
841 \param bPartPNoFilter  indicator to disable filtering on partP
842 \param bPartQNoFilter  indicator to disable filtering on partQ
843 \param iThrCut         threshold value for weak filter decision
844 \param bFilterSecondP  decision weak filter/no filter for partP
845 \param bFilterSecondQ  decision weak filter/no filter for partQ
846 \param bitDepthLuma    luma bit depth
847*/
848__inline Void TComLoopFilter::xPelFilterLuma( Pel* piSrc, Int iOffset, Int tc, Bool sw, Bool bPartPNoFilter, Bool bPartQNoFilter, Int iThrCut, Bool bFilterSecondP, Bool bFilterSecondQ, const Int bitDepthLuma)
849{
850  Int delta;
851
852  Pel m4  = piSrc[0];
853  Pel m3  = piSrc[-iOffset];
854  Pel m5  = piSrc[ iOffset];
855  Pel m2  = piSrc[-iOffset*2];
856  Pel m6  = piSrc[ iOffset*2];
857  Pel m1  = piSrc[-iOffset*3];
858  Pel m7  = piSrc[ iOffset*3];
859  Pel m0  = piSrc[-iOffset*4];
860
861  if (sw)
862  {
863    piSrc[-iOffset]   = Clip3(m3-2*tc, m3+2*tc, ((m1 + 2*m2 + 2*m3 + 2*m4 + m5 + 4) >> 3));
864    piSrc[0]          = Clip3(m4-2*tc, m4+2*tc, ((m2 + 2*m3 + 2*m4 + 2*m5 + m6 + 4) >> 3));
865    piSrc[-iOffset*2] = Clip3(m2-2*tc, m2+2*tc, ((m1 + m2 + m3 + m4 + 2)>>2));
866    piSrc[ iOffset]   = Clip3(m5-2*tc, m5+2*tc, ((m3 + m4 + m5 + m6 + 2)>>2));
867    piSrc[-iOffset*3] = Clip3(m1-2*tc, m1+2*tc, ((2*m0 + 3*m1 + m2 + m3 + m4 + 4 )>>3));
868    piSrc[ iOffset*2] = Clip3(m6-2*tc, m6+2*tc, ((m3 + m4 + m5 + 3*m6 + 2*m7 +4 )>>3));
869  }
870  else
871  {
872    /* Weak filter */
873    delta = (9*(m4-m3) -3*(m5-m2) + 8)>>4 ;
874
875    if ( abs(delta) < iThrCut )
876    {
877      delta = Clip3(-tc, tc, delta);
878      piSrc[-iOffset] = ClipBD((m3+delta), bitDepthLuma);
879      piSrc[0] = ClipBD((m4-delta), bitDepthLuma);
880
881      Int tc2 = tc>>1;
882      if(bFilterSecondP)
883      {
884        Int delta1 = Clip3(-tc2, tc2, (( ((m1+m3+1)>>1)- m2+delta)>>1));
885        piSrc[-iOffset*2] = ClipBD((m2+delta1), bitDepthLuma);
886      }
887      if(bFilterSecondQ)
888      {
889        Int delta2 = Clip3(-tc2, tc2, (( ((m6+m4+1)>>1)- m5-delta)>>1));
890        piSrc[ iOffset] = ClipBD((m5+delta2), bitDepthLuma);
891      }
892    }
893  }
894
895  if(bPartPNoFilter)
896  {
897    piSrc[-iOffset] = m3;
898    piSrc[-iOffset*2] = m2;
899    piSrc[-iOffset*3] = m1;
900  }
901  if(bPartQNoFilter)
902  {
903    piSrc[0] = m4;
904    piSrc[ iOffset] = m5;
905    piSrc[ iOffset*2] = m6;
906  }
907}
908
909/**
910 - Deblocking of one line/column for the chrominance component
911 .
912 \param piSrc           pointer to picture data
913 \param iOffset         offset value for picture data
914 \param tc              tc value
915 \param bPartPNoFilter  indicator to disable filtering on partP
916 \param bPartQNoFilter  indicator to disable filtering on partQ
917 \param bitDepthChroma  chroma bit depth
918 */
919__inline Void TComLoopFilter::xPelFilterChroma( Pel* piSrc, Int iOffset, Int tc, Bool bPartPNoFilter, Bool bPartQNoFilter, const Int bitDepthChroma)
920{
921  Int delta;
922
923  Pel m4  = piSrc[0];
924  Pel m3  = piSrc[-iOffset];
925  Pel m5  = piSrc[ iOffset];
926  Pel m2  = piSrc[-iOffset*2];
927
928  delta = Clip3(-tc,tc, (((( m4 - m3 ) << 2 ) + m2 - m5 + 4 ) >> 3) );
929  piSrc[-iOffset] = ClipBD((m3+delta), bitDepthChroma);
930  piSrc[0] = ClipBD((m4-delta), bitDepthChroma);
931
932  if(bPartPNoFilter)
933  {
934    piSrc[-iOffset] = m3;
935  }
936  if(bPartQNoFilter)
937  {
938    piSrc[0] = m4;
939  }
940}
941
942/**
943 - Decision between strong and weak filter
944 .
945 \param offset         offset value for picture data
946 \param d               d value
947 \param beta            beta value
948 \param tc              tc value
949 \param piSrc           pointer to picture data
950 */
951__inline Bool TComLoopFilter::xUseStrongFiltering( Int offset, Int d, Int beta, Int tc, Pel* piSrc)
952{
953  Pel m4  = piSrc[0];
954  Pel m3  = piSrc[-offset];
955  Pel m7  = piSrc[ offset*3];
956  Pel m0  = piSrc[-offset*4];
957
958  Int d_strong = abs(m0-m3) + abs(m7-m4);
959
960  return ( (d_strong < (beta>>3)) && (d<(beta>>2)) && ( abs(m3-m4) < ((tc*5+1)>>1)) );
961}
962
963__inline Int TComLoopFilter::xCalcDP( Pel* piSrc, Int iOffset)
964{
965  return abs( piSrc[-iOffset*3] - 2*piSrc[-iOffset*2] + piSrc[-iOffset] ) ;
966}
967
968__inline Int TComLoopFilter::xCalcDQ( Pel* piSrc, Int iOffset)
969{
970  return abs( piSrc[0] - 2*piSrc[iOffset] + piSrc[iOffset*2] );
971}
972//! \}
Note: See TracBrowser for help on using the repository browser.