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

Last change on this file since 1537 was 1512, checked in by seregin, 10 years ago

rename isSpatialEnhLayer to requireResampling for clarity since the difference may be in bitdepth only

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