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

Last change on this file since 872 was 872, checked in by tech, 10 years ago

Merged HTM-10.0-dev0@871. (MV-HEVC 7 HLS)

  • Property svn:eol-style set to native
File size: 31.0 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-2014, 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)  ( ((iQpY) < 0) ? (iQpY) : (((iQpY) > 57) ? ((iQpY)-6) : g_aucChromaScale[(iQpY)]) )
52
53#define DEFAULT_INTRA_TC_OFFSET 2 ///< Default intra TC offset
54
55// ====================================================================================================================
56// Tables
57// ====================================================================================================================
58
59const UChar TComLoopFilter::sm_tcTable[54] =
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[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, m_bLFCrossTileBoundary(true)
76{
77  for( UInt uiDir = 0; uiDir < 2; uiDir++ )
78  {
79    m_aapucBS       [uiDir] = NULL;
80    m_aapbEdgeFilter[uiDir] = 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( UInt uiDir = 0; uiDir < 2; uiDir++ )
101  {
102    m_aapucBS       [uiDir] = new UChar[m_uiNumPartitions];
103    m_aapbEdgeFilter[uiDir] = new Bool [m_uiNumPartitions];
104  }
105}
106
107Void TComLoopFilter::destroy()
108{
109  for( UInt uiDir = 0; uiDir < 2; uiDir++ )
110  {
111    if (m_aapucBS)
112    {
113      delete [] m_aapucBS       [uiDir];
114      m_aapucBS [uiDir] = NULL;
115    }
116    if (m_aapbEdgeFilter[uiDir])
117    {
118      delete [] m_aapbEdgeFilter[uiDir];
119      m_aapbEdgeFilter[uiDir] = NULL;
120    }
121  }
122}
123
124/**
125 - call deblocking function for every CU
126 .
127 \param  pcPic   picture class (TComPic) pointer
128 */
129Void TComLoopFilter::loopFilterPic( TComPic* pcPic )
130{
131  // Horizontal filtering
132  for ( UInt uiCUAddr = 0; uiCUAddr < pcPic->getNumCUsInFrame(); uiCUAddr++ )
133  {
134    TComDataCU* pcCU = pcPic->getCU( uiCUAddr );
135
136    ::memset( m_aapucBS       [EDGE_VER], 0, sizeof( UChar ) * m_uiNumPartitions );
137    ::memset( m_aapbEdgeFilter[EDGE_VER], 0, sizeof( Bool  ) * m_uiNumPartitions );
138
139    // CU-based deblocking
140    xDeblockCU( pcCU, 0, 0, EDGE_VER );
141  }
142
143  // Vertical filtering
144  for ( UInt uiCUAddr = 0; uiCUAddr < pcPic->getNumCUsInFrame(); uiCUAddr++ )
145  {
146    TComDataCU* pcCU = pcPic->getCU( uiCUAddr );
147
148    ::memset( m_aapucBS       [EDGE_HOR], 0, sizeof( UChar ) * m_uiNumPartitions );
149    ::memset( m_aapbEdgeFilter[EDGE_HOR], 0, sizeof( Bool  ) * m_uiNumPartitions );
150
151    // CU-based deblocking
152    xDeblockCU( pcCU, 0, 0, EDGE_HOR );
153  }
154}
155
156
157// ====================================================================================================================
158// Protected member functions
159// ====================================================================================================================
160
161/**
162 - Deblocking filter process in CU-based (the same function as conventional's)
163 .
164 \param Edge          the direction of the edge in block boundary (horizonta/vertical), which is added newly
165*/
166Void TComLoopFilter::xDeblockCU( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int Edge )
167{
168  if(pcCU->getPic()==0||pcCU->getPartitionSize(uiAbsZorderIdx)==SIZE_NONE)
169  {
170    return;
171  }
172  TComPic* pcPic     = pcCU->getPic();
173  UInt uiCurNumParts = pcPic->getNumPartInCU() >> (uiDepth<<1);
174  UInt uiQNumParts   = uiCurNumParts>>2;
175 
176  if( pcCU->getDepth(uiAbsZorderIdx) > uiDepth )
177  {
178    for ( UInt uiPartIdx = 0; uiPartIdx < 4; uiPartIdx++, uiAbsZorderIdx+=uiQNumParts )
179    {
180      UInt uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsZorderIdx] ];
181      UInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsZorderIdx] ];
182      if( ( uiLPelX < pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() ) && ( uiTPelY < pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() ) )
183      {
184        xDeblockCU( pcCU, uiAbsZorderIdx, uiDepth+1, Edge );
185      }
186    }
187    return;
188  }
189 
190  xSetLoopfilterParam( pcCU, uiAbsZorderIdx );
191 
192  xSetEdgefilterTU   ( pcCU, uiAbsZorderIdx , uiAbsZorderIdx, uiDepth );
193  xSetEdgefilterPU   ( pcCU, uiAbsZorderIdx );
194 
195  Int iDir = Edge;
196  for( UInt uiPartIdx = uiAbsZorderIdx; uiPartIdx < uiAbsZorderIdx + uiCurNumParts; uiPartIdx++ )
197  {
198    UInt uiBSCheck;
199    if( (g_uiMaxCUWidth >> g_uiMaxCUDepth) == 4 ) 
200    {
201      uiBSCheck = (iDir == EDGE_VER && uiPartIdx%2 == 0) || (iDir == EDGE_HOR && (uiPartIdx-((uiPartIdx>>2)<<2))/2 == 0);
202    }
203    else
204    {
205      uiBSCheck = 1;
206    }
207   
208    if ( m_aapbEdgeFilter[iDir][uiPartIdx] && uiBSCheck )
209    {
210      xGetBoundaryStrengthSingle ( pcCU, iDir, uiPartIdx );
211    }
212  }
213 
214  UInt uiPelsInPart = g_uiMaxCUWidth >> g_uiMaxCUDepth;
215  UInt PartIdxIncr = DEBLOCK_SMALLEST_BLOCK / uiPelsInPart ? DEBLOCK_SMALLEST_BLOCK / uiPelsInPart : 1 ;
216 
217  UInt uiSizeInPU = pcPic->getNumPartInWidth()>>(uiDepth);
218 
219  for ( UInt iEdge = 0; iEdge < uiSizeInPU ; iEdge+=PartIdxIncr)
220  {
221    xEdgeFilterLuma     ( pcCU, uiAbsZorderIdx, uiDepth, iDir, iEdge );
222    if ( (uiPelsInPart>DEBLOCK_SMALLEST_BLOCK) || (iEdge % ( (DEBLOCK_SMALLEST_BLOCK<<1)/uiPelsInPart ) ) == 0 )
223    {
224      xEdgeFilterChroma   ( pcCU, uiAbsZorderIdx, uiDepth, iDir, iEdge );
225    }
226  }
227}
228
229Void TComLoopFilter::xSetEdgefilterMultiple( TComDataCU* pcCU, UInt uiScanIdx, UInt uiDepth, Int iDir, Int iEdgeIdx, Bool bValue,UInt uiWidthInBaseUnits, UInt uiHeightInBaseUnits )
230{ 
231  if ( uiWidthInBaseUnits == 0 )
232  {
233    uiWidthInBaseUnits  = pcCU->getPic()->getNumPartInWidth () >> uiDepth;
234  }
235  if ( uiHeightInBaseUnits == 0 )
236  {
237    uiHeightInBaseUnits = pcCU->getPic()->getNumPartInHeight() >> uiDepth;
238  }
239  const UInt uiNumElem = iDir == 0 ? uiHeightInBaseUnits : uiWidthInBaseUnits;
240  assert( uiNumElem > 0 );
241  assert( uiWidthInBaseUnits > 0 );
242  assert( uiHeightInBaseUnits > 0 );
243  for( UInt ui = 0; ui < uiNumElem; ui++ )
244  {
245    const UInt uiBsIdx = xCalcBsIdx( pcCU, uiScanIdx, iDir, iEdgeIdx, ui );
246    m_aapbEdgeFilter[iDir][uiBsIdx] = bValue;
247    if (iEdgeIdx == 0)
248    {
249      m_aapucBS[iDir][uiBsIdx] = bValue;
250    }
251  }
252}
253
254Void TComLoopFilter::xSetEdgefilterTU( TComDataCU* pcCU, UInt absTUPartIdx, UInt uiAbsZorderIdx, UInt uiDepth )
255{
256  if( pcCU->getTransformIdx( uiAbsZorderIdx ) + pcCU->getDepth( uiAbsZorderIdx) > uiDepth )
257  {
258    const UInt uiCurNumParts = pcCU->getPic()->getNumPartInCU() >> (uiDepth<<1);
259    const UInt uiQNumParts   = uiCurNumParts>>2;
260    for ( UInt uiPartIdx = 0; uiPartIdx < 4; uiPartIdx++, uiAbsZorderIdx+=uiQNumParts )
261    {
262      UInt nsAddr = uiAbsZorderIdx;
263      xSetEdgefilterTU( pcCU,nsAddr, uiAbsZorderIdx, uiDepth + 1 );
264    }
265    return;
266  }
267
268  Int trWidth  = pcCU->getWidth( uiAbsZorderIdx ) >> pcCU->getTransformIdx( uiAbsZorderIdx );
269  Int trHeight = pcCU->getHeight( uiAbsZorderIdx ) >> pcCU->getTransformIdx( uiAbsZorderIdx );
270 
271  UInt uiWidthInBaseUnits  = trWidth / (g_uiMaxCUWidth >> g_uiMaxCUDepth);
272  UInt uiHeightInBaseUnits = trHeight / (g_uiMaxCUWidth >> g_uiMaxCUDepth);
273
274  xSetEdgefilterMultiple( pcCU, absTUPartIdx, uiDepth, EDGE_VER, 0, m_stLFCUParam.bInternalEdge, uiWidthInBaseUnits, uiHeightInBaseUnits );
275  xSetEdgefilterMultiple( pcCU, absTUPartIdx, uiDepth, EDGE_HOR, 0, m_stLFCUParam.bInternalEdge, uiWidthInBaseUnits, uiHeightInBaseUnits );
276}
277
278Void TComLoopFilter::xSetEdgefilterPU( TComDataCU* pcCU, UInt uiAbsZorderIdx )
279{
280  const UInt uiDepth = pcCU->getDepth( uiAbsZorderIdx );
281  const UInt uiWidthInBaseUnits  = pcCU->getPic()->getNumPartInWidth () >> uiDepth;
282  const UInt uiHeightInBaseUnits = pcCU->getPic()->getNumPartInHeight() >> uiDepth;
283  const UInt uiHWidthInBaseUnits  = uiWidthInBaseUnits  >> 1;
284  const UInt uiHHeightInBaseUnits = uiHeightInBaseUnits >> 1;
285  const UInt uiQWidthInBaseUnits  = uiWidthInBaseUnits  >> 2;
286  const UInt uiQHeightInBaseUnits = uiHeightInBaseUnits >> 2;
287 
288  xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, 0, m_stLFCUParam.bLeftEdge );
289  xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, 0, m_stLFCUParam.bTopEdge );
290 
291  switch ( pcCU->getPartitionSize( uiAbsZorderIdx ) )
292  {
293    case SIZE_2Nx2N:
294    {
295      break;
296    }
297    case SIZE_2NxN:
298    {
299      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
300      break;
301    }
302    case SIZE_Nx2N:
303    {
304      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiHWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
305      break;
306    }
307    case SIZE_NxN:
308    {
309      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiHWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
310      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
311      break;
312    }
313    case SIZE_2NxnU:
314    {
315      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiQHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
316      break;
317    }
318    case SIZE_2NxnD:
319    {
320      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHeightInBaseUnits - uiQHeightInBaseUnits, m_stLFCUParam.bInternalEdge );
321      break;
322    }
323    case SIZE_nLx2N:
324    {
325      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiQWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
326      break;
327    }
328    case SIZE_nRx2N:
329    {
330      xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiWidthInBaseUnits - uiQWidthInBaseUnits, m_stLFCUParam.bInternalEdge );
331      break;
332    }
333    default:
334    {
335      break;
336    }
337  }
338}
339
340
341Void TComLoopFilter::xSetLoopfilterParam( TComDataCU* pcCU, UInt uiAbsZorderIdx )
342{
343  UInt uiX           = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsZorderIdx ] ];
344  UInt uiY           = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsZorderIdx ] ];
345 
346  TComDataCU* pcTempCU;
347  UInt        uiTempPartIdx;
348
349  m_stLFCUParam.bInternalEdge = ! pcCU->getSlice()->getDeblockingFilterDisable();
350 
351  if ( (uiX == 0) || pcCU->getSlice()->getDeblockingFilterDisable() )
352  {
353    m_stLFCUParam.bLeftEdge = false;
354  }
355  else
356  {
357    m_stLFCUParam.bLeftEdge = true;
358  }
359  if ( m_stLFCUParam.bLeftEdge )
360  {
361    pcTempCU = pcCU->getPULeft( uiTempPartIdx, uiAbsZorderIdx, !pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), !m_bLFCrossTileBoundary);
362    if ( pcTempCU )
363    {
364      m_stLFCUParam.bLeftEdge = true;
365    }
366    else
367    {
368      m_stLFCUParam.bLeftEdge = false;
369    }
370  }
371 
372  if ( (uiY == 0 ) || pcCU->getSlice()->getDeblockingFilterDisable() )
373  {
374    m_stLFCUParam.bTopEdge = false;
375  }
376  else
377  {
378    m_stLFCUParam.bTopEdge = true;
379  }
380  if ( m_stLFCUParam.bTopEdge )
381  {
382    pcTempCU = pcCU->getPUAbove( uiTempPartIdx, uiAbsZorderIdx, !pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), false, !m_bLFCrossTileBoundary);
383
384    if ( pcTempCU )
385    {
386      m_stLFCUParam.bTopEdge = true;
387    }
388    else
389    {
390      m_stLFCUParam.bTopEdge = false;
391    }
392  }
393}
394
395Void TComLoopFilter::xGetBoundaryStrengthSingle ( TComDataCU* pcCU, Int iDir, UInt uiAbsPartIdx )
396{
397  TComSlice* const pcSlice = pcCU->getSlice();
398 
399  const UInt uiPartQ = uiAbsPartIdx;
400  TComDataCU* const pcCUQ = pcCU;
401 
402  UInt uiPartP;
403  TComDataCU* pcCUP;
404  UInt uiBs = 0;
405 
406  //-- Calculate Block Index
407  if (iDir == EDGE_VER)
408  {
409    pcCUP = pcCUQ->getPULeft(uiPartP, uiPartQ, !pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), !m_bLFCrossTileBoundary);
410  }
411  else  // (iDir == EDGE_HOR)
412  {
413    pcCUP = pcCUQ->getPUAbove(uiPartP, uiPartQ, !pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), false, !m_bLFCrossTileBoundary);
414  }
415 
416  //-- Set BS for Intra MB : BS = 4 or 3
417  if ( pcCUP->isIntra(uiPartP) || pcCUQ->isIntra(uiPartQ) )
418  {
419    uiBs = 2;
420  }
421 
422  //-- Set BS for not Intra MB : BS = 2 or 1 or 0
423  if ( !pcCUP->isIntra(uiPartP) && !pcCUQ->isIntra(uiPartQ) )
424  {
425    UInt nsPartQ = uiPartQ;
426    UInt nsPartP = uiPartP;
427   
428    if ( m_aapucBS[iDir][uiAbsPartIdx] && (pcCUQ->getCbf( nsPartQ, TEXT_LUMA, pcCUQ->getTransformIdx(nsPartQ)) != 0 || pcCUP->getCbf( nsPartP, TEXT_LUMA, pcCUP->getTransformIdx(nsPartP) ) != 0) )
429    {
430      uiBs = 1;
431    }
432    else
433    {
434      if (iDir == EDGE_HOR)
435      {
436        pcCUP = pcCUQ->getPUAbove(uiPartP, uiPartQ, !pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), false, !m_bLFCrossTileBoundary);
437      }
438      if (pcSlice->isInterB() || pcCUP->getSlice()->isInterB())
439      {
440        Int iRefIdx;
441        TComPic *piRefP0, *piRefP1, *piRefQ0, *piRefQ1;
442        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
443        piRefP0 = (iRefIdx < 0) ? NULL : pcCUP->getSlice()->getRefPic(REF_PIC_LIST_0, iRefIdx);
444        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartP);
445        piRefP1 = (iRefIdx < 0) ? NULL : pcCUP->getSlice()->getRefPic(REF_PIC_LIST_1, iRefIdx);
446        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
447        piRefQ0 = (iRefIdx < 0) ? NULL : pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
448        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiPartQ);
449        piRefQ1 = (iRefIdx < 0) ? NULL : pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx);
450       
451        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
452        TComMv pcMvP1 = pcCUP->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartP);
453        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
454        TComMv pcMvQ1 = pcCUQ->getCUMvField(REF_PIC_LIST_1)->getMv(uiPartQ);
455
456        if (piRefP0 == NULL) pcMvP0.setZero();
457        if (piRefP1 == NULL) pcMvP1.setZero();
458        if (piRefQ0 == NULL) pcMvQ0.setZero();
459        if (piRefQ1 == NULL) pcMvQ1.setZero();
460
461        if ( ((piRefP0==piRefQ0)&&(piRefP1==piRefQ1)) || ((piRefP0==piRefQ1)&&(piRefP1==piRefQ0)) )
462        {
463          if ( piRefP0 != piRefP1 )   // Different L0 & L1
464          {
465            if ( piRefP0 == piRefQ0 )
466            {
467              uiBs  = ((abs(pcMvQ0.getHor() - pcMvP0.getHor()) >= 4) ||
468                       (abs(pcMvQ0.getVer() - pcMvP0.getVer()) >= 4) ||
469                       (abs(pcMvQ1.getHor() - pcMvP1.getHor()) >= 4) ||
470                       (abs(pcMvQ1.getVer() - pcMvP1.getVer()) >= 4)) ? 1 : 0;
471            }
472            else
473            {
474              uiBs  = ((abs(pcMvQ1.getHor() - pcMvP0.getHor()) >= 4) ||
475                       (abs(pcMvQ1.getVer() - pcMvP0.getVer()) >= 4) ||
476                       (abs(pcMvQ0.getHor() - pcMvP1.getHor()) >= 4) ||
477                       (abs(pcMvQ0.getVer() - pcMvP1.getVer()) >= 4)) ? 1 : 0;
478            }
479          }
480          else    // Same L0 & L1
481          {
482            uiBs  = ((abs(pcMvQ0.getHor() - pcMvP0.getHor()) >= 4) ||
483                     (abs(pcMvQ0.getVer() - pcMvP0.getVer()) >= 4) ||
484                     (abs(pcMvQ1.getHor() - pcMvP1.getHor()) >= 4) ||
485                     (abs(pcMvQ1.getVer() - pcMvP1.getVer()) >= 4)) &&
486                    ((abs(pcMvQ1.getHor() - pcMvP0.getHor()) >= 4) ||
487                     (abs(pcMvQ1.getVer() - pcMvP0.getVer()) >= 4) ||
488                     (abs(pcMvQ0.getHor() - pcMvP1.getHor()) >= 4) ||
489                     (abs(pcMvQ0.getVer() - pcMvP1.getVer()) >= 4)) ? 1 : 0;
490          }
491        }
492        else // for all different Ref_Idx
493        {
494          uiBs = 1;
495        }
496      }
497      else  // pcSlice->isInterP()
498      {
499        Int iRefIdx;
500        TComPic *piRefP0, *piRefQ0;
501        iRefIdx = pcCUP->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartP);
502        piRefP0 = (iRefIdx < 0) ? NULL : pcCUP->getSlice()->getRefPic(REF_PIC_LIST_0, iRefIdx);
503        iRefIdx = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiPartQ);
504        piRefQ0 = (iRefIdx < 0) ? NULL : pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx);
505        TComMv pcMvP0 = pcCUP->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartP);
506        TComMv pcMvQ0 = pcCUQ->getCUMvField(REF_PIC_LIST_0)->getMv(uiPartQ);
507
508        if (piRefP0 == NULL) pcMvP0.setZero();
509        if (piRefQ0 == NULL) pcMvQ0.setZero();
510       
511        uiBs  = ((piRefP0 != piRefQ0) ||
512                 (abs(pcMvQ0.getHor() - pcMvP0.getHor()) >= 4) ||
513                 (abs(pcMvQ0.getVer() - pcMvP0.getVer()) >= 4)) ? 1 : 0;
514      }
515    }   // enf of "if( one of BCBP == 0 )"
516  }   // enf of "if( not Intra )"
517 
518  m_aapucBS[iDir][uiAbsPartIdx] = uiBs;
519}
520
521
522Void TComLoopFilter::xEdgeFilterLuma( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdge  )
523{
524  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
525  Pel* piSrc    = pcPicYuvRec->getLumaAddr( pcCU->getAddr(), uiAbsZorderIdx );
526  Pel* piTmpSrc = piSrc;
527 
528  Int  iStride = pcPicYuvRec->getStride();
529  Int iQP = 0;
530  Int iQP_P = 0;
531  Int iQP_Q = 0;
532  UInt uiNumParts = pcCU->getPic()->getNumPartInWidth()>>uiDepth;
533 
534  UInt  uiPelsInPart = g_uiMaxCUWidth >> g_uiMaxCUDepth;
535  UInt  uiBsAbsIdx = 0, uiBs = 0;
536  Int   iOffset, iSrcStep;
537 
538  Bool  bPCMFilter = (pcCU->getSlice()->getSPS()->getUsePCM() && pcCU->getSlice()->getSPS()->getPCMFilterDisableFlag())? true : false;
539  Bool  bPartPNoFilter = false;
540  Bool  bPartQNoFilter = false; 
541  UInt  uiPartPIdx = 0;
542  UInt  uiPartQIdx = 0;
543  TComDataCU* pcCUP = pcCU; 
544  TComDataCU* pcCUQ = pcCU;
545  Int  betaOffsetDiv2 = pcCUQ->getSlice()->getDeblockingFilterBetaOffsetDiv2();
546  Int  tcOffsetDiv2 = pcCUQ->getSlice()->getDeblockingFilterTcOffsetDiv2();
547
548  if (iDir == EDGE_VER)
549  {
550    iOffset = 1;
551    iSrcStep = iStride;
552    piTmpSrc += iEdge*uiPelsInPart;
553  }
554  else  // (iDir == EDGE_HOR)
555  {
556    iOffset = iStride;
557    iSrcStep = 1;
558    piTmpSrc += iEdge*uiPelsInPart*iStride;
559  }
560 
561  for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx++ )
562  {
563    uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, iDir, iEdge, iIdx);
564    uiBs = m_aapucBS[iDir][uiBsAbsIdx];
565    if ( uiBs )
566    {
567      iQP_Q = pcCU->getQP( uiBsAbsIdx );
568      uiPartQIdx = uiBsAbsIdx;
569      // Derive neighboring PU index
570      if (iDir == EDGE_VER)
571      {
572        pcCUP = pcCUQ->getPULeft (uiPartPIdx, uiPartQIdx,!pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), !m_bLFCrossTileBoundary);
573      }
574      else  // (iDir == EDGE_HOR)
575      {
576        pcCUP = pcCUQ->getPUAbove(uiPartPIdx, uiPartQIdx,!pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), false, !m_bLFCrossTileBoundary);
577      }
578
579      iQP_P = pcCUP->getQP(uiPartPIdx);
580      iQP = (iQP_P + iQP_Q + 1) >> 1;
581      Int iBitdepthScale = 1 << (g_bitDepthY-8);
582     
583      Int iIndexTC = Clip3(0, MAX_QP+DEFAULT_INTRA_TC_OFFSET, Int(iQP + DEFAULT_INTRA_TC_OFFSET*(uiBs-1) + (tcOffsetDiv2 << 1)));
584      Int iIndexB = Clip3(0, MAX_QP, iQP + (betaOffsetDiv2 << 1));
585     
586      Int iTc =  sm_tcTable[iIndexTC]*iBitdepthScale;
587      Int iBeta = sm_betaTable[iIndexB]*iBitdepthScale;
588      Int iSideThreshold = (iBeta+(iBeta>>1))>>3;
589      Int iThrCut = iTc*10;
590
591      UInt  uiBlocksInPart = uiPelsInPart / 4 ? uiPelsInPart / 4 : 1;
592      for (UInt iBlkIdx = 0; iBlkIdx<uiBlocksInPart; iBlkIdx ++)
593      {
594        Int dp0 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0), iOffset);
595        Int dq0 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0), iOffset);
596        Int dp3 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3), iOffset);
597        Int dq3 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3), iOffset);
598        Int d0 = dp0 + dq0;
599        Int d3 = dp3 + dq3;
600       
601        Int dp = dp0 + dp3;
602        Int dq = dq0 + dq3;
603        Int d =  d0 + d3;
604       
605        if (bPCMFilter || pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
606        {
607          // Check if each of PUs is I_PCM with LF disabling
608          bPartPNoFilter = (bPCMFilter && pcCUP->getIPCMFlag(uiPartPIdx));
609          bPartQNoFilter = (bPCMFilter && pcCUQ->getIPCMFlag(uiPartQIdx));
610
611          // check if each of PUs is lossless coded
612          bPartPNoFilter = bPartPNoFilter || (pcCUP->isLosslessCoded(uiPartPIdx) );
613          bPartQNoFilter = bPartQNoFilter || (pcCUQ->isLosslessCoded(uiPartQIdx) );
614        }
615
616        if (d < iBeta)
617        { 
618          Bool bFilterP = (dp < iSideThreshold);
619          Bool bFilterQ = (dq < iSideThreshold);
620         
621          Bool sw =  xUseStrongFiltering( iOffset, 2*d0, iBeta, iTc, piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0))
622          && xUseStrongFiltering( iOffset, 2*d3, iBeta, iTc, piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3));
623         
624          for ( Int i = 0; i < DEBLOCK_SMALLEST_BLOCK/2; i++)
625          {
626            xPelFilterLuma( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+i), iOffset, iTc, sw, bPartPNoFilter, bPartQNoFilter, iThrCut, bFilterP, bFilterQ);
627          }
628        }
629      }
630    }
631  }
632}
633
634
635Void TComLoopFilter::xEdgeFilterChroma( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdge )
636{
637  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
638  Int         iStride     = pcPicYuvRec->getCStride();
639  Pel*        piSrcCb     = pcPicYuvRec->getCbAddr( pcCU->getAddr(), uiAbsZorderIdx );
640  Pel*        piSrcCr     = pcPicYuvRec->getCrAddr( pcCU->getAddr(), uiAbsZorderIdx );
641  Int iQP = 0;
642  Int iQP_P = 0;
643  Int iQP_Q = 0;
644 
645  UInt  uiPelsInPartChroma = g_uiMaxCUWidth >> (g_uiMaxCUDepth+1);
646 
647  Int   iOffset, iSrcStep;
648 
649  const UInt uiLCUWidthInBaseUnits = pcCU->getPic()->getNumPartInWidth();
650 
651  Bool  bPCMFilter = (pcCU->getSlice()->getSPS()->getUsePCM() && pcCU->getSlice()->getSPS()->getPCMFilterDisableFlag())? true : false;
652  Bool  bPartPNoFilter = false;
653  Bool  bPartQNoFilter = false; 
654  UInt  uiPartPIdx;
655  UInt  uiPartQIdx;
656  TComDataCU* pcCUP; 
657  TComDataCU* pcCUQ = pcCU;
658  Int tcOffsetDiv2 = pcCU->getSlice()->getDeblockingFilterTcOffsetDiv2();
659 
660  // Vertical Position
661  UInt uiEdgeNumInLCUVert = g_auiZscanToRaster[uiAbsZorderIdx]%uiLCUWidthInBaseUnits + iEdge;
662  UInt uiEdgeNumInLCUHor = g_auiZscanToRaster[uiAbsZorderIdx]/uiLCUWidthInBaseUnits + iEdge;
663 
664  if ( (uiPelsInPartChroma < DEBLOCK_SMALLEST_BLOCK) && (( (uiEdgeNumInLCUVert%(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChroma))&&(iDir==0) ) || ( (uiEdgeNumInLCUHor%(DEBLOCK_SMALLEST_BLOCK/uiPelsInPartChroma))&& iDir ) ))
665  {
666    return;
667  }
668 
669  UInt  uiNumParts = pcCU->getPic()->getNumPartInWidth()>>uiDepth;
670 
671  UInt  uiBsAbsIdx;
672  UChar ucBs;
673 
674  Pel* piTmpSrcCb = piSrcCb;
675  Pel* piTmpSrcCr = piSrcCr;
676 
677 
678  if (iDir == EDGE_VER)
679  {
680    iOffset   = 1;
681    iSrcStep  = iStride;
682    piTmpSrcCb += iEdge*uiPelsInPartChroma;
683    piTmpSrcCr += iEdge*uiPelsInPartChroma;
684  }
685  else  // (iDir == EDGE_HOR)
686  {
687    iOffset   = iStride;
688    iSrcStep  = 1;
689    piTmpSrcCb += iEdge*iStride*uiPelsInPartChroma;
690    piTmpSrcCr += iEdge*iStride*uiPelsInPartChroma;
691  }
692 
693  for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx++ )
694  {
695    uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, iDir, iEdge, iIdx);
696    ucBs = m_aapucBS[iDir][uiBsAbsIdx];
697   
698    if ( ucBs > 1)
699    {
700      iQP_Q = pcCU->getQP( uiBsAbsIdx );
701      uiPartQIdx = uiBsAbsIdx;
702      // Derive neighboring PU index
703      if (iDir == EDGE_VER)
704      {
705        pcCUP = pcCUQ->getPULeft (uiPartPIdx, uiPartQIdx,!pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), !m_bLFCrossTileBoundary);
706      }
707      else  // (iDir == EDGE_HOR)
708      {
709        pcCUP = pcCUQ->getPUAbove(uiPartPIdx, uiPartQIdx,!pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), false, !m_bLFCrossTileBoundary);
710      }
711
712      iQP_P = pcCUP->getQP(uiPartPIdx);
713     
714      if (bPCMFilter || pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
715      {
716        // Check if each of PUs is I_PCM with LF disabling
717        bPartPNoFilter = (bPCMFilter && pcCUP->getIPCMFlag(uiPartPIdx));
718        bPartQNoFilter = (bPCMFilter && pcCUQ->getIPCMFlag(uiPartQIdx));
719
720        // check if each of PUs is lossless coded
721        bPartPNoFilter = bPartPNoFilter || (pcCUP->isLosslessCoded(uiPartPIdx));
722        bPartQNoFilter = bPartQNoFilter || (pcCUQ->isLosslessCoded(uiPartQIdx));
723      }
724     
725      for ( UInt chromaIdx = 0; chromaIdx < 2; chromaIdx++ )
726      {
727        Int chromaQPOffset  = (chromaIdx == 0) ? pcCU->getSlice()->getPPS()->getChromaCbQpOffset() : pcCU->getSlice()->getPPS()->getChromaCrQpOffset();
728        Pel* piTmpSrcChroma = (chromaIdx == 0) ? piTmpSrcCb : piTmpSrcCr;
729
730        iQP = QpUV( ((iQP_P + iQP_Q + 1) >> 1) + chromaQPOffset );
731        Int iBitdepthScale = 1 << (g_bitDepthC-8);
732
733        Int iIndexTC = Clip3(0, MAX_QP+DEFAULT_INTRA_TC_OFFSET, iQP + DEFAULT_INTRA_TC_OFFSET*(ucBs - 1) + (tcOffsetDiv2 << 1));
734        Int iTc =  sm_tcTable[iIndexTC]*iBitdepthScale;
735
736        for ( UInt uiStep = 0; uiStep < uiPelsInPartChroma; uiStep++ )
737        {
738          xPelFilterChroma( piTmpSrcChroma + iSrcStep*(uiStep+iIdx*uiPelsInPartChroma), iOffset, iTc , bPartPNoFilter, bPartQNoFilter);
739        }
740      }
741    }
742  }
743}
744
745/**
746 - Deblocking for the luminance component with strong or weak filter
747 .
748 \param piSrc           pointer to picture data
749 \param iOffset         offset value for picture data
750 \param tc              tc value
751 \param sw              decision strong/weak filter
752 \param bPartPNoFilter  indicator to disable filtering on partP
753 \param bPartQNoFilter  indicator to disable filtering on partQ
754 \param iThrCut         threshold value for weak filter decision
755 \param bFilterSecondP  decision weak filter/no filter for partP
756 \param bFilterSecondQ  decision weak filter/no filter for partQ
757*/
758__inline Void TComLoopFilter::xPelFilterLuma( Pel* piSrc, Int iOffset, Int tc , Bool sw, Bool bPartPNoFilter, Bool bPartQNoFilter, Int iThrCut, Bool bFilterSecondP, Bool bFilterSecondQ)
759{
760  Int delta;
761 
762  Pel m4  = piSrc[0];
763  Pel m3  = piSrc[-iOffset];
764  Pel m5  = piSrc[ iOffset];
765  Pel m2  = piSrc[-iOffset*2];
766  Pel m6  = piSrc[ iOffset*2];
767  Pel m1  = piSrc[-iOffset*3];
768  Pel m7  = piSrc[ iOffset*3];
769  Pel m0  = piSrc[-iOffset*4];
770
771  if (sw)
772  {
773    piSrc[-iOffset]   = Clip3(m3-2*tc, m3+2*tc, ((m1 + 2*m2 + 2*m3 + 2*m4 + m5 + 4) >> 3));
774    piSrc[0]          = Clip3(m4-2*tc, m4+2*tc, ((m2 + 2*m3 + 2*m4 + 2*m5 + m6 + 4) >> 3));
775    piSrc[-iOffset*2] = Clip3(m2-2*tc, m2+2*tc, ((m1 + m2 + m3 + m4 + 2)>>2));
776    piSrc[ iOffset]   = Clip3(m5-2*tc, m5+2*tc, ((m3 + m4 + m5 + m6 + 2)>>2));
777    piSrc[-iOffset*3] = Clip3(m1-2*tc, m1+2*tc, ((2*m0 + 3*m1 + m2 + m3 + m4 + 4 )>>3));
778    piSrc[ iOffset*2] = Clip3(m6-2*tc, m6+2*tc, ((m3 + m4 + m5 + 3*m6 + 2*m7 +4 )>>3));
779  }
780  else
781  {
782    /* Weak filter */
783    delta = (9*(m4-m3) -3*(m5-m2) + 8)>>4 ;
784
785    if ( abs(delta) < iThrCut )
786    {
787      delta = Clip3(-tc, tc, delta);       
788      piSrc[-iOffset] = ClipY((m3+delta));
789      piSrc[0] = ClipY((m4-delta));
790
791      Int tc2 = tc>>1;
792      if(bFilterSecondP)
793      {
794        Int delta1 = Clip3(-tc2, tc2, (( ((m1+m3+1)>>1)- m2+delta)>>1));
795        piSrc[-iOffset*2] = ClipY((m2+delta1));
796      }
797      if(bFilterSecondQ)
798      {
799        Int delta2 = Clip3(-tc2, tc2, (( ((m6+m4+1)>>1)- m5-delta)>>1));
800        piSrc[ iOffset] = ClipY((m5+delta2));
801      }
802    }
803  }
804
805  if(bPartPNoFilter)
806  {
807    piSrc[-iOffset] = m3;
808    piSrc[-iOffset*2] = m2;
809    piSrc[-iOffset*3] = m1;
810  }
811  if(bPartQNoFilter)
812  {
813    piSrc[0] = m4;
814    piSrc[ iOffset] = m5;
815    piSrc[ iOffset*2] = m6;
816  }
817}
818
819/**
820 - Deblocking of one line/column for the chrominance component
821 .
822 \param piSrc           pointer to picture data
823 \param iOffset         offset value for picture data
824 \param tc              tc value
825 \param bPartPNoFilter  indicator to disable filtering on partP
826 \param bPartQNoFilter  indicator to disable filtering on partQ
827 */
828__inline Void TComLoopFilter::xPelFilterChroma( Pel* piSrc, Int iOffset, Int tc, Bool bPartPNoFilter, Bool bPartQNoFilter)
829{
830  Int delta;
831 
832  Pel m4  = piSrc[0];
833  Pel m3  = piSrc[-iOffset];
834  Pel m5  = piSrc[ iOffset];
835  Pel m2  = piSrc[-iOffset*2];
836 
837  delta = Clip3(-tc,tc, (((( m4 - m3 ) << 2 ) + m2 - m5 + 4 ) >> 3) );
838  piSrc[-iOffset] = ClipC(m3+delta);
839  piSrc[0] = ClipC(m4-delta);
840
841  if(bPartPNoFilter)
842  {
843    piSrc[-iOffset] = m3;
844  }
845  if(bPartQNoFilter)
846  {
847    piSrc[0] = m4;
848  }
849}
850
851/**
852 - Decision between strong and weak filter
853 .
854 \param offset         offset value for picture data
855 \param d               d value
856 \param beta            beta value
857 \param tc              tc value
858 \param piSrc           pointer to picture data
859 */
860__inline Bool TComLoopFilter::xUseStrongFiltering( Int offset, Int d, Int beta, Int tc, Pel* piSrc)
861{
862  Pel m4  = piSrc[0];
863  Pel m3  = piSrc[-offset];
864  Pel m7  = piSrc[ offset*3];
865  Pel m0  = piSrc[-offset*4];
866
867  Int d_strong = abs(m0-m3) + abs(m7-m4);
868
869  return ( (d_strong < (beta>>3)) && (d<(beta>>2)) && ( abs(m3-m4) < ((tc*5+1)>>1)) );
870}
871
872__inline Int TComLoopFilter::xCalcDP( Pel* piSrc, Int iOffset)
873{
874  return abs( piSrc[-iOffset*3] - 2*piSrc[-iOffset*2] + piSrc[-iOffset] ) ;
875}
876 
877__inline Int TComLoopFilter::xCalcDQ( Pel* piSrc, Int iOffset)
878{
879  return abs( piSrc[0] - 2*piSrc[iOffset] + piSrc[iOffset*2] );
880}
881//! \}
Note: See TracBrowser for help on using the repository browser.