source: 3DVCSoftware/trunk/source/Lib/TLibCommon/TComPic.cpp @ 1313

Last change on this file since 1313 was 1313, checked in by tech, 9 years ago

Merged 14.1-update-dev1@1312.

  • Property svn:eol-style set to native
File size: 16.9 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#if NH_MV
57, m_bPicOutputFlag                        (false)
58#endif
59, m_uiCurrSliceIdx                        (0)
60, m_bCheckLTMSB                           (false)
61#if NH_MV
62, m_layerId                               (0)
63, m_viewId                                (0)
64#if NH_3D
65, m_viewIndex                             (0)
66, m_isDepth                               (false)
67, m_aaiCodedScale                         (0)
68, m_aaiCodedOffset                        (0)
69#endif
70#endif
71
72{
73  for(UInt i=0; i<NUM_PIC_YUV; i++)
74  {
75    m_apcPicYuv[i]      = NULL;
76  }
77#if NH_3D_QTLPC
78  m_bReduceBitsQTL    = 0;
79#endif
80#if NH_3D_NBDV
81  m_iNumDdvCandPics   = 0;
82  m_eRapRefList       = REF_PIC_LIST_0;
83  m_uiRapRefIdx       = 0;
84#endif
85}
86
87TComPic::~TComPic()
88{
89}
90
91Void TComPic::create( const TComSPS &sps, const TComPPS &pps, const Bool bIsVirtual)
92{
93  const ChromaFormat chromaFormatIDC = sps.getChromaFormatIdc();
94  const Int          iWidth          = sps.getPicWidthInLumaSamples();
95  const Int          iHeight         = sps.getPicHeightInLumaSamples();
96  const UInt         uiMaxCuWidth    = sps.getMaxCUWidth();
97  const UInt         uiMaxCuHeight   = sps.getMaxCUHeight();
98  const UInt         uiMaxDepth      = sps.getMaxTotalCUDepth();
99
100  m_picSym.create( sps, pps, uiMaxDepth );
101  if (!bIsVirtual)
102  {
103    m_apcPicYuv[PIC_YUV_ORG    ]   = new TComPicYuv;  m_apcPicYuv[PIC_YUV_ORG     ]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true );
104    m_apcPicYuv[PIC_YUV_TRUE_ORG]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_TRUE_ORG]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true );
105  }
106  m_apcPicYuv[PIC_YUV_REC]  = new TComPicYuv;  m_apcPicYuv[PIC_YUV_REC]->create( iWidth, iHeight, chromaFormatIDC, uiMaxCuWidth, uiMaxCuHeight, uiMaxDepth, true );
107
108  // there are no SEI messages associated with this picture initially
109  if (m_SEIs.size() > 0)
110  {
111    deleteSEIs (m_SEIs);
112  }
113  m_bUsedByCurr = false;
114
115#if H_3D_FCO
116/* initialize the texture to depth reference status */
117  for (int j=0; j<2; j++)
118  {
119      for (int i=0; i<MAX_NUM_REF; i++)
120      {
121          m_aiTexToDepRef[j][i] = -1;
122      }
123  }
124#endif
125
126}
127
128Void TComPic::destroy()
129{
130  m_picSym.destroy();
131
132  for(UInt i=0; i<NUM_PIC_YUV; i++)
133  {
134    if (m_apcPicYuv[i])
135    {
136      m_apcPicYuv[i]->destroy();
137      delete m_apcPicYuv[i];
138      m_apcPicYuv[i]  = NULL;
139    }
140  }
141
142  deleteSEIs(m_SEIs);
143}
144#if NH_3D
145#if NH_3D_ARP
146Void TComPic::getCUAddrAndPartIdx( Int iX, Int iY, Int& riCuAddr, Int& riAbsZorderIdx )
147{
148  Int iMaxCUWidth   = (Int) ( getPicSym()->getSPS().getMaxCUWidth()  );
149  Int iMaxCuHeight  = (Int) ( getPicSym()->getSPS().getMaxCUHeight() );
150
151  UInt uiMaxTotalCUDepth = getPicSym()->getSPS().getMaxTotalCUDepth(); 
152  Int iBaseUnitWidth  = iMaxCUWidth >> uiMaxTotalCUDepth;
153  Int iBaseUnitHeight = iMaxCUWidth >> uiMaxTotalCUDepth;
154
155  Int iNumCuInWidth   = getPicYuvRec()->getWidth(COMPONENT_Y) / iMaxCUWidth;
156  iNumCuInWidth      += ( getPicYuvRec()->getWidth(COMPONENT_Y) % iMaxCUWidth ) ? 1 : 0;
157
158
159  Int iCuX            = iX / iMaxCUWidth;
160  Int iCuY            = iY / iMaxCuHeight;
161  Int iBaseX          = ( iX - iCuX * iMaxCUWidth  ) / iBaseUnitWidth;
162  Int iBaseY          = ( iY - iCuY * iMaxCuHeight ) / iBaseUnitHeight;
163  Int iCuSizeInBases  = iMaxCuHeight                 / iBaseUnitWidth;
164
165  riCuAddr            = iCuY   * iNumCuInWidth + iCuX;
166  Int iRastPartIdx    = iBaseY * iCuSizeInBases  + iBaseX;
167  riAbsZorderIdx      = g_auiRasterToZscan[ iRastPartIdx ];
168}
169#endif
170Void TComPic::compressMotion(Int scale)
171#else
172Void TComPic::compressMotion()
173#endif
174{
175  TComPicSym* pPicSym = getPicSym();
176  for ( UInt uiCUAddr = 0; uiCUAddr < pPicSym->getNumberOfCtusInFrame(); uiCUAddr++ )
177  {
178    TComDataCU* pCtu = pPicSym->getCtu(uiCUAddr);
179#if NH_3D
180    pCtu->compressMV(scale); 
181#else
182    pCtu->compressMV();
183#endif
184   
185  }
186}
187
188Bool  TComPic::getSAOMergeAvailability(Int currAddr, Int mergeAddr)
189{
190  Bool mergeCtbInSliceSeg = (mergeAddr >= getPicSym()->getCtuTsToRsAddrMap(getCtu(currAddr)->getSlice()->getSliceCurStartCtuTsAddr()));
191  Bool mergeCtbInTile     = (getPicSym()->getTileIdxMap(mergeAddr) == getPicSym()->getTileIdxMap(currAddr));
192  return (mergeCtbInSliceSeg && mergeCtbInTile);
193}
194
195UInt TComPic::getSubstreamForCtuAddr(const UInt ctuAddr, const Bool bAddressInRaster, TComSlice *pcSlice)
196{
197  UInt subStrm;
198  const bool bWPPEnabled=pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag();
199  const TComPicSym &picSym            = *(getPicSym());
200
201  if ((bWPPEnabled && picSym.getFrameHeightInCtus()>1) || (picSym.getNumTiles()>1)) // wavefronts, and possibly tiles being used.
202  {
203    if (bWPPEnabled)
204    {
205      const UInt ctuRsAddr                = bAddressInRaster?ctuAddr : picSym.getCtuTsToRsAddrMap(ctuAddr);
206      const UInt frameWidthInCtus         = picSym.getFrameWidthInCtus();
207      const UInt tileIndex                = picSym.getTileIdxMap(ctuRsAddr);
208      const UInt numTileColumns           = (picSym.getNumTileColumnsMinus1()+1);
209      const TComTile *pTile               = picSym.getTComTile(tileIndex);
210      const UInt firstCtuRsAddrOfTile     = pTile->getFirstCtuRsAddr();
211      const UInt tileYInCtus              = firstCtuRsAddrOfTile / frameWidthInCtus;
212      // independent tiles => substreams are "per tile"
213      const UInt ctuLine                  = ctuRsAddr / frameWidthInCtus;
214      const UInt startingSubstreamForTile =(tileYInCtus*numTileColumns) + (pTile->getTileHeightInCtus()*(tileIndex%numTileColumns));
215      subStrm = startingSubstreamForTile + (ctuLine - tileYInCtus);
216    }
217    else
218    {
219      const UInt ctuRsAddr                = bAddressInRaster?ctuAddr : picSym.getCtuTsToRsAddrMap(ctuAddr);
220      const UInt tileIndex                = picSym.getTileIdxMap(ctuRsAddr);
221      subStrm=tileIndex;
222    }
223  }
224  else
225  {
226    // dependent tiles => substreams are "per frame".
227    subStrm = 0;
228  }
229  return subStrm;
230}
231
232#if NH_MV
233Void TComPic::print( Bool legend )
234{
235  if ( legend )
236    std::cout  << std::endl << "LId"        << "\t" << "POC"   << "\t" << "Rec"          << "\t" << "Ref"                       << "\t" << "LT"            <<  "\t" << "OutMark" <<  "\t" << "OutFlag" << std::endl;
237  else
238    std::cout  << getLayerId() << "\t" << getPOC()<< "\t" << getReconMark() << "\t" << getSlice(0)->isReferenced() << "\t" << getIsLongTerm() << "\t" << getOutputMark() << "\t" << getSlice(0)->getPicOutputFlag() <<std::endl;
239}
240
241TComPic* TComPicLists::getPic( Int layerIdInNuh, Int poc )
242{
243  TComPic* pcPic = NULL;
244  for(TComList<TComList<TComPic*>*>::iterator itL = m_lists.begin(); ( itL != m_lists.end() && pcPic == NULL ); itL++)
245  {   
246    for(TComList<TComPic*>::iterator itP=(*itL)->begin(); ( itP!=(*itL)->end() && pcPic == NULL ); itP++)
247    {
248      TComPic* currPic = (*itP); 
249      if ( ( currPic->getPOC() == poc ) && ( currPic->getLayerId() == layerIdInNuh ) )
250      {
251        pcPic = currPic ;     
252      }
253    }
254  }
255  return pcPic;
256}
257
258#if NH_3D
259TComPic* TComPicLists::getPic( Int viewIndex, Bool depthFlag, Int poc )
260{
261  return getPic   ( m_vps->getLayerIdInNuh( viewIndex, depthFlag ), poc );
262}
263#endif
264Void TComPicLists::print()
265{
266  Bool first = true;     
267  for(TComList<TComList<TComPic*>*>::iterator itL = m_lists.begin(); ( itL != m_lists.end() ); itL++)
268  {   
269    for(TComList<TComPic*>::iterator itP=(*itL)->begin(); ( itP!=(*itL)->end() ); itP++)
270    {
271      if ( first )
272      {
273        (*itP)->print( true );       
274        first = false; 
275      }
276      (*itP)->print( false );       
277    }
278  }
279}
280
281TComPicYuv* TComPicLists::getPicYuv( Int layerIdInNuh, Int poc, Bool reconFlag )
282{
283  TComPic*    pcPic = getPic( layerIdInNuh, poc );
284  TComPicYuv* pcPicYuv = NULL;
285
286  if (pcPic != NULL)
287  {
288    if( reconFlag )
289    {
290      if ( pcPic->getReconMark() )
291      {
292        pcPicYuv = pcPic->getPicYuvRec();
293      }
294    }
295    else
296    {
297      pcPicYuv = pcPic->getPicYuvOrg();
298    }
299  };
300
301  return pcPicYuv;
302}
303
304#if NH_3D
305TComPicYuv* TComPicLists::getPicYuv( Int viewIndex, Bool depthFlag, Int poc, Bool recon )
306{ 
307  Int layerIdInNuh = m_vps->getLayerIdInNuh( viewIndex, depthFlag ); 
308  return getPicYuv( layerIdInNuh, poc, recon );
309}
310#if NH_3D_ARP
311TComList<TComPic*>* TComPicLists::getPicList( Int layerIdInNuh )
312{
313  TComList<TComList<TComPic*>*>::iterator itL = m_lists.begin();
314  Int iLayer = 0;
315
316  assert( layerIdInNuh < m_lists.size() );
317
318  while( iLayer != layerIdInNuh )
319  {
320    itL++;
321    iLayer++;
322  }
323
324  return *itL;
325}
326#endif
327#endif
328#endif // NH_MV
329
330#if NH_3D_NBDV
331Int TComPic::getDisCandRefPictures(Int iColPOC)
332{
333  UInt       uiTempLayerCurr = 7;
334  TComSlice* currSlice       = getSlice(getCurrSliceIdx());
335  UInt       numDdvCandPics  = 0;
336
337  if(!currSlice->getEnableTMVPFlag())
338  {
339    return numDdvCandPics;
340  }
341
342  numDdvCandPics += 1;
343
344  UInt pocCurr = currSlice->getPOC();
345  UInt pocDiff = 255;
346
347  for(UInt lpNr = 0; lpNr < (currSlice->isInterB() ? 2: 1); lpNr++)
348  {
349    Bool x = lpNr ? currSlice->getColFromL0Flag() : 1 - currSlice->getColFromL0Flag();
350
351    for(UInt i = 0; i < currSlice->getNumRefIdx(RefPicList(x)); i++)
352    {
353      if(currSlice->getViewIndex() == currSlice->getRefPic((RefPicList)x, i)->getViewIndex() 
354         && (x == currSlice->getColFromL0Flag() || currSlice->getRefPOC((RefPicList)x, i) != iColPOC) && numDdvCandPics != 2)
355      {
356        TComSlice* refSlice    = currSlice->getRefPic((RefPicList)x, i)->getSlice(getCurrSliceIdx());
357        Bool       bRAP        = (refSlice->getViewIndex() && refSlice->isIRAP()) ? 1 : 0; 
358        UInt       uiTempLayer = currSlice->getRefPic((RefPicList)x, i)->getSlice(getCurrSliceIdx())->getTLayer(); 
359       
360        if(bRAP)
361        {
362          this->setRapRefIdx(i);
363          this->setRapRefList((RefPicList)x);
364          numDdvCandPics = 2;
365
366          return numDdvCandPics;
367        }
368        else if (uiTempLayerCurr > uiTempLayer) 
369        {
370           uiTempLayerCurr = uiTempLayer; 
371        }
372      }
373    }
374  }
375
376  UInt z   = -1; // GT: Added to make code compile needs to be checked!
377  UInt idx = 0;
378 
379  for(UInt lpNr = 0; lpNr < (currSlice->isInterB() ? 2 : 1); lpNr++)
380  {
381    Bool x = lpNr ? currSlice->getColFromL0Flag() : 1 - currSlice->getColFromL0Flag();
382   
383    for(UInt i = 0; i < currSlice->getNumRefIdx(RefPicList(x)); i++)
384    {
385      Int iTempPoc = currSlice->getRefPic((RefPicList)x, i)->getPOC();
386      Int iTempDiff = (iTempPoc > pocCurr) ? (iTempPoc - pocCurr) : (pocCurr - iTempPoc);
387     
388      if(currSlice->getViewIndex() == currSlice->getRefPic((RefPicList)x, i)->getViewIndex() && (x == currSlice->getColFromL0Flag() || currSlice->getRefPOC((RefPicList)x, i) != iColPOC) 
389         && currSlice->getRefPic((RefPicList)x, i)->getSlice(getCurrSliceIdx())->getTLayer() == uiTempLayerCurr && pocDiff > iTempDiff)
390      {
391        pocDiff = iTempDiff;
392        z       = x;
393        idx     = i;
394      }
395    }
396  }
397
398  if(pocDiff < 255)
399  {
400    this->setRapRefIdx(idx);
401    this->setRapRefList((RefPicList) z);
402    numDdvCandPics = 2;
403  }
404
405  return numDdvCandPics;
406}
407
408Void TComPic::checkTemporalIVRef()
409{
410  TComSlice* currSlice = getSlice(getCurrSliceIdx());
411  const Int numCandPics = this->getNumDdvCandPics();
412
413  for(Int curCandPic = 0; curCandPic < numCandPics; curCandPic++)
414  {
415    RefPicList eCurRefPicList   = REF_PIC_LIST_0 ;
416    Int        curCandPicRefIdx = 0;
417    if(curCandPic == 0) 
418    { 
419      eCurRefPicList   = RefPicList(currSlice->isInterB() ? 1 - currSlice->getColFromL0Flag() : 0);
420      curCandPicRefIdx = currSlice->getColRefIdx();
421    }
422    else                 
423    {
424      eCurRefPicList   = this->getRapRefList();
425      curCandPicRefIdx = this->getRapRefIdx();
426    }
427
428    TComPic* pcCandColPic = currSlice->getRefPic(eCurRefPicList, curCandPicRefIdx);
429    TComSlice* pcCandColSlice = pcCandColPic->getSlice(0); // currently only support single slice
430
431    if(!pcCandColSlice->isIntra())
432    {
433      for(Int iColRefDir = 0; iColRefDir < (pcCandColSlice->isInterB() ? 2 : 1); iColRefDir++)
434      {
435        for(Int iColRefIdx = 0; iColRefIdx < pcCandColSlice->getNumRefIdx((RefPicList)iColRefDir); iColRefIdx++)
436        {
437          m_abTIVRINCurrRL[curCandPic][iColRefDir][iColRefIdx] = false;
438          Int iColViewIdx    = pcCandColSlice->getViewIndex();
439          Int iColRefViewIdx = pcCandColSlice->getRefPic((RefPicList)iColRefDir, iColRefIdx)->getViewIndex();
440          if(iColViewIdx == iColRefViewIdx)
441          {
442            continue;
443          }
444
445          for(Int iCurrRefDir = 0; (iCurrRefDir < (currSlice->isInterB() ? 2 : 1)) && (m_abTIVRINCurrRL[curCandPic][iColRefDir][iColRefIdx] == false); iCurrRefDir++)
446          {
447            for(Int iCurrRefIdx = 0; iCurrRefIdx < currSlice->getNumRefIdx((RefPicList)iCurrRefDir); iCurrRefIdx++)
448            {
449              if(currSlice->getRefPic((RefPicList)iCurrRefDir, iCurrRefIdx)->getViewIndex() == iColRefViewIdx)
450              { 
451                m_abTIVRINCurrRL[curCandPic][iColRefDir][iColRefIdx] = true;
452                break;
453              }
454            }
455          }
456        }
457      }
458    }
459  }
460}
461
462Bool TComPic::isTempIVRefValid(Int currCandPic, Int iColRefDir, Int iColRefIdx)
463{
464  return m_abTIVRINCurrRL[currCandPic][iColRefDir][iColRefIdx];
465}
466
467Void TComPic::checkTextureRef()
468{
469  TComSlice* pcCurrSlice = getSlice(getCurrSliceIdx());
470  TComPic* pcTextPic = pcCurrSlice->getIvPic(0, getViewIndex());
471#if H_3D_FCO
472  if ( pcTextPic )
473  {
474#endif
475    TComSlice* pcTextSlice = pcTextPic->getSlice(0); // currently only support single slice
476
477    for(Int iTextRefDir = 0; (iTextRefDir < (pcTextSlice->isInterB() ? 2 :1) ) && !pcTextSlice->isIntra(); iTextRefDir++)
478    {
479      for(Int iTextRefIdx =0; iTextRefIdx < pcTextSlice->getNumRefIdx((RefPicList)iTextRefDir); iTextRefIdx++)
480      {
481        Int iTextRefPOC    = pcTextSlice->getRefPOC((RefPicList)iTextRefDir, iTextRefIdx);
482        Int iTextRefViewId = pcTextSlice->getRefPic((RefPicList)iTextRefDir, iTextRefIdx)->getViewIndex();
483        m_aiTexToDepRef[iTextRefDir][iTextRefIdx] = -1;
484        Int iCurrRefDir = iTextRefDir;
485
486        for(Int iCurrRefIdx = 0; (iCurrRefIdx<pcCurrSlice->getNumRefIdx((RefPicList)iCurrRefDir)) && (m_aiTexToDepRef[iTextRefDir][iTextRefIdx] < 0); iCurrRefIdx++)
487        {
488          if(pcCurrSlice->getRefPOC((RefPicList)iCurrRefDir, iCurrRefIdx ) == iTextRefPOC && 
489             pcCurrSlice->getRefPic((RefPicList)iCurrRefDir, iCurrRefIdx)->getViewIndex() == iTextRefViewId)
490          { 
491            m_aiTexToDepRef[iTextRefDir][iTextRefIdx] = iCurrRefIdx;
492          }
493        }
494      }
495    }
496#if H_3D_FCO
497  }
498#endif
499}
500
501Int TComPic::isTextRefValid(Int iTextRefDir, Int iTextRefIdx)
502{
503  return m_aiTexToDepRef[iTextRefDir][iTextRefIdx];
504}
505#endif
506
507
508//! \}
Note: See TracBrowser for help on using the repository browser.