source: 3DVCSoftware/trunk/source/Lib/TLibCommon/TComPicSym.cpp @ 1245

Last change on this file since 1245 was 1179, checked in by tech, 10 years ago

Merged branch 13.1-dev0@1178.

  • 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     TComPicSym.cpp
35    \brief    picture symbol class
36*/
37
38#include "TComPicSym.h"
39#include "TComSampleAdaptiveOffset.h"
40#include "TComSlice.h"
41
42//! \ingroup TLibCommon
43//! \{
44
45// ====================================================================================================================
46// Constructor / destructor / create / destroy
47// ====================================================================================================================
48
49TComPicSym::TComPicSym()
50:m_uiWidthInCU(0)
51,m_uiHeightInCU(0)
52,m_uiMaxCUWidth(0)
53,m_uiMaxCUHeight(0)
54,m_uiMinCUWidth(0)
55,m_uiMinCUHeight(0)
56,m_uhTotalDepth(0)
57,m_uiNumPartitions(0)
58,m_uiNumPartInWidth(0)
59,m_uiNumPartInHeight(0)
60,m_uiNumCUsInFrame(0)
61,m_apcTComSlice(NULL)
62,m_uiNumAllocatedSlice (0)
63,m_apcTComDataCU (NULL)
64,m_iNumColumnsMinus1 (0)
65,m_iNumRowsMinus1(0)
66,m_puiCUOrderMap(0)
67,m_puiTileIdxMap(NULL)
68,m_puiInverseCUOrderMap(NULL)
69,m_saoBlkParams(NULL)
70{};
71
72
73Void TComPicSym::create  ( Int iPicWidth, Int iPicHeight, UInt uiMaxWidth, UInt uiMaxHeight, UInt uiMaxDepth )
74{
75  UInt i;
76
77  m_uhTotalDepth      = uiMaxDepth;
78  m_uiNumPartitions   = 1<<(m_uhTotalDepth<<1);
79 
80  m_uiMaxCUWidth      = uiMaxWidth;
81  m_uiMaxCUHeight     = uiMaxHeight;
82 
83  m_uiMinCUWidth      = uiMaxWidth  >> m_uhTotalDepth;
84  m_uiMinCUHeight     = uiMaxHeight >> m_uhTotalDepth;
85 
86  m_uiNumPartInWidth  = m_uiMaxCUWidth  / m_uiMinCUWidth;
87  m_uiNumPartInHeight = m_uiMaxCUHeight / m_uiMinCUHeight;
88 
89  m_uiWidthInCU       = ( iPicWidth %m_uiMaxCUWidth  ) ? iPicWidth /m_uiMaxCUWidth  + 1 : iPicWidth /m_uiMaxCUWidth;
90  m_uiHeightInCU      = ( iPicHeight%m_uiMaxCUHeight ) ? iPicHeight/m_uiMaxCUHeight + 1 : iPicHeight/m_uiMaxCUHeight;
91 
92  m_uiNumCUsInFrame   = m_uiWidthInCU * m_uiHeightInCU;
93  m_apcTComDataCU     = new TComDataCU*[m_uiNumCUsInFrame];
94 
95  if (m_uiNumAllocatedSlice>0)
96  {
97    for ( i=0; i<m_uiNumAllocatedSlice ; i++ )
98    {
99      delete m_apcTComSlice[i];
100    }
101    delete [] m_apcTComSlice;
102  }
103  m_apcTComSlice      = new TComSlice*[m_uiNumCUsInFrame];
104  m_apcTComSlice[0]   = new TComSlice;
105  m_uiNumAllocatedSlice = 1;
106  for ( i=0; i<m_uiNumCUsInFrame ; i++ )
107  {
108    m_apcTComDataCU[i] = new TComDataCU;
109    m_apcTComDataCU[i]->create( m_uiNumPartitions, m_uiMaxCUWidth, m_uiMaxCUHeight, false, m_uiMaxCUWidth >> m_uhTotalDepth
110#if ADAPTIVE_QP_SELECTION
111      , true
112#endif     
113      );
114  }
115
116  m_puiCUOrderMap = new UInt[m_uiNumCUsInFrame+1];
117  m_puiTileIdxMap = new UInt[m_uiNumCUsInFrame];
118  m_puiInverseCUOrderMap = new UInt[m_uiNumCUsInFrame+1];
119
120  for( i=0; i<m_uiNumCUsInFrame; i++ )
121  {
122    m_puiCUOrderMap[i] = i;
123    m_puiInverseCUOrderMap[i] = i;
124  }
125
126  m_saoBlkParams = new SAOBlkParam[m_uiNumCUsInFrame];
127}
128
129Void TComPicSym::destroy()
130{
131  if (m_uiNumAllocatedSlice>0)
132  {
133    for (Int i = 0; i<m_uiNumAllocatedSlice ; i++ )
134    {
135      delete m_apcTComSlice[i];
136    }
137    delete [] m_apcTComSlice;
138  }
139  m_apcTComSlice = NULL;
140 
141  for (Int i = 0; i < m_uiNumCUsInFrame; i++)
142  {
143    m_apcTComDataCU[i]->destroy();
144    delete m_apcTComDataCU[i];
145    m_apcTComDataCU[i] = NULL;
146  }
147  delete [] m_apcTComDataCU;
148  m_apcTComDataCU = NULL;
149
150  delete [] m_puiCUOrderMap;
151  m_puiCUOrderMap = NULL;
152
153  delete [] m_puiTileIdxMap;
154  m_puiTileIdxMap = NULL;
155
156  delete [] m_puiInverseCUOrderMap;
157  m_puiInverseCUOrderMap = NULL;
158 
159  if(m_saoBlkParams)
160  {
161    delete[] m_saoBlkParams; m_saoBlkParams = NULL;
162  }
163}
164
165Void TComPicSym::allocateNewSlice()
166{
167  assert ((m_uiNumAllocatedSlice + 1) <= m_uiNumCUsInFrame);
168  m_apcTComSlice[m_uiNumAllocatedSlice ++] = new TComSlice;
169  if (m_uiNumAllocatedSlice>=2)
170  {
171    m_apcTComSlice[m_uiNumAllocatedSlice-1]->copySliceInfo( m_apcTComSlice[m_uiNumAllocatedSlice-2] );
172    m_apcTComSlice[m_uiNumAllocatedSlice-1]->initSlice();
173  }
174}
175
176Void TComPicSym::clearSliceBuffer()
177{
178  UInt i;
179  for (i = 1; i < m_uiNumAllocatedSlice; i++)
180  {
181    delete m_apcTComSlice[i];
182  }
183  m_uiNumAllocatedSlice = 1;
184}
185
186UInt TComPicSym::getPicSCUEncOrder( UInt SCUAddr )
187{ 
188  return getInverseCUOrderMap(SCUAddr/m_uiNumPartitions)*m_uiNumPartitions + SCUAddr%m_uiNumPartitions; 
189}
190
191UInt TComPicSym::getPicSCUAddr( UInt SCUEncOrder )
192{
193  return getCUOrderMap(SCUEncOrder/m_uiNumPartitions)*m_uiNumPartitions + SCUEncOrder%m_uiNumPartitions;
194}
195
196Void TComPicSym::initTiles(TComPPS *pps)
197{
198  //set NumColumnsMinus1 and NumRowsMinus1
199  setNumColumnsMinus1( pps->getNumTileColumnsMinus1() );
200  setNumRowsMinus1( pps->getTileNumRowsMinus1() );
201
202  const Int numCols = pps->getNumTileColumnsMinus1() + 1;
203  const Int numRows = pps->getTileNumRowsMinus1() + 1;
204  const Int numTiles = numRows * numCols;
205
206  // allocate memory for tile parameters
207  m_tileParameters.resize(numTiles);
208
209  if( pps->getTileUniformSpacingFlag() )
210  {
211    //set width and height for each (uniform) tile
212    for(Int row=0; row < numRows; row++)
213    {
214      for(Int col=0; col < numCols; col++)
215      {
216        const Int tileIdx = row * numCols + col;
217        m_tileParameters[tileIdx].setTileWidth( (col+1)*getFrameWidthInCU()/numCols
218                                              - (col*getFrameWidthInCU())/numCols );
219        m_tileParameters[tileIdx].setTileHeight( (row+1)*getFrameHeightInCU()/numRows
220                                               - (row*getFrameHeightInCU())/numRows );
221      }
222    }
223  }
224  else
225  {
226    //set the width for each tile
227    for(Int row=0; row < numRows; row++)
228    {
229      Int cumulativeTileWidth = 0;
230      for(Int col=0; col < getNumColumnsMinus1(); col++)
231  {
232        m_tileParameters[row * numCols + col].setTileWidth( pps->getTileColumnWidth(col) );
233        cumulativeTileWidth += pps->getTileColumnWidth(col);
234  }
235      m_tileParameters[row * numCols + getNumColumnsMinus1()].setTileWidth( getFrameWidthInCU()-cumulativeTileWidth );
236}
237
238    //set the height for each tile
239    for(Int col=0; col < numCols; col++)
240{
241      Int cumulativeTileHeight = 0;
242      for(Int row=0; row < getNumRowsMinus1(); row++)
243      {
244        m_tileParameters[row * numCols + col].setTileHeight( pps->getTileRowHeight(row) );
245        cumulativeTileHeight += pps->getTileRowHeight(row);
246      }
247      m_tileParameters[getNumRowsMinus1() * numCols + col].setTileHeight( getFrameHeightInCU()-cumulativeTileHeight );
248    }
249  }
250
251#if TILE_SIZE_CHECK
252  Int minWidth  = 1;
253  Int minHeight = 1;
254  const Int profileIdc = pps->getSPS()->getPTL()->getGeneralPTL()->getProfileIdc();
255  if (  profileIdc == Profile::MAIN || profileIdc == Profile::MAIN10)
256  {
257    if (pps->getTilesEnabledFlag())
258    {
259      minHeight = 64  / g_uiMaxCUHeight;
260      minWidth  = 256 / g_uiMaxCUWidth;
261    }
262  }
263  for(Int row=0; row < numRows; row++)
264  {
265    for(Int col=0; col < numCols; col++)
266    {
267      const Int tileIdx = row * numCols + col;
268      assert (m_tileParameters[tileIdx].getTileWidth() >= minWidth);
269      assert (m_tileParameters[tileIdx].getTileHeight() >= minHeight);
270    }
271  }
272#endif
273
274  //initialize each tile of the current picture
275  for( Int row=0; row < numRows; row++ )
276  {
277    for( Int col=0; col < numCols; col++ )
278    {
279      const Int tileIdx = row * numCols + col;
280
281      //initialize the RightEdgePosInCU for each tile
282      Int rightEdgePosInCTU = 0;
283      for( Int i=0; i <= col; i++ )
284      {
285        rightEdgePosInCTU += m_tileParameters[row * numCols + i].getTileWidth();
286      }
287      m_tileParameters[tileIdx].setRightEdgePosInCU(rightEdgePosInCTU-1);
288
289      //initialize the BottomEdgePosInCU for each tile
290      Int bottomEdgePosInCTU = 0;
291      for( Int i=0; i <= row; i++ )
292      {
293        bottomEdgePosInCTU += m_tileParameters[i * numCols + col].getTileHeight();
294      }
295      m_tileParameters[tileIdx].setBottomEdgePosInCU(bottomEdgePosInCTU-1);
296
297      //initialize the FirstCUAddr for each tile
298      m_tileParameters[tileIdx].setFirstCUAddr( (m_tileParameters[tileIdx].getBottomEdgePosInCU() - m_tileParameters[tileIdx].getTileHeight() + 1) * getFrameWidthInCU() + 
299                                                 m_tileParameters[tileIdx].getRightEdgePosInCU() - m_tileParameters[tileIdx].getTileWidth() + 1);
300    }
301  }
302
303  Int  columnIdx = 0;
304  Int  rowIdx = 0;
305
306  //initialize the TileIdxMap
307  for( Int i=0; i<m_uiNumCUsInFrame; i++)
308  {
309    for( Int col=0; col < numCols; col++)
310    {
311      if(i % getFrameWidthInCU() <= m_tileParameters[col].getRightEdgePosInCU())
312      {
313        columnIdx = col;
314        break;
315      }
316    }
317    for(Int row=0; row < numRows; row++)
318    {
319      if(i / getFrameWidthInCU() <= m_tileParameters[row*numCols].getBottomEdgePosInCU())
320      {
321        rowIdx = row;
322        break;
323      }
324    }
325    m_puiTileIdxMap[i] = rowIdx * numCols + columnIdx;
326  }
327
328}
329
330UInt TComPicSym::xCalculateNxtCUAddr( UInt uiCurrCUAddr )
331{
332  UInt  uiNxtCUAddr;
333  UInt  uiTileIdx;
334 
335  //get the tile index for the current LCU
336  uiTileIdx = this->getTileIdxMap(uiCurrCUAddr);
337
338  //get the raster scan address for the next LCU
339  if( uiCurrCUAddr % m_uiWidthInCU == this->getTComTile(uiTileIdx)->getRightEdgePosInCU() && uiCurrCUAddr / m_uiWidthInCU == this->getTComTile(uiTileIdx)->getBottomEdgePosInCU() )
340  //the current LCU is the last LCU of the tile
341  {
342    if(uiTileIdx == (m_iNumColumnsMinus1+1)*(m_iNumRowsMinus1+1)-1)
343    {
344      uiNxtCUAddr = m_uiNumCUsInFrame;
345    }
346    else
347    {
348      uiNxtCUAddr = this->getTComTile(uiTileIdx+1)->getFirstCUAddr();
349    }
350  } 
351  else //the current LCU is not the last LCU of the tile
352  {
353    if( uiCurrCUAddr % m_uiWidthInCU == this->getTComTile(uiTileIdx)->getRightEdgePosInCU() )  //the current LCU is on the rightmost edge of the tile
354    {
355      uiNxtCUAddr = uiCurrCUAddr + m_uiWidthInCU - this->getTComTile(uiTileIdx)->getTileWidth() + 1;
356    }
357    else
358    {
359      uiNxtCUAddr = uiCurrCUAddr + 1;
360    }
361  }
362
363  return uiNxtCUAddr;
364}
365
366Void TComPicSym::deriveLoopFilterBoundaryAvailibility(Int ctu,
367                                                      Bool& isLeftAvail,
368                                                      Bool& isRightAvail,
369                                                      Bool& isAboveAvail,
370                                                      Bool& isBelowAvail,
371                                                      Bool& isAboveLeftAvail,
372                                                      Bool& isAboveRightAvail,
373                                                      Bool& isBelowLeftAvail,
374                                                      Bool& isBelowRightAvail
375                                                      )
376{
377
378  isLeftAvail      = (ctu % m_uiWidthInCU != 0);
379  isRightAvail     = (ctu % m_uiWidthInCU != m_uiWidthInCU-1);
380  isAboveAvail     = (ctu >= m_uiWidthInCU );
381  isBelowAvail     = (ctu <  m_uiNumCUsInFrame - m_uiWidthInCU);
382  isAboveLeftAvail = (isAboveAvail && isLeftAvail);
383  isAboveRightAvail= (isAboveAvail && isRightAvail);
384  isBelowLeftAvail = (isBelowAvail && isLeftAvail);
385  isBelowRightAvail= (isBelowAvail && isRightAvail);
386
387  Bool isLoopFiltAcrossTilePPS = getCU(ctu)->getSlice()->getPPS()->getLoopFilterAcrossTilesEnabledFlag();
388
389  {
390    TComDataCU* ctuCurr  = getCU(ctu);
391    TComDataCU* ctuLeft  = isLeftAvail ?getCU(ctu-1):NULL;
392    TComDataCU* ctuRight = isRightAvail?getCU(ctu+1):NULL;
393    TComDataCU* ctuAbove = isAboveAvail?getCU(ctu-m_uiWidthInCU):NULL;
394    TComDataCU* ctuBelow = isBelowAvail?getCU(ctu+m_uiWidthInCU):NULL;
395    TComDataCU* ctuAboveLeft  = isAboveLeftAvail ? getCU(ctu-m_uiWidthInCU-1):NULL;
396    TComDataCU* ctuAboveRigtht= isAboveRightAvail? getCU(ctu-m_uiWidthInCU+1):NULL;
397    TComDataCU* ctuBelowLeft  = isBelowLeftAvail ? getCU(ctu+m_uiWidthInCU-1):NULL;
398    TComDataCU* ctuBelowRight = isBelowRightAvail? getCU(ctu+m_uiWidthInCU+1):NULL;
399
400    {
401      //left
402      if(ctuLeft != NULL)
403      {
404        isLeftAvail = (ctuCurr->getSlice()->getSliceCurStartCUAddr() != ctuLeft->getSlice()->getSliceCurStartCUAddr())?ctuCurr->getSlice()->getLFCrossSliceBoundaryFlag():true;
405      }
406      //above
407      if(ctuAbove != NULL)
408      {
409        isAboveAvail = (ctuCurr->getSlice()->getSliceCurStartCUAddr() != ctuAbove->getSlice()->getSliceCurStartCUAddr())?ctuCurr->getSlice()->getLFCrossSliceBoundaryFlag():true;
410      }
411      //right
412      if(ctuRight != NULL)
413      {
414        isRightAvail = (ctuCurr->getSlice()->getSliceCurStartCUAddr() != ctuRight->getSlice()->getSliceCurStartCUAddr())?ctuRight->getSlice()->getLFCrossSliceBoundaryFlag():true;
415      }
416      //below
417      if(ctuBelow != NULL)
418      {
419        isBelowAvail = (ctuCurr->getSlice()->getSliceCurStartCUAddr() != ctuBelow->getSlice()->getSliceCurStartCUAddr())?ctuBelow->getSlice()->getLFCrossSliceBoundaryFlag():true;
420      }
421      //above-left
422      if(ctuAboveLeft != NULL)
423      {
424        isAboveLeftAvail = (ctuCurr->getSlice()->getSliceCurStartCUAddr() != ctuAboveLeft->getSlice()->getSliceCurStartCUAddr())?ctuCurr->getSlice()->getLFCrossSliceBoundaryFlag():true;
425      }
426      //below-right
427      if(ctuBelowRight != NULL)
428{
429        isBelowRightAvail = (ctuCurr->getSlice()->getSliceCurStartCUAddr() != ctuBelowRight->getSlice()->getSliceCurStartCUAddr())?ctuBelowRight->getSlice()->getLFCrossSliceBoundaryFlag():true;
430      }
431
432
433      //above-right
434      if(ctuAboveRigtht != NULL)
435      {
436        Int curSliceStartEncOrder  = ctuCurr->getSlice()->getSliceCurStartCUAddr();
437        Int aboveRigthtSliceStartEncOrder = ctuAboveRigtht->getSlice()->getSliceCurStartCUAddr();
438
439        isAboveRightAvail = (curSliceStartEncOrder == aboveRigthtSliceStartEncOrder)?(true):
440          (
441          (curSliceStartEncOrder > aboveRigthtSliceStartEncOrder)?(ctuCurr->getSlice()->getLFCrossSliceBoundaryFlag())
442          :(ctuAboveRigtht->getSlice()->getLFCrossSliceBoundaryFlag())
443          );         
444      }
445      //below-left
446      if(ctuBelowLeft != NULL)
447      {
448        Int curSliceStartEncOrder  = ctuCurr->getSlice()->getSliceCurStartCUAddr();
449        Int belowLeftSliceStartEncOrder = ctuBelowLeft->getSlice()->getSliceCurStartCUAddr();
450
451        isBelowLeftAvail = (curSliceStartEncOrder == belowLeftSliceStartEncOrder)?(true):
452          (
453          (curSliceStartEncOrder > belowLeftSliceStartEncOrder)?(ctuCurr->getSlice()->getLFCrossSliceBoundaryFlag())
454          :(ctuBelowLeft->getSlice()->getLFCrossSliceBoundaryFlag())
455          );
456      }       
457    }
458
459    if(!isLoopFiltAcrossTilePPS)
460    {     
461      isLeftAvail      = (!isLeftAvail      ) ?false:(getTileIdxMap( ctuLeft->getAddr()         ) == getTileIdxMap( ctu ));
462      isAboveAvail     = (!isAboveAvail     ) ?false:(getTileIdxMap( ctuAbove->getAddr()        ) == getTileIdxMap( ctu ));
463      isRightAvail     = (!isRightAvail     ) ?false:(getTileIdxMap( ctuRight->getAddr()        ) == getTileIdxMap( ctu ));
464      isBelowAvail     = (!isBelowAvail     ) ?false:(getTileIdxMap( ctuBelow->getAddr()        ) == getTileIdxMap( ctu ));
465      isAboveLeftAvail = (!isAboveLeftAvail ) ?false:(getTileIdxMap( ctuAboveLeft->getAddr()    ) == getTileIdxMap( ctu ));
466      isAboveRightAvail= (!isAboveRightAvail) ?false:(getTileIdxMap( ctuAboveRigtht->getAddr()  ) == getTileIdxMap( ctu ));
467      isBelowLeftAvail = (!isBelowLeftAvail ) ?false:(getTileIdxMap( ctuBelowLeft->getAddr()    ) == getTileIdxMap( ctu ));
468      isBelowRightAvail= (!isBelowRightAvail) ?false:(getTileIdxMap( ctuBelowRight->getAddr()   ) == getTileIdxMap( ctu ));
469    }
470  }
471
472}
473
474TComTile::TComTile()
475: m_uiTileWidth         (0)
476, m_uiTileHeight        (0)
477, m_uiRightEdgePosInCU  (0)
478, m_uiBottomEdgePosInCU (0)
479, m_uiFirstCUAddr       (0)
480
481{
482}
483
484TComTile::~TComTile()
485{
486}
487//! \}
Note: See TracBrowser for help on using the repository browser.