source: SHVCSoftware/branches/HM-10.0-dev-SHM/source/Lib/TLibCommon/TComPic.cpp @ 582

Last change on this file since 582 was 113, checked in by seregin, 12 years ago

address compile warning

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