source: 3DVCSoftware/branches/HTM-12.2-dev2-Samsung/source/Lib/TLibDecoder/TDecSlice.cpp @ 1100

Last change on this file since 1100 was 1100, checked in by samsung-htm, 9 years ago

Integration of JCT3V-J0037 (Item1 and Item4)

  • Property svn:eol-style set to native
File size: 16.7 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-2014, 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#if LGE_DEFAULT_DV_J0046 && !SEC_ARP_VIEW_REF_CHECK_J0037 && !SEC_DBBP_VIEW_REF_CHECK_J0037
283    pcSlice->setDefaultRefViewIdx( -1 );
284    pcSlice->setDefaultRefViewIdxAvailableFlag( false ); 
285
286    Int valid = 0;
287    Int viewIndex = 0;
288    for( UInt uiBId = 0; uiBId < pcSlice->getViewIndex() && valid==0; uiBId++ )
289    {
290        UInt        uiBaseId    = uiBId;
291        TComPic*    pcBasePic   = pcSlice->getIvPic( false, uiBaseId );
292        for( Int iRefListId = 0; ( iRefListId < (pcSlice->isInterB()? 2:1) ) && !pcSlice->isIntra() && valid==0; iRefListId++ )
293        {
294            RefPicList  eRefPicListTest = RefPicList( iRefListId );
295            Int         iNumRefPics = pcSlice->getNumRefIdx( eRefPicListTest ) ;
296            for( Int iRefIndex = 0; iRefIndex < iNumRefPics; iRefIndex++ )
297            { 
298                if(pcBasePic->getPOC() == pcSlice->getRefPic( eRefPicListTest, iRefIndex )->getPOC() 
299                    && pcBasePic->getViewIndex() == pcSlice->getRefPic( eRefPicListTest, iRefIndex )->getViewIndex())
300                {
301                    valid=1;
302                    viewIndex = uiBaseId;
303                    break;
304                }
305            }
306        }
307    }
308    if( valid )
309    {
310        pcSlice->setDefaultRefViewIdx( viewIndex );
311        pcSlice->setDefaultRefViewIdxAvailableFlag( true );   
312    }
313#endif
314
315    if ( (iCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr()) && // 1st in tile.
316         (iCUAddr!=0) && (iCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())
317         && (iCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU())
318         ) // !1st in frame && !1st in slice
319    {
320      if (pcSlice->getPPS()->getNumSubstreams() > 1)
321      {
322        // We're crossing into another tile, tiles are independent.
323        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
324        // have to perform it here.
325        // For TILES_DECODER, there can be a header at the start of the 1st substream in a tile.  These are read when the substreams
326        // are extracted, not here.
327      }
328      else
329      {
330        SliceType sliceType  = pcSlice->getSliceType();
331        if (pcSlice->getCabacInitFlag())
332        {
333          switch (sliceType)
334          {
335          case P_SLICE:           // change initialization table to B_SLICE intialization
336            sliceType = B_SLICE; 
337            break;
338          case B_SLICE:           // change initialization table to P_SLICE intialization
339            sliceType = P_SLICE; 
340            break;
341          default     :           // should not occur
342            assert(0);
343          }
344        }
345        m_pcEntropyDecoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
346      }
347     
348    }
349
350#if ENC_DEC_TRACE
351    g_bJustDoIt = g_bEncDecTraceEnable;
352#endif
353
354    if ( pcSlice->getSPS()->getUseSAO() )
355      {
356      SAOBlkParam& saoblkParam = (rpcPic->getPicSym()->getSAOBlkParam())[iCUAddr];
357      if (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma())
358      {
359        Bool sliceEnabled[NUM_SAO_COMPONENTS];
360        sliceEnabled[SAO_Y] = pcSlice->getSaoEnabledFlag();
361        sliceEnabled[SAO_Cb]= sliceEnabled[SAO_Cr]= pcSlice->getSaoEnabledFlagChroma();
362
363        Bool leftMergeAvail = false;
364        Bool aboveMergeAvail= false;
365
366        //merge left condition
367        Int rx = (iCUAddr % uiWidthInLCUs);
368        if(rx > 0)
369        {
370          leftMergeAvail = rpcPic->getSAOMergeAvailability(iCUAddr, iCUAddr-1);
371        }
372        //merge up condition
373        Int ry = (iCUAddr / uiWidthInLCUs);
374        if(ry > 0)
375        {
376          aboveMergeAvail = rpcPic->getSAOMergeAvailability(iCUAddr, iCUAddr-uiWidthInLCUs);
377      }
378
379        pcSbacDecoder->parseSAOBlkParam( saoblkParam, sliceEnabled, leftMergeAvail, aboveMergeAvail);
380    }
381      else 
382        {
383        saoblkParam[SAO_Y ].modeIdc = SAO_MODE_OFF;
384        saoblkParam[SAO_Cb].modeIdc = SAO_MODE_OFF;
385        saoblkParam[SAO_Cr].modeIdc = SAO_MODE_OFF;
386      }
387    }
388    m_pcCuDecoder->decodeCU     ( pcCU, uiIsLast );
389    m_pcCuDecoder->decompressCU ( pcCU );
390   
391#if ENC_DEC_TRACE
392    g_bJustDoIt = g_bEncDecTraceDisable;
393#endif
394    pcSbacDecoders[uiSubStrm].load(pcSbacDecoder);
395
396    if ( uiCol == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getRightEdgePosInCU()
397        && pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()
398        && !uiIsLast )
399    {
400      // Parse end_of_substream_one_bit for WPP case
401      UInt binVal;
402      pcSbacDecoder->parseTerminatingBit( binVal );
403      assert( binVal );
404    }
405
406    //Store probabilities of second LCU in line into buffer
407    if ( (uiCol == uiTileLCUX+1)&& (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()) )
408    {
409      m_pcBufferSbacDecoders[uiTileCol].loadContexts( &pcSbacDecoders[uiSubStrm] );
410    }
411    if( uiIsLast && depSliceSegmentsEnabled )
412    {
413      if (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
414       {
415         CTXMem[1]->loadContexts( &m_pcBufferSbacDecoders[uiTileCol] );//ctx 2.LCU
416       }
417      CTXMem[0]->loadContexts( pcSbacDecoder );//ctx end of dep.slice
418      return;
419    }
420  }
421}
422
423ParameterSetManagerDecoder::ParameterSetManagerDecoder()
424: m_vpsBuffer(MAX_NUM_VPS)
425, m_spsBuffer(MAX_NUM_SPS)
426, m_ppsBuffer(MAX_NUM_PPS)
427{
428}
429
430ParameterSetManagerDecoder::~ParameterSetManagerDecoder()
431{
432
433}
434
435TComVPS* ParameterSetManagerDecoder::getPrefetchedVPS  (Int vpsId)
436{
437  if (m_vpsBuffer.getPS(vpsId) != NULL )
438  {
439    return m_vpsBuffer.getPS(vpsId);
440  }
441  else
442  {
443    return getVPS(vpsId);
444  }
445}
446
447
448TComSPS* ParameterSetManagerDecoder::getPrefetchedSPS  (Int spsId)
449{
450  if (m_spsBuffer.getPS(spsId) != NULL )
451  {
452    return m_spsBuffer.getPS(spsId);
453  }
454  else
455  {
456    return getSPS(spsId);
457  }
458}
459
460TComPPS* ParameterSetManagerDecoder::getPrefetchedPPS  (Int ppsId)
461{
462  if (m_ppsBuffer.getPS(ppsId) != NULL )
463  {
464    return m_ppsBuffer.getPS(ppsId);
465  }
466  else
467  {
468    return getPPS(ppsId);
469  }
470}
471
472Void     ParameterSetManagerDecoder::applyPrefetchedPS()
473{
474  m_vpsMap.mergePSList(m_vpsBuffer);
475  m_ppsMap.mergePSList(m_ppsBuffer);
476  m_spsMap.mergePSList(m_spsBuffer);
477}
478
479//! \}
Note: See TracBrowser for help on using the repository browser.