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

Last change on this file since 296 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: 14.1 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     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}
58
59Void TDecSlice::create( TComSlice* pcSlice, Int iWidth, Int iHeight, UInt uiMaxWidth, UInt uiMaxHeight, UInt uiMaxDepth )
60{
61}
62
63Void TDecSlice::destroy()
64{
65  if ( m_pcBufferSbacDecoders )
66  {
67    delete[] m_pcBufferSbacDecoders;
68    m_pcBufferSbacDecoders = NULL;
69  }
70  if ( m_pcBufferBinCABACs )
71  {
72    delete[] m_pcBufferBinCABACs;
73    m_pcBufferBinCABACs = NULL;
74  }
75  if ( m_pcBufferLowLatSbacDecoders )
76  {
77    delete[] m_pcBufferLowLatSbacDecoders;
78    m_pcBufferLowLatSbacDecoders = NULL;
79  }
80  if ( m_pcBufferLowLatBinCABACs )
81  {
82    delete[] m_pcBufferLowLatBinCABACs;
83    m_pcBufferLowLatBinCABACs = NULL;
84  }
85}
86
87Void TDecSlice::init(TDecEntropy* pcEntropyDecoder, TDecCu* pcCuDecoder)
88{
89  m_pcEntropyDecoder  = pcEntropyDecoder;
90  m_pcCuDecoder       = pcCuDecoder;
91}
92
93Void TDecSlice::decompressSlice(TComInputBitstream* pcBitstream, TComInputBitstream** ppcSubstreams, TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders)
94{
95  TComDataCU* pcCU;
96  UInt        uiIsLast = 0;
97  Int   iStartCUEncOrder = max(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU(), rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getEntropySliceCurStartCUAddr()/rpcPic->getNumPartInCU());
98  Int   iStartCUAddr = rpcPic->getPicSym()->getCUOrderMap(iStartCUEncOrder);
99
100  // decoder don't need prediction & residual frame buffer
101  rpcPic->setPicYuvPred( 0 );
102  rpcPic->setPicYuvResi( 0 );
103 
104#if ENC_DEC_TRACE
105  g_bJustDoIt = g_bEncDecTraceEnable;
106#endif
107  DTRACE_CABAC_VL( g_nSymbolCounter++ );
108  DTRACE_CABAC_T( "\tPOC: " );
109  DTRACE_CABAC_V( rpcPic->getPOC() );
110  DTRACE_CABAC_T( "\n" );
111
112#if ENC_DEC_TRACE
113  g_bJustDoIt = g_bEncDecTraceDisable;
114#endif
115
116  UInt uiTilesAcross   = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
117  TComSlice*  pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx());
118  UInt iSymbolMode    = pcSlice->getPPS()->getEntropyCodingMode();
119  Int  iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
120
121  if( iSymbolMode )
122  {
123    m_pcBufferSbacDecoders = new TDecSbac    [uiTilesAcross]; 
124    m_pcBufferBinCABACs    = new TDecBinCABAC[uiTilesAcross];
125    for (UInt ui = 0; ui < uiTilesAcross; ui++)
126    {
127      m_pcBufferSbacDecoders[ui].init(&m_pcBufferBinCABACs[ui]);
128    }
129    //save init. state
130    for (UInt ui = 0; ui < uiTilesAcross; ui++)
131    {
132      m_pcBufferSbacDecoders[ui].load(pcSbacDecoder);
133    }
134  } 
135  if( iSymbolMode )
136  {
137    m_pcBufferLowLatSbacDecoders = new TDecSbac    [uiTilesAcross]; 
138    m_pcBufferLowLatBinCABACs    = new TDecBinCABAC[uiTilesAcross];
139    for (UInt ui = 0; ui < uiTilesAcross; ui++)
140      m_pcBufferLowLatSbacDecoders[ui].init(&m_pcBufferLowLatBinCABACs[ui]);
141    //save init. state
142    for (UInt ui = 0; ui < uiTilesAcross; ui++)
143      m_pcBufferLowLatSbacDecoders[ui].load(pcSbacDecoder);
144  }
145
146  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
147  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
148  UInt uiCol=0, uiLin=0, uiSubStrm=0;
149
150  UInt uiTileCol;
151  UInt uiTileStartLCU;
152  UInt uiTileLCUX;
153  UInt uiTileLCUY;
154  UInt uiTileWidth;
155  UInt uiTileHeight;
156  Int iNumSubstreamsPerTile = 1; // if independent.
157
158  for( Int iCUAddr = iStartCUAddr; !uiIsLast && iCUAddr < rpcPic->getNumCUsInFrame(); iCUAddr = rpcPic->getPicSym()->xCalculateNxtCUAddr(iCUAddr) )
159  {
160    pcCU = rpcPic->getCU( iCUAddr );
161    pcCU->initCU( rpcPic, iCUAddr );
162    uiTileCol = rpcPic->getPicSym()->getTileIdxMap(iCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
163    uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr();
164    uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
165    uiTileLCUY = uiTileStartLCU / uiWidthInLCUs;
166    uiTileWidth = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getTileWidth();
167    uiTileHeight = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getTileHeight();
168    uiCol     = iCUAddr % uiWidthInLCUs;
169    uiLin     = iCUAddr / uiWidthInLCUs;
170    // inherit from TR if necessary, select substream to use.
171    if( iSymbolMode && pcSlice->getPPS()->getNumSubstreams() > 1 )
172    {
173      if (pcSlice->getPPS()->getNumSubstreams() > 1)
174      {
175        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
176        iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
177        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(iCUAddr)*iNumSubstreamsPerTile
178                      + uiLin%iNumSubstreamsPerTile;
179      }
180      else
181      {
182        // dependent tiles => substreams are "per frame".
183        uiSubStrm = uiLin % iNumSubstreams;
184      }
185      m_pcEntropyDecoder->setBitstream( ppcSubstreams[uiSubStrm] );
186      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
187      if (pcSlice->getPPS()->getNumSubstreams() > 1 && uiCol == uiTileLCUX)
188      {
189        // We'll sync if the TR is available.
190        TComDataCU *pcCUUp = pcCU->getCUAbove();
191        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
192        TComDataCU *pcCUTR = NULL;
193        if ( pcCUUp && ((iCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
194        {
195          pcCUTR = rpcPic->getCU( iCUAddr - uiWidthInCU + 1 );
196        }
197        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
198
199        if ( (true/*bEnforceSliceRestriction*/ &&
200             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
201             ((pcCUTR->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) ||
202             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr)))
203             ))||
204             (true/*bEnforceEntropySliceRestriction*/ &&
205             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
206             ((pcCUTR->getSCUAddr()+uiMaxParts-1) < pcSlice->getEntropySliceCurStartCUAddr()) ||
207             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr)))
208             ))
209           )
210        {
211          // TR not available.
212        }
213        else
214        {
215          // TR is available, we use it.
216            pcSbacDecoders[uiSubStrm].loadContexts( &m_pcBufferSbacDecoders[uiTileCol] );
217        }
218      }
219      pcSbacDecoder->load(&pcSbacDecoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to pcSbacDecoders)
220    }
221    else if ( iSymbolMode && pcSlice->getPPS()->getNumSubstreams() <= 1 )
222    {
223      // Set variables to appropriate values to avoid later code change.
224      iNumSubstreamsPerTile = 1;
225    }
226
227    if ( (iCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr()) && // 1st in tile.
228         (iCUAddr!=0) && (iCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())) // !1st in frame && !1st in slice
229    {
230      if (pcSlice->getPPS()->getNumSubstreams() > 1)
231      {
232        // We're crossing into another tile, tiles are independent.
233        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
234        // have to perform it here.
235        // For TILES_DECODER, there can be a header at the start of the 1st substream in a tile.  These are read when the substreams
236        // are extracted, not here.
237      }
238      else
239      {
240#if CABAC_INIT_FLAG
241        SliceType sliceType  = pcSlice->getSliceType();
242        if (pcSlice->getCabacInitFlag())
243        {
244          switch (sliceType)
245          {
246          case P_SLICE:           // change initialization table to B_SLICE intialization
247            sliceType = B_SLICE; 
248            break;
249          case B_SLICE:           // change initialization table to P_SLICE intialization
250            sliceType = P_SLICE; 
251            break;
252          default     :           // should not occur
253            assert(0);
254          }
255        }
256        m_pcEntropyDecoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
257#else
258        m_pcEntropyDecoder->updateContextTables( pcSlice->getSliceType(), pcSlice->getSliceQp() );
259#endif
260      }
261     
262      Bool bTileMarkerFoundFlag = false;
263      TComInputBitstream *pcTmpPtr;
264      pcTmpPtr = ppcSubstreams[uiSubStrm]; // for CABAC
265
266      for (UInt uiIdx=0; uiIdx<pcTmpPtr->getTileMarkerLocationCount(); uiIdx++)
267      {
268        if ( pcTmpPtr->getByteLocation() == (pcTmpPtr->getTileMarkerLocation( uiIdx )+2) )
269        {
270          bTileMarkerFoundFlag = true;
271          break;
272        }
273      }
274
275      if (bTileMarkerFoundFlag)
276      {
277        UInt uiTileIdx;
278        // Read tile index
279        m_pcEntropyDecoder->readTileMarker( uiTileIdx, rpcPic->getPicSym()->getBitsUsedByTileIdx() );
280      }
281    }
282
283
284
285#if ENC_DEC_TRACE
286    g_bJustDoIt = g_bEncDecTraceEnable;
287#endif
288    if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() )
289    {
290      pcSlice->getAPS()->getSaoParam()->bSaoFlag[0] = pcSlice->getSaoEnabledFlag();
291      if (iCUAddr == iStartCUAddr)
292      {
293        pcSlice->getAPS()->getSaoParam()->bSaoFlag[1] = pcSlice->getSaoEnabledFlagCb();
294        pcSlice->getAPS()->getSaoParam()->bSaoFlag[2] = pcSlice->getSaoEnabledFlagCr();
295      }
296      Int numCuInWidth     = pcSlice->getAPS()->getSaoParam()->numCuInWidth;
297      Int cuAddrInSlice = iCUAddr - pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU();
298      Int cuAddrUpInSlice  = cuAddrInSlice - numCuInWidth;
299      Int rx = iCUAddr % numCuInWidth;
300      Int ry = iCUAddr / numCuInWidth;
301      pcSbacDecoder->parseSaoOneLcuInterleaving(rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, cuAddrInSlice, cuAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag() );
302    }
303
304    m_pcCuDecoder->decodeCU     ( pcCU, uiIsLast );
305    m_pcCuDecoder->decompressCU ( pcCU );
306   
307#if ENC_DEC_TRACE
308    g_bJustDoIt = g_bEncDecTraceDisable;
309#endif
310    if( iSymbolMode )
311    {
312      /*If at the end of a LCU line but not at the end of a substream, perform CABAC flush*/
313      if (!uiIsLast && pcSlice->getPPS()->getNumSubstreams() > 1)
314      {
315        if ((uiCol == uiTileLCUX+uiTileWidth-1) && (uiLin+iNumSubstreamsPerTile < uiTileLCUY+uiTileHeight))
316        {
317          m_pcEntropyDecoder->decodeFlush();
318        }
319      }
320      pcSbacDecoders[uiSubStrm].load(pcSbacDecoder);
321
322      //Store probabilities of second LCU in line into buffer
323      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX+1))
324      {
325        m_pcBufferSbacDecoders[uiTileCol].loadContexts( &pcSbacDecoders[uiSubStrm] );
326      }
327
328    }
329  }
330
331}
332
333ParameterSetManagerDecoder::ParameterSetManagerDecoder()
334: m_spsBuffer(256)
335, m_ppsBuffer(16)
336, m_apsBuffer(64)
337#if VIDYO_VPS_INTEGRATION|QC_MVHEVC_B0046
338, m_vpsBuffer(16)
339#endif
340{
341
342}
343
344ParameterSetManagerDecoder::~ParameterSetManagerDecoder()
345{
346
347}
348
349#if VIDYO_VPS_INTEGRATION|QC_MVHEVC_B0046
350TComVPS* ParameterSetManagerDecoder::getPrefetchedVPS  (Int vpsId)
351{
352  if (m_vpsBuffer.getPS(vpsId) != NULL )
353  {
354    return m_vpsBuffer.getPS(vpsId);
355  }
356  else
357  {
358    return getVPS(vpsId);
359  }
360}
361#endif
362
363TComSPS* ParameterSetManagerDecoder::getPrefetchedSPS  (Int spsId)
364{
365  if (m_spsBuffer.getPS(spsId) != NULL )
366  {
367    return m_spsBuffer.getPS(spsId);
368  }
369  else
370  {
371    return getSPS(spsId);
372  }
373}
374
375TComPPS* ParameterSetManagerDecoder::getPrefetchedPPS  (Int ppsId)
376{
377  if (m_ppsBuffer.getPS(ppsId) != NULL )
378  {
379    return m_ppsBuffer.getPS(ppsId);
380  }
381  else
382  {
383    return getPPS(ppsId);
384  }
385}
386
387TComAPS* ParameterSetManagerDecoder::getPrefetchedAPS  (Int apsId)
388{
389  if (m_apsBuffer.getPS(apsId) != NULL )
390  {
391    return m_apsBuffer.getPS(apsId);
392  }
393  else
394  {
395    return getAPS(apsId);
396  }
397}
398
399Void     ParameterSetManagerDecoder::applyPrefetchedPS()
400{
401  m_apsMap.mergePSList(m_apsBuffer);
402  m_ppsMap.mergePSList(m_ppsBuffer);
403  m_spsMap.mergePSList(m_spsBuffer);
404#if VIDYO_VPS_INTEGRATION|QC_MVHEVC_B0046
405  m_vpsMap.mergePSList(m_vpsBuffer);
406#endif
407}
408
409//! \}
Note: See TracBrowser for help on using the repository browser.