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

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

fix for compilation warning, provided by Thijs Vermeir <thijs.vermeir@…>

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