source: SHVCSoftware/branches/SHM-2.1-dev/source/Lib/TLibCommon/TComPic.cpp @ 577

Last change on this file since 577 was 282, checked in by seregin, 12 years ago

merge with SHM-2.1-multilayers-dev branch

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