source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibCommon/TComPic.cpp @ 1497

Last change on this file since 1497 was 1487, checked in by fujitsu, 9 years ago

Added support of scalable range extension profiles. Also corrected few issues such as the confWindow wrong initialization. Code is controlled by the macro SCALABLE_REXT.

  • Property svn:eol-style set to native
File size: 17.1 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-2015, 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     TComPic.cpp
35    \brief    picture class
36*/
37
38#include "TComPic.h"
39#include "SEI.h"
40
41//! \ingroup TLibCommon
42//! \{
43
44// ====================================================================================================================
45// Constructor / destructor / create / destroy
46// ====================================================================================================================
47
48TComPic::TComPic()
49: m_uiTLayer                              (0)
50, m_bUsedByCurr                           (false)
51, m_bIsLongTerm                           (false)
52, m_pcPicYuvPred                          (NULL)
53, m_pcPicYuvResi                          (NULL)
54, m_bReconstructed                        (false)
55, m_bNeededForOutput                      (false)
56, m_uiCurrSliceIdx                        (0)
57, m_bCheckLTMSB                           (false)
58#if SVC_EXTENSION
59, m_layerId( 0 )
60#endif
61{
62#if SVC_EXTENSION
63  memset( m_pcFullPelBaseRec, 0, sizeof( m_pcFullPelBaseRec ) );
64  memset( m_bSpatialEnhLayer, false, sizeof( m_bSpatialEnhLayer ) );
65  memset( m_equalPictureSizeAndOffsetFlag, false, sizeof( m_equalPictureSizeAndOffsetFlag ) );
66  memset( m_mvScalingFactor, 0, sizeof( m_mvScalingFactor ) );
67  memset( m_posScalingFactor, 0, sizeof( m_posScalingFactor ) );
68#endif
69  for(UInt i=0; i<NUM_PIC_YUV; i++)
70  {
71    m_apcPicYuv[i]      = NULL;
72  }
73}
74
75TComPic::~TComPic()
76{
77}
78#if SVC_EXTENSION
79Void TComPic::create( const TComVPS &vps, const TComSPS &sps, const TComPPS &pps, const Bool bIsVirtual, const UInt layerId )
80{
81  const ChromaFormat chromaFormatIDC = vps.getChromaFormatIdc(&sps, layerId);
82  const Int          iWidth          = vps.getPicWidthInLumaSamples(&sps, layerId);
83  const Int          iHeight         = vps.getPicHeightInLumaSamples(&sps, layerId);
84  const UInt         uiMaxCuWidth    = sps.getMaxCUWidth();
85  const UInt         uiMaxCuHeight   = sps.getMaxCUHeight();
86  const UInt         uiMaxDepth      = sps.getMaxTotalCUDepth();
87 
88  const Window& conformanceWindow = vps.getConformanceWindow( &sps, layerId );
89
90  m_layerId = layerId;
91
92  m_picSym.create( vps, sps, pps, uiMaxDepth, layerId );
93
94  if (!bIsVirtual)
95  {
96    m_apcPicYuv[PIC_YUV_ORG]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_ORG]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true, &conformanceWindow );
97    m_apcPicYuv[PIC_YUV_TRUE_ORG]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_TRUE_ORG]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true, &conformanceWindow );
98  }
99  m_apcPicYuv[PIC_YUV_REC]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_REC]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true, &conformanceWindow );
100
101  for( Int i = 0; i < MAX_LAYERS; i++ )
102  {
103    if( m_bSpatialEnhLayer[i] )
104    {
105      m_pcFullPelBaseRec[i] = new TComPicYuv;  m_pcFullPelBaseRec[i]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true, &conformanceWindow );
106    }
107  }   
108
109  // there are no SEI messages associated with this picture initially
110  if (m_SEIs.size() > 0)
111  {
112    deleteSEIs (m_SEIs);
113  }
114  m_bUsedByCurr = false;
115}
116#else
117Void TComPic::create( const TComSPS &sps, const TComPPS &pps, const Bool bIsVirtual)
118{
119  const ChromaFormat chromaFormatIDC = sps.getChromaFormatIdc();
120  const Int          iWidth          = sps.getPicWidthInLumaSamples();
121  const Int          iHeight         = sps.getPicHeightInLumaSamples();
122  const UInt         uiMaxCuWidth    = sps.getMaxCUWidth();
123  const UInt         uiMaxCuHeight   = sps.getMaxCUHeight();
124  const UInt         uiMaxDepth      = sps.getMaxTotalCUDepth();
125
126  m_picSym.create( sps, pps, uiMaxDepth );
127  if (!bIsVirtual)
128  {
129    m_apcPicYuv[PIC_YUV_ORG    ]   = new TComPicYuv;  m_apcPicYuv[PIC_YUV_ORG     ]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true );
130    m_apcPicYuv[PIC_YUV_TRUE_ORG]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_TRUE_ORG]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true );
131  }
132  m_apcPicYuv[PIC_YUV_REC]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_REC]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true );
133
134  // there are no SEI messages associated with this picture initially
135  if (m_SEIs.size() > 0)
136  {
137    deleteSEIs (m_SEIs);
138  }
139  m_bUsedByCurr = false;
140}
141#endif
142
143Void TComPic::destroy()
144{
145  m_picSym.destroy();
146
147  for(UInt i=0; i<NUM_PIC_YUV; i++)
148  {
149    if (m_apcPicYuv[i])
150    {
151      m_apcPicYuv[i]->destroy();
152      delete m_apcPicYuv[i];
153      m_apcPicYuv[i]  = NULL;
154    }
155  }
156
157  deleteSEIs(m_SEIs);
158#if SVC_EXTENSION
159  for( Int i = 0; i < MAX_LAYERS; i++ )
160  {
161    if( m_bSpatialEnhLayer[i] && m_pcFullPelBaseRec[i] )
162    {
163      m_pcFullPelBaseRec[i]->destroy();
164      delete m_pcFullPelBaseRec[i];
165      m_pcFullPelBaseRec[i]  = NULL;
166    }
167  }
168
169  for( Int comp = 0; comp < 2; comp++ )
170  {
171    if( m_mvScalingFactor[comp] )
172    {
173      delete [] m_mvScalingFactor[comp];
174      m_mvScalingFactor[comp] = NULL;
175    }
176
177    if( m_posScalingFactor[comp] )
178    {
179      delete [] m_posScalingFactor[comp];
180      m_posScalingFactor[comp] = NULL;
181    }
182  }
183#endif
184}
185
186Void TComPic::compressMotion()
187{
188  TComPicSym* pPicSym = getPicSym();
189  for ( UInt uiCUAddr = 0; uiCUAddr < pPicSym->getNumberOfCtusInFrame(); uiCUAddr++ )
190  {
191    TComDataCU* pCtu = pPicSym->getCtu(uiCUAddr);
192    pCtu->compressMV();
193  }
194}
195
196Bool  TComPic::getSAOMergeAvailability(Int currAddr, Int mergeAddr)
197{
198  Bool mergeCtbInSliceSeg = (mergeAddr >= getPicSym()->getCtuTsToRsAddrMap(getCtu(currAddr)->getSlice()->getSliceCurStartCtuTsAddr()));
199  Bool mergeCtbInTile     = (getPicSym()->getTileIdxMap(mergeAddr) == getPicSym()->getTileIdxMap(currAddr));
200  return (mergeCtbInSliceSeg && mergeCtbInTile);
201}
202
203UInt TComPic::getSubstreamForCtuAddr(const UInt ctuAddr, const Bool bAddressInRaster, TComSlice *pcSlice)
204{
205  UInt subStrm;
206  const bool bWPPEnabled=pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag();
207  const TComPicSym &picSym            = *(getPicSym());
208
209  if ((bWPPEnabled && picSym.getFrameHeightInCtus()>1) || (picSym.getNumTiles()>1)) // wavefronts, and possibly tiles being used.
210  {
211    if (bWPPEnabled)
212    {
213      const UInt ctuRsAddr                = bAddressInRaster?ctuAddr : picSym.getCtuTsToRsAddrMap(ctuAddr);
214      const UInt frameWidthInCtus         = picSym.getFrameWidthInCtus();
215      const UInt tileIndex                = picSym.getTileIdxMap(ctuRsAddr);
216      const UInt numTileColumns           = (picSym.getNumTileColumnsMinus1()+1);
217      const TComTile *pTile               = picSym.getTComTile(tileIndex);
218      const UInt firstCtuRsAddrOfTile     = pTile->getFirstCtuRsAddr();
219      const UInt tileYInCtus              = firstCtuRsAddrOfTile / frameWidthInCtus;
220      // independent tiles => substreams are "per tile"
221      const UInt ctuLine                  = ctuRsAddr / frameWidthInCtus;
222      const UInt startingSubstreamForTile =(tileYInCtus*numTileColumns) + (pTile->getTileHeightInCtus()*(tileIndex%numTileColumns));
223      subStrm = startingSubstreamForTile + (ctuLine - tileYInCtus);
224    }
225    else
226    {
227      const UInt ctuRsAddr                = bAddressInRaster?ctuAddr : picSym.getCtuTsToRsAddrMap(ctuAddr);
228      const UInt tileIndex                = picSym.getTileIdxMap(ctuRsAddr);
229      subStrm=tileIndex;
230    }
231  }
232  else
233  {
234    // dependent tiles => substreams are "per frame".
235    subStrm = 0;
236  }
237  return subStrm;
238}
239
240#if SVC_EXTENSION
241Void TComPic::createMvScalingFactor(UInt numOfILRPs)
242{
243  // picture object might be reused and hence m_mvScalingFactor[0] can be already allocated
244  if(m_mvScalingFactor[0])
245  {
246    delete m_mvScalingFactor[0];
247  }
248  m_mvScalingFactor[0] = new Int[numOfILRPs];
249
250  // picture object might be reused and hence m_mvScalingFactor[1] can be already allocated
251  if(m_mvScalingFactor[1])
252  {
253    delete m_mvScalingFactor[1];
254  }
255  m_mvScalingFactor[1] = new Int[numOfILRPs];
256}
257
258Void TComPic::createPosScalingFactor(UInt numOfILRPs)
259{
260  // picture object might be reused and hence m_posScalingFactor[0] can be already allocated
261  if(m_posScalingFactor[0])
262  {
263    delete m_posScalingFactor[0];
264  }
265  m_posScalingFactor[0] = new Int[numOfILRPs];
266
267  // picture object might be reused and hence m_posScalingFactor[1] can be already allocated
268  if(m_posScalingFactor[1])
269  {
270    delete m_posScalingFactor[1];
271  }
272  m_posScalingFactor[1] = new Int[numOfILRPs];
273}
274
275Void copyOnetoOnePicture(    // SVC_NONCOLL
276                  Pel *in,       
277                  Pel *out,     
278                  Int nCols,
279                  Int nRows, 
280                  Int fullRowWidth)
281{
282  Int rX;
283
284  for (rX = 0; rX < nRows; rX++)       
285  {
286    memcpy( out, in, sizeof(Pel) * nCols );
287    in = in + fullRowWidth;
288    out = out + fullRowWidth;
289  }
290}
291
292Void TComPic::copyUpsampledPictureYuv(TComPicYuv*   pcPicYuvIn, TComPicYuv*   pcPicYuvOut)
293{
294#if SCALABLE_REXT
295  Int upsampledRowWidthLuma = pcPicYuvOut->getStride(COMPONENT_Y); // 2 * pcPicYuvOut->getLumaMargin() + pcPicYuvOut->getWidth();
296  copyOnetoOnePicture(
297    pcPicYuvIn->getAddr(COMPONENT_Y),       
298    pcPicYuvOut->getAddr(COMPONENT_Y),     
299    pcPicYuvOut->getWidth(COMPONENT_Y), 
300    pcPicYuvOut->getHeight(COMPONENT_Y),
301    upsampledRowWidthLuma);
302
303  if(pcPicYuvOut->getChromaFormat() != CHROMA_400)
304  {
305    Int upsampledRowWidthChroma = pcPicYuvOut->getStride(COMPONENT_Cb); //2 * pcPicYuvOut->getChromaMargin() + (pcPicYuvOut->getWidth()>>1);
306
307    copyOnetoOnePicture(
308      pcPicYuvIn->getAddr(COMPONENT_Cr),       
309      pcPicYuvOut->getAddr(COMPONENT_Cr),     
310      pcPicYuvOut->getWidth(COMPONENT_Cr), 
311      pcPicYuvOut->getHeight(COMPONENT_Cr),
312      upsampledRowWidthChroma);
313    copyOnetoOnePicture(
314      pcPicYuvIn->getAddr(COMPONENT_Cb),       
315      pcPicYuvOut->getAddr(COMPONENT_Cb),     
316      pcPicYuvOut->getWidth(COMPONENT_Cb), 
317      pcPicYuvOut->getHeight(COMPONENT_Cb),
318      upsampledRowWidthChroma);
319  }
320#else
321  Int upsampledRowWidthLuma = pcPicYuvOut->getStride(COMPONENT_Y); // 2 * pcPicYuvOut->getLumaMargin() + pcPicYuvOut->getWidth();
322  Int upsampledRowWidthCroma = pcPicYuvOut->getStride(COMPONENT_Cb); //2 * pcPicYuvOut->getChromaMargin() + (pcPicYuvOut->getWidth()>>1);
323
324  copyOnetoOnePicture(
325    pcPicYuvIn->getAddr(COMPONENT_Y),       
326    pcPicYuvOut->getAddr(COMPONENT_Y),     
327    pcPicYuvOut->getWidth(COMPONENT_Y), 
328    pcPicYuvOut->getHeight(COMPONENT_Y),
329    upsampledRowWidthLuma);
330  copyOnetoOnePicture(
331    pcPicYuvIn->getAddr(COMPONENT_Cr),       
332    pcPicYuvOut->getAddr(COMPONENT_Cr),     
333    pcPicYuvOut->getWidth(COMPONENT_Y)>>1, 
334    pcPicYuvOut->getHeight(COMPONENT_Y)>>1,
335    upsampledRowWidthCroma);
336  copyOnetoOnePicture(
337    pcPicYuvIn->getAddr(COMPONENT_Cb),       
338    pcPicYuvOut->getAddr(COMPONENT_Cb),     
339    pcPicYuvOut->getWidth(COMPONENT_Y)>>1, 
340    pcPicYuvOut->getHeight(COMPONENT_Y)>>1,
341    upsampledRowWidthCroma);
342#endif
343}
344
345Void TComPic::copyUpsampledMvField(UInt refLayerIdc, Int** mvScalingFactor, Int** posScalingFactor)
346{
347  const TComSPS *sps       = getSlice(0)->getSPS();
348  const UInt uiMaxDepth    = sps->getMaxTotalCUDepth();
349  const UInt numPartitions = 1<<(uiMaxDepth<<1);
350  const UInt widthMinPU    = sps->getMaxCUWidth()  / (1<<uiMaxDepth);
351  const UInt heightMinPU   = sps->getMaxCUHeight() / (1<<uiMaxDepth);
352  const Int  unitNum       = max( 1, (Int)((16/widthMinPU)*(16/heightMinPU)) ); 
353
354  for(UInt cuIdx = 0; cuIdx < getPicSym()->getNumberOfCtusInFrame(); cuIdx++)  //each LCU
355  {
356    TComDataCU* pcCUDes = getCtu(cuIdx);
357
358    for(UInt absPartIdx = 0; absPartIdx < numPartitions; absPartIdx+=unitNum )  //each 16x16 unit
359    {
360      //pixel position of each unit in up-sampled layer
361      UInt pelX = pcCUDes->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[absPartIdx] ];
362      UInt pelY = pcCUDes->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[absPartIdx] ];
363      UInt baseCUAddr, baseAbsPartIdx;
364
365      TComDataCU *pcColCU = 0;
366      pcColCU = pcCUDes->getBaseColCU(refLayerIdc, pelX, pelY, baseCUAddr, baseAbsPartIdx, posScalingFactor, true);
367
368      if( pcColCU && pcColCU->getPredictionMode(baseAbsPartIdx) == MODE_INTER )  //base layer unit not skip and invalid mode
369      {
370        for(UInt refPicList = 0; refPicList < 2; refPicList++)  //for each reference list
371        {
372          TComMvField sMvFieldBase, sMvField;
373          pcColCU->getMvField( pcColCU, baseAbsPartIdx, (RefPicList)refPicList, sMvFieldBase);
374          pcCUDes->scaleBaseMV( refLayerIdc, sMvField, sMvFieldBase, mvScalingFactor );
375
376          pcCUDes->getCUMvField((RefPicList)refPicList)->setMvField(sMvField, absPartIdx);
377          pcCUDes->setPredictionMode(absPartIdx, MODE_INTER);
378        }
379      }
380      else
381      {
382        TComMvField zeroMvField;  //zero MV and invalid reference index
383        pcCUDes->getCUMvField(REF_PIC_LIST_0)->setMvField(zeroMvField, absPartIdx);
384        pcCUDes->getCUMvField(REF_PIC_LIST_1)->setMvField(zeroMvField, absPartIdx);
385        pcCUDes->setPredictionMode(absPartIdx, MODE_INTRA);
386      }
387
388      for(UInt i = 1; i < unitNum; i++ ) 
389      {
390        pcCUDes->getCUMvField(REF_PIC_LIST_0)->setMvField(pcCUDes->getCUMvField(REF_PIC_LIST_0)->getMv(absPartIdx), pcCUDes->getCUMvField(REF_PIC_LIST_0)->getRefIdx(absPartIdx), absPartIdx + i);
391        pcCUDes->getCUMvField(REF_PIC_LIST_1)->setMvField(pcCUDes->getCUMvField(REF_PIC_LIST_1)->getMv(absPartIdx), pcCUDes->getCUMvField(REF_PIC_LIST_1)->getRefIdx(absPartIdx), absPartIdx + i);
392        pcCUDes->setPredictionMode(absPartIdx+i, pcCUDes->getPredictionMode(absPartIdx));
393      }
394    }
395    memset( pcCUDes->getPartitionSize(), SIZE_2Nx2N, sizeof(SChar)*numPartitions );
396  }
397}
398
399Void TComPic::initUpsampledMvField()
400{
401  const TComSPS *sps         = getSlice(0)->getSPS();
402  const UInt uiMaxDepth      = sps->getMaxTotalCUDepth();
403  const UInt uiNumPartitions = 1<<(uiMaxDepth<<1);
404
405  for(UInt cuIdx = 0; cuIdx < getPicSym()->getNumberOfCtusInFrame(); cuIdx++)  //each LCU
406  {
407    TComDataCU* pcCUDes = getCtu(cuIdx);
408    TComMvField zeroMvField;
409    for(UInt list = 0; list < 2; list++)  //each reference list
410    {
411      for(UInt i = 0; i < uiNumPartitions; i++ ) 
412      {
413        pcCUDes->getCUMvField(REF_PIC_LIST_0)->setMvField(zeroMvField, i);
414        pcCUDes->getCUMvField(REF_PIC_LIST_1)->setMvField(zeroMvField, i);
415        pcCUDes->setPredictionMode(i, MODE_INTRA);
416        pcCUDes->setPartitionSize(i, SIZE_2Nx2N);
417      }
418    }
419  }
420  return;
421}
422
423Bool TComPic::checkSameRefInfo()
424{
425  Bool bSameRefInfo = true;
426  TComSlice * pSlice0 = getSlice( 0 );
427  for( UInt uSliceID = getNumAllocatedSlice() - 1 ; bSameRefInfo && uSliceID > 0 ; uSliceID-- )
428  {
429    TComSlice * pSliceN = getSlice( uSliceID );
430    if( pSlice0->getSliceType() != pSliceN->getSliceType() )
431    {
432      bSameRefInfo = false;
433    }
434    else if( pSlice0->getSliceType() != I_SLICE )
435    {
436      Int nListNum = pSlice0->getSliceType() == B_SLICE ? 2 : 1;
437      for( Int nList = 0 ; nList < nListNum ; nList++ )
438      {
439        RefPicList eRefList = ( RefPicList )nList;
440        if( pSlice0->getNumRefIdx( eRefList ) == pSliceN->getNumRefIdx( eRefList ) )
441        {
442          for( Int refIdx = pSlice0->getNumRefIdx( eRefList ) - 1 ; refIdx >= 0 ; refIdx-- )
443          {
444            if( pSlice0->getRefPic( eRefList , refIdx ) != pSliceN->getRefPic( eRefList , refIdx ) )
445            {
446              bSameRefInfo = false;
447              break;
448            }
449          }
450        }
451        else
452        {
453          bSameRefInfo = false;
454          break;
455        }
456      }
457    }
458  }
459
460  return( bSameRefInfo ); 
461}
462#endif //SVC_EXTENSION
463
464//! \}
Note: See TracBrowser for help on using the repository browser.