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

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

Further fixes.

  • 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  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  for( Int iCUAddr = iStartCUAddr; !uiIsLast && iCUAddr < rpcPic->getNumCUsInFrame(); iCUAddr = rpcPic->getPicSym()->xCalculateNxtCUAddr(iCUAddr) )
224  {
225    pcCU = rpcPic->getCU( iCUAddr );
226    pcCU->initCU( rpcPic, iCUAddr );
227    uiTileCol = rpcPic->getPicSym()->getTileIdxMap(iCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
228    uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr();
229    uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
230    uiCol     = iCUAddr % uiWidthInLCUs;
231    // The 'line' is now relative to the 1st line in the slice, not the 1st line in the picture.
232    uiLin     = (iCUAddr/uiWidthInLCUs)-(iStartCUAddr/uiWidthInLCUs);
233    // inherit from TR if necessary, select substream to use.
234    if( (pcSlice->getPPS()->getNumSubstreams() > 1) || ( depSliceSegmentsEnabled  && (uiCol == uiTileLCUX)&&(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()) ))
235    {
236      // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
237      iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
238      uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(iCUAddr)*iNumSubstreamsPerTile
239                  + uiLin%iNumSubstreamsPerTile;
240      m_pcEntropyDecoder->setBitstream( ppcSubstreams[uiSubStrm] );
241      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
242      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX)&&(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()))
243      {
244        // We'll sync if the TR is available.
245        TComDataCU *pcCUUp = pcCU->getCUAbove();
246        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
247        TComDataCU *pcCUTR = NULL;
248        if ( pcCUUp && ((iCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
249        {
250          pcCUTR = rpcPic->getCU( iCUAddr - uiWidthInCU + 1 );
251        }
252        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
253
254        if ( (true/*bEnforceSliceRestriction*/ &&
255             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
256             ((pcCUTR->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) ||
257             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr)))
258             ))
259           )
260        {
261          // TR not available.
262        }
263        else
264        {
265          // TR is available, we use it.
266          pcSbacDecoders[uiSubStrm].loadContexts( &m_pcBufferSbacDecoders[uiTileCol] );
267        }
268      }
269      pcSbacDecoder->load(&pcSbacDecoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to pcSbacDecoders)
270    }
271    else if ( pcSlice->getPPS()->getNumSubstreams() <= 1 )
272    {
273      // Set variables to appropriate values to avoid later code change.
274      iNumSubstreamsPerTile = 1;
275    }
276
277    if ( (iCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr()) && // 1st in tile.
278         (iCUAddr!=0) && (iCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())
279         && (iCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU())
280         ) // !1st in frame && !1st in slice
281    {
282      if (pcSlice->getPPS()->getNumSubstreams() > 1)
283      {
284        // We're crossing into another tile, tiles are independent.
285        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
286        // have to perform it here.
287        // For TILES_DECODER, there can be a header at the start of the 1st substream in a tile.  These are read when the substreams
288        // are extracted, not here.
289      }
290      else
291      {
292        SliceType sliceType  = pcSlice->getSliceType();
293        if (pcSlice->getCabacInitFlag())
294        {
295          switch (sliceType)
296          {
297          case P_SLICE:           // change initialization table to B_SLICE intialization
298            sliceType = B_SLICE; 
299            break;
300          case B_SLICE:           // change initialization table to P_SLICE intialization
301            sliceType = P_SLICE; 
302            break;
303          default     :           // should not occur
304            assert(0);
305          }
306        }
307        m_pcEntropyDecoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
308      }
309     
310    }
311
312#if ENC_DEC_TRACE
313    g_bJustDoIt = g_bEncDecTraceEnable;
314#endif
315    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
316    {
317      SAOParam *saoParam = rpcPic->getPicSym()->getSaoParam();
318      saoParam->bSaoFlag[0] = pcSlice->getSaoEnabledFlag();
319      if (iCUAddr == iStartCUAddr)
320      {
321        saoParam->bSaoFlag[1] = pcSlice->getSaoEnabledFlagChroma();
322      }
323      Int numCuInWidth     = saoParam->numCuInWidth;
324      Int cuAddrInSlice = iCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
325      Int cuAddrUpInSlice  = cuAddrInSlice - numCuInWidth;
326      Int rx = iCUAddr % numCuInWidth;
327      Int ry = iCUAddr / numCuInWidth;
328      Int allowMergeLeft = 1;
329      Int allowMergeUp   = 1;
330      if (rx!=0)
331      {
332        if (rpcPic->getPicSym()->getTileIdxMap(iCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr))
333        {
334          allowMergeLeft = 0;
335        }
336      }
337      if (ry!=0)
338      {
339        if (rpcPic->getPicSym()->getTileIdxMap(iCUAddr-numCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(iCUAddr))
340        {
341          allowMergeUp = 0;
342        }
343      }
344      pcSbacDecoder->parseSaoOneLcuInterleaving(rx, ry, saoParam,pcCU, cuAddrInSlice, cuAddrUpInSlice, allowMergeLeft, allowMergeUp);
345    }
346    else if ( pcSlice->getSPS()->getUseSAO() )
347    {
348      Int addr = pcCU->getAddr();
349      SAOParam *saoParam = rpcPic->getPicSym()->getSaoParam();
350      for (Int cIdx=0; cIdx<3; cIdx++)
351      {
352        SaoLcuParam *saoLcuParam = &(saoParam->saoLcuParam[cIdx][addr]);
353        if ( ((cIdx == 0) && !pcSlice->getSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice->getSaoEnabledFlagChroma()))
354        {
355          saoLcuParam->mergeUpFlag   = 0;
356          saoLcuParam->mergeLeftFlag = 0;
357          saoLcuParam->subTypeIdx    = 0;
358          saoLcuParam->typeIdx       = -1;
359          saoLcuParam->offset[0]     = 0;
360          saoLcuParam->offset[1]     = 0;
361          saoLcuParam->offset[2]     = 0;
362          saoLcuParam->offset[3]     = 0;
363        }
364      }
365    }
366    m_pcCuDecoder->decodeCU     ( pcCU, uiIsLast );
367    m_pcCuDecoder->decompressCU ( pcCU );
368   
369#if ENC_DEC_TRACE
370    g_bJustDoIt = g_bEncDecTraceDisable;
371#endif
372    pcSbacDecoders[uiSubStrm].load(pcSbacDecoder);
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.