source: 3DVCSoftware/trunk/source/Lib/TLibDecoder/TDecSlice.cpp @ 1198

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

Merged branch 13.1-dev0@1178.

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