source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibDecoder/TDecSlice.cpp @ 1165

Last change on this file since 1165 was 1029, checked in by seregin, 10 years ago

merge with SHM-upgrade branch

  • Property svn:eol-style set to native
File size: 10.8 KB
RevLine 
[313]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
[1029]4 * granted under this license.
[313]5 *
[595]6 * Copyright (c) 2010-2014, ITU/ISO/IEC
[313]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     TDecSlice.cpp
35    \brief    slice decoder class
36*/
37
38#include "TDecSlice.h"
39
40//! \ingroup TLibDecoder
41//! \{
42
43#if SVC_EXTENSION
[834]44ParameterSetMap<TComVPS> ParameterSetManagerDecoder::m_vpsBuffer(MAX_NUM_VPS);
45ParameterSetMap<TComSPS> ParameterSetManagerDecoder::m_spsBuffer(MAX_NUM_SPS);
46ParameterSetMap<TComPPS> ParameterSetManagerDecoder::m_ppsBuffer(MAX_NUM_PPS);
[313]47#endif
48
49//////////////////////////////////////////////////////////////////////
50// Construction/Destruction
51//////////////////////////////////////////////////////////////////////
52
53TDecSlice::TDecSlice()
54{
55}
56
57TDecSlice::~TDecSlice()
58{
59}
60
61Void TDecSlice::create()
62{
63}
64
65Void TDecSlice::destroy()
66{
67}
68
69#if SVC_EXTENSION
[644]70Void TDecSlice::init(TDecEntropy* pcEntropyDecoder, TDecCu* pcCuDecoder, UInt* saoMaxOffsetQVal)
[313]71{
72  m_pcEntropyDecoder  = pcEntropyDecoder;
73  m_pcCuDecoder       = pcCuDecoder;
[644]74  m_saoMaxOffsetQVal  = saoMaxOffsetQVal;
[313]75}
76#else
77Void TDecSlice::init(TDecEntropy* pcEntropyDecoder, TDecCu* pcCuDecoder)
78{
79  m_pcEntropyDecoder  = pcEntropyDecoder;
80  m_pcCuDecoder       = pcCuDecoder;
81}
82#endif
83
[1029]84Void TDecSlice::decompressSlice(TComInputBitstream** ppcSubstreams, TComPic* pcPic, TDecSbac* pcSbacDecoder)
[313]85{
[1029]86  TComSlice* pcSlice                 = pcPic->getSlice(pcPic->getCurrSliceIdx());
[313]87
[1029]88  const Int  startCtuTsAddr          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
89  const Int  startCtuRsAddr          = pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTsAddr);
90  const UInt numCtusInFrame          = pcPic->getNumberOfCtusInFrame();
91
92  const UInt frameWidthInCtus        = pcPic->getPicSym()->getFrameWidthInCtus();
93  const Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
94  const Bool wavefrontsEnabled       = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag();
95
96  m_pcEntropyDecoder->setEntropyDecoder ( pcSbacDecoder  );
97  m_pcEntropyDecoder->setBitstream      ( ppcSubstreams[0] );
98  m_pcEntropyDecoder->resetEntropy      (pcSlice);
99
100  // decoder doesn't need prediction & residual frame buffer
101  pcPic->setPicYuvPred( 0 );
102  pcPic->setPicYuvResi( 0 );
103
[313]104#if ENC_DEC_TRACE
105  g_bJustDoIt = g_bEncDecTraceEnable;
106#endif
107  DTRACE_CABAC_VL( g_nSymbolCounter++ );
108  DTRACE_CABAC_T( "\tPOC: " );
[1029]109  DTRACE_CABAC_V( pcPic->getPOC() );
[313]110  DTRACE_CABAC_T( "\n" );
111
112#if ENC_DEC_TRACE
113  g_bJustDoIt = g_bEncDecTraceDisable;
114#endif
115
[1029]116  // The first CTU of the slice is the first coded substream, but the global substream number, as calculated by getSubstreamForCtuAddr may be higher.
117  // This calculates the common offset for all substreams in this slice.
118  const UInt subStreamOffset=pcPic->getSubstreamForCtuAddr(startCtuRsAddr, true, pcSlice);
[313]119
120
[1029]121  if (depSliceSegmentsEnabled)
[313]122  {
[1029]123    // modify initial contexts with previous slice segment if this is a dependent slice.
124    const UInt startTileIdx=pcPic->getPicSym()->getTileIdxMap(startCtuRsAddr);
125    const TComTile *pCurrentTile=pcPic->getPicSym()->getTComTile(startTileIdx);
126    const UInt firstCtuRsAddrOfTile = pCurrentTile->getFirstCtuRsAddr();
[313]127
[1029]128    if( pcSlice->getDependentSliceSegmentFlag() && startCtuRsAddr != firstCtuRsAddrOfTile)
[313]129    {
[1029]130      if ( pCurrentTile->getTileWidthInCtus() >= 2 || !wavefrontsEnabled)
[313]131      {
[1029]132        pcSbacDecoder->loadContexts(&m_lastSliceSegmentEndContextState);
[313]133      }
134    }
135  }
[1029]136
137  // for every CTU in the slice segment...
138
139  Bool isLastCtuOfSliceSegment = false;
140  for( UInt ctuTsAddr = startCtuTsAddr; !isLastCtuOfSliceSegment && ctuTsAddr < numCtusInFrame; ctuTsAddr++)
[313]141  {
[1029]142    const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr);
143    const TComTile &currentTile = *(pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr)));
144    const UInt firstCtuRsAddrOfTile = currentTile.getFirstCtuRsAddr();
145    const UInt tileXPosInCtus = firstCtuRsAddrOfTile % frameWidthInCtus;
146    const UInt tileYPosInCtus = firstCtuRsAddrOfTile / frameWidthInCtus;
147    const UInt ctuXPosInCtus  = ctuRsAddr % frameWidthInCtus;
148    const UInt ctuYPosInCtus  = ctuRsAddr / frameWidthInCtus;
149    const UInt uiSubStrm=pcPic->getSubstreamForCtuAddr(ctuRsAddr, true, pcSlice)-subStreamOffset;
150    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
151    pCtu->initCtu( pcPic, ctuRsAddr );
152
153    m_pcEntropyDecoder->setBitstream( ppcSubstreams[uiSubStrm] );
154
155    // set up CABAC contexts' state for this CTU
156    if (ctuRsAddr == firstCtuRsAddrOfTile)
[313]157    {
[1029]158      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
[313]159      {
[1029]160        m_pcEntropyDecoder->resetEntropy(pcSlice);
[313]161      }
162    }
[1029]163    else if (ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled)
[313]164    {
[1029]165      // Synchronize cabac probabilities with upper-right CTU if it's available and at the start of a line.
166      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
[313]167      {
[1029]168        m_pcEntropyDecoder->resetEntropy(pcSlice);
[313]169      }
[1029]170      TComDataCU *pCtuUp = pCtu->getCtuAbove();
171      if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus)  )
[313]172      {
[1029]173        TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 );
174        if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) )
[313]175        {
[1029]176          // Top-right is available, so use it.
177          pcSbacDecoder->loadContexts( &m_entropyCodingSyncContextState );
[313]178        }
179      }
180    }
181
182#if ENC_DEC_TRACE
183    g_bJustDoIt = g_bEncDecTraceEnable;
184#endif
[540]185
186    if ( pcSlice->getSPS()->getUseSAO() )
187    {
[1029]188      SAOBlkParam& saoblkParam = (pcPic->getPicSym()->getSAOBlkParam())[ctuRsAddr];
189      Bool bIsSAOSliceEnabled = false;
190      Bool sliceEnabled[MAX_NUM_COMPONENT];
191      for(Int comp=0; comp < MAX_NUM_COMPONENT; comp++)
[540]192      {
[1029]193        ComponentID compId=ComponentID(comp);
194        sliceEnabled[compId] = pcSlice->getSaoEnabledFlag(toChannelType(compId)) && (comp < pcPic->getNumberValidComponents());
195        if (sliceEnabled[compId]) bIsSAOSliceEnabled=true;
196        saoblkParam[compId].modeIdc = SAO_MODE_OFF;
197      }
198      if (bIsSAOSliceEnabled)
199      {
[540]200        Bool leftMergeAvail = false;
201        Bool aboveMergeAvail= false;
202
203        //merge left condition
[1029]204        Int rx = (ctuRsAddr % frameWidthInCtus);
[540]205        if(rx > 0)
206        {
[1029]207          leftMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-1);
[540]208        }
209        //merge up condition
[1029]210        Int ry = (ctuRsAddr / frameWidthInCtus);
[540]211        if(ry > 0)
212        {
[1029]213          aboveMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-frameWidthInCtus);
[540]214        }
[644]215#if SVC_EXTENSION
216        pcSbacDecoder->parseSAOBlkParam( saoblkParam, m_saoMaxOffsetQVal, sliceEnabled, leftMergeAvail, aboveMergeAvail);
217#else
[540]218        pcSbacDecoder->parseSAOBlkParam( saoblkParam, sliceEnabled, leftMergeAvail, aboveMergeAvail);
[1029]219#endif     
[540]220      }
221    }
222
[1029]223    m_pcCuDecoder->decodeCtu     ( pCtu, isLastCtuOfSliceSegment );
224    m_pcCuDecoder->decompressCtu ( pCtu );
225
[313]226#if ENC_DEC_TRACE
227    g_bJustDoIt = g_bEncDecTraceDisable;
228#endif
229
[1029]230    //Store probabilities of second CTU in line into buffer
231    if ( ctuXPosInCtus == tileXPosInCtus+1 && wavefrontsEnabled)
[313]232    {
[1029]233      m_entropyCodingSyncContextState.loadContexts( pcSbacDecoder );
234    }
235
236    // Should the sub-stream/stream be terminated after this CTU?
237    // (end of slice-segment, end of tile, end of wavefront-CTU-row)
238    if (isLastCtuOfSliceSegment ||
239         (  ctuXPosInCtus + 1 == tileXPosInCtus + currentTile.getTileWidthInCtus() &&
240          ( ctuYPosInCtus + 1 == tileYPosInCtus + currentTile.getTileHeightInCtus() || wavefrontsEnabled)
241         )
242       )
243    {
[313]244      UInt binVal;
245      pcSbacDecoder->parseTerminatingBit( binVal );
246      assert( binVal );
[1029]247#if DECODER_CHECK_SUBSTREAM_AND_SLICE_TRAILING_BYTES
248      pcSbacDecoder->parseRemainingBytes(!isLastCtuOfSliceSegment);
249#endif
[313]250
[1029]251      if (isLastCtuOfSliceSegment)
252      {
253        if(!pcSlice->getDependentSliceSegmentFlag())
254        {
255          pcSlice->setSliceCurEndCtuTsAddr( ctuTsAddr+1 );
256        }
257        pcSlice->setSliceSegmentCurEndCtuTsAddr( ctuTsAddr+1 );
258        break;
259      }
[313]260    }
261  }
[1029]262
263  assert(isLastCtuOfSliceSegment == true);
264
265
266  if( depSliceSegmentsEnabled )
267  {
268    m_lastSliceSegmentEndContextState.loadContexts( pcSbacDecoder );//ctx end of dep.slice
269  }
270
[313]271}
272
273ParameterSetManagerDecoder::ParameterSetManagerDecoder()
[834]274#if !SVC_EXTENSION
[313]275: m_vpsBuffer(MAX_NUM_VPS)
276, m_spsBuffer(MAX_NUM_SPS)
277, m_ppsBuffer(MAX_NUM_PPS)
278#endif
279{
280}
281
282ParameterSetManagerDecoder::~ParameterSetManagerDecoder()
283{
284
285}
286
287TComVPS* ParameterSetManagerDecoder::getPrefetchedVPS  (Int vpsId)
288{
289  if (m_vpsBuffer.getPS(vpsId) != NULL )
290  {
291    return m_vpsBuffer.getPS(vpsId);
292  }
293  else
294  {
295    return getVPS(vpsId);
296  }
297}
298
299
300TComSPS* ParameterSetManagerDecoder::getPrefetchedSPS  (Int spsId)
301{
302  if (m_spsBuffer.getPS(spsId) != NULL )
303  {
304    return m_spsBuffer.getPS(spsId);
305  }
306  else
307  {
308    return getSPS(spsId);
309  }
310}
311
312TComPPS* ParameterSetManagerDecoder::getPrefetchedPPS  (Int ppsId)
313{
314  if (m_ppsBuffer.getPS(ppsId) != NULL )
315  {
316    return m_ppsBuffer.getPS(ppsId);
317  }
318  else
319  {
320    return getPPS(ppsId);
321  }
322}
323
324Void     ParameterSetManagerDecoder::applyPrefetchedPS()
325{
326  m_vpsMap.mergePSList(m_vpsBuffer);
327  m_ppsMap.mergePSList(m_ppsBuffer);
328  m_spsMap.mergePSList(m_spsBuffer);
329}
330
331//! \}
Note: See TracBrowser for help on using the repository browser.