source: SHVCSoftware/branches/SHM-1.0-dev/source/Lib/TLibCommon/TComPic.cpp @ 26

Last change on this file since 26 was 25, checked in by qualcomm, 12 years ago

L0336: motion field mapping of inter-layer reference picture from Qualcomm, cjianle@…

File size: 25.3 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6 * Copyright (c) 2010-2012, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TComPic.cpp
35    \brief    picture class
36*/
37
38#include "TComPic.h"
39#include "SEI.h"
40
41//! \ingroup TLibCommon
42//! \{
43
44// ====================================================================================================================
45// Constructor / destructor / create / destroy
46// ====================================================================================================================
47
48TComPic::TComPic()
49: m_uiTLayer                              (0)
50, m_bUsedByCurr                           (false)
51, m_bIsLongTerm                           (false)
52, m_bIsUsedAsLongTerm                     (false)
53, m_apcPicSym                             (NULL)
54, m_pcPicYuvPred                          (NULL)
55, m_pcPicYuvResi                          (NULL)
56, m_bReconstructed                        (false)
57, m_bNeededForOutput                      (false)
58, m_uiCurrSliceIdx                        (0)
59, m_pSliceSUMap                           (NULL)
60, m_pbValidSlice                          (NULL)
61, m_sliceGranularityForNDBFilter          (0)
62, m_bIndependentSliceBoundaryForNDBFilter (false)
63, m_bIndependentTileBoundaryForNDBFilter  (false)
64, m_pNDBFilterYuvTmp                      (NULL)
65, m_bCheckLTMSB                           (false)
66, m_SEIs                                  (NULL)
67#if SVC_EXTENSION
68, m_bSpatialEnhLayer( false )
69, m_pcFullPelBaseRec( NULL )
70#if REF_IDX_ME_AROUND_ZEROMV || REF_IDX_ME_ZEROMV || ENCODER_FAST_MODE || REF_IDX_MFM
71, m_bIsILR                                (false)
72#endif
73#if REF_IDX_MFM
74, m_bIsUpsampledMvField                   (false) 
75, m_apcTComUpsampledMvFieldCU             (NULL)
76, m_peUpsampledPredMode                   (NULL)
77, m_iNumCUInUpsampledPic                  (-1)
78#endif
79#endif
80{
81  m_apcPicYuv[0]      = NULL;
82  m_apcPicYuv[1]      = NULL;
83}
84
85TComPic::~TComPic()
86{
87}
88
89#if SVC_UPSAMPLING
90Void TComPic::create( Int iWidth, Int iHeight, UInt uiMaxWidth, UInt uiMaxHeight, UInt uiMaxDepth, TComSPS* pcSps,  Bool bIsVirtual )
91{
92  m_apcPicSym     = new TComPicSym;  m_apcPicSym   ->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth );
93  if (!bIsVirtual)
94  {
95    m_apcPicYuv[0]  = new TComPicYuv;  m_apcPicYuv[0]->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth, pcSps );
96  }
97  m_apcPicYuv[1]  = new TComPicYuv;  m_apcPicYuv[1]->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth, pcSps );
98 
99  if (m_bSpatialEnhLayer)
100  {
101    m_pcFullPelBaseRec = new TComPicYuv;  m_pcFullPelBaseRec->create( iWidth, iHeight, uiMaxWidth, uiMaxHeight, uiMaxDepth, pcSps );
102  }
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
564Void TComPic::createUpSampledMvField(Int upSampledHeight, Int upSampledWidth, UInt uiMaxWidth, UInt uiMaxHeight, UInt uiMaxDepth )
565{
566        UInt uiNumPartitions   = 1<<(uiMaxDepth<<1);
567        UInt uiWidthInCU       = ( upSampledWidth % uiMaxWidth  ) ? upSampledWidth /uiMaxWidth  + 1 : upSampledWidth /uiMaxWidth;
568  UInt uiHeightInCU      = ( upSampledHeight% uiMaxHeight ) ? upSampledHeight/uiMaxHeight + 1 : upSampledHeight/uiMaxHeight;
569        UInt uiNumCUsInFrame   = uiWidthInCU * uiHeightInCU;
570        m_iNumCUInUpsampledPic = uiNumCUsInFrame;
571
572        m_apcTComUpsampledMvFieldCU     = new TComUpsampledMvFieldCU*[uiNumCUsInFrame];
573        m_peUpsampledPredMode           = new char*[uiNumCUsInFrame];
574
575        for (Int i = 0; i < uiNumCUsInFrame; i++ )
576        {
577                m_apcTComUpsampledMvFieldCU[i] = new TComUpsampledMvFieldCU;
578                m_apcTComUpsampledMvFieldCU[i]->createMvField(i, uiWidthInCU, uiNumPartitions);  //create Mv field
579                m_apcTComUpsampledMvFieldCU[i]->initMvField();                                   //initialize Mv field
580
581          m_peUpsampledPredMode[i]     = new char[uiNumPartitions];
582        }
583
584        return;
585}
586
587Void TComPic::deriveUnitIdxBase(UInt uiUpsamplePelX, UInt uiUpsamplePelY, float ratio, UInt& uiBaseCUAddr, UInt& uiBaseAbsPartIdx)
588{
589  //pixel in the base layer
590  UInt uiPelX       = (UInt)((float)uiUpsamplePelX/ratio);
591  UInt uiPelY       = (UInt)((float)uiUpsamplePelY/ratio);
592  UInt uiBaseWidth  = getPicYuvRec()->getWidth();
593  UInt uiBaseHeight = getPicYuvRec()->getHeight();
594
595  UInt uiWidthInCU       = ( uiBaseWidth % g_uiMaxCUWidth  ) ? uiBaseWidth /g_uiMaxCUWidth  + 1 : uiBaseWidth /g_uiMaxCUWidth;
596  UInt uiHeightInCU      = ( uiBaseHeight% g_uiMaxCUHeight ) ? uiBaseHeight/ g_uiMaxCUHeight + 1 : uiBaseHeight/ g_uiMaxCUHeight;
597
598  uiPelX     = (UInt)Clip3<UInt>(0, uiWidthInCU * g_uiMaxCUWidth - 1, uiPelX);
599  uiPelY     = (UInt)Clip3<UInt>(0, uiHeightInCU * g_uiMaxCUHeight - 1, uiPelY);
600 
601  uiBaseCUAddr = uiPelY / g_uiMaxCUHeight * uiWidthInCU + uiPelX / g_uiMaxCUWidth;
602
603  UInt uiWidthMinPU = g_uiMaxCUWidth / (1<<g_uiMaxCUDepth);
604  UInt uiHeightMinPU = g_uiMaxCUHeight/(1<<g_uiMaxCUDepth);
605 
606  UInt uiAbsPelX = uiPelX - (uiPelX / g_uiMaxCUWidth) * g_uiMaxCUWidth;
607  UInt uiAbsPelY = uiPelY - (uiPelY / g_uiMaxCUHeight) * g_uiMaxCUHeight;
608
609  UInt RasterIdx = uiAbsPelY / uiHeightMinPU * (g_uiMaxCUWidth/uiWidthMinPU) + uiAbsPelX / uiWidthMinPU;
610  uiBaseAbsPartIdx = g_auiRasterToZscan[RasterIdx];
611
612  return;
613}
614
615
616//MV field up-sampling
617Void TComPic::doTheUpSampleMvField(UInt upSampleRatio)
618{
619  UInt uiWidthMinPU      = g_uiMaxCUWidth/(1<<g_uiMaxCUDepth);
620  UInt uiHeightMinPU     = g_uiMaxCUHeight/(1<<g_uiMaxCUDepth);
621  UInt uiNumPartitions   = 1<<(g_uiMaxCUDepth<<1);
622  UInt uiPelX, uiPelY;
623  UInt uiBaseCUAddr, uiBaseAbsPartIdx;
624  float ratio = 0;
625
626  //????????????????????????????
627  if(upSampleRatio == 0)       //ONE_TO_ONE
628    ratio = 1.0;
629  else if(upSampleRatio == 1)  //ONE_TO_TWO
630    ratio = 2.0;
631  else if(upSampleRatio == 2)  //TWO_TO_THREE
632    ratio = 1.5;
633
634  for(UInt uiCUAddr = 0; uiCUAddr < m_iNumCUInUpsampledPic; uiCUAddr++)  //each LCU
635  {
636    TComUpsampledMvFieldCU*& pcMvFieldCU = getUpsampledMvFieldCU(uiCUAddr);
637    pcMvFieldCU->initMvField();                                          //MV field initialization
638
639    Int unitNum = max (1, (Int)((16/uiWidthMinPU)*(16/uiHeightMinPU)) ); 
640    for(UInt uiAbsPartIdx = 0; uiAbsPartIdx < uiNumPartitions; uiAbsPartIdx+=unitNum )  //each 16x16 unit
641    {
642      //pixel position of each unit in up-sampled layer
643      uiPelX = pcMvFieldCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
644      uiPelY = pcMvFieldCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
645
646      //????????????????????????????
647      deriveUnitIdxBase(uiPelX + 8, uiPelY + 8, ratio, uiBaseCUAddr, uiBaseAbsPartIdx);
648      if( (getCU(uiBaseCUAddr)->getPredictionMode(uiBaseAbsPartIdx) != MODE_NONE) && (getCU(uiBaseCUAddr)->getPredictionMode(uiBaseAbsPartIdx) != MODE_INTRA) )  //base layer unit not skip and invalid mode
649      {
650        for(UInt list = 0; list < 2; list++)  //each list
651        { 
652          TComMv cMv = getCU(uiBaseCUAddr)->getCUMvField((RefPicList)list)->getMv(uiBaseAbsPartIdx);
653          Int refIdx = getCU(uiBaseCUAddr)->getCUMvField((RefPicList)list)->getRefIdx(uiBaseAbsPartIdx);
654        //????????????????????????????
655        Int Hor = (Short) (ratio * cMv.getHor());
656        Int Ver = (Short) (ratio * cMv.getVer());
657
658        TComMv cScaledMv(Hor, Ver);
659        TComMvField sMvField;
660        sMvField.setMvField(cScaledMv, refIdx);
661
662        pcMvFieldCU->getCUMvField((RefPicList)list)->setMvField(sMvField, uiAbsPartIdx);
663        m_peUpsampledPredMode[uiCUAddr][uiAbsPartIdx] = MODE_INTER;
664        }
665      }
666      else
667      {
668        TComMvField zeroMvField;  //zero MV and invalid reference index
669        pcMvFieldCU->getCUMvField(REF_PIC_LIST_0)->setMvField(zeroMvField, uiAbsPartIdx);
670        pcMvFieldCU->getCUMvField(REF_PIC_LIST_1)->setMvField(zeroMvField, uiAbsPartIdx);
671
672          m_peUpsampledPredMode[uiCUAddr][uiAbsPartIdx]     = MODE_INTRA;
673      }
674
675      //MV compression
676      for(UInt i = 1; i < unitNum; i++ ) 
677      {
678        pcMvFieldCU->getCUMvField(REF_PIC_LIST_0)->setMvField(pcMvFieldCU->getCUMvField(REF_PIC_LIST_0)->getMv(uiAbsPartIdx), pcMvFieldCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(uiAbsPartIdx), uiAbsPartIdx + i);
679        pcMvFieldCU->getCUMvField(REF_PIC_LIST_1)->setMvField(pcMvFieldCU->getCUMvField(REF_PIC_LIST_1)->getMv(uiAbsPartIdx), pcMvFieldCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(uiAbsPartIdx), uiAbsPartIdx + i);
680          m_peUpsampledPredMode[uiCUAddr][uiAbsPartIdx+i]     = m_peUpsampledPredMode[uiCUAddr][uiAbsPartIdx];
681      }
682
683    }  //ending for(UInt uiAbsPartIdx = 0; uiAbsPartIdx < uiNumPartitions; uiAbsPartIdx++)
684  }  //ending for(UInt uiCUAddr = 0; uiCUAddr < m_iNumCUInUpsampledPic; uiCUAddr++)
685  return;
686}
687
688Void TComPic::copyUpsampledMvField(TComPic* pcPicBase)
689{
690  assert( getPicSym()->getNumberOfCUsInFrame() == pcPicBase->getNumCUInUpsampledPic() );
691
692  for(UInt cuIdx = 0; cuIdx < getPicSym()->getNumberOfCUsInFrame(); cuIdx++)  //each LCU
693  {
694    UInt uiNumPartitions   = 1<<(g_uiMaxCUDepth<<1);
695
696    TComDataCU*             pcCUDes = getCU(cuIdx);
697    TComUpsampledMvFieldCU* pcMvFieldCU = pcPicBase->getUpsampledMvFieldCU(cuIdx);
698    for(UInt list = 0; list < 2; list++)  //each reference list
699    {
700      TComCUMvField* pcCUMvFieldDes = pcCUDes->getCUMvField((RefPicList)list);
701      TComCUMvField* pcCUMvFieldOrg = pcMvFieldCU->getCUMvField((RefPicList)list);
702
703      assert(pcCUMvFieldDes->getNumPartition() == pcCUMvFieldOrg->getNumPartition());
704      assert(pcCUMvFieldDes->getNumPartition() == uiNumPartitions);
705
706      pcCUMvFieldDes->clearMvField();
707      pcCUMvFieldDes->copyFrom(pcCUMvFieldOrg, pcCUMvFieldDes->getNumPartition(), 0);     
708    }
709
710    char* pPredModeSrc = pcPicBase->getUpsampledPreModeCU(cuIdx);
711    char* pPredModeDst = pcCUDes->getPredictionMode();
712    memcpy(pPredModeDst, pPredModeSrc, sizeof(char)*uiNumPartitions);
713    memset( pcCUDes->getPartitionSize(), SIZE_2Nx2N, sizeof(char)*uiNumPartitions);
714  }
715}
716#endif
717
718#endif
719
720//! \}
Note: See TracBrowser for help on using the repository browser.