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

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

port rev 4256

  • Property svn:eol-style set to native
File size: 14.0 KB
RevLine 
[313]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
[1029]4 * granted under this license.
[313]5 *
[1259]6 * Copyright (c) 2010-2015, ITU/ISO/IEC
[313]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)
[595]57, m_bCheckLTMSB                           (false)
58#if SVC_EXTENSION
59, m_layerId( 0 )
[540]60#endif
[313]61{
62#if SVC_EXTENSION
63  memset( m_pcFullPelBaseRec, 0, sizeof( m_pcFullPelBaseRec ) );
64  memset( m_bSpatialEnhLayer, false, sizeof( m_bSpatialEnhLayer ) );
[901]65  memset( m_equalPictureSizeAndOffsetFlag, false, sizeof( m_equalPictureSizeAndOffsetFlag ) );
[313]66#endif
[1029]67  for(UInt i=0; i<NUM_PIC_YUV; i++)
68  {
69    m_apcPicYuv[i]      = NULL;
70  }
[313]71}
72
73TComPic::~TComPic()
74{
75}
[815]76#if SVC_EXTENSION
[1235]77Void TComPic::create( const TComVPS &vps, const TComSPS &sps, const TComPPS &pps, const UInt uiMaxWidth, const UInt uiMaxHeight, const UInt uiMaxDepth, const Bool bIsVirtual, const UInt layerId )
[313]78{
[1235]79  const ChromaFormat chromaFormatIDC = vps.getChromaFormatIdc(&sps, layerId);
80  const Int iWidth  = vps.getPicWidthInLumaSamples(&sps, layerId);
81  const Int iHeight = vps.getPicHeightInLumaSamples(&sps, layerId);
82 
83  const Window& conformanceWindow = vps.getConformanceWindow( &sps, layerId );
84
85  m_picSym.create( vps, sps, pps, uiMaxWidth, uiMaxHeight, uiMaxDepth, layerId );
86
[313]87  if (!bIsVirtual)
88  {
[1029]89    m_apcPicYuv[PIC_YUV_ORG]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_ORG]->create( iWidth, iHeight, chromaFormatIDC, uiMaxWidth, uiMaxHeight, uiMaxDepth, &conformanceWindow );
90    m_apcPicYuv[PIC_YUV_TRUE_ORG]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_TRUE_ORG]->create( iWidth, iHeight, chromaFormatIDC, uiMaxWidth, uiMaxHeight, uiMaxDepth, &conformanceWindow );
[313]91  }
[1029]92  m_apcPicYuv[PIC_YUV_REC]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_REC]->create( iWidth, iHeight, chromaFormatIDC, uiMaxWidth, uiMaxHeight, uiMaxDepth, &conformanceWindow );
[313]93
94  for( Int i = 0; i < MAX_LAYERS; i++ )
95  {
96    if( m_bSpatialEnhLayer[i] )
97    {
[869]98      m_pcFullPelBaseRec[i] = new TComPicYuv;  m_pcFullPelBaseRec[i]->create( iWidth, iHeight, chromaFormatIDC, uiMaxWidth, uiMaxHeight, uiMaxDepth, &conformanceWindow );
[313]99    }
[1235]100  }   
[313]101
102  // there are no SEI messages associated with this picture initially
103  if (m_SEIs.size() > 0)
104  {
105    deleteSEIs (m_SEIs);
106  }
107  m_bUsedByCurr = false;
108}
109#else
[1235]110Void TComPic::create( const TComSPS &sps, const TComPPS &pps, const UInt uiMaxWidth, const UInt uiMaxHeight, const UInt uiMaxDepth, const Bool bIsVirtual)
[313]111{
[1235]112  const ChromaFormat chromaFormatIDC=sps.getChromaFormatIdc();
113  const Int iWidth  = sps.getPicWidthInLumaSamples();
114  const Int iHeight = sps.getPicHeightInLumaSamples();
115
116  m_picSym.create( sps, pps, uiMaxWidth, uiMaxHeight, uiMaxDepth );
[313]117  if (!bIsVirtual)
118  {
[1235]119    m_apcPicYuv[PIC_YUV_ORG    ]   = new TComPicYuv;  m_apcPicYuv[PIC_YUV_ORG     ]->create( iWidth, iHeight, chromaFormatIDC, uiMaxWidth, uiMaxHeight, uiMaxDepth );
[1029]120    m_apcPicYuv[PIC_YUV_TRUE_ORG]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_TRUE_ORG]->create( iWidth, iHeight, chromaFormatIDC, uiMaxWidth, uiMaxHeight, uiMaxDepth );
[313]121  }
[1029]122  m_apcPicYuv[PIC_YUV_REC]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_REC]->create( iWidth, iHeight, chromaFormatIDC, uiMaxWidth, uiMaxHeight, uiMaxDepth );
123
[313]124  // there are no SEI messages associated with this picture initially
125  if (m_SEIs.size() > 0)
126  {
127    deleteSEIs (m_SEIs);
128  }
129  m_bUsedByCurr = false;
130}
131#endif
132
133Void TComPic::destroy()
134{
[1235]135  m_picSym.destroy();
[1029]136
137  for(UInt i=0; i<NUM_PIC_YUV; i++)
[313]138  {
[1029]139    if (m_apcPicYuv[i])
140    {
141      m_apcPicYuv[i]->destroy();
142      delete m_apcPicYuv[i];
143      m_apcPicYuv[i]  = NULL;
144    }
[313]145  }
[1029]146
[313]147  deleteSEIs(m_SEIs);
[815]148#if SVC_EXTENSION
[313]149  for( Int i = 0; i < MAX_LAYERS; i++ )
150  {
[827]151    if( m_bSpatialEnhLayer[i] && m_pcFullPelBaseRec[i] )
[313]152    {
153      m_pcFullPelBaseRec[i]->destroy();
154      delete m_pcFullPelBaseRec[i];
155      m_pcFullPelBaseRec[i]  = NULL;
156    }
157  }
158#endif
159}
160
161Void TComPic::compressMotion()
162{
[1029]163  TComPicSym* pPicSym = getPicSym();
164  for ( UInt uiCUAddr = 0; uiCUAddr < pPicSym->getNumberOfCtusInFrame(); uiCUAddr++ )
[313]165  {
[1029]166    TComDataCU* pCtu = pPicSym->getCtu(uiCUAddr);
167    pCtu->compressMV();
168  }
[313]169}
[595]170
[540]171Bool  TComPic::getSAOMergeAvailability(Int currAddr, Int mergeAddr)
172{
[1029]173  Bool mergeCtbInSliceSeg = (mergeAddr >= getPicSym()->getCtuTsToRsAddrMap(getCtu(currAddr)->getSlice()->getSliceCurStartCtuTsAddr()));
[540]174  Bool mergeCtbInTile     = (getPicSym()->getTileIdxMap(mergeAddr) == getPicSym()->getTileIdxMap(currAddr));
175  return (mergeCtbInSliceSeg && mergeCtbInTile);
176}
[313]177
[1029]178UInt TComPic::getSubstreamForCtuAddr(const UInt ctuAddr, const Bool bAddressInRaster, TComSlice *pcSlice)
179{
180  UInt subStrm;
[1235]181  const bool bWPPEnabled=pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag();
182  const TComPicSym &picSym            = *(getPicSym());
[1029]183
[1235]184  if ((bWPPEnabled && picSym.getFrameHeightInCtus()>1) || (picSym.getNumTiles()>1)) // wavefronts, and possibly tiles being used.
[1029]185  {
[1235]186    if (bWPPEnabled)
[1029]187    {
188      const UInt ctuRsAddr                = bAddressInRaster?ctuAddr : picSym.getCtuTsToRsAddrMap(ctuAddr);
189      const UInt frameWidthInCtus         = picSym.getFrameWidthInCtus();
190      const UInt tileIndex                = picSym.getTileIdxMap(ctuRsAddr);
191      const UInt numTileColumns           = (picSym.getNumTileColumnsMinus1()+1);
192      const TComTile *pTile               = picSym.getTComTile(tileIndex);
193      const UInt firstCtuRsAddrOfTile     = pTile->getFirstCtuRsAddr();
194      const UInt tileYInCtus              = firstCtuRsAddrOfTile / frameWidthInCtus;
195      // independent tiles => substreams are "per tile"
196      const UInt ctuLine                  = ctuRsAddr / frameWidthInCtus;
197      const UInt startingSubstreamForTile =(tileYInCtus*numTileColumns) + (pTile->getTileHeightInCtus()*(tileIndex%numTileColumns));
198      subStrm = startingSubstreamForTile + (ctuLine - tileYInCtus);
199    }
200    else
201    {
202      const UInt ctuRsAddr                = bAddressInRaster?ctuAddr : picSym.getCtuTsToRsAddrMap(ctuAddr);
203      const UInt tileIndex                = picSym.getTileIdxMap(ctuRsAddr);
204      subStrm=tileIndex;
205    }
206  }
207  else
208  {
209    // dependent tiles => substreams are "per frame".
210    subStrm = 0;
211  }
212  return subStrm;
213}
214
[442]215#if SVC_EXTENSION
[313]216Void copyOnetoOnePicture(    // SVC_NONCOLL
217                  Pel *in,       
218                  Pel *out,     
219                  Int nCols,
220                  Int nRows, 
221                  Int fullRowWidth)
222{
223  Int rX;
224
225  for (rX = 0; rX < nRows; rX++)       
226  {
227    memcpy( out, in, sizeof(Pel) * nCols );
228    in = in + fullRowWidth;
229    out = out + fullRowWidth;
230  }
231}
232
233Void TComPic::copyUpsampledPictureYuv(TComPicYuv*   pcPicYuvIn, TComPicYuv*   pcPicYuvOut)
234{
[1029]235  Int upsampledRowWidthLuma = pcPicYuvOut->getStride(COMPONENT_Y); // 2 * pcPicYuvOut->getLumaMargin() + pcPicYuvOut->getWidth();
236  Int upsampledRowWidthCroma = pcPicYuvOut->getStride(COMPONENT_Cb); //2 * pcPicYuvOut->getChromaMargin() + (pcPicYuvOut->getWidth()>>1);
[313]237
238  copyOnetoOnePicture(
[1029]239    pcPicYuvIn->getAddr(COMPONENT_Y),       
240    pcPicYuvOut->getAddr(COMPONENT_Y),     
241    pcPicYuvOut->getWidth(COMPONENT_Y), 
242    pcPicYuvOut->getHeight(COMPONENT_Y),
[313]243    upsampledRowWidthLuma);
244  copyOnetoOnePicture(
[1029]245    pcPicYuvIn->getAddr(COMPONENT_Cr),       
246    pcPicYuvOut->getAddr(COMPONENT_Cr),     
247    pcPicYuvOut->getWidth(COMPONENT_Y)>>1, 
248    pcPicYuvOut->getHeight(COMPONENT_Y)>>1,
[313]249    upsampledRowWidthCroma);
250  copyOnetoOnePicture(
[1029]251    pcPicYuvIn->getAddr(COMPONENT_Cb),       
252    pcPicYuvOut->getAddr(COMPONENT_Cb),     
253    pcPicYuvOut->getWidth(COMPONENT_Y)>>1, 
254    pcPicYuvOut->getHeight(COMPONENT_Y)>>1,
[313]255    upsampledRowWidthCroma);
256}
257
258Void TComPic::copyUpsampledMvField(UInt refLayerIdc, TComPic* pcPicBase)
259{
[822]260  UInt numPartitions = 1<<(g_uiMaxCUDepth<<1);
261  UInt widthMinPU    = g_uiMaxCUWidth/(1<<g_uiMaxCUDepth);
262  UInt heightMinPU   = g_uiMaxCUHeight/(1<<g_uiMaxCUDepth);
263  Int  unitNum       = max (1, (Int)((16/widthMinPU)*(16/heightMinPU)) ); 
[313]264
[1029]265  for(UInt cuIdx = 0; cuIdx < getPicSym()->getNumberOfCtusInFrame(); cuIdx++)  //each LCU
[313]266  {
[1029]267    TComDataCU* pcCUDes = getCtu(cuIdx);
[313]268
269    for(UInt absPartIdx = 0; absPartIdx < numPartitions; absPartIdx+=unitNum )  //each 16x16 unit
270    {
271      //pixel position of each unit in up-sampled layer
272      UInt  pelX = pcCUDes->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[absPartIdx] ];
273      UInt  pelY = pcCUDes->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[absPartIdx] ];
274      UInt baseCUAddr, baseAbsPartIdx;
275
276      TComDataCU *pcColCU = 0;
[822]277      pcColCU = pcCUDes->getBaseColCU(refLayerIdc, pelX, pelY, baseCUAddr, baseAbsPartIdx, true);
[313]278
[1029]279      if( pcColCU && pcColCU->getPredictionMode(baseAbsPartIdx) == MODE_INTER )  //base layer unit not skip and invalid mode
[313]280      {
281        for(UInt refPicList = 0; refPicList < 2; refPicList++)  //for each reference list
282        {
283          TComMvField sMvFieldBase, sMvField;
284          pcColCU->getMvField( pcColCU, baseAbsPartIdx, (RefPicList)refPicList, sMvFieldBase);
285          pcCUDes->scaleBaseMV( refLayerIdc, sMvField, sMvFieldBase );
286
287          pcCUDes->getCUMvField((RefPicList)refPicList)->setMvField(sMvField, absPartIdx);
288          pcCUDes->setPredictionMode(absPartIdx, MODE_INTER);
289        }
290      }
291      else
292      {
293        TComMvField zeroMvField;  //zero MV and invalid reference index
294        pcCUDes->getCUMvField(REF_PIC_LIST_0)->setMvField(zeroMvField, absPartIdx);
295        pcCUDes->getCUMvField(REF_PIC_LIST_1)->setMvField(zeroMvField, absPartIdx);
296        pcCUDes->setPredictionMode(absPartIdx, MODE_INTRA);
297      }
298
299      for(UInt i = 1; i < unitNum; i++ ) 
300      {
301        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);
302        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);
303        pcCUDes->setPredictionMode(absPartIdx+i, pcCUDes->getPredictionMode(absPartIdx));
304      }
305    }
[822]306    memset( pcCUDes->getPartitionSize(), SIZE_2Nx2N, sizeof(Char)*numPartitions );
[313]307  }
308}
309
310Void TComPic::initUpsampledMvField()
311{
312  UInt uiNumPartitions   = 1<<(g_uiMaxCUDepth<<1);
313
[1029]314  for(UInt cuIdx = 0; cuIdx < getPicSym()->getNumberOfCtusInFrame(); cuIdx++)  //each LCU
[313]315  {
[1029]316    TComDataCU* pcCUDes = getCtu(cuIdx);
[313]317    TComMvField zeroMvField;
318    for(UInt list = 0; list < 2; list++)  //each reference list
319    {
320      for(UInt i = 0; i < uiNumPartitions; i++ ) 
321      {
322        pcCUDes->getCUMvField(REF_PIC_LIST_0)->setMvField(zeroMvField, i);
323        pcCUDes->getCUMvField(REF_PIC_LIST_1)->setMvField(zeroMvField, i);
324        pcCUDes->setPredictionMode(i, MODE_INTRA);
325        pcCUDes->setPartitionSize(i, SIZE_2Nx2N);
326      }
327    }
328  }
329  return;
330}
331
[494]332Bool TComPic::checkSameRefInfo()
333{
334  Bool bSameRefInfo = true;
335  TComSlice * pSlice0 = getSlice( 0 );
336  for( UInt uSliceID = getNumAllocatedSlice() - 1 ; bSameRefInfo && uSliceID > 0 ; uSliceID-- )
337  {
338    TComSlice * pSliceN = getSlice( uSliceID );
339    if( pSlice0->getSliceType() != pSliceN->getSliceType() )
340    {
341      bSameRefInfo = false;
342    }
343    else if( pSlice0->getSliceType() != I_SLICE )
344    {
345      Int nListNum = pSlice0->getSliceType() == B_SLICE ? 2 : 1;
346      for( Int nList = 0 ; nList < nListNum ; nList++ )
347      {
348        RefPicList eRefList = ( RefPicList )nList;
349        if( pSlice0->getNumRefIdx( eRefList ) == pSliceN->getNumRefIdx( eRefList ) )
350        {
351          for( Int refIdx = pSlice0->getNumRefIdx( eRefList ) - 1 ; refIdx >= 0 ; refIdx-- )
352          {
353            if( pSlice0->getRefPic( eRefList , refIdx ) != pSliceN->getRefPic( eRefList , refIdx ) )
354            {
355              bSameRefInfo = false;
356              break;
357            }
358          }
359        }
360        else
361        {
362          bSameRefInfo = false;
363          break;
364        }
365      }
366    }
367  }
[313]368
[494]369  return( bSameRefInfo ); 
370}
[1029]371#endif //SVC_EXTENSION
[494]372
[313]373//! \}
Note: See TracBrowser for help on using the repository browser.