source: SHVCSoftware/branches/SHM-1.1-dev/source/Lib/TLibCommon/TComPic.cpp @ 47

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

REUSE_BLKMAPPING: using the base layer get co-located block function for motion mapping

File size: 30.3 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-2012, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TComPic.cpp
35    \brief    picture class
36*/
37
38#include "TComPic.h"
39#include "SEI.h"
40
41//! \ingroup TLibCommon
42//! \{
43
44// ====================================================================================================================
45// Constructor / destructor / create / destroy
46// ====================================================================================================================
47
48TComPic::TComPic()
49: m_uiTLayer                              (0)
50, m_bUsedByCurr                           (false)
51, m_bIsLongTerm                           (false)
52, m_bIsUsedAsLongTerm                     (false)
53, m_apcPicSym                             (NULL)
54, m_pcPicYuvPred                          (NULL)
55, m_pcPicYuvResi                          (NULL)
56, m_bReconstructed                        (false)
57, m_bNeededForOutput                      (false)
58, m_uiCurrSliceIdx                        (0)
59, m_pSliceSUMap                           (NULL)
60, m_pbValidSlice                          (NULL)
61, m_sliceGranularityForNDBFilter          (0)
62, m_bIndependentSliceBoundaryForNDBFilter (false)
63, m_bIndependentTileBoundaryForNDBFilter  (false)
64, m_pNDBFilterYuvTmp                      (NULL)
65, m_bCheckLTMSB                           (false)
66, m_SEIs                                  (NULL)
67#if SVC_EXTENSION
68, m_bSpatialEnhLayer( false )
69, m_pcFullPelBaseRec( NULL )
70#if REF_IDX_ME_AROUND_ZEROMV || REF_IDX_ME_ZEROMV || ENCODER_FAST_MODE || REF_IDX_MFM
71, m_bIsILR                                (false)
72#endif
73
74#endif
75{
76  m_apcPicYuv[0]      = NULL;
77  m_apcPicYuv[1]      = NULL;
78}
79
80TComPic::~TComPic()
81{
82}
83
84#if SVC_UPSAMPLING
85Void TComPic::create( Int iWidth, Int iHeight, UInt uiMaxWidth, UInt uiMaxHeight, UInt uiMaxDepth, TComSPS* pcSps,  Bool bIsVirtual )
86{
87  m_apcPicSym     = new TComPicSym;  m_apcPicSym   ->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth );
88  if (!bIsVirtual)
89  {
90    m_apcPicYuv[0]  = new TComPicYuv;  m_apcPicYuv[0]->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth, pcSps );
91  }
92  m_apcPicYuv[1]  = new TComPicYuv;  m_apcPicYuv[1]->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth, pcSps );
93 
94  if (m_bSpatialEnhLayer)
95  {
96    m_pcFullPelBaseRec = new TComPicYuv;  m_pcFullPelBaseRec->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth, pcSps );
97  }
98
99  /* there are no SEI messages associated with this picture initially */
100  m_SEIs = NULL;
101  m_bUsedByCurr = false;
102  return;
103}
104#if REF_IDX_FRAMEWORK
105Void TComPic::createWithOutYuv( Int iWidth, Int iHeight, UInt uiMaxWidth, UInt uiMaxHeight, UInt uiMaxDepth, TComSPS* pcSps,  Bool bIsVirtual)
106{
107  m_apcPicSym     = new TComPicSym;  m_apcPicSym   ->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth );
108  if (!bIsVirtual)
109  {
110    m_apcPicYuv[0]  = new TComPicYuv;  m_apcPicYuv[0]->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth, pcSps );
111  }
112  m_apcPicYuv[1]  = NULL;
113 
114#if SVC_UPSAMPLING
115  if (m_bSpatialEnhLayer)
116  {
117    m_pcFullPelBaseRec = new TComPicYuv;  m_pcFullPelBaseRec->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth, pcSps );
118  }
119#endif
120
121  /* there are no SEI messages associated with this picture initially */
122  m_SEIs = NULL;
123  m_bUsedByCurr = false;
124  return;
125}
126#endif
127#else
128
129Void TComPic::create( Int iWidth, Int iHeight, UInt uiMaxWidth, UInt uiMaxHeight, UInt uiMaxDepth, Bool bIsVirtual )
130{
131  m_apcPicSym     = new TComPicSym;  m_apcPicSym   ->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth );
132  if (!bIsVirtual)
133  {
134    m_apcPicYuv[0]  = new TComPicYuv;  m_apcPicYuv[0]->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth );
135  }
136  m_apcPicYuv[1]  = new TComPicYuv;  m_apcPicYuv[1]->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth );
137 
138  /* there are no SEI messages associated with this picture initially */
139  m_SEIs = NULL;
140  m_bUsedByCurr = false;
141  return;
142}
143#endif
144
145Void TComPic::destroy()
146{
147  if (m_apcPicSym)
148  {
149    m_apcPicSym->destroy();
150    delete m_apcPicSym;
151    m_apcPicSym = NULL;
152  }
153 
154  if (m_apcPicYuv[0])
155  {
156    m_apcPicYuv[0]->destroy();
157    delete m_apcPicYuv[0];
158    m_apcPicYuv[0]  = NULL;
159  }
160 
161  if (m_apcPicYuv[1])
162  {
163    m_apcPicYuv[1]->destroy();
164    delete m_apcPicYuv[1];
165    m_apcPicYuv[1]  = NULL;
166  }
167 
168#if SVC_EXTENSION && SVC_UPSAMPLING
169  if (m_bSpatialEnhLayer)
170  {
171    m_pcFullPelBaseRec->destroy();
172    delete m_pcFullPelBaseRec;    m_pcFullPelBaseRec  = NULL;
173  }
174#endif
175
176  delete m_SEIs;
177}
178
179Void TComPic::compressMotion()
180{
181  TComPicSym* pPicSym = getPicSym(); 
182  for ( UInt uiCUAddr = 0; uiCUAddr < pPicSym->getFrameHeightInCU()*pPicSym->getFrameWidthInCU(); uiCUAddr++ )
183  {
184    TComDataCU* pcCU = pPicSym->getCU(uiCUAddr);
185    pcCU->compressMV(); 
186  } 
187}
188
189/** Create non-deblocked filter information
190 * \param pSliceStartAddress array for storing slice start addresses
191 * \param numSlices number of slices in picture
192 * \param sliceGranularityDepth slice granularity
193 * \param bNDBFilterCrossSliceBoundary cross-slice-boundary in-loop filtering; true for "cross".
194 * \param numTiles number of tiles in picture
195 * \param bNDBFilterCrossTileBoundary cross-tile-boundary in-loop filtering; true for "cross".
196 */
197Void TComPic::createNonDBFilterInfo(std::vector<Int> sliceStartAddress, Int sliceGranularityDepth
198                                    ,std::vector<Bool>* LFCrossSliceBoundary
199                                    ,Int numTiles
200                                    ,Bool bNDBFilterCrossTileBoundary)
201{
202  UInt maxNumSUInLCU = getNumPartInCU();
203  UInt numLCUInPic   = getNumCUsInFrame();
204  UInt picWidth      = getSlice(0)->getSPS()->getPicWidthInLumaSamples();
205  UInt picHeight     = getSlice(0)->getSPS()->getPicHeightInLumaSamples();
206  Int  numLCUsInPicWidth = getFrameWidthInCU();
207  Int  numLCUsInPicHeight= getFrameHeightInCU();
208  UInt maxNumSUInLCUWidth = getNumPartInWidth();
209  UInt maxNumSUInLCUHeight= getNumPartInHeight();
210  Int  numSlices = (Int) sliceStartAddress.size() - 1;
211  m_bIndependentSliceBoundaryForNDBFilter = false;
212  if(numSlices > 1)
213  {
214    for(Int s=0; s< numSlices; s++)
215    {
216      if((*LFCrossSliceBoundary)[s] == false)
217      {
218        m_bIndependentSliceBoundaryForNDBFilter = true;
219      }
220    }
221  }
222  m_sliceGranularityForNDBFilter = sliceGranularityDepth;
223  m_bIndependentTileBoundaryForNDBFilter  = (bNDBFilterCrossTileBoundary)?(false) :((numTiles > 1)?(true):(false));
224
225  m_pbValidSlice = new Bool[numSlices];
226  for(Int s=0; s< numSlices; s++)
227  {
228    m_pbValidSlice[s] = true;
229  }
230  m_pSliceSUMap = new Int[maxNumSUInLCU * numLCUInPic];
231
232  //initialization
233  for(UInt i=0; i< (maxNumSUInLCU * numLCUInPic); i++ )
234  {
235    m_pSliceSUMap[i] = -1;
236  }
237  for( UInt CUAddr = 0; CUAddr < numLCUInPic ; CUAddr++ )
238  {
239    TComDataCU* pcCU = getCU( CUAddr );
240    pcCU->setSliceSUMap(m_pSliceSUMap + (CUAddr* maxNumSUInLCU)); 
241    pcCU->getNDBFilterBlocks()->clear();
242  }
243  m_vSliceCUDataLink.clear();
244
245  m_vSliceCUDataLink.resize(numSlices);
246
247  UInt startAddr, endAddr, firstCUInStartLCU, startLCU, endLCU, lastCUInEndLCU, uiAddr;
248  UInt LPelX, TPelY, LCUX, LCUY;
249  UInt currSU;
250  UInt startSU, endSU;
251
252  for(Int s=0; s< numSlices; s++)
253  {
254    //1st step: decide the real start address
255    startAddr = sliceStartAddress[s];
256    endAddr   = sliceStartAddress[s+1] -1;
257
258    startLCU            = startAddr / maxNumSUInLCU;
259    firstCUInStartLCU   = startAddr % maxNumSUInLCU;
260
261    endLCU              = endAddr   / maxNumSUInLCU;
262    lastCUInEndLCU      = endAddr   % maxNumSUInLCU;   
263
264    uiAddr = m_apcPicSym->getCUOrderMap(startLCU);
265
266    LCUX      = getCU(uiAddr)->getCUPelX();
267    LCUY      = getCU(uiAddr)->getCUPelY();
268    LPelX     = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[firstCUInStartLCU] ];
269    TPelY     = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[firstCUInStartLCU] ];
270    currSU    = firstCUInStartLCU;
271
272    Bool bMoveToNextLCU = false;
273    Bool bSliceInOneLCU = (startLCU == endLCU);
274
275    while(!( LPelX < picWidth ) || !( TPelY < picHeight ))
276    {
277      currSU ++;
278
279      if(bSliceInOneLCU)
280      {
281        if(currSU > lastCUInEndLCU)
282        {
283          m_pbValidSlice[s] = false;
284          break;
285        }
286      }
287
288      if(currSU >= maxNumSUInLCU )
289      {
290        bMoveToNextLCU = true;
291        break;
292      }
293
294      LPelX = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[currSU] ];
295      TPelY = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[currSU] ];
296
297    }
298
299
300    if(!m_pbValidSlice[s])
301    {
302      continue;
303    }
304
305    if(currSU != firstCUInStartLCU)
306    {
307      if(!bMoveToNextLCU)
308      {
309        firstCUInStartLCU = currSU;
310      }
311      else
312      {
313        startLCU++;
314        firstCUInStartLCU = 0;
315        assert( startLCU < getNumCUsInFrame());
316      }
317      assert(startLCU*maxNumSUInLCU + firstCUInStartLCU < endAddr);
318    }
319
320
321    //2nd step: assign NonDBFilterInfo to each processing block
322    for(UInt i= startLCU; i <= endLCU; i++)
323    {
324      startSU = (i == startLCU)?(firstCUInStartLCU):(0);
325      endSU   = (i == endLCU  )?(lastCUInEndLCU   ):(maxNumSUInLCU -1);
326
327      uiAddr = m_apcPicSym->getCUOrderMap(i);
328      Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr);
329
330      TComDataCU* pcCU = getCU(uiAddr);
331      m_vSliceCUDataLink[s].push_back(pcCU);
332
333      createNonDBFilterInfoLCU(iTileID, s, pcCU, startSU, endSU, m_sliceGranularityForNDBFilter, picWidth, picHeight);
334    }
335  }
336
337  //step 3: border availability
338  for(Int s=0; s< numSlices; s++)
339  {
340    if(!m_pbValidSlice[s])
341    {
342      continue;
343    }
344
345    for(Int i=0; i< m_vSliceCUDataLink[s].size(); i++)
346    {
347      TComDataCU* pcCU = m_vSliceCUDataLink[s][i];
348      uiAddr = pcCU->getAddr();
349
350      if(pcCU->getPic()==0)
351      {
352        continue;
353      }
354      Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr);
355      Bool bTopTileBoundary = false, bDownTileBoundary= false, bLeftTileBoundary= false, bRightTileBoundary= false;
356
357      if(m_bIndependentTileBoundaryForNDBFilter)
358      {
359        //left
360        if( uiAddr % numLCUsInPicWidth != 0)
361        {
362          bLeftTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr -1) != iTileID )?true:false;
363        }
364        //right
365        if( (uiAddr % numLCUsInPicWidth) != (numLCUsInPicWidth -1) )
366        {
367          bRightTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr +1) != iTileID)?true:false;
368        }
369        //top
370        if( uiAddr >= numLCUsInPicWidth)
371        {
372          bTopTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr - numLCUsInPicWidth) !=  iTileID )?true:false;
373        }
374        //down
375        if( uiAddr + numLCUsInPicWidth < numLCUInPic )
376        {
377          bDownTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr + numLCUsInPicWidth) != iTileID)?true:false;
378        }
379
380      }
381
382      pcCU->setNDBFilterBlockBorderAvailability(numLCUsInPicWidth, numLCUsInPicHeight, maxNumSUInLCUWidth, maxNumSUInLCUHeight,picWidth, picHeight
383        , *LFCrossSliceBoundary
384        ,bTopTileBoundary, bDownTileBoundary, bLeftTileBoundary, bRightTileBoundary
385        ,m_bIndependentTileBoundaryForNDBFilter);
386
387    }
388
389  }
390
391  if( m_bIndependentSliceBoundaryForNDBFilter || m_bIndependentTileBoundaryForNDBFilter)
392  {
393    m_pNDBFilterYuvTmp = new TComPicYuv();
394    m_pNDBFilterYuvTmp->create(picWidth, picHeight, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);
395  }
396
397}
398
399/** Create non-deblocked filter information for LCU
400 * \param tileID tile index
401 * \param sliceID slice index
402 * \param pcCU CU data pointer
403 * \param startSU start SU index in LCU
404 * \param endSU end SU index in LCU
405 * \param sliceGranularyDepth slice granularity
406 * \param picWidth picture width
407 * \param picHeight picture height
408 */
409Void TComPic::createNonDBFilterInfoLCU(Int tileID, Int sliceID, TComDataCU* pcCU, UInt startSU, UInt endSU, Int sliceGranularyDepth, UInt picWidth, UInt picHeight)
410{
411  UInt LCUX          = pcCU->getCUPelX();
412  UInt LCUY          = pcCU->getCUPelY();
413  Int* pCUSliceMap    = pcCU->getSliceSUMap();
414  UInt maxNumSUInLCU = getNumPartInCU();
415  UInt maxNumSUInSGU = maxNumSUInLCU >> (sliceGranularyDepth << 1);
416  UInt maxNumSUInLCUWidth = getNumPartInWidth();
417  UInt LPelX, TPelY;
418  UInt currSU;
419
420
421  //get the number of valid NBFilterBLock
422  currSU   = startSU;
423  while(currSU <= endSU)
424  {
425    LPelX = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[currSU] ];
426    TPelY = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[currSU] ];
427
428    while(!( LPelX < picWidth ) || !( TPelY < picHeight ))
429    {
430      currSU += maxNumSUInSGU;
431      if(currSU >= maxNumSUInLCU || currSU > endSU)
432      {
433        break;
434      }
435      LPelX = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[currSU] ];
436      TPelY = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[currSU] ];
437    }
438
439    if(currSU >= maxNumSUInLCU || currSU > endSU)
440    {
441      break;
442    }
443
444    NDBFBlockInfo NDBFBlock;
445
446    NDBFBlock.tileID  = tileID;
447    NDBFBlock.sliceID = sliceID;
448    NDBFBlock.posY    = TPelY;
449    NDBFBlock.posX    = LPelX;
450    NDBFBlock.startSU = currSU;
451
452    UInt uiLastValidSU  = currSU;
453    UInt uiIdx, uiLPelX_su, uiTPelY_su;
454    for(uiIdx = currSU; uiIdx < currSU + maxNumSUInSGU; uiIdx++)
455    {
456      if(uiIdx > endSU)
457      {
458        break;       
459      }
460      uiLPelX_su   = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[uiIdx] ];
461      uiTPelY_su   = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[uiIdx] ];
462      if( !(uiLPelX_su < picWidth ) || !( uiTPelY_su < picHeight ))
463      {
464        continue;
465      }
466      pCUSliceMap[uiIdx] = sliceID;
467      uiLastValidSU = uiIdx;
468    }
469    NDBFBlock.endSU = uiLastValidSU;
470
471    UInt rTLSU = g_auiZscanToRaster[ NDBFBlock.startSU ];
472    UInt rBRSU = g_auiZscanToRaster[ NDBFBlock.endSU   ];
473    NDBFBlock.widthSU  = (rBRSU % maxNumSUInLCUWidth) - (rTLSU % maxNumSUInLCUWidth)+ 1;
474    NDBFBlock.heightSU = (UInt)(rBRSU / maxNumSUInLCUWidth) - (UInt)(rTLSU / maxNumSUInLCUWidth)+ 1;
475    NDBFBlock.width    = NDBFBlock.widthSU  * getMinCUWidth();
476    NDBFBlock.height   = NDBFBlock.heightSU * getMinCUHeight();
477
478    pcCU->getNDBFilterBlocks()->push_back(NDBFBlock);
479
480    currSU += maxNumSUInSGU;
481  }
482
483}
484
485/** destroy non-deblocked filter information for LCU
486 */
487Void TComPic::destroyNonDBFilterInfo()
488{
489  if(m_pbValidSlice != NULL)
490  {
491    delete[] m_pbValidSlice;
492    m_pbValidSlice = NULL;
493  }
494
495  if(m_pSliceSUMap != NULL)
496  {
497    delete[] m_pSliceSUMap;
498    m_pSliceSUMap = NULL;
499  }
500  for( UInt CUAddr = 0; CUAddr < getNumCUsInFrame() ; CUAddr++ )
501  {
502    TComDataCU* pcCU = getCU( CUAddr );
503    pcCU->getNDBFilterBlocks()->clear();
504  }
505
506  if( m_bIndependentSliceBoundaryForNDBFilter || m_bIndependentTileBoundaryForNDBFilter)
507  {
508    m_pNDBFilterYuvTmp->destroy();
509    delete m_pNDBFilterYuvTmp;
510    m_pNDBFilterYuvTmp = NULL;
511  }
512
513}
514
515#if REF_IDX_FRAMEWORK
516Void copyOnetoOnePicture(    // SVC_NONCOLL
517                  Pel *in,       
518                  Pel *out,     
519                  Int nCols,
520                  Int nRows, 
521                  Int fullRowWidth)
522{
523  Int rX;
524
525  for (rX = 0; rX < nRows; rX++)       
526  {
527    memcpy( out, in, sizeof(Pel) * nCols );
528    in = in + fullRowWidth;
529    out = out + fullRowWidth;
530  }
531}
532
533Void TComPic:: copyUpsampledPictureYuv(TComPicYuv*   pcPicYuvIn, TComPicYuv*   pcPicYuvOut)
534{
535  Int upsampledRowWidthLuma = pcPicYuvOut->getStride(); // 2 * pcPicYuvOut->getLumaMargin() + pcPicYuvOut->getWidth();
536  Int upsampledRowWidthCroma = pcPicYuvOut->getCStride(); //2 * pcPicYuvOut->getChromaMargin() + (pcPicYuvOut->getWidth()>>1);
537
538  copyOnetoOnePicture(
539    pcPicYuvIn->getLumaAddr(),       
540    pcPicYuvOut->getLumaAddr(),     
541    pcPicYuvOut->getWidth(), 
542    pcPicYuvOut->getHeight(),
543    upsampledRowWidthLuma);
544  copyOnetoOnePicture(
545    pcPicYuvIn->getCrAddr(),       
546    pcPicYuvOut->getCrAddr(),     
547    pcPicYuvOut->getWidth()>>1, 
548    pcPicYuvOut->getHeight()>>1,
549    upsampledRowWidthCroma);
550  copyOnetoOnePicture(
551    pcPicYuvIn->getCbAddr(),       
552    pcPicYuvOut->getCbAddr(),     
553    pcPicYuvOut->getWidth()>>1, 
554    pcPicYuvOut->getHeight()>>1,
555    upsampledRowWidthCroma);
556}
557
558#if REF_IDX_MFM
559#if !REUSE_BLKMAPPING
560Void TComPic::deriveUnitIdxBase( UInt uiUpsamplePelX, UInt uiUpsamplePelY, UInt ratio, UInt& uiBaseCUAddr, UInt& uiBaseAbsPartIdx )
561{
562  //pixel in the base layer
563
564  UInt uiPelX       = (uiUpsamplePelX<<1)/ratio;
565  UInt uiPelY       = (uiUpsamplePelY<<1)/ratio;
566  UInt uiBaseWidth  = getPicYuvRec()->getWidth();
567  UInt uiBaseHeight = getPicYuvRec()->getHeight();
568 
569  UInt uiWidthInCU       = ( uiBaseWidth % g_uiMaxCUWidth  ) ? uiBaseWidth /g_uiMaxCUWidth  + 1 : uiBaseWidth /g_uiMaxCUWidth;
570
571#if MFM_CLIPPING_FIX
572  uiPelX     = (UInt)Clip3<UInt>(0, getPicYuvRec()->getWidth() - 1, uiPelX);
573  uiPelY     = (UInt)Clip3<UInt>(0, getPicYuvRec()->getHeight() - 1, uiPelY);
574#else
575  UInt uiHeightInCU      = ( uiBaseHeight% g_uiMaxCUHeight ) ? uiBaseHeight/ g_uiMaxCUHeight + 1 : uiBaseHeight/ g_uiMaxCUHeight;
576
577  uiPelX     = (UInt)Clip3<UInt>(0, uiWidthInCU * g_uiMaxCUWidth - 1, uiPelX);
578  uiPelY     = (UInt)Clip3<UInt>(0, uiHeightInCU * g_uiMaxCUHeight - 1, uiPelY);
579#endif
580 
581  uiBaseCUAddr = uiPelY / g_uiMaxCUHeight * uiWidthInCU + uiPelX / g_uiMaxCUWidth;
582
583  UInt uiWidthMinPU = g_uiMaxCUWidth / (1<<g_uiMaxCUDepth);
584  UInt uiHeightMinPU = g_uiMaxCUHeight/(1<<g_uiMaxCUDepth);
585 
586  UInt uiAbsPelX = uiPelX - (uiPelX / g_uiMaxCUWidth) * g_uiMaxCUWidth;
587  UInt uiAbsPelY = uiPelY - (uiPelY / g_uiMaxCUHeight) * g_uiMaxCUHeight;
588
589  UInt RasterIdx = uiAbsPelY / uiHeightMinPU * (g_uiMaxCUWidth/uiWidthMinPU) + uiAbsPelX / uiWidthMinPU;
590  uiBaseAbsPartIdx = g_auiRasterToZscan[RasterIdx];
591
592  return;
593}
594#endif
595
596Void TComPic::copyUpsampledMvField(TComPic* pcPicBase)
597{
598#if !REUSE_MVSCALE || !REUSE_BLKMAPPING || AVC_SYNTAX
599  Int iBWidth   = pcPicBase->getPicYuvRec()->getWidth () - pcPicBase->getPicYuvRec()->getPicCropLeftOffset() - pcPicBase->getPicYuvRec()->getPicCropRightOffset();
600  Int iBHeight  = pcPicBase->getPicYuvRec()->getHeight() - pcPicBase->getPicYuvRec()->getPicCropTopOffset() - pcPicBase->getPicYuvRec()->getPicCropBottomOffset();
601
602  Int iEWidth   = getPicYuvRec()->getWidth() -  getPicYuvRec()->getPicCropLeftOffset() - getPicYuvRec()->getPicCropRightOffset();
603  Int iEHeight  = getPicYuvRec()->getHeight() - getPicYuvRec()->getPicCropTopOffset() -  getPicYuvRec()->getPicCropBottomOffset();
604#endif
605 
606#if !REUSE_MVSCALE  || !REUSE_BLKMAPPING
607  UInt upSampleRatio = 0;
608  if(iEWidth == iBWidth && iEHeight == iBHeight)
609  {
610    upSampleRatio = 2;
611  }
612  else if(2*iEWidth == 3*iBWidth && 2*iEHeight == 3*iBHeight)
613  {
614    upSampleRatio = 3;
615  }
616  else if(iEWidth == 2*iBWidth && iEHeight == 2*iBHeight)
617  {
618    upSampleRatio = 4;
619  }
620  else
621  {
622    assert(0);
623  }
624#endif
625
626  for(UInt cuIdx = 0; cuIdx < getPicSym()->getNumberOfCUsInFrame(); cuIdx++)  //each LCU
627  {
628    UInt uiNumPartitions   = 1<<(g_uiMaxCUDepth<<1);
629
630    TComDataCU*             pcCUDes = getCU(cuIdx);
631
632    UInt uiWidthMinPU      = g_uiMaxCUWidth/(1<<g_uiMaxCUDepth);
633    UInt uiHeightMinPU     = g_uiMaxCUHeight/(1<<g_uiMaxCUDepth);
634    Int unitNum = max (1, (Int)((16/uiWidthMinPU)*(16/uiHeightMinPU)) ); 
635
636    for(UInt uiAbsPartIdx = 0; uiAbsPartIdx < uiNumPartitions; uiAbsPartIdx+=unitNum )  //each 16x16 unit
637    {
638      //pixel position of each unit in up-sampled layer
639      UInt  uiPelX = pcCUDes->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
640      UInt  uiPelY = pcCUDes->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
641      UInt uiBaseCUAddr, uiBaseAbsPartIdx;
642
643#if REUSE_BLKMAPPING
644      TComDataCU *pcColCU = 0;
645      pcColCU = pcCUDes->getBaseColCU(uiPelX + 8, uiPelY + 8, uiBaseCUAddr, uiBaseAbsPartIdx);
646#else
647      pcPicBase->deriveUnitIdxBase(uiPelX + 8, uiPelY + 8, upSampleRatio, uiBaseCUAddr, uiBaseAbsPartIdx);
648#endif
649
650#if AVC_SYNTAX
651      Int iBX = ( (uiPelX + 8) * iBWidth + iEWidth/2 ) / iEWidth;
652      Int iBY = ( (uiPelY + 8) * iBHeight+ iEHeight/2 ) / iEHeight;
653
654#if REUSE_BLKMAPPING
655      if( ( iBX < iBWidth && iBY < iBHeight ) && pcColCU && (pcColCU->getPredictionMode(uiBaseAbsPartIdx) != MODE_NONE) && (pcColCU->getPredictionMode(uiBaseAbsPartIdx) != MODE_INTRA) )  //base layer unit not skip and invalid mode
656#else
657      if( ( iBX < iBWidth && iBY < iBHeight ) && (pcPicBase->getCU(uiBaseCUAddr)->getPredictionMode(uiBaseAbsPartIdx) != MODE_NONE) && (pcPicBase->getCU(uiBaseCUAddr)->getPredictionMode(uiBaseAbsPartIdx) != MODE_INTRA) )  //base layer unit not skip and invalid mode
658#endif
659#else
660#if REUSE_BLKMAPPING
661      if( pcColCU && (pcColCU->getPredictionMode(uiBaseAbsPartIdx) != MODE_NONE) && (pcColCU->getPredictionMode(uiBaseAbsPartIdx) != MODE_INTRA) )  //base layer unit not skip and invalid mode
662#else
663      if( (pcPicBase->getCU(uiBaseCUAddr)->getPredictionMode(uiBaseAbsPartIdx) != MODE_NONE) && (pcPicBase->getCU(uiBaseCUAddr)->getPredictionMode(uiBaseAbsPartIdx) != MODE_INTRA) )  //base layer unit not skip and invalid mode
664#endif
665#endif
666      {
667        for(UInt refPicList = 0; refPicList < 2; refPicList++)  //for each reference list
668        {
669#if REUSE_MVSCALE
670          TComMvField sMvFieldBase, sMvField;
671#if REUSE_BLKMAPPING
672          pcColCU->getMvField( pcColCU, uiBaseAbsPartIdx, (RefPicList)refPicList, sMvFieldBase);
673#else
674          pcPicBase->getCU(uiBaseCUAddr)->getMvField( pcPicBase->getCU(uiBaseCUAddr), uiBaseAbsPartIdx, (RefPicList)refPicList, sMvFieldBase);
675#endif
676          pcCUDes->scaleBaseMV( sMvField, sMvFieldBase );
677#else
678          TComMv cMv = pcPicBase->getCU(uiBaseCUAddr)->getCUMvField((RefPicList)refPicList)->getMv(uiBaseAbsPartIdx);
679          Int refIdx = pcPicBase->getCU(uiBaseCUAddr)->getCUMvField((RefPicList)refPicList)->getRefIdx(uiBaseAbsPartIdx);
680
681          Int Hor =  ((Int)upSampleRatio * cMv.getHor())/2 ;
682          Int Ver =  ((Int)upSampleRatio * cMv.getVer())/2 ;
683
684          TComMv cScaledMv(Hor, Ver);
685          TComMvField sMvField;
686          sMvField.setMvField(cScaledMv, refIdx);
687#endif
688
689          pcCUDes->getCUMvField((RefPicList)refPicList)->setMvField(sMvField, uiAbsPartIdx);
690          pcCUDes->setPredictionMode(uiAbsPartIdx, MODE_INTER);
691        }
692      }
693      else
694      {
695        TComMvField zeroMvField;  //zero MV and invalid reference index
696        pcCUDes->getCUMvField(REF_PIC_LIST_0)->setMvField(zeroMvField, uiAbsPartIdx);
697        pcCUDes->getCUMvField(REF_PIC_LIST_1)->setMvField(zeroMvField, uiAbsPartIdx);
698        pcCUDes->setPredictionMode(uiAbsPartIdx, MODE_INTRA);
699      }
700
701      for(UInt i = 1; i < unitNum; i++ ) 
702      {
703        pcCUDes->getCUMvField(REF_PIC_LIST_0)->setMvField(pcCUDes->getCUMvField(REF_PIC_LIST_0)->getMv(uiAbsPartIdx), pcCUDes->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiAbsPartIdx), uiAbsPartIdx + i);
704        pcCUDes->getCUMvField(REF_PIC_LIST_1)->setMvField(pcCUDes->getCUMvField(REF_PIC_LIST_1)->getMv(uiAbsPartIdx), pcCUDes->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiAbsPartIdx), uiAbsPartIdx + i);
705        pcCUDes->setPredictionMode(uiAbsPartIdx+i, pcCUDes->getPredictionMode(uiAbsPartIdx))  ;
706      }
707    }
708      memset( pcCUDes->getPartitionSize(), SIZE_2Nx2N, sizeof(char)*uiNumPartitions);
709  }
710}
711#endif
712
713#endif
714
715#if AVC_SYNTAX
716Void TComPic::readBLSyntax( fstream* filestream, UInt numBytes )
717{
718  if( !filestream->good() )
719  {
720    return;
721  }
722
723  UInt   uiWidth      = this->getPicYuvRec()->getWidth() - this->getPicYuvRec()->getPicCropLeftOffset() - this->getPicYuvRec()->getPicCropRightOffset();
724  UInt   uiHeight     = this->getPicYuvRec()->getHeight() - this->getPicYuvRec()->getPicCropTopOffset() - this->getPicYuvRec()->getPicCropBottomOffset();
725  UInt64 uiPOC        = (UInt64)this->getPOC();
726  UInt   uiPartWidth  = uiWidth / 4;
727  UInt   uiPartHeight = uiHeight / 4;
728
729  UInt uiNumPartInWidth    = this->getNumPartInWidth();
730  UInt uiNumPartInHeight   = this->getNumPartInHeight();
731  UInt uiNumPartLCUInWidth = this->getFrameWidthInCU();
732
733  UInt64 uiPos = (UInt64)uiPOC * uiWidth * uiHeight * numBytes / 16;
734   
735  filestream->seekg( uiPos, ios_base::beg );
736
737  for( Int i = 0; i < this->getNumCUsInFrame(); i++ )
738  {
739    TComDataCU* pcCU = this->getCU( i );
740    pcCU->initCU( this, i );
741  }
742
743  for( Int i = 0; i < uiPartHeight; i++ )
744  {
745    for( Int j = 0; j < uiPartWidth; j++ )
746    {
747      UInt uiX = ( j / uiNumPartInWidth );
748      UInt uiY = ( i / uiNumPartInHeight );
749
750      UInt uiLCUAddr = uiY * uiNumPartLCUInWidth + uiX;
751      UInt uiPartAddr = ( i - uiY * uiNumPartInHeight ) * uiNumPartInWidth + ( j - uiX * uiNumPartInWidth );
752      uiPartAddr = g_auiRasterToZscan[uiPartAddr];
753     
754      TComDataCU* pcCU = this->getCU( uiLCUAddr );
755     
756      TComMv mv;
757      Short temp;
758
759      // RefIdxL0
760      Char refIdxL0 = -1;
761      filestream->read( &refIdxL0, 1 );
762      assert( refIdxL0 >= -1 );
763      pcCU->getCUMvField( REF_PIC_LIST_0 )->setRefIdx( (Int)refIdxL0, uiPartAddr );
764
765      // RefIdxL1
766      Char refIdxL1 = -1;
767      filestream->read( &refIdxL1, 1 );
768      assert( refIdxL1 >= -1 );
769      pcCU->getCUMvField( REF_PIC_LIST_1 )->setRefIdx( (Int)refIdxL1, uiPartAddr );
770
771      // MV L0
772      temp = 0;
773      filestream->read( reinterpret_cast<char*>(&temp), 2 );
774      mv.setHor( (Short)temp );
775      temp = 0;
776      filestream->read( reinterpret_cast<char*>(&temp), 2 );
777      mv.setVer( (Short)temp );
778      pcCU->getCUMvField( REF_PIC_LIST_0 )->setMv( mv, uiPartAddr );
779
780      // MV L1
781      temp = 0;
782      filestream->read( reinterpret_cast<char*>(&temp), 2 );
783      mv.setHor( (Short)temp );
784      temp = 0;
785      filestream->read( reinterpret_cast<char*>(&temp), 2 );
786      mv.setVer( (Short)temp );
787      pcCU->getCUMvField( REF_PIC_LIST_1 )->setMv( mv, uiPartAddr );
788
789      // set dependent information
790      pcCU->setPredictionMode( uiPartAddr, ( refIdxL0 == NOT_VALID && refIdxL1 == NOT_VALID ) ? MODE_INTRA : MODE_INTER );
791      UInt uiInterDir = ( refIdxL0 != NOT_VALID ) + ( refIdxL1 != NOT_VALID && pcCU->getSlice()->isInterB() ) * 2;
792      assert( uiInterDir >= 0 && uiInterDir <= 3 );
793      pcCU->setInterDir( uiPartAddr, uiInterDir );
794    }
795  }
796}
797#endif
798
799#if SYNTAX_OUTPUT
800Void TComPic::wrireBLSyntax( fstream* filestream, UInt numBytes )
801{
802  if( !filestream->good() )
803  {
804    return;
805  }
806
807  UInt   uiWidth      = this->getPicYuvRec()->getWidth() - getSlice(0)->getSPS()->getPicCropLeftOffset() - getSlice(0)->getSPS()->getPicCropRightOffset();
808  UInt   uiHeight     = this->getPicYuvRec()->getHeight() - getSlice(0)->getSPS()->getPicCropTopOffset() - getSlice(0)->getSPS()->getPicCropBottomOffset();
809  UInt64 uiPOC        = (UInt64)this->getPOC();
810  UInt   uiPartWidth  = uiWidth / 4;
811  UInt   uiPartHeight = uiHeight / 4;
812
813  UInt uiNumPartInWidth    = this->getNumPartInWidth();
814  UInt uiNumPartInHeight   = this->getNumPartInHeight();
815  UInt uiNumPartLCUInWidth = this->getFrameWidthInCU();
816
817  filestream->seekg( uiPOC * uiWidth * uiHeight * numBytes / 16 );
818   
819  for( Int i = 0; i < uiPartHeight; i++ )
820  {
821    for( Int j = 0; j < uiPartWidth; j++ )
822    {
823      UInt uiX = ( j / uiNumPartInWidth );
824      UInt uiY = ( i / uiNumPartInHeight );
825
826      UInt uiLCUAddr = uiY * uiNumPartLCUInWidth + uiX;
827      UInt uiPartAddr = ( i - uiY * uiNumPartInHeight ) * uiNumPartInWidth + ( j - uiX * uiNumPartInWidth );
828      uiPartAddr = g_auiRasterToZscan[uiPartAddr];
829     
830      TComDataCU* pcCU = this->getCU( uiLCUAddr );
831     
832      TComMv mv;
833      Short temp;
834      Char refIdxL0 = NOT_VALID, refIdxL1 = NOT_VALID;
835
836      // RefIdx
837      if( !pcCU->isIntra( uiPartAddr ) )
838      {
839        refIdxL0 = (Char)pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiPartAddr );
840        refIdxL1 = (Char)pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiPartAddr );
841      }
842      assert( refIdxL0 >= - 1 && refIdxL1 >= - 1 );
843      filestream->put( refIdxL0 );
844      filestream->put( refIdxL1 );
845
846      // MV L0
847      mv.setZero();
848      if( refIdxL0 >= 0 )
849      {
850        mv = pcCU->getCUMvField( REF_PIC_LIST_0 )->getMv( uiPartAddr );
851      }
852      temp = (Short)mv.getHor();
853      filestream->write( reinterpret_cast<char*>(&temp), 2 );
854      temp = (Short)mv.getVer();
855      filestream->write( reinterpret_cast<char*>(&temp), 2 );
856
857      // MV L1
858      mv.setZero();
859      if( refIdxL1 >= 0 )
860      {
861        mv = pcCU->getCUMvField( REF_PIC_LIST_1 )->getMv( uiPartAddr );
862      }
863      temp = (Short)mv.getHor();
864      filestream->write( reinterpret_cast<char*>(&temp), 2 );
865      temp = (Short)mv.getVer();
866      filestream->write( reinterpret_cast<char*>(&temp), 2 );
867    }
868  }
869}
870#endif
871
872
873//! \}
Note: See TracBrowser for help on using the repository browser.