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

Last change on this file since 443 was 443, checked in by tech, 11 years ago
  • Reintegrated branch 6.2-dev0 rev. 442.
  • Changed version number.
  • Added coding results.
  • 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-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 LGE_SAO_MIGRATION_D0091
289    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
290    {
291        SAOParam *saoParam =  pcSlice->getAPS()->getSaoParam();
292        saoParam->bSaoFlag[0] = pcSlice->getSaoEnabledFlag();
293    if (iCUAddr == iStartCUAddr)
294    {
295        saoParam->bSaoFlag[1] = pcSlice->getSaoEnabledFlagChroma();
296    }
297    Int numCuInWidth     = saoParam->numCuInWidth;
298    Int cuAddrInSlice = iCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
299    Int cuAddrUpInSlice  = cuAddrInSlice - numCuInWidth;
300    Int rx = iCUAddr % numCuInWidth;
301    Int ry = iCUAddr / numCuInWidth;
302    Int allowMergeLeft = 1;
303    Int allowMergeUp   = 1;
304    if (rx!=0)
305    {
306        if (rpcPic->getPicSym()->getTileIdxMap(iCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr))
307        {
308            allowMergeLeft = 0;
309        }
310    }
311    if (ry!=0)
312    {
313        if (rpcPic->getPicSym()->getTileIdxMap(iCUAddr-numCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr))
314        {
315        allowMergeUp = 0;
316        }
317    }
318    pcSbacDecoder->parseSaoOneLcuInterleaving(rx, ry, saoParam,pcCU, cuAddrInSlice, cuAddrUpInSlice, allowMergeLeft, allowMergeUp);
319    }
320#else
321    if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() )
322    {
323      pcSlice->getAPS()->getSaoParam()->bSaoFlag[0] = pcSlice->getSaoEnabledFlag();
324      if (iCUAddr == iStartCUAddr)
325      {
326        pcSlice->getAPS()->getSaoParam()->bSaoFlag[1] = pcSlice->getSaoEnabledFlagCb();
327        pcSlice->getAPS()->getSaoParam()->bSaoFlag[2] = pcSlice->getSaoEnabledFlagCr();
328      }
329      Int numCuInWidth     = pcSlice->getAPS()->getSaoParam()->numCuInWidth;
330      Int cuAddrInSlice = iCUAddr - pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU();
331      Int cuAddrUpInSlice  = cuAddrInSlice - numCuInWidth;
332      Int rx = iCUAddr % numCuInWidth;
333      Int ry = iCUAddr / numCuInWidth;
334      pcSbacDecoder->parseSaoOneLcuInterleaving(rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, cuAddrInSlice, cuAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag() );
335    }
336#endif
337
338    m_pcCuDecoder->decodeCU     ( pcCU, uiIsLast );
339    m_pcCuDecoder->decompressCU ( pcCU );
340   
341#if ENC_DEC_TRACE
342    g_bJustDoIt = g_bEncDecTraceDisable;
343#endif
344    if( iSymbolMode )
345    {
346      /*If at the end of a LCU line but not at the end of a substream, perform CABAC flush*/
347      if (!uiIsLast && pcSlice->getPPS()->getNumSubstreams() > 1)
348      {
349        if ((uiCol == uiTileLCUX+uiTileWidth-1) && (uiLin+iNumSubstreamsPerTile < uiTileLCUY+uiTileHeight))
350        {
351          m_pcEntropyDecoder->decodeFlush();
352        }
353      }
354      pcSbacDecoders[uiSubStrm].load(pcSbacDecoder);
355
356      //Store probabilities of second LCU in line into buffer
357      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX+1))
358      {
359        m_pcBufferSbacDecoders[uiTileCol].loadContexts( &pcSbacDecoders[uiSubStrm] );
360      }
361
362    }
363  }
364
365}
366
367ParameterSetManagerDecoder::ParameterSetManagerDecoder()
368: m_spsBuffer(256)
369, m_ppsBuffer(16)
370, m_apsBuffer(64)
371#if VIDYO_VPS_INTEGRATION|QC_MVHEVC_B0046
372, m_vpsBuffer(16)
373#endif
374{
375
376}
377
378ParameterSetManagerDecoder::~ParameterSetManagerDecoder()
379{
380
381}
382
383#if VIDYO_VPS_INTEGRATION|QC_MVHEVC_B0046
384TComVPS* ParameterSetManagerDecoder::getPrefetchedVPS  (Int vpsId)
385{
386  if (m_vpsBuffer.getPS(vpsId) != NULL )
387  {
388    return m_vpsBuffer.getPS(vpsId);
389  }
390  else
391  {
392    return getVPS(vpsId);
393  }
394}
395#endif
396
397TComSPS* ParameterSetManagerDecoder::getPrefetchedSPS  (Int spsId)
398{
399  if (m_spsBuffer.getPS(spsId) != NULL )
400  {
401    return m_spsBuffer.getPS(spsId);
402  }
403  else
404  {
405    return getSPS(spsId);
406  }
407}
408
409TComPPS* ParameterSetManagerDecoder::getPrefetchedPPS  (Int ppsId)
410{
411  if (m_ppsBuffer.getPS(ppsId) != NULL )
412  {
413    return m_ppsBuffer.getPS(ppsId);
414  }
415  else
416  {
417    return getPPS(ppsId);
418  }
419}
420
421TComAPS* ParameterSetManagerDecoder::getPrefetchedAPS  (Int apsId)
422{
423  if (m_apsBuffer.getPS(apsId) != NULL )
424  {
425    return m_apsBuffer.getPS(apsId);
426  }
427  else
428  {
429    return getAPS(apsId);
430  }
431}
432
433Void     ParameterSetManagerDecoder::applyPrefetchedPS()
434{
435  m_apsMap.mergePSList(m_apsBuffer);
436  m_ppsMap.mergePSList(m_ppsBuffer);
437  m_spsMap.mergePSList(m_spsBuffer);
438#if VIDYO_VPS_INTEGRATION|QC_MVHEVC_B0046
439  m_vpsMap.mergePSList(m_vpsBuffer);
440#endif
441}
442
443//! \}
Note: See TracBrowser for help on using the repository browser.