source: SHVCSoftware/trunk/source/Lib/TLibCommon/TComPic.cpp @ 540

Last change on this file since 540 was 540, checked in by seregin, 11 years ago

merge SHM-4.1-dev branch

  • Property svn:eol-style set to native
File size: 28.0 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#if SVC_EXTENSION
51, m_layerId( 0 )
52#endif
53, m_bUsedByCurr                           (false)
54, m_bIsLongTerm                           (false)
55, m_apcPicSym                             (NULL)
56, m_pcPicYuvPred                          (NULL)
57, m_pcPicYuvResi                          (NULL)
58, m_bReconstructed                        (false)
59, m_bNeededForOutput                      (false)
60, m_uiCurrSliceIdx                        (0)
61#if !HM_CLEANUP_SAO
62, m_pSliceSUMap                           (NULL)
63, m_pbValidSlice                          (NULL)
64, m_sliceGranularityForNDBFilter          (0)
65, m_bIndependentSliceBoundaryForNDBFilter (false)
66, m_bIndependentTileBoundaryForNDBFilter  (false)
67, m_pNDBFilterYuvTmp                      (NULL)
68#endif
69, m_bCheckLTMSB                           (false)
70{
71#if SVC_EXTENSION
72  memset( m_pcFullPelBaseRec, 0, sizeof( m_pcFullPelBaseRec ) );
73  memset( m_bSpatialEnhLayer, false, sizeof( m_bSpatialEnhLayer ) );
74#endif
75  m_apcPicYuv[0]      = NULL;
76  m_apcPicYuv[1]      = NULL;
77}
78
79TComPic::~TComPic()
80{
81}
82#if SVC_UPSAMPLING
83#if AUXILIARY_PICTURES
84Void TComPic::create( Int iWidth, Int iHeight, ChromaFormat chromaFormatIDC, UInt uiMaxWidth, UInt uiMaxHeight, UInt uiMaxDepth, Window &conformanceWindow, Window &defaultDisplayWindow,
85                      Int *numReorderPics, TComSPS* pcSps, Bool bIsVirtual)
86#else
87Void TComPic::create( Int iWidth, Int iHeight, UInt uiMaxWidth, UInt uiMaxHeight, UInt uiMaxDepth, Window &conformanceWindow, Window &defaultDisplayWindow,
88                      Int *numReorderPics, TComSPS* pcSps, Bool bIsVirtual)
89#endif
90{
91  m_apcPicSym     = new TComPicSym;  m_apcPicSym   ->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth );
92  if (!bIsVirtual)
93  {
94#if AUXILIARY_PICTURES
95    m_apcPicYuv[0]  = new TComPicYuv;  m_apcPicYuv[0]->create( iWidth, iHeight, chromaFormatIDC, uiMaxWidth, uiMaxHeight, uiMaxDepth, pcSps );
96#else
97    m_apcPicYuv[0]  = new TComPicYuv;  m_apcPicYuv[0]->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth, pcSps );
98#endif
99  }
100#if AUXILIARY_PICTURES
101  m_apcPicYuv[1]  = new TComPicYuv;  m_apcPicYuv[1]->create( iWidth, iHeight, chromaFormatIDC, uiMaxWidth, uiMaxHeight, uiMaxDepth, pcSps );
102#else
103  m_apcPicYuv[1]  = new TComPicYuv;  m_apcPicYuv[1]->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth, pcSps );
104#endif
105
106  for( Int i = 0; i < MAX_LAYERS; i++ )
107  {
108    if( m_bSpatialEnhLayer[i] )
109    {
110#if AUXILIARY_PICTURES
111      m_pcFullPelBaseRec[i] = new TComPicYuv;  m_pcFullPelBaseRec[i]->create( iWidth, iHeight, chromaFormatIDC, uiMaxWidth, uiMaxHeight, uiMaxDepth, pcSps );
112#else
113      m_pcFullPelBaseRec[i] = new TComPicYuv;  m_pcFullPelBaseRec[i]->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth, pcSps );
114#endif
115    }
116  }
117
118  m_layerId = pcSps ? pcSps->getLayerId() : 0;
119
120  // there are no SEI messages associated with this picture initially
121  if (m_SEIs.size() > 0)
122  {
123    deleteSEIs (m_SEIs);
124  }
125  m_bUsedByCurr = false;
126
127  /* store conformance window parameters with picture */
128  m_conformanceWindow = conformanceWindow;
129 
130  /* store display window parameters with picture */
131  m_defaultDisplayWindow = defaultDisplayWindow;
132
133  /* store number of reorder pics with picture */
134  memcpy(m_numReorderPics, numReorderPics, MAX_TLAYER*sizeof(Int));
135
136  return;
137}
138#else
139Void TComPic::create( Int iWidth, Int iHeight, UInt uiMaxWidth, UInt uiMaxHeight, UInt uiMaxDepth, Window &conformanceWindow, Window &defaultDisplayWindow,
140                      Int *numReorderPics, Bool bIsVirtual)
141
142{
143  m_apcPicSym     = new TComPicSym;  m_apcPicSym   ->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth );
144  if (!bIsVirtual)
145  {
146    m_apcPicYuv[0]  = new TComPicYuv;  m_apcPicYuv[0]->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth );
147  }
148  m_apcPicYuv[1]  = new TComPicYuv;  m_apcPicYuv[1]->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth );
149 
150  // there are no SEI messages associated with this picture initially
151  if (m_SEIs.size() > 0)
152  {
153    deleteSEIs (m_SEIs);
154  }
155  m_bUsedByCurr = false;
156
157  /* store conformance window parameters with picture */
158  m_conformanceWindow = conformanceWindow;
159 
160  /* store display window parameters with picture */
161  m_defaultDisplayWindow = defaultDisplayWindow;
162
163  /* store number of reorder pics with picture */
164  memcpy(m_numReorderPics, numReorderPics, MAX_TLAYER*sizeof(Int));
165
166  return;
167}
168#endif
169
170Void TComPic::destroy()
171{
172  if (m_apcPicSym)
173  {
174    m_apcPicSym->destroy();
175    delete m_apcPicSym;
176    m_apcPicSym = NULL;
177  }
178 
179  if (m_apcPicYuv[0])
180  {
181    m_apcPicYuv[0]->destroy();
182    delete m_apcPicYuv[0];
183    m_apcPicYuv[0]  = NULL;
184  }
185 
186  if (m_apcPicYuv[1])
187  {
188    m_apcPicYuv[1]->destroy();
189    delete m_apcPicYuv[1];
190    m_apcPicYuv[1]  = NULL;
191  }
192 
193  deleteSEIs(m_SEIs);
194#if SVC_EXTENSION && SVC_UPSAMPLING
195  for( Int i = 0; i < MAX_LAYERS; i++ )
196  {
197    if( m_bSpatialEnhLayer[i] )
198    {
199      m_pcFullPelBaseRec[i]->destroy();
200      delete m_pcFullPelBaseRec[i];
201      m_pcFullPelBaseRec[i]  = NULL;
202    }
203  }
204#endif
205}
206
207Void TComPic::compressMotion()
208{
209  TComPicSym* pPicSym = getPicSym(); 
210  for ( UInt uiCUAddr = 0; uiCUAddr < pPicSym->getFrameHeightInCU()*pPicSym->getFrameWidthInCU(); uiCUAddr++ )
211  {
212    TComDataCU* pcCU = pPicSym->getCU(uiCUAddr);
213    pcCU->compressMV(); 
214  } 
215}
216#if HM_CLEANUP_SAO
217Bool  TComPic::getSAOMergeAvailability(Int currAddr, Int mergeAddr)
218{
219  Bool mergeCtbInSliceSeg = (mergeAddr >= getPicSym()->getCUOrderMap(getCU(currAddr)->getSlice()->getSliceCurStartCUAddr()/getNumPartInCU()));
220  Bool mergeCtbInTile     = (getPicSym()->getTileIdxMap(mergeAddr) == getPicSym()->getTileIdxMap(currAddr));
221  return (mergeCtbInSliceSeg && mergeCtbInTile);
222}
223#else
224/** Create non-deblocked filter information
225 * \param pSliceStartAddress array for storing slice start addresses
226 * \param numSlices number of slices in picture
227 * \param sliceGranularityDepth slice granularity
228 * \param bNDBFilterCrossSliceBoundary cross-slice-boundary in-loop filtering; true for "cross".
229 * \param numTiles number of tiles in picture
230 * \param bNDBFilterCrossTileBoundary cross-tile-boundary in-loop filtering; true for "cross".
231 */
232Void TComPic::createNonDBFilterInfo(std::vector<Int> sliceStartAddress, Int sliceGranularityDepth
233                                    ,std::vector<Bool>* LFCrossSliceBoundary
234                                    ,Int numTiles
235                                    ,Bool bNDBFilterCrossTileBoundary)
236{
237  UInt maxNumSUInLCU = getNumPartInCU();
238  UInt numLCUInPic   = getNumCUsInFrame();
239#if REPN_FORMAT_IN_VPS
240  UInt picWidth      = getSlice(0)->getPicWidthInLumaSamples();
241  UInt picHeight     = getSlice(0)->getPicHeightInLumaSamples();
242#else
243  UInt picWidth      = getSlice(0)->getSPS()->getPicWidthInLumaSamples();
244  UInt picHeight     = getSlice(0)->getSPS()->getPicHeightInLumaSamples();
245#endif
246  Int  numLCUsInPicWidth = getFrameWidthInCU();
247  Int  numLCUsInPicHeight= getFrameHeightInCU();
248  UInt maxNumSUInLCUWidth = getNumPartInWidth();
249  UInt maxNumSUInLCUHeight= getNumPartInHeight();
250  Int  numSlices = (Int) sliceStartAddress.size() - 1;
251  m_bIndependentSliceBoundaryForNDBFilter = false;
252  if(numSlices > 1)
253  {
254    for(Int s=0; s< numSlices; s++)
255    {
256      if((*LFCrossSliceBoundary)[s] == false)
257      {
258        m_bIndependentSliceBoundaryForNDBFilter = true;
259      }
260    }
261  }
262  m_sliceGranularityForNDBFilter = sliceGranularityDepth;
263  m_bIndependentTileBoundaryForNDBFilter  = (bNDBFilterCrossTileBoundary)?(false) :((numTiles > 1)?(true):(false));
264
265  m_pbValidSlice = new Bool[numSlices];
266  for(Int s=0; s< numSlices; s++)
267  {
268    m_pbValidSlice[s] = true;
269  }
270  m_pSliceSUMap = new Int[maxNumSUInLCU * numLCUInPic];
271
272  //initialization
273  for(UInt i=0; i< (maxNumSUInLCU * numLCUInPic); i++ )
274  {
275    m_pSliceSUMap[i] = -1;
276  }
277  for( UInt CUAddr = 0; CUAddr < numLCUInPic ; CUAddr++ )
278  {
279    TComDataCU* pcCU = getCU( CUAddr );
280    pcCU->setSliceSUMap(m_pSliceSUMap + (CUAddr* maxNumSUInLCU)); 
281    pcCU->getNDBFilterBlocks()->clear();
282  }
283  m_vSliceCUDataLink.clear();
284
285  m_vSliceCUDataLink.resize(numSlices);
286
287  UInt startAddr, endAddr, firstCUInStartLCU, startLCU, endLCU, lastCUInEndLCU, uiAddr;
288  UInt LPelX, TPelY, LCUX, LCUY;
289  UInt currSU;
290  UInt startSU, endSU;
291
292  for(Int s=0; s< numSlices; s++)
293  {
294    //1st step: decide the real start address
295    startAddr = sliceStartAddress[s];
296    endAddr   = sliceStartAddress[s+1] -1;
297
298    startLCU            = startAddr / maxNumSUInLCU;
299    firstCUInStartLCU   = startAddr % maxNumSUInLCU;
300
301    endLCU              = endAddr   / maxNumSUInLCU;
302    lastCUInEndLCU      = endAddr   % maxNumSUInLCU;   
303
304    uiAddr = m_apcPicSym->getCUOrderMap(startLCU);
305
306    LCUX      = getCU(uiAddr)->getCUPelX();
307    LCUY      = getCU(uiAddr)->getCUPelY();
308    LPelX     = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[firstCUInStartLCU] ];
309    TPelY     = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[firstCUInStartLCU] ];
310    currSU    = firstCUInStartLCU;
311
312    Bool bMoveToNextLCU = false;
313    Bool bSliceInOneLCU = (startLCU == endLCU);
314
315    while(!( LPelX < picWidth ) || !( TPelY < picHeight ))
316    {
317      currSU ++;
318
319      if(bSliceInOneLCU)
320      {
321        if(currSU > lastCUInEndLCU)
322        {
323          m_pbValidSlice[s] = false;
324          break;
325        }
326      }
327
328      if(currSU >= maxNumSUInLCU )
329      {
330        bMoveToNextLCU = true;
331        break;
332      }
333
334      LPelX = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[currSU] ];
335      TPelY = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[currSU] ];
336
337    }
338
339
340    if(!m_pbValidSlice[s])
341    {
342      continue;
343    }
344
345    if(currSU != firstCUInStartLCU)
346    {
347      if(!bMoveToNextLCU)
348      {
349        firstCUInStartLCU = currSU;
350      }
351      else
352      {
353        startLCU++;
354        firstCUInStartLCU = 0;
355        assert( startLCU < getNumCUsInFrame());
356      }
357      assert(startLCU*maxNumSUInLCU + firstCUInStartLCU < endAddr);
358    }
359
360
361    //2nd step: assign NonDBFilterInfo to each processing block
362    for(UInt i= startLCU; i <= endLCU; i++)
363    {
364      startSU = (i == startLCU)?(firstCUInStartLCU):(0);
365      endSU   = (i == endLCU  )?(lastCUInEndLCU   ):(maxNumSUInLCU -1);
366
367      uiAddr = m_apcPicSym->getCUOrderMap(i);
368      Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr);
369
370      TComDataCU* pcCU = getCU(uiAddr);
371      m_vSliceCUDataLink[s].push_back(pcCU);
372
373      createNonDBFilterInfoLCU(iTileID, s, pcCU, startSU, endSU, m_sliceGranularityForNDBFilter, picWidth, picHeight);
374    }
375  }
376
377  //step 3: border availability
378  for(Int s=0; s< numSlices; s++)
379  {
380    if(!m_pbValidSlice[s])
381    {
382      continue;
383    }
384
385    for(Int i=0; i< m_vSliceCUDataLink[s].size(); i++)
386    {
387      TComDataCU* pcCU = m_vSliceCUDataLink[s][i];
388      uiAddr = pcCU->getAddr();
389
390      if(pcCU->getPic()==0)
391      {
392        continue;
393      }
394      Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr);
395      Bool bTopTileBoundary = false, bDownTileBoundary= false, bLeftTileBoundary= false, bRightTileBoundary= false;
396
397      if(m_bIndependentTileBoundaryForNDBFilter)
398      {
399        //left
400        if( uiAddr % numLCUsInPicWidth != 0)
401        {
402          bLeftTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr -1) != iTileID )?true:false;
403        }
404        //right
405        if( (uiAddr % numLCUsInPicWidth) != (numLCUsInPicWidth -1) )
406        {
407          bRightTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr +1) != iTileID)?true:false;
408        }
409        //top
410        if( uiAddr >= numLCUsInPicWidth)
411        {
412          bTopTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr - numLCUsInPicWidth) !=  iTileID )?true:false;
413        }
414        //down
415        if( uiAddr + numLCUsInPicWidth < numLCUInPic )
416        {
417          bDownTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr + numLCUsInPicWidth) != iTileID)?true:false;
418        }
419
420      }
421
422      pcCU->setNDBFilterBlockBorderAvailability(numLCUsInPicWidth, numLCUsInPicHeight, maxNumSUInLCUWidth, maxNumSUInLCUHeight,picWidth, picHeight
423        , *LFCrossSliceBoundary
424        ,bTopTileBoundary, bDownTileBoundary, bLeftTileBoundary, bRightTileBoundary
425        ,m_bIndependentTileBoundaryForNDBFilter);
426
427    }
428
429  }
430
431  if( m_bIndependentSliceBoundaryForNDBFilter || m_bIndependentTileBoundaryForNDBFilter)
432  {
433    m_pNDBFilterYuvTmp = new TComPicYuv();
434#if AUXILIARY_PICTURES
435    m_pNDBFilterYuvTmp->create(picWidth, picHeight, getChromaFormat(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);
436#else
437    m_pNDBFilterYuvTmp->create(picWidth, picHeight, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);
438#endif
439
440  }
441
442}
443
444/** Create non-deblocked filter information for LCU
445 * \param tileID tile index
446 * \param sliceID slice index
447 * \param pcCU CU data pointer
448 * \param startSU start SU index in LCU
449 * \param endSU end SU index in LCU
450 * \param sliceGranularyDepth slice granularity
451 * \param picWidth picture width
452 * \param picHeight picture height
453 */
454Void TComPic::createNonDBFilterInfoLCU(Int tileID, Int sliceID, TComDataCU* pcCU, UInt startSU, UInt endSU, Int sliceGranularyDepth, UInt picWidth, UInt picHeight)
455{
456  UInt LCUX          = pcCU->getCUPelX();
457  UInt LCUY          = pcCU->getCUPelY();
458  Int* pCUSliceMap    = pcCU->getSliceSUMap();
459  UInt maxNumSUInLCU = getNumPartInCU();
460  UInt maxNumSUInSGU = maxNumSUInLCU >> (sliceGranularyDepth << 1);
461  UInt maxNumSUInLCUWidth = getNumPartInWidth();
462  UInt LPelX, TPelY;
463  UInt currSU;
464
465
466  //get the number of valid NBFilterBLock
467  currSU   = startSU;
468  while(currSU <= endSU)
469  {
470    LPelX = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[currSU] ];
471    TPelY = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[currSU] ];
472
473    while(!( LPelX < picWidth ) || !( TPelY < picHeight ))
474    {
475      currSU += maxNumSUInSGU;
476      if(currSU >= maxNumSUInLCU || currSU > endSU)
477      {
478        break;
479      }
480      LPelX = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[currSU] ];
481      TPelY = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[currSU] ];
482    }
483
484    if(currSU >= maxNumSUInLCU || currSU > endSU)
485    {
486      break;
487    }
488
489    NDBFBlockInfo NDBFBlock;
490
491    NDBFBlock.tileID  = tileID;
492    NDBFBlock.sliceID = sliceID;
493    NDBFBlock.posY    = TPelY;
494    NDBFBlock.posX    = LPelX;
495    NDBFBlock.startSU = currSU;
496
497    UInt uiLastValidSU  = currSU;
498    UInt uiIdx, uiLPelX_su, uiTPelY_su;
499    for(uiIdx = currSU; uiIdx < currSU + maxNumSUInSGU; uiIdx++)
500    {
501      if(uiIdx > endSU)
502      {
503        break;       
504      }
505      uiLPelX_su   = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[uiIdx] ];
506      uiTPelY_su   = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[uiIdx] ];
507      if( !(uiLPelX_su < picWidth ) || !( uiTPelY_su < picHeight ))
508      {
509        continue;
510      }
511      pCUSliceMap[uiIdx] = sliceID;
512      uiLastValidSU = uiIdx;
513    }
514    NDBFBlock.endSU = uiLastValidSU;
515
516    UInt rTLSU = g_auiZscanToRaster[ NDBFBlock.startSU ];
517    UInt rBRSU = g_auiZscanToRaster[ NDBFBlock.endSU   ];
518    NDBFBlock.widthSU  = (rBRSU % maxNumSUInLCUWidth) - (rTLSU % maxNumSUInLCUWidth)+ 1;
519    NDBFBlock.heightSU = (UInt)(rBRSU / maxNumSUInLCUWidth) - (UInt)(rTLSU / maxNumSUInLCUWidth)+ 1;
520    NDBFBlock.width    = NDBFBlock.widthSU  * getMinCUWidth();
521    NDBFBlock.height   = NDBFBlock.heightSU * getMinCUHeight();
522
523    pcCU->getNDBFilterBlocks()->push_back(NDBFBlock);
524
525    currSU += maxNumSUInSGU;
526  }
527
528}
529
530/** destroy non-deblocked filter information for LCU
531 */
532Void TComPic::destroyNonDBFilterInfo()
533{
534  if(m_pbValidSlice != NULL)
535  {
536    delete[] m_pbValidSlice;
537    m_pbValidSlice = NULL;
538  }
539
540  if(m_pSliceSUMap != NULL)
541  {
542    delete[] m_pSliceSUMap;
543    m_pSliceSUMap = NULL;
544  }
545  for( UInt CUAddr = 0; CUAddr < getNumCUsInFrame() ; CUAddr++ )
546  {
547    TComDataCU* pcCU = getCU( CUAddr );
548    pcCU->getNDBFilterBlocks()->clear();
549  }
550
551  if( m_bIndependentSliceBoundaryForNDBFilter || m_bIndependentTileBoundaryForNDBFilter)
552  {
553    m_pNDBFilterYuvTmp->destroy();
554    delete m_pNDBFilterYuvTmp;
555    m_pNDBFilterYuvTmp = NULL;
556  }
557
558}
559#endif
560
561#if SVC_EXTENSION
562Void copyOnetoOnePicture(    // SVC_NONCOLL
563                  Pel *in,       
564                  Pel *out,     
565                  Int nCols,
566                  Int nRows, 
567                  Int fullRowWidth)
568{
569  Int rX;
570
571  for (rX = 0; rX < nRows; rX++)       
572  {
573    memcpy( out, in, sizeof(Pel) * nCols );
574    in = in + fullRowWidth;
575    out = out + fullRowWidth;
576  }
577}
578
579Void TComPic::copyUpsampledPictureYuv(TComPicYuv*   pcPicYuvIn, TComPicYuv*   pcPicYuvOut)
580{
581  Int upsampledRowWidthLuma = pcPicYuvOut->getStride(); // 2 * pcPicYuvOut->getLumaMargin() + pcPicYuvOut->getWidth();
582  Int upsampledRowWidthCroma = pcPicYuvOut->getCStride(); //2 * pcPicYuvOut->getChromaMargin() + (pcPicYuvOut->getWidth()>>1);
583
584  copyOnetoOnePicture(
585    pcPicYuvIn->getLumaAddr(),       
586    pcPicYuvOut->getLumaAddr(),     
587    pcPicYuvOut->getWidth(), 
588    pcPicYuvOut->getHeight(),
589    upsampledRowWidthLuma);
590  copyOnetoOnePicture(
591    pcPicYuvIn->getCrAddr(),       
592    pcPicYuvOut->getCrAddr(),     
593    pcPicYuvOut->getWidth()>>1, 
594    pcPicYuvOut->getHeight()>>1,
595    upsampledRowWidthCroma);
596  copyOnetoOnePicture(
597    pcPicYuvIn->getCbAddr(),       
598    pcPicYuvOut->getCbAddr(),     
599    pcPicYuvOut->getWidth()>>1, 
600    pcPicYuvOut->getHeight()>>1,
601    upsampledRowWidthCroma);
602}
603
604#if REF_IDX_MFM
605Void TComPic::copyUpsampledMvField(UInt refLayerIdc, TComPic* pcPicBase)
606{
607  UInt numPartitions   = 1<<(g_uiMaxCUDepth<<1);
608  UInt widthMinPU      = g_uiMaxCUWidth/(1<<g_uiMaxCUDepth);
609  UInt heightMinPU     = g_uiMaxCUHeight/(1<<g_uiMaxCUDepth);
610  Int  unitNum         = max (1, (Int)((16/widthMinPU)*(16/heightMinPU)) ); 
611
612  for(UInt cuIdx = 0; cuIdx < getPicSym()->getNumberOfCUsInFrame(); cuIdx++)  //each LCU
613  {
614    TComDataCU* pcCUDes = getCU(cuIdx);
615
616    for(UInt absPartIdx = 0; absPartIdx < numPartitions; absPartIdx+=unitNum )  //each 16x16 unit
617    {
618      //pixel position of each unit in up-sampled layer
619      UInt  pelX = pcCUDes->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[absPartIdx] ];
620      UInt  pelY = pcCUDes->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[absPartIdx] ];
621      UInt baseCUAddr, baseAbsPartIdx;
622
623      TComDataCU *pcColCU = 0;
624      pcColCU = pcCUDes->getBaseColCU(refLayerIdc, pelX + 8, pelY + 8, baseCUAddr, baseAbsPartIdx, 1);
625
626      if( pcColCU && (pcColCU->getPredictionMode(baseAbsPartIdx) != MODE_NONE) && (pcColCU->getPredictionMode(baseAbsPartIdx) != MODE_INTRA) )  //base layer unit not skip and invalid mode
627      {
628        for(UInt refPicList = 0; refPicList < 2; refPicList++)  //for each reference list
629        {
630          TComMvField sMvFieldBase, sMvField;
631          pcColCU->getMvField( pcColCU, baseAbsPartIdx, (RefPicList)refPicList, sMvFieldBase);
632          pcCUDes->scaleBaseMV( refLayerIdc, sMvField, sMvFieldBase );
633
634          pcCUDes->getCUMvField((RefPicList)refPicList)->setMvField(sMvField, absPartIdx);
635          pcCUDes->setPredictionMode(absPartIdx, MODE_INTER);
636        }
637      }
638      else
639      {
640        TComMvField zeroMvField;  //zero MV and invalid reference index
641        pcCUDes->getCUMvField(REF_PIC_LIST_0)->setMvField(zeroMvField, absPartIdx);
642        pcCUDes->getCUMvField(REF_PIC_LIST_1)->setMvField(zeroMvField, absPartIdx);
643        pcCUDes->setPredictionMode(absPartIdx, MODE_INTRA);
644      }
645
646      for(UInt i = 1; i < unitNum; i++ ) 
647      {
648        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);
649        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);
650        pcCUDes->setPredictionMode(absPartIdx+i, pcCUDes->getPredictionMode(absPartIdx));
651      }
652    }
653    memset( pcCUDes->getPartitionSize(), SIZE_2Nx2N, sizeof(Char)*numPartitions);
654  }
655}
656
657Void TComPic::initUpsampledMvField()
658{
659  UInt uiNumPartitions   = 1<<(g_uiMaxCUDepth<<1);
660
661  for(UInt cuIdx = 0; cuIdx < getPicSym()->getNumberOfCUsInFrame(); cuIdx++)  //each LCU
662  {
663    TComDataCU* pcCUDes = getCU(cuIdx);
664    TComMvField zeroMvField;
665    for(UInt list = 0; list < 2; list++)  //each reference list
666    {
667      for(UInt i = 0; i < uiNumPartitions; i++ ) 
668      {
669        pcCUDes->getCUMvField(REF_PIC_LIST_0)->setMvField(zeroMvField, i);
670        pcCUDes->getCUMvField(REF_PIC_LIST_1)->setMvField(zeroMvField, i);
671        pcCUDes->setPredictionMode(i, MODE_INTRA);
672        pcCUDes->setPartitionSize(i, SIZE_2Nx2N);
673      }
674    }
675  }
676  return;
677}
678#endif
679#endif
680
681#if AVC_SYNTAX
682Void TComPic::readBLSyntax( fstream* filestream, UInt numBytes )
683{
684  if( !filestream->good() )
685  {
686    return;
687  }
688
689  UInt   width      = this->getPicYuvRec()->getWidth();
690  UInt   height     = this->getPicYuvRec()->getHeight();
691
692  UInt64 poc        = (UInt64)this->getPOC();
693  UInt   partWidth  = width / 4;
694  UInt   partHeight = height / 4;
695
696  UInt numPartInWidth    = this->getNumPartInWidth();
697  UInt numPartInHeight   = this->getNumPartInHeight();
698  UInt numPartLCUInWidth = this->getFrameWidthInCU();
699
700  UInt64 uiPos = (UInt64)poc * width * height * numBytes / 16;
701   
702  filestream->seekg( uiPos, ios_base::beg );
703
704  for( Int i = 0; i < partHeight; i++ )
705  {
706    for( Int j = 0; j < partWidth; j++ )
707    {
708      UInt x = ( j / numPartInWidth );
709      UInt y = ( i / numPartInHeight );
710
711      UInt addrLCU = y * numPartLCUInWidth + x;
712      UInt partAddr = ( i - y * numPartInHeight ) * numPartInWidth + ( j - x * numPartInWidth );
713      partAddr = g_auiRasterToZscan[partAddr];
714     
715      TComDataCU* pcCU = this->getCU( addrLCU );
716     
717      TComMv mv;
718      Short temp;
719
720      // RefIdxL0
721      Char refIdxL0 = -1;
722      filestream->read( &refIdxL0, 1 );
723      assert( refIdxL0 >= -1 );
724      pcCU->getCUMvField( REF_PIC_LIST_0 )->setRefIdx( (Int)refIdxL0, partAddr );
725
726      // RefIdxL1
727      Char refIdxL1 = -1;
728      filestream->read( &refIdxL1, 1 );
729      assert( refIdxL1 >= -1 );
730      pcCU->getCUMvField( REF_PIC_LIST_1 )->setRefIdx( (Int)refIdxL1, partAddr );
731
732      // MV L0
733      temp = 0;
734      filestream->read( reinterpret_cast<char*>(&temp), 2 );
735      mv.setHor( (Short)temp );
736      temp = 0;
737      filestream->read( reinterpret_cast<char*>(&temp), 2 );
738      mv.setVer( (Short)temp );
739      pcCU->getCUMvField( REF_PIC_LIST_0 )->setMv( mv, partAddr );
740
741      // MV L1
742      temp = 0;
743      filestream->read( reinterpret_cast<char*>(&temp), 2 );
744      mv.setHor( (Short)temp );
745      temp = 0;
746      filestream->read( reinterpret_cast<char*>(&temp), 2 );
747      mv.setVer( (Short)temp );
748      pcCU->getCUMvField( REF_PIC_LIST_1 )->setMv( mv, partAddr );
749
750      // set dependent information
751      pcCU->setPredictionMode( partAddr, ( refIdxL0 == NOT_VALID && refIdxL1 == NOT_VALID ) ? MODE_INTRA : MODE_INTER );
752      UInt interDir = ( refIdxL0 != NOT_VALID ) + ( refIdxL1 != NOT_VALID && this->getSlice(0)->isInterB() ) * 2;
753      assert( interDir <= 3 );
754      pcCU->setInterDir( partAddr, interDir );     
755    }
756  }
757}
758#endif
759
760#if SYNTAX_OUTPUT
761Void TComPic::wrireBLSyntax( fstream* filestream, UInt numBytes )
762{
763  if( !filestream->good() )
764  {
765    return;
766  }
767
768  UInt   width       = this->getPicYuvRec()->getWidth();
769  UInt   height      = this->getPicYuvRec()->getHeight();
770
771  UInt64 poc        = (UInt64)this->getPOC();
772  UInt   partWidth  = width / 4;
773  UInt   partHeight = height / 4;
774
775  UInt numPartInWidth    = this->getNumPartInWidth();
776  UInt numPartInHeight   = this->getNumPartInHeight();
777  UInt numPartLCUInWidth = this->getFrameWidthInCU();
778
779  filestream->seekg( poc * width * height * numBytes / 16 );
780   
781  for( Int i = 0; i < partHeight; i++ )
782  {
783    for( Int j = 0; j < partWidth; j++ )
784    {
785      UInt x = ( j / numPartInWidth );
786      UInt y = ( i / numPartInHeight );
787
788      UInt addrLCU = y * numPartLCUInWidth + x;
789      UInt partAddr = ( i - y * numPartInHeight ) * numPartInWidth + ( j - x * numPartInWidth );
790      partAddr = g_auiRasterToZscan[partAddr];
791     
792      TComDataCU* pcCU = this->getCU( addrLCU );
793     
794      TComMv mv;
795      Short temp;
796      Char refIdxL0 = NOT_VALID, refIdxL1 = NOT_VALID;
797
798      // RefIdx
799      if( !pcCU->isIntra( partAddr ) )
800      {
801        refIdxL0 = (Char)pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( partAddr );
802        refIdxL1 = (Char)pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( partAddr );
803      }
804      assert( refIdxL0 >= - 1 && refIdxL1 >= - 1 );
805      filestream->put( refIdxL0 );
806      filestream->put( refIdxL1 );
807
808      // MV L0
809      mv.setZero();
810      if( refIdxL0 >= 0 )
811      {
812        mv = pcCU->getCUMvField( REF_PIC_LIST_0 )->getMv( partAddr );
813      }
814      temp = (Short)mv.getHor();
815      filestream->write( reinterpret_cast<char*>(&temp), 2 );
816      temp = (Short)mv.getVer();
817      filestream->write( reinterpret_cast<char*>(&temp), 2 );
818
819      // MV L1
820      mv.setZero();
821      if( refIdxL1 >= 0 )
822      {
823        mv = pcCU->getCUMvField( REF_PIC_LIST_1 )->getMv( partAddr );
824      }
825      temp = (Short)mv.getHor();
826      filestream->write( reinterpret_cast<char*>(&temp), 2 );
827      temp = (Short)mv.getVer();
828      filestream->write( reinterpret_cast<char*>(&temp), 2 );
829    }
830  }
831}
832#endif
833
834#if MFM_ENCCONSTRAINT
835Bool TComPic::checkSameRefInfo()
836{
837  Bool bSameRefInfo = true;
838  TComSlice * pSlice0 = getSlice( 0 );
839  for( UInt uSliceID = getNumAllocatedSlice() - 1 ; bSameRefInfo && uSliceID > 0 ; uSliceID-- )
840  {
841    TComSlice * pSliceN = getSlice( uSliceID );
842    if( pSlice0->getSliceType() != pSliceN->getSliceType() )
843    {
844      bSameRefInfo = false;
845    }
846    else if( pSlice0->getSliceType() != I_SLICE )
847    {
848      Int nListNum = pSlice0->getSliceType() == B_SLICE ? 2 : 1;
849      for( Int nList = 0 ; nList < nListNum ; nList++ )
850      {
851        RefPicList eRefList = ( RefPicList )nList;
852        if( pSlice0->getNumRefIdx( eRefList ) == pSliceN->getNumRefIdx( eRefList ) )
853        {
854          for( Int refIdx = pSlice0->getNumRefIdx( eRefList ) - 1 ; refIdx >= 0 ; refIdx-- )
855          {
856            if( pSlice0->getRefPic( eRefList , refIdx ) != pSliceN->getRefPic( eRefList , refIdx ) )
857            {
858              bSameRefInfo = false;
859              break;
860            }
861          }
862        }
863        else
864        {
865          bSameRefInfo = false;
866          break;
867        }
868      }
869    }
870  }
871
872  return( bSameRefInfo ); 
873}
874#endif
875
876//! \}
Note: See TracBrowser for help on using the repository browser.