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

Last change on this file since 1550 was 1550, checked in by seregin, 9 years ago

port rev 4732, update copyright notice to include 2016

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