source: 3DVCSoftware/branches/HTM-DEV-0.1-dev/source/Lib/TLibCommon/TComPic.cpp @ 330

Last change on this file since 330 was 324, checked in by tech, 12 years ago

Initial development version for update to latest HM version.
Includes MV-HEVC and basic extensions for 3D-HEVC.

  • Property svn:eol-style set to native
File size: 15.1 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-2013, 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_bIsUsedAsLongTerm                     (false)
53, m_apcPicSym                             (NULL)
54, m_pcPicYuvPred                          (NULL)
55, m_pcPicYuvResi                          (NULL)
56, m_bReconstructed                        (false)
57, m_bNeededForOutput                      (false)
58, m_uiCurrSliceIdx                        (0)
59, m_pSliceSUMap                           (NULL)
60, m_pbValidSlice                          (NULL)
61, m_sliceGranularityForNDBFilter          (0)
62, m_bIndependentSliceBoundaryForNDBFilter (false)
63, m_bIndependentTileBoundaryForNDBFilter  (false)
64, m_pNDBFilterYuvTmp                      (NULL)
65, m_bCheckLTMSB                           (false)
66#if H_MV
67, m_layerId                               (0)
68, m_viewId                                (0)
69#if H_3D
70, m_isDepth                               (false)
71#endif
72#endif
73{
74  m_apcPicYuv[0]      = NULL;
75  m_apcPicYuv[1]      = NULL;
76}
77
78TComPic::~TComPic()
79{
80}
81
82Void TComPic::create( Int iWidth, Int iHeight, UInt uiMaxWidth, UInt uiMaxHeight, UInt uiMaxDepth, Window &conformanceWindow, Window &defaultDisplayWindow,
83                      Int *numReorderPics, Bool bIsVirtual)
84
85{
86  m_apcPicSym     = new TComPicSym;  m_apcPicSym   ->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth );
87  if (!bIsVirtual)
88  {
89    m_apcPicYuv[0]  = new TComPicYuv;  m_apcPicYuv[0]->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth );
90  }
91  m_apcPicYuv[1]  = new TComPicYuv;  m_apcPicYuv[1]->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth );
92 
93  // there are no SEI messages associated with this picture initially
94  if (m_SEIs.size() > 0)
95  {
96    deleteSEIs (m_SEIs);
97  }
98  m_bUsedByCurr = false;
99
100  /* store conformance window parameters with picture */
101  m_conformanceWindow = conformanceWindow;
102 
103  /* store display window parameters with picture */
104  m_defaultDisplayWindow = defaultDisplayWindow;
105
106  /* store number of reorder pics with picture */
107  memcpy(m_numReorderPics, numReorderPics, MAX_TLAYER*sizeof(Int));
108
109  return;
110}
111
112Void TComPic::destroy()
113{
114  if (m_apcPicSym)
115  {
116    m_apcPicSym->destroy();
117    delete m_apcPicSym;
118    m_apcPicSym = NULL;
119  }
120 
121  if (m_apcPicYuv[0])
122  {
123    m_apcPicYuv[0]->destroy();
124    delete m_apcPicYuv[0];
125    m_apcPicYuv[0]  = NULL;
126  }
127 
128  if (m_apcPicYuv[1])
129  {
130    m_apcPicYuv[1]->destroy();
131    delete m_apcPicYuv[1];
132    m_apcPicYuv[1]  = NULL;
133  }
134 
135  deleteSEIs(m_SEIs);
136}
137
138Void TComPic::compressMotion()
139{
140  TComPicSym* pPicSym = getPicSym(); 
141  for ( UInt uiCUAddr = 0; uiCUAddr < pPicSym->getFrameHeightInCU()*pPicSym->getFrameWidthInCU(); uiCUAddr++ )
142  {
143    TComDataCU* pcCU = pPicSym->getCU(uiCUAddr);
144    pcCU->compressMV(); 
145  } 
146}
147
148/** Create non-deblocked filter information
149 * \param pSliceStartAddress array for storing slice start addresses
150 * \param numSlices number of slices in picture
151 * \param sliceGranularityDepth slice granularity
152 * \param bNDBFilterCrossSliceBoundary cross-slice-boundary in-loop filtering; true for "cross".
153 * \param numTiles number of tiles in picture
154 * \param bNDBFilterCrossTileBoundary cross-tile-boundary in-loop filtering; true for "cross".
155 */
156Void TComPic::createNonDBFilterInfo(std::vector<Int> sliceStartAddress, Int sliceGranularityDepth
157                                    ,std::vector<Bool>* LFCrossSliceBoundary
158                                    ,Int numTiles
159                                    ,Bool bNDBFilterCrossTileBoundary)
160{
161  UInt maxNumSUInLCU = getNumPartInCU();
162  UInt numLCUInPic   = getNumCUsInFrame();
163  UInt picWidth      = getSlice(0)->getSPS()->getPicWidthInLumaSamples();
164  UInt picHeight     = getSlice(0)->getSPS()->getPicHeightInLumaSamples();
165  Int  numLCUsInPicWidth = getFrameWidthInCU();
166  Int  numLCUsInPicHeight= getFrameHeightInCU();
167  UInt maxNumSUInLCUWidth = getNumPartInWidth();
168  UInt maxNumSUInLCUHeight= getNumPartInHeight();
169  Int  numSlices = (Int) sliceStartAddress.size() - 1;
170  m_bIndependentSliceBoundaryForNDBFilter = false;
171  if(numSlices > 1)
172  {
173    for(Int s=0; s< numSlices; s++)
174    {
175      if((*LFCrossSliceBoundary)[s] == false)
176      {
177        m_bIndependentSliceBoundaryForNDBFilter = true;
178      }
179    }
180  }
181  m_sliceGranularityForNDBFilter = sliceGranularityDepth;
182  m_bIndependentTileBoundaryForNDBFilter  = (bNDBFilterCrossTileBoundary)?(false) :((numTiles > 1)?(true):(false));
183
184  m_pbValidSlice = new Bool[numSlices];
185  for(Int s=0; s< numSlices; s++)
186  {
187    m_pbValidSlice[s] = true;
188  }
189  m_pSliceSUMap = new Int[maxNumSUInLCU * numLCUInPic];
190
191  //initialization
192  for(UInt i=0; i< (maxNumSUInLCU * numLCUInPic); i++ )
193  {
194    m_pSliceSUMap[i] = -1;
195  }
196  for( UInt CUAddr = 0; CUAddr < numLCUInPic ; CUAddr++ )
197  {
198    TComDataCU* pcCU = getCU( CUAddr );
199    pcCU->setSliceSUMap(m_pSliceSUMap + (CUAddr* maxNumSUInLCU)); 
200    pcCU->getNDBFilterBlocks()->clear();
201  }
202  m_vSliceCUDataLink.clear();
203
204  m_vSliceCUDataLink.resize(numSlices);
205
206  UInt startAddr, endAddr, firstCUInStartLCU, startLCU, endLCU, lastCUInEndLCU, uiAddr;
207  UInt LPelX, TPelY, LCUX, LCUY;
208  UInt currSU;
209  UInt startSU, endSU;
210
211  for(Int s=0; s< numSlices; s++)
212  {
213    //1st step: decide the real start address
214    startAddr = sliceStartAddress[s];
215    endAddr   = sliceStartAddress[s+1] -1;
216
217    startLCU            = startAddr / maxNumSUInLCU;
218    firstCUInStartLCU   = startAddr % maxNumSUInLCU;
219
220    endLCU              = endAddr   / maxNumSUInLCU;
221    lastCUInEndLCU      = endAddr   % maxNumSUInLCU;   
222
223    uiAddr = m_apcPicSym->getCUOrderMap(startLCU);
224
225    LCUX      = getCU(uiAddr)->getCUPelX();
226    LCUY      = getCU(uiAddr)->getCUPelY();
227    LPelX     = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[firstCUInStartLCU] ];
228    TPelY     = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[firstCUInStartLCU] ];
229    currSU    = firstCUInStartLCU;
230
231    Bool bMoveToNextLCU = false;
232    Bool bSliceInOneLCU = (startLCU == endLCU);
233
234    while(!( LPelX < picWidth ) || !( TPelY < picHeight ))
235    {
236      currSU ++;
237
238      if(bSliceInOneLCU)
239      {
240        if(currSU > lastCUInEndLCU)
241        {
242          m_pbValidSlice[s] = false;
243          break;
244        }
245      }
246
247      if(currSU >= maxNumSUInLCU )
248      {
249        bMoveToNextLCU = true;
250        break;
251      }
252
253      LPelX = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[currSU] ];
254      TPelY = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[currSU] ];
255
256    }
257
258
259    if(!m_pbValidSlice[s])
260    {
261      continue;
262    }
263
264    if(currSU != firstCUInStartLCU)
265    {
266      if(!bMoveToNextLCU)
267      {
268        firstCUInStartLCU = currSU;
269      }
270      else
271      {
272        startLCU++;
273        firstCUInStartLCU = 0;
274        assert( startLCU < getNumCUsInFrame());
275      }
276      assert(startLCU*maxNumSUInLCU + firstCUInStartLCU < endAddr);
277    }
278
279
280    //2nd step: assign NonDBFilterInfo to each processing block
281    for(UInt i= startLCU; i <= endLCU; i++)
282    {
283      startSU = (i == startLCU)?(firstCUInStartLCU):(0);
284      endSU   = (i == endLCU  )?(lastCUInEndLCU   ):(maxNumSUInLCU -1);
285
286      uiAddr = m_apcPicSym->getCUOrderMap(i);
287      Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr);
288
289      TComDataCU* pcCU = getCU(uiAddr);
290      m_vSliceCUDataLink[s].push_back(pcCU);
291
292      createNonDBFilterInfoLCU(iTileID, s, pcCU, startSU, endSU, m_sliceGranularityForNDBFilter, picWidth, picHeight);
293    }
294  }
295
296  //step 3: border availability
297  for(Int s=0; s< numSlices; s++)
298  {
299    if(!m_pbValidSlice[s])
300    {
301      continue;
302    }
303
304    for(Int i=0; i< m_vSliceCUDataLink[s].size(); i++)
305    {
306      TComDataCU* pcCU = m_vSliceCUDataLink[s][i];
307      uiAddr = pcCU->getAddr();
308
309      if(pcCU->getPic()==0)
310      {
311        continue;
312      }
313      Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr);
314      Bool bTopTileBoundary = false, bDownTileBoundary= false, bLeftTileBoundary= false, bRightTileBoundary= false;
315
316      if(m_bIndependentTileBoundaryForNDBFilter)
317      {
318        //left
319        if( uiAddr % numLCUsInPicWidth != 0)
320        {
321          bLeftTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr -1) != iTileID )?true:false;
322        }
323        //right
324        if( (uiAddr % numLCUsInPicWidth) != (numLCUsInPicWidth -1) )
325        {
326          bRightTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr +1) != iTileID)?true:false;
327        }
328        //top
329        if( uiAddr >= numLCUsInPicWidth)
330        {
331          bTopTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr - numLCUsInPicWidth) !=  iTileID )?true:false;
332        }
333        //down
334        if( uiAddr + numLCUsInPicWidth < numLCUInPic )
335        {
336          bDownTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr + numLCUsInPicWidth) != iTileID)?true:false;
337        }
338
339      }
340
341      pcCU->setNDBFilterBlockBorderAvailability(numLCUsInPicWidth, numLCUsInPicHeight, maxNumSUInLCUWidth, maxNumSUInLCUHeight,picWidth, picHeight
342        , *LFCrossSliceBoundary
343        ,bTopTileBoundary, bDownTileBoundary, bLeftTileBoundary, bRightTileBoundary
344        ,m_bIndependentTileBoundaryForNDBFilter);
345
346    }
347
348  }
349
350  if( m_bIndependentSliceBoundaryForNDBFilter || m_bIndependentTileBoundaryForNDBFilter)
351  {
352    m_pNDBFilterYuvTmp = new TComPicYuv();
353    m_pNDBFilterYuvTmp->create(picWidth, picHeight, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);
354  }
355
356}
357
358/** Create non-deblocked filter information for LCU
359 * \param tileID tile index
360 * \param sliceID slice index
361 * \param pcCU CU data pointer
362 * \param startSU start SU index in LCU
363 * \param endSU end SU index in LCU
364 * \param sliceGranularyDepth slice granularity
365 * \param picWidth picture width
366 * \param picHeight picture height
367 */
368Void TComPic::createNonDBFilterInfoLCU(Int tileID, Int sliceID, TComDataCU* pcCU, UInt startSU, UInt endSU, Int sliceGranularyDepth, UInt picWidth, UInt picHeight)
369{
370  UInt LCUX          = pcCU->getCUPelX();
371  UInt LCUY          = pcCU->getCUPelY();
372  Int* pCUSliceMap    = pcCU->getSliceSUMap();
373  UInt maxNumSUInLCU = getNumPartInCU();
374  UInt maxNumSUInSGU = maxNumSUInLCU >> (sliceGranularyDepth << 1);
375  UInt maxNumSUInLCUWidth = getNumPartInWidth();
376  UInt LPelX, TPelY;
377  UInt currSU;
378
379
380  //get the number of valid NBFilterBLock
381  currSU   = startSU;
382  while(currSU <= endSU)
383  {
384    LPelX = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[currSU] ];
385    TPelY = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[currSU] ];
386
387    while(!( LPelX < picWidth ) || !( TPelY < picHeight ))
388    {
389      currSU += maxNumSUInSGU;
390      if(currSU >= maxNumSUInLCU || currSU > endSU)
391      {
392        break;
393      }
394      LPelX = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[currSU] ];
395      TPelY = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[currSU] ];
396    }
397
398    if(currSU >= maxNumSUInLCU || currSU > endSU)
399    {
400      break;
401    }
402
403    NDBFBlockInfo NDBFBlock;
404
405    NDBFBlock.tileID  = tileID;
406    NDBFBlock.sliceID = sliceID;
407    NDBFBlock.posY    = TPelY;
408    NDBFBlock.posX    = LPelX;
409    NDBFBlock.startSU = currSU;
410
411    UInt uiLastValidSU  = currSU;
412    UInt uiIdx, uiLPelX_su, uiTPelY_su;
413    for(uiIdx = currSU; uiIdx < currSU + maxNumSUInSGU; uiIdx++)
414    {
415      if(uiIdx > endSU)
416      {
417        break;       
418      }
419      uiLPelX_su   = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[uiIdx] ];
420      uiTPelY_su   = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[uiIdx] ];
421      if( !(uiLPelX_su < picWidth ) || !( uiTPelY_su < picHeight ))
422      {
423        continue;
424      }
425      pCUSliceMap[uiIdx] = sliceID;
426      uiLastValidSU = uiIdx;
427    }
428    NDBFBlock.endSU = uiLastValidSU;
429
430    UInt rTLSU = g_auiZscanToRaster[ NDBFBlock.startSU ];
431    UInt rBRSU = g_auiZscanToRaster[ NDBFBlock.endSU   ];
432    NDBFBlock.widthSU  = (rBRSU % maxNumSUInLCUWidth) - (rTLSU % maxNumSUInLCUWidth)+ 1;
433    NDBFBlock.heightSU = (UInt)(rBRSU / maxNumSUInLCUWidth) - (UInt)(rTLSU / maxNumSUInLCUWidth)+ 1;
434    NDBFBlock.width    = NDBFBlock.widthSU  * getMinCUWidth();
435    NDBFBlock.height   = NDBFBlock.heightSU * getMinCUHeight();
436
437    pcCU->getNDBFilterBlocks()->push_back(NDBFBlock);
438
439    currSU += maxNumSUInSGU;
440  }
441
442}
443
444/** destroy non-deblocked filter information for LCU
445 */
446Void TComPic::destroyNonDBFilterInfo()
447{
448  if(m_pbValidSlice != NULL)
449  {
450    delete[] m_pbValidSlice;
451    m_pbValidSlice = NULL;
452  }
453
454  if(m_pSliceSUMap != NULL)
455  {
456    delete[] m_pSliceSUMap;
457    m_pSliceSUMap = NULL;
458  }
459  for( UInt CUAddr = 0; CUAddr < getNumCUsInFrame() ; CUAddr++ )
460  {
461    TComDataCU* pcCU = getCU( CUAddr );
462    pcCU->getNDBFilterBlocks()->clear();
463  }
464
465  if( m_bIndependentSliceBoundaryForNDBFilter || m_bIndependentTileBoundaryForNDBFilter)
466  {
467    m_pNDBFilterYuvTmp->destroy();
468    delete m_pNDBFilterYuvTmp;
469    m_pNDBFilterYuvTmp = NULL;
470  }
471
472}
473#if H_MV
474Void TComPic::print( Bool legend )
475{
476  if ( legend )
477    std::cout  << "LId"        << "\t" << "POC"   << "\t" << "Rec"          << "\t" << "Ref"                       << "\t" << "LT"            << std::endl;
478  else
479    std::cout  << getLayerId() << "\t" << getPOC()<< "\t" << getReconMark() << "\t" << getSlice(0)->isReferenced() << "\t" << getIsLongTerm() << std::endl;
480}
481#endif
482
483//! \}
Note: See TracBrowser for help on using the repository browser.