source: 3DVCSoftware/branches/HTM-DEV-0.3-dev0/source/Lib/TLibDecoder/TDecSlice.cpp @ 498

Last change on this file since 498 was 498, checked in by tech, 11 years ago

Further fixes and new nonctc cfg files.

  • Property svn:eol-style set to native
File size: 15.6 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-2013, 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
126  DTRACE_CABAC_T( "\tLayer: " );
127  DTRACE_CABAC_V( rpcPic->getLayerId()  );
128#endif
129
130  DTRACE_CABAC_T( "\n" );
131
132#if ENC_DEC_TRACE
133  g_bJustDoIt = g_bEncDecTraceDisable;
134#endif
135
136  UInt uiTilesAcross   = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
137  TComSlice*  pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx());
138  Int  iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
139
140  // delete decoders if already allocated in previous slice
141  if (m_pcBufferSbacDecoders)
142  {
143    delete [] m_pcBufferSbacDecoders;
144  }
145  if (m_pcBufferBinCABACs) 
146  {
147    delete [] m_pcBufferBinCABACs;
148  }
149  // allocate new decoders based on tile numbaer
150  m_pcBufferSbacDecoders = new TDecSbac    [uiTilesAcross]; 
151  m_pcBufferBinCABACs    = new TDecBinCABAC[uiTilesAcross];
152  for (UInt ui = 0; ui < uiTilesAcross; ui++)
153  {
154    m_pcBufferSbacDecoders[ui].init(&m_pcBufferBinCABACs[ui]);
155  }
156  //save init. state
157  for (UInt ui = 0; ui < uiTilesAcross; ui++)
158  {
159    m_pcBufferSbacDecoders[ui].load(pcSbacDecoder);
160  }
161
162  // free memory if already allocated in previous call
163  if (m_pcBufferLowLatSbacDecoders)
164  {
165    delete [] m_pcBufferLowLatSbacDecoders;
166  }
167  if (m_pcBufferLowLatBinCABACs)
168  {
169    delete [] m_pcBufferLowLatBinCABACs;
170  }
171  m_pcBufferLowLatSbacDecoders = new TDecSbac    [uiTilesAcross]; 
172  m_pcBufferLowLatBinCABACs    = new TDecBinCABAC[uiTilesAcross];
173  for (UInt ui = 0; ui < uiTilesAcross; ui++)
174  {
175    m_pcBufferLowLatSbacDecoders[ui].init(&m_pcBufferLowLatBinCABACs[ui]);
176  }
177  //save init. state
178  for (UInt ui = 0; ui < uiTilesAcross; ui++)
179  {
180    m_pcBufferLowLatSbacDecoders[ui].load(pcSbacDecoder);
181  }
182
183  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
184  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
185  UInt uiCol=0, uiLin=0, uiSubStrm=0;
186
187  UInt uiTileCol;
188  UInt uiTileStartLCU;
189  UInt uiTileLCUX;
190  Int iNumSubstreamsPerTile = 1; // if independent.
191  Bool depSliceSegmentsEnabled = rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getPPS()->getDependentSliceSegmentsEnabledFlag();
192  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iStartCUAddr))->getFirstCUAddr();
193  if( depSliceSegmentsEnabled )
194  {
195    if( (!rpcPic->getSlice(rpcPic->getCurrSliceIdx())->isNextSlice()) &&
196       iStartCUAddr != rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iStartCUAddr))->getFirstCUAddr())
197    {
198      if(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
199      {
200        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(iStartCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
201        m_pcBufferSbacDecoders[uiTileCol].loadContexts( CTXMem[1]  );//2.LCU
202        if ( (iStartCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
203        {
204          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
205          uiCol     = iStartCUAddr % uiWidthInLCUs;
206          if(uiCol==uiTileLCUX)
207          {
208            CTXMem[0]->loadContexts(pcSbacDecoder);
209          }
210        }
211      }
212      pcSbacDecoder->loadContexts(CTXMem[0] ); //end of depSlice-1
213      pcSbacDecoders[uiSubStrm].loadContexts(pcSbacDecoder);
214    }
215    else
216    {
217      if(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
218      {
219        CTXMem[1]->loadContexts(pcSbacDecoder);
220      }
221      CTXMem[0]->loadContexts(pcSbacDecoder);
222    }
223  }
224  for( Int iCUAddr = iStartCUAddr; !uiIsLast && iCUAddr < rpcPic->getNumCUsInFrame(); iCUAddr = rpcPic->getPicSym()->xCalculateNxtCUAddr(iCUAddr) )
225  {
226    pcCU = rpcPic->getCU( iCUAddr );
227    pcCU->initCU( rpcPic, iCUAddr );
228    uiTileCol = rpcPic->getPicSym()->getTileIdxMap(iCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
229    uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr();
230    uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
231    uiCol     = iCUAddr % uiWidthInLCUs;
232    // The 'line' is now relative to the 1st line in the slice, not the 1st line in the picture.
233    uiLin     = (iCUAddr/uiWidthInLCUs)-(iStartCUAddr/uiWidthInLCUs);
234    // inherit from TR if necessary, select substream to use.
235    if( (pcSlice->getPPS()->getNumSubstreams() > 1) || ( depSliceSegmentsEnabled  && (uiCol == uiTileLCUX)&&(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()) ))
236    {
237      // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
238      iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
239      uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(iCUAddr)*iNumSubstreamsPerTile
240                  + uiLin%iNumSubstreamsPerTile;
241      m_pcEntropyDecoder->setBitstream( ppcSubstreams[uiSubStrm] );
242      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
243      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX)&&(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()))
244      {
245        // We'll sync if the TR is available.
246        TComDataCU *pcCUUp = pcCU->getCUAbove();
247        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
248        TComDataCU *pcCUTR = NULL;
249        if ( pcCUUp && ((iCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
250        {
251          pcCUTR = rpcPic->getCU( iCUAddr - uiWidthInCU + 1 );
252        }
253        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
254
255        if ( (true/*bEnforceSliceRestriction*/ &&
256             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
257             ((pcCUTR->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) ||
258             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr)))
259             ))
260           )
261        {
262          // TR not available.
263        }
264        else
265        {
266          // TR is available, we use it.
267          pcSbacDecoders[uiSubStrm].loadContexts( &m_pcBufferSbacDecoders[uiTileCol] );
268        }
269      }
270      pcSbacDecoder->load(&pcSbacDecoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to pcSbacDecoders)
271    }
272    else if ( pcSlice->getPPS()->getNumSubstreams() <= 1 )
273    {
274      // Set variables to appropriate values to avoid later code change.
275      iNumSubstreamsPerTile = 1;
276    }
277
278    if ( (iCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr()) && // 1st in tile.
279         (iCUAddr!=0) && (iCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())
280         && (iCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU())
281         ) // !1st in frame && !1st in slice
282    {
283      if (pcSlice->getPPS()->getNumSubstreams() > 1)
284      {
285        // We're crossing into another tile, tiles are independent.
286        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
287        // have to perform it here.
288        // For TILES_DECODER, there can be a header at the start of the 1st substream in a tile.  These are read when the substreams
289        // are extracted, not here.
290      }
291      else
292      {
293        SliceType sliceType  = pcSlice->getSliceType();
294        if (pcSlice->getCabacInitFlag())
295        {
296          switch (sliceType)
297          {
298          case P_SLICE:           // change initialization table to B_SLICE intialization
299            sliceType = B_SLICE; 
300            break;
301          case B_SLICE:           // change initialization table to P_SLICE intialization
302            sliceType = P_SLICE; 
303            break;
304          default     :           // should not occur
305            assert(0);
306          }
307        }
308        m_pcEntropyDecoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
309      }
310     
311    }
312
313#if ENC_DEC_TRACE
314    g_bJustDoIt = g_bEncDecTraceEnable;
315#endif
316    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
317    {
318      SAOParam *saoParam = rpcPic->getPicSym()->getSaoParam();
319      saoParam->bSaoFlag[0] = pcSlice->getSaoEnabledFlag();
320      if (iCUAddr == iStartCUAddr)
321      {
322        saoParam->bSaoFlag[1] = pcSlice->getSaoEnabledFlagChroma();
323      }
324      Int numCuInWidth     = saoParam->numCuInWidth;
325      Int cuAddrInSlice = iCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
326      Int cuAddrUpInSlice  = cuAddrInSlice - numCuInWidth;
327      Int rx = iCUAddr % numCuInWidth;
328      Int ry = iCUAddr / numCuInWidth;
329      Int allowMergeLeft = 1;
330      Int allowMergeUp   = 1;
331      if (rx!=0)
332      {
333        if (rpcPic->getPicSym()->getTileIdxMap(iCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr))
334        {
335          allowMergeLeft = 0;
336        }
337      }
338      if (ry!=0)
339      {
340        if (rpcPic->getPicSym()->getTileIdxMap(iCUAddr-numCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr))
341        {
342          allowMergeUp = 0;
343        }
344      }
345      pcSbacDecoder->parseSaoOneLcuInterleaving(rx, ry, saoParam,pcCU, cuAddrInSlice, cuAddrUpInSlice, allowMergeLeft, allowMergeUp);
346    }
347    else if ( pcSlice->getSPS()->getUseSAO() )
348    {
349      Int addr = pcCU->getAddr();
350      SAOParam *saoParam = rpcPic->getPicSym()->getSaoParam();
351      for (Int cIdx=0; cIdx<3; cIdx++)
352      {
353        SaoLcuParam *saoLcuParam = &(saoParam->saoLcuParam[cIdx][addr]);
354        if ( ((cIdx == 0) && !pcSlice->getSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice->getSaoEnabledFlagChroma()))
355        {
356          saoLcuParam->mergeUpFlag   = 0;
357          saoLcuParam->mergeLeftFlag = 0;
358          saoLcuParam->subTypeIdx    = 0;
359          saoLcuParam->typeIdx       = -1;
360          saoLcuParam->offset[0]     = 0;
361          saoLcuParam->offset[1]     = 0;
362          saoLcuParam->offset[2]     = 0;
363          saoLcuParam->offset[3]     = 0;
364        }
365      }
366    }
367    m_pcCuDecoder->decodeCU     ( pcCU, uiIsLast );
368    m_pcCuDecoder->decompressCU ( pcCU );
369   
370#if ENC_DEC_TRACE
371    g_bJustDoIt = g_bEncDecTraceDisable;
372#endif
373    pcSbacDecoders[uiSubStrm].load(pcSbacDecoder);
374
375    //Store probabilities of second LCU in line into buffer
376    if ( (uiCol == uiTileLCUX+1)&& (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()) )
377    {
378      m_pcBufferSbacDecoders[uiTileCol].loadContexts( &pcSbacDecoders[uiSubStrm] );
379    }
380    if( uiIsLast && depSliceSegmentsEnabled )
381    {
382      if (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
383       {
384         CTXMem[1]->loadContexts( &m_pcBufferSbacDecoders[uiTileCol] );//ctx 2.LCU
385       }
386      CTXMem[0]->loadContexts( pcSbacDecoder );//ctx end of dep.slice
387      return;
388    }
389  }
390}
391
392ParameterSetManagerDecoder::ParameterSetManagerDecoder()
393: m_vpsBuffer(MAX_NUM_VPS)
394, m_spsBuffer(MAX_NUM_SPS)
395, m_ppsBuffer(MAX_NUM_PPS)
396{
397}
398
399ParameterSetManagerDecoder::~ParameterSetManagerDecoder()
400{
401
402}
403
404TComVPS* ParameterSetManagerDecoder::getPrefetchedVPS  (Int vpsId)
405{
406  if (m_vpsBuffer.getPS(vpsId) != NULL )
407  {
408    return m_vpsBuffer.getPS(vpsId);
409  }
410  else
411  {
412    return getVPS(vpsId);
413  }
414}
415
416
417TComSPS* ParameterSetManagerDecoder::getPrefetchedSPS  (Int spsId)
418{
419  if (m_spsBuffer.getPS(spsId) != NULL )
420  {
421    return m_spsBuffer.getPS(spsId);
422  }
423  else
424  {
425    return getSPS(spsId);
426  }
427}
428
429TComPPS* ParameterSetManagerDecoder::getPrefetchedPPS  (Int ppsId)
430{
431  if (m_ppsBuffer.getPS(ppsId) != NULL )
432  {
433    return m_ppsBuffer.getPS(ppsId);
434  }
435  else
436  {
437    return getPPS(ppsId);
438  }
439}
440
441Void     ParameterSetManagerDecoder::applyPrefetchedPS()
442{
443  m_vpsMap.mergePSList(m_vpsBuffer);
444  m_ppsMap.mergePSList(m_ppsBuffer);
445  m_spsMap.mergePSList(m_spsBuffer);
446}
447
448//! \}
Note: See TracBrowser for help on using the repository browser.