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

Last change on this file since 852 was 834, checked in by seregin, 10 years ago

make parameter sets static

  • Property svn:eol-style set to native
File size: 15.8 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     TDecSlice.cpp
35    \brief    slice decoder class
36*/
37
38#include "TDecSlice.h"
39
40//! \ingroup TLibDecoder
41//! \{
42
43#if SVC_EXTENSION
44ParameterSetMap<TComVPS> ParameterSetManagerDecoder::m_vpsBuffer(MAX_NUM_VPS);
45ParameterSetMap<TComSPS> ParameterSetManagerDecoder::m_spsBuffer(MAX_NUM_SPS);
46ParameterSetMap<TComPPS> ParameterSetManagerDecoder::m_ppsBuffer(MAX_NUM_PPS);
47#endif
48
49//////////////////////////////////////////////////////////////////////
50// Construction/Destruction
51//////////////////////////////////////////////////////////////////////
52
53TDecSlice::TDecSlice()
54{
55  m_pcBufferSbacDecoders = NULL;
56  m_pcBufferBinCABACs    = NULL;
57  m_pcBufferLowLatSbacDecoders = NULL;
58  m_pcBufferLowLatBinCABACs    = NULL;
59}
60
61TDecSlice::~TDecSlice()
62{
63  for (std::vector<TDecSbac*>::iterator i = CTXMem.begin(); i != CTXMem.end(); i++)
64  {
65    delete (*i);
66  }
67  CTXMem.clear();
68}
69
70Void TDecSlice::initCtxMem(  UInt i )               
71{   
72  for (std::vector<TDecSbac*>::iterator j = CTXMem.begin(); j != CTXMem.end(); j++)
73  {
74    delete (*j);
75  }
76  CTXMem.clear(); 
77  CTXMem.resize(i); 
78}
79
80Void TDecSlice::create()
81{
82}
83
84Void TDecSlice::destroy()
85{
86  if ( m_pcBufferSbacDecoders )
87  {
88    delete[] m_pcBufferSbacDecoders;
89    m_pcBufferSbacDecoders = NULL;
90  }
91  if ( m_pcBufferBinCABACs )
92  {
93    delete[] m_pcBufferBinCABACs;
94    m_pcBufferBinCABACs = NULL;
95  }
96  if ( m_pcBufferLowLatSbacDecoders )
97  {
98    delete[] m_pcBufferLowLatSbacDecoders;
99    m_pcBufferLowLatSbacDecoders = NULL;
100  }
101  if ( m_pcBufferLowLatBinCABACs )
102  {
103    delete[] m_pcBufferLowLatBinCABACs;
104    m_pcBufferLowLatBinCABACs = NULL;
105  }
106}
107
108#if SVC_EXTENSION
109Void TDecSlice::init(TDecEntropy* pcEntropyDecoder, TDecCu* pcCuDecoder, UInt* saoMaxOffsetQVal)
110{
111  m_pcEntropyDecoder  = pcEntropyDecoder;
112  m_pcCuDecoder       = pcCuDecoder;
113  m_saoMaxOffsetQVal  = saoMaxOffsetQVal;
114}
115#else
116Void TDecSlice::init(TDecEntropy* pcEntropyDecoder, TDecCu* pcCuDecoder)
117{
118  m_pcEntropyDecoder  = pcEntropyDecoder;
119  m_pcCuDecoder       = pcCuDecoder;
120}
121#endif
122
123Void TDecSlice::decompressSlice(TComInputBitstream** ppcSubstreams, TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders)
124{
125  TComDataCU* pcCU;
126  UInt        uiIsLast = 0;
127  Int   iStartCUEncOrder = max(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU(), rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU());
128  Int   iStartCUAddr = rpcPic->getPicSym()->getCUOrderMap(iStartCUEncOrder);
129
130  // decoder don't need prediction & residual frame buffer
131  rpcPic->setPicYuvPred( 0 );
132  rpcPic->setPicYuvResi( 0 );
133 
134#if ENC_DEC_TRACE
135  g_bJustDoIt = g_bEncDecTraceEnable;
136#endif
137  DTRACE_CABAC_VL( g_nSymbolCounter++ );
138  DTRACE_CABAC_T( "\tPOC: " );
139  DTRACE_CABAC_V( rpcPic->getPOC() );
140  DTRACE_CABAC_T( "\n" );
141
142#if ENC_DEC_TRACE
143  g_bJustDoIt = g_bEncDecTraceDisable;
144#endif
145
146  UInt uiTilesAcross   = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
147  TComSlice*  pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx());
148  Int  iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
149
150  // delete decoders if already allocated in previous slice
151  if (m_pcBufferSbacDecoders)
152  {
153    delete [] m_pcBufferSbacDecoders;
154  }
155  if (m_pcBufferBinCABACs) 
156  {
157    delete [] m_pcBufferBinCABACs;
158  }
159  // allocate new decoders based on tile numbaer
160  m_pcBufferSbacDecoders = new TDecSbac    [uiTilesAcross]; 
161  m_pcBufferBinCABACs    = new TDecBinCABAC[uiTilesAcross];
162  for (UInt ui = 0; ui < uiTilesAcross; ui++)
163  {
164    m_pcBufferSbacDecoders[ui].init(&m_pcBufferBinCABACs[ui]);
165  }
166  //save init. state
167  for (UInt ui = 0; ui < uiTilesAcross; ui++)
168  {
169    m_pcBufferSbacDecoders[ui].load(pcSbacDecoder);
170  }
171
172  // free memory if already allocated in previous call
173  if (m_pcBufferLowLatSbacDecoders)
174  {
175    delete [] m_pcBufferLowLatSbacDecoders;
176  }
177  if (m_pcBufferLowLatBinCABACs)
178  {
179    delete [] m_pcBufferLowLatBinCABACs;
180  }
181  m_pcBufferLowLatSbacDecoders = new TDecSbac    [uiTilesAcross]; 
182  m_pcBufferLowLatBinCABACs    = new TDecBinCABAC[uiTilesAcross];
183  for (UInt ui = 0; ui < uiTilesAcross; ui++)
184  {
185    m_pcBufferLowLatSbacDecoders[ui].init(&m_pcBufferLowLatBinCABACs[ui]);
186  }
187  //save init. state
188  for (UInt ui = 0; ui < uiTilesAcross; ui++)
189  {
190    m_pcBufferLowLatSbacDecoders[ui].load(pcSbacDecoder);
191  }
192
193  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
194  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
195  UInt uiCol=0, uiLin=0, uiSubStrm=0;
196
197  UInt uiTileCol;
198  UInt uiTileStartLCU;
199  UInt uiTileLCUX;
200  Int iNumSubstreamsPerTile = 1; // if independent.
201  Bool depSliceSegmentsEnabled = rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getPPS()->getDependentSliceSegmentsEnabledFlag();
202  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iStartCUAddr))->getFirstCUAddr();
203  if( depSliceSegmentsEnabled )
204  {
205    if( (!rpcPic->getSlice(rpcPic->getCurrSliceIdx())->isNextSlice()) &&
206       iStartCUAddr != rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iStartCUAddr))->getFirstCUAddr())
207    {
208      if(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
209      {
210        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(iStartCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
211        m_pcBufferSbacDecoders[uiTileCol].loadContexts( CTXMem[1]  );//2.LCU
212        if ( (iStartCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
213        {
214          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
215          uiCol     = iStartCUAddr % uiWidthInLCUs;
216          if(uiCol==uiTileLCUX)
217          {
218            CTXMem[0]->loadContexts(pcSbacDecoder);
219          }
220        }
221      }
222      pcSbacDecoder->loadContexts(CTXMem[0] ); //end of depSlice-1
223      pcSbacDecoders[uiSubStrm].loadContexts(pcSbacDecoder);
224    }
225    else
226    {
227      if(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
228      {
229        CTXMem[1]->loadContexts(pcSbacDecoder);
230      }
231      CTXMem[0]->loadContexts(pcSbacDecoder);
232    }
233  }
234  for( Int iCUAddr = iStartCUAddr; !uiIsLast && iCUAddr < rpcPic->getNumCUsInFrame(); iCUAddr = rpcPic->getPicSym()->xCalculateNxtCUAddr(iCUAddr) )
235  {
236    pcCU = rpcPic->getCU( iCUAddr );
237    pcCU->initCU( rpcPic, iCUAddr );
238    uiTileCol = rpcPic->getPicSym()->getTileIdxMap(iCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
239    uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr();
240    uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
241    uiCol     = iCUAddr % uiWidthInLCUs;
242    // The 'line' is now relative to the 1st line in the slice, not the 1st line in the picture.
243    uiLin     = (iCUAddr/uiWidthInLCUs)-(iStartCUAddr/uiWidthInLCUs);
244    // inherit from TR if necessary, select substream to use.
245    if( (pcSlice->getPPS()->getNumSubstreams() > 1) || ( depSliceSegmentsEnabled  && (uiCol == uiTileLCUX)&&(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()) ))
246    {
247      // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
248      iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
249      uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(iCUAddr)*iNumSubstreamsPerTile
250                  + uiLin%iNumSubstreamsPerTile;
251      m_pcEntropyDecoder->setBitstream( ppcSubstreams[uiSubStrm] );
252      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
253      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX)&&(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()))
254      {
255        // We'll sync if the TR is available.
256        TComDataCU *pcCUUp = pcCU->getCUAbove();
257        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
258        TComDataCU *pcCUTR = NULL;
259        if ( pcCUUp && ((iCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
260        {
261          pcCUTR = rpcPic->getCU( iCUAddr - uiWidthInCU + 1 );
262        }
263        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
264
265        if ( (true/*bEnforceSliceRestriction*/ &&
266             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
267             ((pcCUTR->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) ||
268             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr)))
269             ))
270           )
271        {
272          // TR not available.
273        }
274        else
275        {
276          // TR is available, we use it.
277          pcSbacDecoders[uiSubStrm].loadContexts( &m_pcBufferSbacDecoders[uiTileCol] );
278        }
279      }
280      pcSbacDecoder->load(&pcSbacDecoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to pcSbacDecoders)
281    }
282    else if ( pcSlice->getPPS()->getNumSubstreams() <= 1 )
283    {
284      // Set variables to appropriate values to avoid later code change.
285      iNumSubstreamsPerTile = 1;
286    }
287
288    if ( (iCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr()) && // 1st in tile.
289         (iCUAddr!=0) && (iCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())
290         && (iCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU())
291         ) // !1st in frame && !1st in slice
292    {
293      if (pcSlice->getPPS()->getNumSubstreams() > 1)
294      {
295        // We're crossing into another tile, tiles are independent.
296        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
297        // have to perform it here.
298        // For TILES_DECODER, there can be a header at the start of the 1st substream in a tile.  These are read when the substreams
299        // are extracted, not here.
300      }
301      else
302      {
303        SliceType sliceType  = pcSlice->getSliceType();
304        if (pcSlice->getCabacInitFlag())
305        {
306          switch (sliceType)
307          {
308          case P_SLICE:           // change initialization table to B_SLICE intialization
309            sliceType = B_SLICE; 
310            break;
311          case B_SLICE:           // change initialization table to P_SLICE intialization
312            sliceType = P_SLICE; 
313            break;
314          default     :           // should not occur
315            assert(0);
316          }
317        }
318        m_pcEntropyDecoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
319      }
320     
321    }
322
323#if ENC_DEC_TRACE
324    g_bJustDoIt = g_bEncDecTraceEnable;
325#endif
326
327    if ( pcSlice->getSPS()->getUseSAO() )
328    {
329      SAOBlkParam& saoblkParam = (rpcPic->getPicSym()->getSAOBlkParam())[iCUAddr];
330      if (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma())
331      {
332        Bool sliceEnabled[NUM_SAO_COMPONENTS];
333        sliceEnabled[SAO_Y] = pcSlice->getSaoEnabledFlag();
334        sliceEnabled[SAO_Cb]= sliceEnabled[SAO_Cr]= pcSlice->getSaoEnabledFlagChroma();
335
336        Bool leftMergeAvail = false;
337        Bool aboveMergeAvail= false;
338
339        //merge left condition
340        Int rx = (iCUAddr % uiWidthInLCUs);
341        if(rx > 0)
342        {
343          leftMergeAvail = rpcPic->getSAOMergeAvailability(iCUAddr, iCUAddr-1);
344        }
345        //merge up condition
346        Int ry = (iCUAddr / uiWidthInLCUs);
347        if(ry > 0)
348        {
349          aboveMergeAvail = rpcPic->getSAOMergeAvailability(iCUAddr, iCUAddr-uiWidthInLCUs);
350        }
351#if SVC_EXTENSION
352        pcSbacDecoder->parseSAOBlkParam( saoblkParam, m_saoMaxOffsetQVal, sliceEnabled, leftMergeAvail, aboveMergeAvail);
353#else
354        pcSbacDecoder->parseSAOBlkParam( saoblkParam, sliceEnabled, leftMergeAvail, aboveMergeAvail);
355#endif
356      }
357      else 
358      {
359        saoblkParam[SAO_Y ].modeIdc = SAO_MODE_OFF;
360        saoblkParam[SAO_Cb].modeIdc = SAO_MODE_OFF;
361        saoblkParam[SAO_Cr].modeIdc = SAO_MODE_OFF;
362      }
363    }
364
365    m_pcCuDecoder->decodeCU     ( pcCU, uiIsLast );
366    m_pcCuDecoder->decompressCU ( pcCU );
367   
368#if ENC_DEC_TRACE
369    g_bJustDoIt = g_bEncDecTraceDisable;
370#endif
371    pcSbacDecoders[uiSubStrm].load(pcSbacDecoder);
372
373    if ( uiCol == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getRightEdgePosInCU()
374        && pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()
375        && !uiIsLast )
376    {
377      // Parse end_of_substream_one_bit for WPP case
378      UInt binVal;
379      pcSbacDecoder->parseTerminatingBit( binVal );
380      assert( binVal );
381    }
382
383    //Store probabilities of second LCU in line into buffer
384    if ( (uiCol == uiTileLCUX+1)&& (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()) )
385    {
386      m_pcBufferSbacDecoders[uiTileCol].loadContexts( &pcSbacDecoders[uiSubStrm] );
387    }
388    if( uiIsLast && depSliceSegmentsEnabled )
389    {
390      if (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
391       {
392         CTXMem[1]->loadContexts( &m_pcBufferSbacDecoders[uiTileCol] );//ctx 2.LCU
393       }
394      CTXMem[0]->loadContexts( pcSbacDecoder );//ctx end of dep.slice
395      return;
396    }
397  }
398}
399
400ParameterSetManagerDecoder::ParameterSetManagerDecoder()
401#if !SVC_EXTENSION
402: m_vpsBuffer(MAX_NUM_VPS)
403, m_spsBuffer(MAX_NUM_SPS)
404, m_ppsBuffer(MAX_NUM_PPS)
405#endif
406{
407}
408
409ParameterSetManagerDecoder::~ParameterSetManagerDecoder()
410{
411
412}
413
414TComVPS* ParameterSetManagerDecoder::getPrefetchedVPS  (Int vpsId)
415{
416  if (m_vpsBuffer.getPS(vpsId) != NULL )
417  {
418    return m_vpsBuffer.getPS(vpsId);
419  }
420  else
421  {
422    return getVPS(vpsId);
423  }
424}
425
426
427TComSPS* ParameterSetManagerDecoder::getPrefetchedSPS  (Int spsId)
428{
429  if (m_spsBuffer.getPS(spsId) != NULL )
430  {
431    return m_spsBuffer.getPS(spsId);
432  }
433  else
434  {
435    return getSPS(spsId);
436  }
437}
438
439TComPPS* ParameterSetManagerDecoder::getPrefetchedPPS  (Int ppsId)
440{
441  if (m_ppsBuffer.getPS(ppsId) != NULL )
442  {
443    return m_ppsBuffer.getPS(ppsId);
444  }
445  else
446  {
447    return getPPS(ppsId);
448  }
449}
450
451Void     ParameterSetManagerDecoder::applyPrefetchedPS()
452{
453  m_vpsMap.mergePSList(m_vpsBuffer);
454  m_ppsMap.mergePSList(m_ppsBuffer);
455  m_spsMap.mergePSList(m_spsBuffer);
456}
457
458//! \}
Note: See TracBrowser for help on using the repository browser.