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

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

port simulcast

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