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

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

port rev 4324 (g_uiMaxDepth, g_uiAddDepth)

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