Ticket #42: TDecTop.cpp

File TDecTop.cpp, 11.9 KB (added by anonymous, 14 years ago)
Line 
1/* ====================================================================================================================
2
3  The copyright in this software is being made available under the License included below.
4  This software may be subject to other third party and   contributor rights, including patent rights, and no such
5  rights are granted under this license.
6
7  Copyright (c) 2010, SAMSUNG ELECTRONICS CO., LTD. and BRITISH BROADCASTING CORPORATION
8  All rights reserved.
9
10  Redistribution and use in source and binary forms, with or without modification, are permitted only for
11  the purpose of developing standards within the Joint Collaborative Team on Video Coding and for testing and
12  promoting such standards. The following conditions are required to be met:
13
14    * Redistributions of source code must retain the above copyright notice, this list of conditions and
15      the following disclaimer.
16    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
17      the following disclaimer in the documentation and/or other materials provided with the distribution.
18    * Neither the name of SAMSUNG ELECTRONICS CO., LTD. nor the name of the BRITISH BROADCASTING CORPORATION
19      may be used to endorse or promote products derived from this software without specific prior written permission.
20
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
22  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 * ====================================================================================================================
30*/
31
32/** \file     TDecTop.cpp
33    \brief    decoder class
34*/
35
36#include "TDecTop.h"
37
38TDecTop::TDecTop()
39{
40  m_iGopSize      = 0;
41  m_bGopSizeSet   = false;
42  m_iMaxRefPicNum = 0;
43  m_uiValidPS = 0;
44#if HHI_RQT
45#if ENC_DEC_TRACE
46  g_hTrace = fopen( "TraceDec.txt", "wb" );
47  g_bJustDoIt = g_bEncDecTraceDisable;
48  g_nSymbolCounter = 0;
49#endif
50#endif
51}
52
53TDecTop::~TDecTop()
54{
55#if HHI_RQT
56#if ENC_DEC_TRACE
57  fclose( g_hTrace );
58#endif
59#endif
60}
61
62Void TDecTop::create()
63{
64  m_cGopDecoder.create();
65  m_apcSlicePilot = new TComSlice;
66}
67
68Void TDecTop::destroy()
69{
70  m_cGopDecoder.destroy();
71
72  delete m_apcSlicePilot;
73  m_apcSlicePilot = NULL;
74
75  m_cSliceDecoder.destroy();
76}
77
78Void TDecTop::init()
79{
80  // initialize ROM
81  initROM();
82
83  m_cGopDecoder.  init( &m_cEntropyDecoder, &m_cSbacDecoder, &m_cBinCABAC, &m_cBinMultiCABAC, &m_cBinPIPE, &m_cBinMultiPIPE, &m_cBinV2VwLB, &m_cCavlcDecoder, &m_cSliceDecoder, &m_cLoopFilter, &m_cAdaptiveLoopFilter );
84  m_cSliceDecoder.init( &m_cEntropyDecoder, &m_cCuDecoder );
85  m_cEntropyDecoder.init(&m_cPrediction);
86}
87
88Void TDecTop::deletePicBuffer ( )
89{
90  TComList<TComPic*>::iterator  iterPic   = m_cListPic.begin();
91  Int iSize = Int( m_cListPic.size() );
92
93  for (Int i = 0; i < iSize; i++ )
94  {
95    TComPic* pcPic = *(iterPic++);
96    pcPic->destroy();
97
98    delete pcPic;
99    pcPic = NULL;
100  }
101
102  // destroy ALF temporary buffers
103  m_cAdaptiveLoopFilter.destroy();
104
105#if HHI_DEBLOCKING_FILTER || TENTM_DEBLOCKING_FILTER
106  m_cLoopFilter.        destroy();
107#endif
108
109  // destroy ROM
110  destroyROM();
111}
112
113Void TDecTop::xUpdateGopSize (TComSlice* pcSlice)
114{
115  if ( !pcSlice->isIntra() && !m_bGopSizeSet)
116  {
117    m_iGopSize    = pcSlice->getPOC();
118    m_bGopSizeSet = true;
119
120    m_cGopDecoder.setGopSize(m_iGopSize);
121  }
122}
123
124Void TDecTop::xGetNewPicBuffer ( TComSlice* pcSlice, TComPic*& rpcPic )
125{
126  xUpdateGopSize(pcSlice);
127
128  m_iMaxRefPicNum = Max(m_iMaxRefPicNum, Max(Max(2, pcSlice->getNumRefIdx(REF_PIC_LIST_0)+1), m_iGopSize/2 + 2 + pcSlice->getNumRefIdx(REF_PIC_LIST_0)));
129
130  if (m_cListPic.size() < (UInt)m_iMaxRefPicNum)
131  {
132    rpcPic = new TComPic;
133
134    rpcPic->create ( pcSlice->getSPS()->getWidth(), pcSlice->getSPS()->getHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, true);
135    m_cListPic.pushBack( rpcPic );
136
137    return;
138  }
139
140  Bool bBufferIsAvailable = false;
141  TComList<TComPic*>::iterator  iterPic   = m_cListPic.begin();
142  while (iterPic != m_cListPic.end())
143  {
144    rpcPic = *(iterPic++);
145    if ( rpcPic->getReconMark() == false )
146    {
147      bBufferIsAvailable = true;
148      break;
149    }
150  }
151
152  if ( !bBufferIsAvailable )
153  {
154    pcSlice->sortPicList(m_cListPic);
155    iterPic = m_cListPic.begin();
156    rpcPic = *(iterPic);
157    rpcPic->setReconMark(false);
158
159    // mark it should be extended
160    rpcPic->getPicYuvRec()->setBorderExtension(false);
161
162#if HHI_INTERP_FILTER
163    rpcPic->getPicYuvRecFilt()->setBorderExtension(false);
164#endif
165  }
166}
167
168Void TDecTop::decode (Bool bEos, TComBitstream* pcBitstream, UInt& ruiPOC, TComList<TComPic*>*& rpcListPic)
169{
170  rpcListPic = NULL;
171  TComPic*    pcPic = NULL;
172  TComPic*    pcOrgRefList[2][MAX_REF_PIC_NUM];
173
174  // Initialize entropy decoder
175  m_cEntropyDecoder.setEntropyDecoder (&m_cCavlcDecoder);
176  m_cEntropyDecoder.setBitstream      (pcBitstream);
177
178#if HHI_NAL_UNIT_SYNTAX
179  // don't feel like adding the whole chain of interface crap just to access the first byte in the buffer
180  const UChar* pucBuffer = reinterpret_cast<const UChar*>(pcBitstream->getStartStream());
181  const NalUnitType eNalUnitType = NalUnitType(pucBuffer[0]&31); 
182  const bool bDecodeSPS   = ( NAL_UNIT_SPS == eNalUnitType );
183  const bool bDecodePPS   = ( NAL_UNIT_PPS == eNalUnitType );
184  const bool bDecodeSlice = ( NAL_UNIT_CODED_SLICE == eNalUnitType );
185#else
186  const bool bDecodeSlice = true;
187  bool bDecodeSPS   = false;
188  bool bDecodePPS   = false;
189  if( 0 == m_uiValidPS )
190  {
191    bDecodeSPS = bDecodePPS = true;
192  }
193#endif
194
195  if( bDecodeSPS )
196  {
197    m_cEntropyDecoder.decodeSPS( &m_cSPS );
198
199    Int i;
200    for (i = 0; i < m_cSPS.getMaxCUDepth() - 1; i++)
201    {
202      m_cSPS.setAMPAcc( i, m_cSPS.getUseAMP() );
203    }
204
205    for (i = m_cSPS.getMaxCUDepth() - 1; i < m_cSPS.getMaxCUDepth(); i++)
206    {
207      m_cSPS.setAMPAcc( i, 0 );
208    }
209
210    // initialize DIF
211    m_cPrediction.setDIFTap ( m_cSPS.getDIFTap () );
212
213    // create ALF temporary buffer
214    m_cAdaptiveLoopFilter.create( m_cSPS.getWidth(), m_cSPS.getHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
215
216#if HHI_DEBLOCKING_FILTER || TENTM_DEBLOCKING_FILTER
217    m_cLoopFilter.        create( g_uiMaxCUDepth );
218#endif
219    m_uiValidPS |= 1;
220  }
221
222  if( bDecodePPS )
223  {
224    m_cEntropyDecoder.decodePPS( &m_cPPS );
225    m_uiValidPS |= 2;
226  }
227
228  if( false == bDecodeSlice )
229  {
230    return;
231  }
232
233  // make sure we already received both parameter sets
234  assert( 3 == m_uiValidPS );
235
236  m_apcSlicePilot->initSlice();
237
238  //  Read slice header
239  m_apcSlicePilot->setSPS( &m_cSPS );
240  m_apcSlicePilot->setPPS( &m_cPPS );
241  m_cEntropyDecoder.decodeSliceHeader (m_apcSlicePilot);
242#ifdef QC_SIFO
243  if( m_apcSlicePilot->getUseSIFO() )
244  {
245    m_cSliceDecoder.initSIFOFilters(m_cSPS.getDIFTap(),&m_cPrediction);
246    m_cEntropyDecoder.decodeSwitched_Filters(m_apcSlicePilot, &m_cPrediction);
247  }
248#endif
249
250  // Buffer initialize for prediction.
251  m_cPrediction.initTempBuff();
252#ifdef EDGE_BASED_PREDICTION
253  //Initialise edge based prediction for the current slice
254  m_cPrediction.getEdgeBasedPred()->setEdgePredictionEnable(m_apcSlicePilot->getEdgePredictionEnable());
255  m_cPrediction.getEdgeBasedPred()->setThreshold(m_apcSlicePilot->getEdgeDetectionThreshold());
256#endif //EDGE_BASED_PREDICTION
257  //  Get a new picture buffer
258  xGetNewPicBuffer (m_apcSlicePilot, pcPic);
259
260  // Recursive structure
261  m_cCuDecoder.create ( g_uiMaxCUDepth, g_uiMaxCUWidth, g_uiMaxCUHeight );
262  m_cCuDecoder.init   ( &m_cEntropyDecoder, &m_cTrQuant, &m_cPrediction );
263#if HHI_ALLOW_ROT_SWITCH
264  m_cTrQuant.init     ( g_uiMaxCUWidth, g_uiMaxCUHeight, m_apcSlicePilot->getSPS()->getMaxTrSize(), m_apcSlicePilot->getSPS()->getUseROT() );
265#else
266  m_cTrQuant.init     ( g_uiMaxCUWidth, g_uiMaxCUHeight, m_apcSlicePilot->getSPS()->getMaxTrSize() );
267#endif
268
269  m_cSliceDecoder.create( m_apcSlicePilot, m_apcSlicePilot->getSPS()->getWidth(), m_apcSlicePilot->getSPS()->getHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
270
271  //  Set picture slice pointer
272  TComSlice*  pcSlice = m_apcSlicePilot;
273  m_apcSlicePilot = pcPic->getPicSym()->getSlice();
274  pcPic->getPicSym()->setSlice(pcSlice);
275
276  // Set reference list
277  pcSlice->setRefPicList( m_cListPic );
278
279  // HierP + GPB case
280  if ( m_cSPS.getUseLDC() && pcSlice->isInterB() )
281  {
282    Int iNumRefIdx = pcSlice->getNumRefIdx(REF_PIC_LIST_0);
283    pcSlice->setNumRefIdx( REF_PIC_LIST_1, iNumRefIdx );
284
285    for (Int iRefIdx = 0; iRefIdx < iNumRefIdx; iRefIdx++)
286    {
287      pcSlice->setRefPic(pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx), REF_PIC_LIST_1, iRefIdx);
288    }
289  }
290
291  // For generalized B
292  // note: maybe not existed case (always L0 is copied to L1 if L1 is empty)
293  if (pcSlice->isInterB() && pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0)
294  {
295    Int iNumRefIdx = pcSlice->getNumRefIdx(REF_PIC_LIST_0);
296    pcSlice->setNumRefIdx        ( REF_PIC_LIST_1, iNumRefIdx );
297
298    for (Int iRefIdx = 0; iRefIdx < iNumRefIdx; iRefIdx++)
299    {
300      pcSlice->setRefPic(pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx), REF_PIC_LIST_1, iRefIdx);
301    }
302  }
303
304  // quality-based reference reordering (QBO)
305  if ( !pcSlice->isIntra() && pcSlice->getSPS()->getUseQBO() )
306  {
307    Int iMinIdx = 0, iMinQP, iRefIdx, iCnt;
308    TComPic* pRef;
309
310    // save original reference list & generate new reference list
311    for ( Int iList = 0; iList < 2; iList++ )
312    {
313      iMinQP = pcSlice->getSliceQp();
314
315      Int iNumRefIdx = pcSlice->getNumRefIdx( (RefPicList)iList );
316      for ( iRefIdx = 0; iRefIdx < iNumRefIdx; iRefIdx++ )
317      {
318        pRef = pcSlice->getRefPic( (RefPicList)iList, iRefIdx );
319        pcOrgRefList[ (RefPicList)iList ][ iRefIdx ] = pRef;
320      }
321      for ( iRefIdx = 0; iRefIdx < iNumRefIdx; iRefIdx++ )
322      {
323        pRef = pcSlice->getRefPic( (RefPicList)iList, iRefIdx );
324        if ( pRef->getSlice()->getSliceQp() <= iMinQP )
325        {
326          iMinIdx = iRefIdx;
327          break;
328        }
329      }
330
331      // set highest quality reference to zero index
332      pcSlice->setRefPic( pcOrgRefList[ (RefPicList)iList ][ iMinIdx ], (RefPicList)iList, 0 );
333
334      iCnt = 1;
335      for ( iRefIdx = 0; iRefIdx < iNumRefIdx; iRefIdx++ )
336      {
337        if ( iRefIdx == iMinIdx ) continue;
338        pcSlice->setRefPic( pcOrgRefList[ (RefPicList)iList ][ iRefIdx ], (RefPicList)iList, iCnt++ );
339      }
340    }
341  }
342
343  // Weighted prediction ----------------------------------------
344  m_cSliceDecoder.generateRefPicNew(pcSlice);
345
346  //---------------
347  pcSlice->setRefPOCList();
348
349  //  Decode a picture
350  m_cGopDecoder.decompressGop ( bEos, pcBitstream, pcPic );
351
352  // quality-based reference reordering (QBO)
353  if ( !pcSlice->isIntra() && pcSlice->getSPS()->getUseQBO() )
354  {
355    // restore original reference list
356    for ( Int iList = 0; iList < 2; iList++ )
357    {
358      Int iNumRefIdx = pcSlice->getNumRefIdx( (RefPicList)iList );
359      for ( Int iRefIdx = 0; iRefIdx < iNumRefIdx; iRefIdx++ )
360      {
361        pcSlice->setRefPic( pcOrgRefList[ (RefPicList)iList ][ iRefIdx ], (RefPicList)iList, iRefIdx );
362      }
363    }
364  }
365
366  pcSlice->sortPicList(m_cListPic);       //  sorting for application output
367
368  ruiPOC = pcPic->getSlice()->getPOC();
369
370  rpcListPic = &m_cListPic;
371
372  m_cCuDecoder.destroy();
373
374  return;
375}
376