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

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

port rev 4323 (g_uiMaxCUWidth, g_uiMaxCUHeight)

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