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

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

formating the code, lossless

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