source: SHVCSoftware/branches/SHM-upgrade/source/Lib/TLibCommon/TComPic.cpp

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

initial porting

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