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

Last change on this file since 1413 was 1413, checked in by tech, 6 years ago

Merged HTM-16.2-dev@1412

  • Property svn:eol-style set to native
File size: 33.7 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2017, 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( ( uiLPelX < sps.getPicWidthInLumaSamples() ) && ( uiTPelY < sps.getPicHeightInLumaSamples() ) )
188      {
189        xDeblockCU( pcCU, uiAbsZorderIdx, uiDepth+1, edgeDir );
190      }
191    }
192    return;
193  }
194
195  xSetLoopfilterParam( pcCU, uiAbsZorderIdx );
196  TComTURecurse tuRecurse(pcCU, uiAbsZorderIdx);
197  xSetEdgefilterTU   ( tuRecurse );
198  xSetEdgefilterPU   ( pcCU, uiAbsZorderIdx );
199
200  const UInt uiPelsInPart = sps.getMaxCUWidth() >> sps.getMaxTotalCUDepth();
201
202  for( UInt uiPartIdx = uiAbsZorderIdx; uiPartIdx < uiAbsZorderIdx + uiCurNumParts; uiPartIdx++ )
203  {
204    UInt uiBSCheck;
205    if( uiPelsInPart == 4 )
206    {
207      uiBSCheck = (edgeDir == EDGE_VER && uiPartIdx%2 == 0) || (edgeDir == EDGE_HOR && (uiPartIdx-((uiPartIdx>>2)<<2))/2 == 0);
208    }
209    else
210    {
211      uiBSCheck = 1;
212    }
213
214    if ( m_aapbEdgeFilter[edgeDir][uiPartIdx] && uiBSCheck )
215    {
216      xGetBoundaryStrengthSingle ( pcCU, edgeDir, uiPartIdx );
217    }
218  }
219
220  UInt PartIdxIncr = DEBLOCK_SMALLEST_BLOCK / uiPelsInPart ? DEBLOCK_SMALLEST_BLOCK / uiPelsInPart : 1 ;
221
222  UInt uiSizeInPU = pcPic->getNumPartInCtuWidth()>>(uiDepth);
223  const ChromaFormat chFmt=pcPic->getChromaFormat();
224  const UInt shiftFactor  = edgeDir == EDGE_VER ? pcPic->getComponentScaleX(COMPONENT_Cb) : pcPic->getComponentScaleY(COMPONENT_Cb);
225  const Bool bAlwaysDoChroma=chFmt==CHROMA_444;
226
227  for ( Int iEdge = 0; iEdge < uiSizeInPU ; iEdge+=PartIdxIncr)
228  {
229    xEdgeFilterLuma     ( pcCU, uiAbsZorderIdx, uiDepth, edgeDir, iEdge );
230    if ( chFmt!=CHROMA_400 && (bAlwaysDoChroma ||
231                               (uiPelsInPart>DEBLOCK_SMALLEST_BLOCK) ||
232                               (iEdge % ( (DEBLOCK_SMALLEST_BLOCK<<shiftFactor)/uiPelsInPart ) ) == 0
233                              )
234       )
235    {
236      xEdgeFilterChroma   ( pcCU, uiAbsZorderIdx, uiDepth, edgeDir, iEdge );
237    }
238  }
239}
240
241Void TComLoopFilter::xSetEdgefilterMultiple( TComDataCU*    pcCU,
242                                             UInt           uiAbsZorderIdx,
243                                             UInt           uiDepth,
244                                             DeblockEdgeDir edgeDir,
245                                             Int            iEdgeIdx,
246                                             Bool           bValue,
247                                             UInt           uiWidthInBaseUnits,
248                                             UInt           uiHeightInBaseUnits,
249                                             const TComRectangle *rect)
250{
251  if ( uiWidthInBaseUnits == 0 )
252  {
253    uiWidthInBaseUnits  = pcCU->getPic()->getNumPartInCtuWidth () >> uiDepth;
254  }
255  if ( uiHeightInBaseUnits == 0 )
256  {
257    uiHeightInBaseUnits = pcCU->getPic()->getNumPartInCtuHeight() >> uiDepth;
258  }
259  const UInt uiNumElem = edgeDir == EDGE_VER ? 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, uiAbsZorderIdx, edgeDir, iEdgeIdx, ui, rect );
266    m_aapbEdgeFilter[edgeDir][uiBsIdx] = bValue;
267    if (iEdgeIdx == 0)
268    {
269      m_aapucBS[edgeDir][uiBsIdx] = bValue;
270    }
271  }
272}
273
274Void TComLoopFilter::xSetEdgefilterTU(  TComTU &rTu )
275{
276  TComDataCU* pcCU  = rTu.getCU();
277  UInt uiTransDepthTotal = rTu.GetTransformDepthTotal();
278
279  if( pcCU->getTransformIdx( rTu.GetAbsPartIdxTU() ) + pcCU->getDepth( rTu.GetAbsPartIdxTU()) > uiTransDepthTotal )
280  {
281    TComTURecurse tuChild(rTu, false);
282    do
283    {
284      xSetEdgefilterTU( tuChild );
285    } while (tuChild.nextSection(rTu));
286    return;
287  }
288
289  const TComRectangle &rect = rTu.getRect(COMPONENT_Y);
290  const TComSPS &sps=*(pcCU->getSlice()->getSPS());
291
292  const UInt uiWidthInBaseUnits  = rect.width  / (sps.getMaxCUWidth()  >> sps.getMaxTotalCUDepth());
293  const UInt uiHeightInBaseUnits = rect.height / (sps.getMaxCUHeight() >> sps.getMaxTotalCUDepth());
294
295  xSetEdgefilterMultiple( pcCU, rTu.GetAbsPartIdxCU(), uiTransDepthTotal, EDGE_VER, 0, m_stLFCUParam.bInternalEdge, uiWidthInBaseUnits, uiHeightInBaseUnits, &rect );
296  xSetEdgefilterMultiple( pcCU, rTu.GetAbsPartIdxCU(), uiTransDepthTotal, EDGE_HOR, 0, m_stLFCUParam.bInternalEdge, uiWidthInBaseUnits, uiHeightInBaseUnits, &rect );
297}
298
299Void TComLoopFilter::xSetEdgefilterPU( TComDataCU* pcCU, UInt uiAbsZorderIdx )
300{
301  const UInt uiDepth = pcCU->getDepth( uiAbsZorderIdx );
302  const UInt uiWidthInBaseUnits  = pcCU->getPic()->getNumPartInCtuWidth () >> uiDepth;
303  const UInt uiHeightInBaseUnits = pcCU->getPic()->getNumPartInCtuHeight() >> uiDepth;
304  const UInt uiHWidthInBaseUnits  = uiWidthInBaseUnits  >> 1;
305  const UInt uiHHeightInBaseUnits = uiHeightInBaseUnits >> 1;
306  const UInt uiQWidthInBaseUnits  = uiWidthInBaseUnits  >> 2;
307  const UInt uiQHeightInBaseUnits = uiHeightInBaseUnits >> 2;
308
309  xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, 0, m_stLFCUParam.bLeftEdge );
310  xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, 0, m_stLFCUParam.bTopEdge );
311
312  switch ( pcCU->getPartitionSize( uiAbsZorderIdx ) )
313  {
314    case SIZE_2Nx2N:
315    {
316      break;
317    }
318    case SIZE_2NxN:
319    {
320      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
321      break;
322    }
323    case SIZE_Nx2N:
324    {
325      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiHWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
326      break;
327    }
328    case SIZE_NxN:
329    {
330      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiHWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
331      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
332      break;
333    }
334    case SIZE_2NxnU:
335    {
336      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiQHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
337      break;
338    }
339    case SIZE_2NxnD:
340    {
341      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHeightInBaseUnits - uiQHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
342      break;
343    }
344    case SIZE_nLx2N:
345    {
346      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiQWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
347      break;
348    }
349    case SIZE_nRx2N:
350    {
351      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiWidthInBaseUnits - uiQWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
352      break;
353    }
354    default:
355    {
356      break;
357    }
358  }
359}
360
361
362Void TComLoopFilter::xSetLoopfilterParam( TComDataCU* pcCU, UInt uiAbsZorderIdx )
363{
364  UInt uiX           = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsZorderIdx ] ];
365  UInt uiY           = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsZorderIdx ] ];
366
367  UInt        uiTempPartIdx;
368
369  m_stLFCUParam.bInternalEdge = ! pcCU->getSlice()->getDeblockingFilterDisable();
370
371  if ( (uiX == 0) || pcCU->getSlice()->getDeblockingFilterDisable() )
372  {
373    m_stLFCUParam.bLeftEdge = false;
374  }
375  else
376  {
377    m_stLFCUParam.bLeftEdge = true;
378  }
379  if ( m_stLFCUParam.bLeftEdge )
380  {
381    const TComDataCU* pcTempCU = pcCU->getPULeft( uiTempPartIdx, uiAbsZorderIdx, !pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), !m_bLFCrossTileBoundary);
382
383    if ( pcTempCU != NULL )
384    {
385      m_stLFCUParam.bLeftEdge = true;
386    }
387    else
388    {
389      m_stLFCUParam.bLeftEdge = false;
390    }
391  }
392
393  if ( (uiY == 0 ) || pcCU->getSlice()->getDeblockingFilterDisable() )
394  {
395    m_stLFCUParam.bTopEdge = false;
396  }
397  else
398  {
399    m_stLFCUParam.bTopEdge = true;
400  }
401  if ( m_stLFCUParam.bTopEdge )
402  {
403    const TComDataCU* pcTempCU = pcCU->getPUAbove( uiTempPartIdx, uiAbsZorderIdx, !pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), false, !m_bLFCrossTileBoundary);
404
405    if ( pcTempCU != NULL )
406    {
407      m_stLFCUParam.bTopEdge = true;
408    }
409    else
410    {
411      m_stLFCUParam.bTopEdge = false;
412    }
413  }
414}
415
416Void TComLoopFilter::xGetBoundaryStrengthSingle ( TComDataCU* pCtu, DeblockEdgeDir edgeDir, UInt uiAbsPartIdx4x4BlockWithinCtu )
417{
418  TComSlice * const pcSlice = pCtu->getSlice();
419
420  const Bool lfCrossSliceBoundaryFlag=pCtu->getSlice()->getLFCrossSliceBoundaryFlag();
421
422  const UInt uiPartQ = uiAbsPartIdx4x4BlockWithinCtu;
423  TComDataCU* const pcCUQ = pCtu;
424
425  UInt uiPartP;
426  const TComDataCU* pcCUP;
427  UInt uiBs = 0;
428
429  //-- Calculate Block Index
430  if (edgeDir == EDGE_VER)
431  {
432    pcCUP = pcCUQ->getPULeft(uiPartP, uiPartQ, !lfCrossSliceBoundaryFlag, !m_bLFCrossTileBoundary);
433  }
434  else  // (edgeDir == EDGE_HOR)
435  {
436    pcCUP = pcCUQ->getPUAbove(uiPartP, uiPartQ, !pCtu->getSlice()->getLFCrossSliceBoundaryFlag(), false, !m_bLFCrossTileBoundary);
437  }
438
439  //-- Set BS for Intra MB : BS = 4 or 3
440  if ( pcCUP->isIntra(uiPartP) || pcCUQ->isIntra(uiPartQ) )
441  {
442    uiBs = 2;
443  }
444
445  //-- Set BS for not Intra MB : BS = 2 or 1 or 0
446  if ( !pcCUP->isIntra(uiPartP) && !pcCUQ->isIntra(uiPartQ) )
447  {
448    UInt nsPartQ = uiPartQ;
449    UInt nsPartP = uiPartP;
450
451    if ( m_aapucBS[edgeDir][uiAbsPartIdx4x4BlockWithinCtu] && (pcCUQ->getCbf( nsPartQ, COMPONENT_Y, pcCUQ->getTransformIdx(nsPartQ)) != 0 || pcCUP->getCbf( nsPartP, COMPONENT_Y, pcCUP->getTransformIdx(nsPartP) ) != 0) )
452    {
453      uiBs = 1;
454    }
455    else
456    {
457      if (pcSlice->isInterB() || pcCUP->getSlice()->isInterB())
458      {
459        Int iRefIdx;
460        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
461        const TComPic *piRefP0 = (iRefIdx < 0) ? NULL : pcCUP->getSlice()->getRefPic(REF_PIC_LIST_0, iRefIdx);
462        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartP);
463        const TComPic *piRefP1 = (iRefIdx < 0) ? NULL : pcCUP->getSlice()->getRefPic(REF_PIC_LIST_1, iRefIdx);
464        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
465        const TComPic *piRefQ0 = (iRefIdx < 0) ? NULL : pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
466        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartQ);
467        const TComPic *piRefQ1 = (iRefIdx < 0) ? NULL : pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx);
468
469        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
470        TComMv pcMvP1 = pcCUP->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartP);
471        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
472        TComMv pcMvQ1 = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartQ);
473
474        if (piRefP0 == NULL)
475        {
476          pcMvP0.setZero();
477        }
478        if (piRefP1 == NULL)
479        {
480          pcMvP1.setZero();
481        }
482        if (piRefQ0 == NULL)
483        {
484          pcMvQ0.setZero();
485        }
486        if (piRefQ1 == NULL)
487        {
488          pcMvQ1.setZero();
489        }
490
491        if ( ((piRefP0==piRefQ0)&&(piRefP1==piRefQ1)) || ((piRefP0==piRefQ1)&&(piRefP1==piRefQ0)) )
492        {
493          if ( piRefP0 != piRefP1 )   // Different L0 & L1
494          {
495            if ( piRefP0 == piRefQ0 )
496            {
497              uiBs  = ((abs(pcMvQ0.getHor() - pcMvP0.getHor()) >= 4) ||
498                       (abs(pcMvQ0.getVer() - pcMvP0.getVer()) >= 4) ||
499                       (abs(pcMvQ1.getHor() - pcMvP1.getHor()) >= 4) ||
500                       (abs(pcMvQ1.getVer() - pcMvP1.getVer()) >= 4)) ? 1 : 0;
501            }
502            else
503            {
504              uiBs  = ((abs(pcMvQ1.getHor() - pcMvP0.getHor()) >= 4) ||
505                       (abs(pcMvQ1.getVer() - pcMvP0.getVer()) >= 4) ||
506                       (abs(pcMvQ0.getHor() - pcMvP1.getHor()) >= 4) ||
507                       (abs(pcMvQ0.getVer() - pcMvP1.getVer()) >= 4)) ? 1 : 0;
508            }
509          }
510          else    // Same L0 & L1
511          {
512            uiBs  = ((abs(pcMvQ0.getHor() - pcMvP0.getHor()) >= 4) ||
513                     (abs(pcMvQ0.getVer() - pcMvP0.getVer()) >= 4) ||
514                     (abs(pcMvQ1.getHor() - pcMvP1.getHor()) >= 4) ||
515                     (abs(pcMvQ1.getVer() - pcMvP1.getVer()) >= 4)) &&
516                    ((abs(pcMvQ1.getHor() - pcMvP0.getHor()) >= 4) ||
517                     (abs(pcMvQ1.getVer() - pcMvP0.getVer()) >= 4) ||
518                     (abs(pcMvQ0.getHor() - pcMvP1.getHor()) >= 4) ||
519                     (abs(pcMvQ0.getVer() - pcMvP1.getVer()) >= 4)) ? 1 : 0;
520          }
521        }
522        else // for all different Ref_Idx
523        {
524          uiBs = 1;
525        }
526      }
527      else  // pcSlice->isInterP()
528      {
529        Int iRefIdx;
530        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
531        const TComPic *piRefP0 = (iRefIdx < 0) ? NULL : pcCUP->getSlice()->getRefPic(REF_PIC_LIST_0, iRefIdx);
532        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
533        const TComPic *piRefQ0 = (iRefIdx < 0) ? NULL : pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
534        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
535        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
536
537        if (piRefP0 == NULL)
538        {
539          pcMvP0.setZero();
540        }
541        if (piRefQ0 == NULL)
542        {
543          pcMvQ0.setZero();
544        }
545
546        uiBs  = ((piRefP0 != piRefQ0) ||
547                 (abs(pcMvQ0.getHor() - pcMvP0.getHor()) >= 4) ||
548                 (abs(pcMvQ0.getVer() - pcMvP0.getVer()) >= 4)) ? 1 : 0;
549      }
550    }   // enf of "if( one of BCBP == 0 )"
551  }   // enf of "if( not Intra )"
552
553  m_aapucBS[edgeDir][uiAbsPartIdx4x4BlockWithinCtu] = uiBs;
554}
555
556
557Void TComLoopFilter::xEdgeFilterLuma( TComDataCU* const pcCU, const UInt uiAbsZorderIdx, const UInt uiDepth, const DeblockEdgeDir edgeDir, const Int iEdge  )
558{
559        TComPicYuv *pcPicYuvRec                   = pcCU->getPic()->getPicYuvRec();
560        Pel        *piSrc                         = pcPicYuvRec->getAddr(COMPONENT_Y, pcCU->getCtuRsAddr(), uiAbsZorderIdx );
561        Pel        *piTmpSrc                      = piSrc;
562  const TComSPS    &sps                           = *(pcCU->getSlice()->getSPS());
563  const Bool        ppsTransquantBypassEnabledFlag = pcCU->getSlice()->getPPS()->getTransquantBypassEnabledFlag();
564  const Int         bitDepthLuma                  = sps.getBitDepth(CHANNEL_TYPE_LUMA);
565  const Bool        lfCrossSliceBoundaryFlag      = pcCU->getSlice()->getLFCrossSliceBoundaryFlag();
566
567  Int  iStride = pcPicYuvRec->getStride(COMPONENT_Y);
568  Int iQP = 0;
569  Int iQP_P = 0;
570  Int iQP_Q = 0;
571  UInt uiNumParts = pcCU->getPic()->getNumPartInCtuWidth()>>uiDepth;
572
573  UInt  uiPelsInPart = sps.getMaxCUWidth() >> sps.getMaxTotalCUDepth();
574  UInt  uiBsAbsIdx = 0, uiBs = 0;
575  Int   iOffset, iSrcStep;
576
577  Bool  bPCMFilter = (sps.getUsePCM() && sps.getPCMFilterDisableFlag())? true : false;
578  Bool  bPartPNoFilter = false;
579  Bool  bPartQNoFilter = false;
580  UInt  uiPartPIdx = 0;
581  UInt  uiPartQIdx = 0;
582  const TComDataCU* pcCUP = pcCU;
583  TComDataCU* pcCUQ = pcCU;
584  Int  betaOffsetDiv2 = pcCUQ->getSlice()->getDeblockingFilterBetaOffsetDiv2();
585  Int  tcOffsetDiv2 = pcCUQ->getSlice()->getDeblockingFilterTcOffsetDiv2();
586
587  if (edgeDir == EDGE_VER)
588  {
589    iOffset = 1;
590    iSrcStep = iStride;
591    piTmpSrc += iEdge*uiPelsInPart;
592  }
593  else  // (edgeDir == EDGE_HOR)
594  {
595    iOffset = iStride;
596    iSrcStep = 1;
597    piTmpSrc += iEdge*uiPelsInPart*iStride;
598  }
599
600  const Int iBitdepthScale = 1 << (bitDepthLuma-8);
601
602  for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx++ )
603  {
604    uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, edgeDir, iEdge, iIdx);
605    uiBs = m_aapucBS[edgeDir][uiBsAbsIdx];
606    if ( uiBs )
607    {
608      iQP_Q = pcCU->getQP( uiBsAbsIdx );
609      uiPartQIdx = uiBsAbsIdx;
610      // Derive neighboring PU index
611      if (edgeDir == EDGE_VER)
612      {
613        pcCUP = pcCUQ->getPULeft (uiPartPIdx, uiPartQIdx,!lfCrossSliceBoundaryFlag, !m_bLFCrossTileBoundary);
614      }
615      else  // (iDir == EDGE_HOR)
616      {
617        pcCUP = pcCUQ->getPUAbove(uiPartPIdx, uiPartQIdx,!lfCrossSliceBoundaryFlag, false, !m_bLFCrossTileBoundary);
618      }
619
620      iQP_P = pcCUP->getQP(uiPartPIdx);
621      iQP = (iQP_P + iQP_Q + 1) >> 1;
622
623      Int iIndexTC = Clip3(0, MAX_QP+DEFAULT_INTRA_TC_OFFSET, Int(iQP + DEFAULT_INTRA_TC_OFFSET*(uiBs-1) + (tcOffsetDiv2 << 1)));
624      Int iIndexB = Clip3(0, MAX_QP, iQP + (betaOffsetDiv2 << 1));
625
626      Int iTc =  sm_tcTable[iIndexTC]*iBitdepthScale;
627      Int iBeta = sm_betaTable[iIndexB]*iBitdepthScale;
628      Int iSideThreshold = (iBeta+(iBeta>>1))>>3;
629      Int iThrCut = iTc*10;
630
631
632      UInt  uiBlocksInPart = uiPelsInPart / 4 ? uiPelsInPart / 4 : 1;
633      for (UInt iBlkIdx = 0; iBlkIdx<uiBlocksInPart; iBlkIdx ++)
634      {
635        Int dp0 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0), iOffset);
636        Int dq0 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0), iOffset);
637        Int dp3 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3), iOffset);
638        Int dq3 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3), iOffset);
639        Int d0 = dp0 + dq0;
640        Int d3 = dp3 + dq3;
641
642        Int dp = dp0 + dp3;
643        Int dq = dq0 + dq3;
644        Int d =  d0 + d3;
645
646        if (bPCMFilter || ppsTransquantBypassEnabledFlag)
647        {
648          // Check if each of PUs is I_PCM with LF disabling
649          bPartPNoFilter = (bPCMFilter && pcCUP->getIPCMFlag(uiPartPIdx));
650          bPartQNoFilter = (bPCMFilter && pcCUQ->getIPCMFlag(uiPartQIdx));
651
652          // check if each of PUs is lossless coded
653          bPartPNoFilter = bPartPNoFilter || (pcCUP->isLosslessCoded(uiPartPIdx) );
654          bPartQNoFilter = bPartQNoFilter || (pcCUQ->isLosslessCoded(uiPartQIdx) );
655        }
656
657        if (d < iBeta)
658        {
659          Bool bFilterP = (dp < iSideThreshold);
660          Bool bFilterQ = (dq < iSideThreshold);
661
662          Bool sw =  xUseStrongFiltering( iOffset, 2*d0, iBeta, iTc, piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0))
663          && xUseStrongFiltering( iOffset, 2*d3, iBeta, iTc, piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3));
664
665          for ( Int i = 0; i < DEBLOCK_SMALLEST_BLOCK/2; i++)
666          {
667            xPelFilterLuma( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+i), iOffset, iTc, sw, bPartPNoFilter, bPartQNoFilter, iThrCut, bFilterP, bFilterQ, bitDepthLuma);
668          }
669        }
670      }
671    }
672  }
673}
674
675
676Void TComLoopFilter::xEdgeFilterChroma( TComDataCU* const pcCU, const UInt uiAbsZorderIdx, const UInt uiDepth, const DeblockEdgeDir edgeDir, const Int iEdge )
677{
678        TComPicYuv *pcPicYuvRec    = pcCU->getPic()->getPicYuvRec();
679        Int         iStride        = pcPicYuvRec->getStride(COMPONENT_Cb);
680        Pel        *piSrcCb        = pcPicYuvRec->getAddr( COMPONENT_Cb, pcCU->getCtuRsAddr(), uiAbsZorderIdx );
681        Pel        *piSrcCr        = pcPicYuvRec->getAddr( COMPONENT_Cr, pcCU->getCtuRsAddr(), uiAbsZorderIdx );
682  const TComSPS    &sps            = *(pcCU->getSlice()->getSPS());
683  const Int         bitDepthChroma = sps.getBitDepth(CHANNEL_TYPE_CHROMA);
684
685  const UInt  uiPelsInPartChromaH = sps.getMaxCUWidth() >> (sps.getMaxTotalCUDepth()+pcPicYuvRec->getComponentScaleX(COMPONENT_Cb));
686  const UInt  uiPelsInPartChromaV = sps.getMaxCUHeight() >> (sps.getMaxTotalCUDepth()+pcPicYuvRec->getComponentScaleY(COMPONENT_Cb));
687
688  Int iQP = 0;
689  Int iQP_P = 0;
690  Int iQP_Q = 0;
691
692  Int   iOffset, iSrcStep;
693  UInt  uiLoopLength;
694
695  const UInt uiCtuWidthInBaseUnits = pcCU->getPic()->getNumPartInCtuWidth();
696
697  Bool  bPCMFilter = (pcCU->getSlice()->getSPS()->getUsePCM() && pcCU->getSlice()->getSPS()->getPCMFilterDisableFlag())? true : false;
698  Bool  bPartPNoFilter = false;
699  Bool  bPartQNoFilter = false;
700  TComDataCU* pcCUQ = pcCU;
701  Int tcOffsetDiv2 = pcCU->getSlice()->getDeblockingFilterTcOffsetDiv2();
702
703  // Vertical Position
704  UInt uiEdgeNumInCtuVert = g_auiZscanToRaster[uiAbsZorderIdx]%uiCtuWidthInBaseUnits + iEdge;
705  UInt uiEdgeNumInCtuHor = g_auiZscanToRaster[uiAbsZorderIdx]/uiCtuWidthInBaseUnits + iEdge;
706
707  if ( (uiPelsInPartChromaH < DEBLOCK_SMALLEST_BLOCK) && (uiPelsInPartChromaV < DEBLOCK_SMALLEST_BLOCK) &&
708       (
709         ( (uiEdgeNumInCtuVert%(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChromaH)) && (edgeDir==EDGE_VER) ) ||
710         ( (uiEdgeNumInCtuHor %(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChromaV)) && (edgeDir==EDGE_HOR) )
711       )
712     )
713  {
714    return;
715  }
716
717
718  const Bool lfCrossSliceBoundaryFlag=pcCU->getSlice()->getLFCrossSliceBoundaryFlag();
719
720  UInt  uiNumParts = pcCU->getPic()->getNumPartInCtuWidth()>>uiDepth;
721
722  UInt  uiBsAbsIdx;
723  UChar ucBs;
724
725  Pel* piTmpSrcCb = piSrcCb;
726  Pel* piTmpSrcCr = piSrcCr;
727
728  if (edgeDir == EDGE_VER)
729  {
730    iOffset   = 1;
731    iSrcStep  = iStride;
732    piTmpSrcCb += iEdge*uiPelsInPartChromaH;
733    piTmpSrcCr += iEdge*uiPelsInPartChromaH;
734    uiLoopLength=uiPelsInPartChromaV;
735  }
736  else  // (edgeDir == EDGE_HOR)
737  {
738    iOffset   = iStride;
739    iSrcStep  = 1;
740    piTmpSrcCb += iEdge*iStride*uiPelsInPartChromaV;
741    piTmpSrcCr += iEdge*iStride*uiPelsInPartChromaV;
742    uiLoopLength=uiPelsInPartChromaH;
743  }
744
745  const Int iBitdepthScale = 1 << (pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_CHROMA)-8);
746
747  for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx++ )
748  {
749    uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, edgeDir, iEdge, iIdx);
750    ucBs = m_aapucBS[edgeDir][uiBsAbsIdx];
751
752    if ( ucBs > 1)
753    {
754      iQP_Q = pcCU->getQP( uiBsAbsIdx );
755      UInt  uiPartQIdx = uiBsAbsIdx;
756      // Derive neighboring PU index
757      const TComDataCU* pcCUP;
758      UInt  uiPartPIdx;
759
760      if (edgeDir == EDGE_VER)
761      {
762        pcCUP = pcCUQ->getPULeft (uiPartPIdx, uiPartQIdx,!lfCrossSliceBoundaryFlag, !m_bLFCrossTileBoundary);
763      }
764      else  // (edgeDir == EDGE_HOR)
765      {
766        pcCUP = pcCUQ->getPUAbove(uiPartPIdx, uiPartQIdx,!lfCrossSliceBoundaryFlag, false, !m_bLFCrossTileBoundary);
767      }
768
769      iQP_P = pcCUP->getQP(uiPartPIdx);
770
771      if (bPCMFilter || pcCU->getSlice()->getPPS()->getTransquantBypassEnabledFlag())
772      {
773        // Check if each of PUs is I_PCM with LF disabling
774        bPartPNoFilter = (bPCMFilter && pcCUP->getIPCMFlag(uiPartPIdx));
775        bPartQNoFilter = (bPCMFilter && pcCUQ->getIPCMFlag(uiPartQIdx));
776
777        // check if each of PUs is lossless coded
778        bPartPNoFilter = bPartPNoFilter || (pcCUP->isLosslessCoded(uiPartPIdx));
779        bPartQNoFilter = bPartQNoFilter || (pcCUQ->isLosslessCoded(uiPartQIdx));
780      }
781
782      for ( UInt chromaIdx = 0; chromaIdx < 2; chromaIdx++ )
783      {
784        Int chromaQPOffset  = pcCU->getSlice()->getPPS()->getQpOffset(ComponentID(chromaIdx + 1));
785        Pel* piTmpSrcChroma = (chromaIdx == 0) ? piTmpSrcCb : piTmpSrcCr;
786
787        iQP = ((iQP_P + iQP_Q + 1) >> 1) + chromaQPOffset;
788        if (iQP >= chromaQPMappingTableSize)
789        {
790          if (pcPicYuvRec->getChromaFormat()==CHROMA_420)
791          {
792            iQP -=6;
793          }
794          else if (iQP>51)
795          {
796            iQP=51;
797          }
798        }
799        else if (iQP >= 0 )
800        {
801          iQP = getScaledChromaQP(iQP, pcPicYuvRec->getChromaFormat());
802        }
803
804        Int iIndexTC = Clip3(0, MAX_QP+DEFAULT_INTRA_TC_OFFSET, iQP + DEFAULT_INTRA_TC_OFFSET*(ucBs - 1) + (tcOffsetDiv2 << 1));
805        Int iTc =  sm_tcTable[iIndexTC]*iBitdepthScale;
806
807        for ( UInt uiStep = 0; uiStep < uiLoopLength; uiStep++ )
808        {
809          xPelFilterChroma( piTmpSrcChroma + iSrcStep*(uiStep+iIdx*uiLoopLength), iOffset, iTc , bPartPNoFilter, bPartQNoFilter, bitDepthChroma);
810        }
811      }
812    }
813  }
814}
815
816/**
817 - Deblocking for the luminance component with strong or weak filter
818 .
819 \param piSrc           pointer to picture data
820 \param iOffset         offset value for picture data
821 \param tc              tc value
822 \param sw              decision strong/weak filter
823 \param bPartPNoFilter  indicator to disable filtering on partP
824 \param bPartQNoFilter  indicator to disable filtering on partQ
825 \param iThrCut         threshold value for weak filter decision
826 \param bFilterSecondP  decision weak filter/no filter for partP
827 \param bFilterSecondQ  decision weak filter/no filter for partQ
828 \param bitDepthLuma    luma bit depth
829*/
830__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)
831{
832  Int delta;
833
834  Pel m4  = piSrc[0];
835  Pel m3  = piSrc[-iOffset];
836  Pel m5  = piSrc[ iOffset];
837  Pel m2  = piSrc[-iOffset*2];
838  Pel m6  = piSrc[ iOffset*2];
839  Pel m1  = piSrc[-iOffset*3];
840  Pel m7  = piSrc[ iOffset*3];
841  Pel m0  = piSrc[-iOffset*4];
842
843  if (sw)
844  {
845    piSrc[-iOffset]   = Clip3(m3-2*tc, m3+2*tc, ((m1 + 2*m2 + 2*m3 + 2*m4 + m5 + 4) >> 3));
846    piSrc[0]          = Clip3(m4-2*tc, m4+2*tc, ((m2 + 2*m3 + 2*m4 + 2*m5 + m6 + 4) >> 3));
847    piSrc[-iOffset*2] = Clip3(m2-2*tc, m2+2*tc, ((m1 + m2 + m3 + m4 + 2)>>2));
848    piSrc[ iOffset]   = Clip3(m5-2*tc, m5+2*tc, ((m3 + m4 + m5 + m6 + 2)>>2));
849    piSrc[-iOffset*3] = Clip3(m1-2*tc, m1+2*tc, ((2*m0 + 3*m1 + m2 + m3 + m4 + 4 )>>3));
850    piSrc[ iOffset*2] = Clip3(m6-2*tc, m6+2*tc, ((m3 + m4 + m5 + 3*m6 + 2*m7 +4 )>>3));
851  }
852  else
853  {
854    /* Weak filter */
855    delta = (9*(m4-m3) -3*(m5-m2) + 8)>>4 ;
856
857    if ( abs(delta) < iThrCut )
858    {
859      delta = Clip3(-tc, tc, delta);
860      piSrc[-iOffset] = ClipBD((m3+delta), bitDepthLuma);
861      piSrc[0] = ClipBD((m4-delta), bitDepthLuma);
862
863      Int tc2 = tc>>1;
864      if(bFilterSecondP)
865      {
866        Int delta1 = Clip3(-tc2, tc2, (( ((m1+m3+1)>>1)- m2+delta)>>1));
867        piSrc[-iOffset*2] = ClipBD((m2+delta1), bitDepthLuma);
868      }
869      if(bFilterSecondQ)
870      {
871        Int delta2 = Clip3(-tc2, tc2, (( ((m6+m4+1)>>1)- m5-delta)>>1));
872        piSrc[ iOffset] = ClipBD((m5+delta2), bitDepthLuma);
873      }
874    }
875  }
876
877  if(bPartPNoFilter)
878  {
879    piSrc[-iOffset] = m3;
880    piSrc[-iOffset*2] = m2;
881    piSrc[-iOffset*3] = m1;
882  }
883  if(bPartQNoFilter)
884  {
885    piSrc[0] = m4;
886    piSrc[ iOffset] = m5;
887    piSrc[ iOffset*2] = m6;
888  }
889}
890
891/**
892 - Deblocking of one line/column for the chrominance component
893 .
894 \param piSrc           pointer to picture data
895 \param iOffset         offset value for picture data
896 \param tc              tc value
897 \param bPartPNoFilter  indicator to disable filtering on partP
898 \param bPartQNoFilter  indicator to disable filtering on partQ
899 \param bitDepthChroma  chroma bit depth
900 */
901__inline Void TComLoopFilter::xPelFilterChroma( Pel* piSrc, Int iOffset, Int tc, Bool bPartPNoFilter, Bool bPartQNoFilter, const Int bitDepthChroma)
902{
903  Int delta;
904
905  Pel m4  = piSrc[0];
906  Pel m3  = piSrc[-iOffset];
907  Pel m5  = piSrc[ iOffset];
908  Pel m2  = piSrc[-iOffset*2];
909
910  delta = Clip3(-tc,tc, (((( m4 - m3 ) << 2 ) + m2 - m5 + 4 ) >> 3) );
911  piSrc[-iOffset] = ClipBD((m3+delta), bitDepthChroma);
912  piSrc[0] = ClipBD((m4-delta), bitDepthChroma);
913
914  if(bPartPNoFilter)
915  {
916    piSrc[-iOffset] = m3;
917  }
918  if(bPartQNoFilter)
919  {
920    piSrc[0] = m4;
921  }
922}
923
924/**
925 - Decision between strong and weak filter
926 .
927 \param offset         offset value for picture data
928 \param d               d value
929 \param beta            beta value
930 \param tc              tc value
931 \param piSrc           pointer to picture data
932 */
933__inline Bool TComLoopFilter::xUseStrongFiltering( Int offset, Int d, Int beta, Int tc, Pel* piSrc)
934{
935  Pel m4  = piSrc[0];
936  Pel m3  = piSrc[-offset];
937  Pel m7  = piSrc[ offset*3];
938  Pel m0  = piSrc[-offset*4];
939
940  Int d_strong = abs(m0-m3) + abs(m7-m4);
941
942  return ( (d_strong < (beta>>3)) && (d<(beta>>2)) && ( abs(m3-m4) < ((tc*5+1)>>1)) );
943}
944
945__inline Int TComLoopFilter::xCalcDP( Pel* piSrc, Int iOffset)
946{
947  return abs( piSrc[-iOffset*3] - 2*piSrc[-iOffset*2] + piSrc[-iOffset] ) ;
948}
949
950__inline Int TComLoopFilter::xCalcDQ( Pel* piSrc, Int iOffset)
951{
952  return abs( piSrc[0] - 2*piSrc[iOffset] + piSrc[iOffset*2] );
953}
954//! \}
Note: See TracBrowser for help on using the repository browser.