source: 3DVCSoftware/branches/HTM-6.0-dev0/source/Lib/TLibCommon/TComLoopFilter.cpp @ 312

Last change on this file since 312 was 296, checked in by tech, 11 years ago

Reintegrated branch 5.1-dev0 rev. 295.

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