source: 3DVCSoftware/branches/0.1-poznan-univ/source/Lib/TLibCommon/TComDepthMapGenerator.cpp @ 4

Last change on this file since 4 was 2, checked in by hhi, 13 years ago

inital import

  • Property svn:eol-style set to native
File size: 57.6 KB
Line 
1
2
3/** \file     TComDepthMapGenerator.cpp
4    \brief    depth map generator class
5*/
6
7
8
9#include "CommonDef.h"
10#include "TComDepthMapGenerator.h"
11
12
13
14TComDepthMapGenerator::TComDepthMapGenerator()
15{
16  m_bCreated            = false;
17  m_bInit               = false;
18  m_bDecoder            = false;
19  m_pcPrediction        = 0;
20  m_pcSPSAccess         = 0;
21  m_pcAUPicAccess       = 0;
22  m_uiMaxDepth          = 0;
23  m_uiOrgDepthBitDepth  = 0;
24  m_ppcYuv              = 0;
25  m_ppcCU               = 0;
26}
27
28TComDepthMapGenerator::~TComDepthMapGenerator()
29{
30  destroy ();
31  uninit  ();
32}
33
34Void
35TComDepthMapGenerator::create( Bool bDecoder, UInt uiPicWidth, UInt uiPicHeight, UInt uiMaxCUDepth, UInt uiMaxCUWidth, UInt uiMaxCUHeight, UInt uiOrgBitDepth )
36{
37  destroy();
38  m_bDecoder            = bDecoder;
39  m_uiMaxDepth          = uiMaxCUDepth;
40  m_uiOrgDepthBitDepth  = uiOrgBitDepth;
41  m_ppcYuv              = new TComYuv*    [ m_uiMaxDepth ];
42  m_ppcCU               = new TComDataCU* [ m_uiMaxDepth ];
43  for( UInt uiDepth = 0; uiDepth < m_uiMaxDepth; uiDepth++ )
44  {
45    UInt  uiNumPart = 1 << ( ( m_uiMaxDepth - uiDepth ) << 1 );
46    UInt  uiWidth   = uiMaxCUWidth  >> uiDepth;
47    UInt  uiHeight  = uiMaxCUHeight >> uiDepth;
48
49    m_ppcYuv[ uiDepth ] = new TComYuv;    m_ppcYuv[ uiDepth ]->create(            uiWidth, uiHeight       );
50    m_ppcCU [ uiDepth ] = new TComDataCU; m_ppcCU [ uiDepth ]->create( uiNumPart, uiWidth, uiHeight, true );
51  }
52  m_cTmpPic.create( uiPicWidth, uiPicHeight, uiMaxCUWidth, uiMaxCUHeight, uiMaxCUDepth );
53  xSetChroma( &m_cTmpPic, ( 1 << uiOrgBitDepth ) >> 1 );
54  m_bCreated    = true;
55}
56
57Void
58TComDepthMapGenerator::destroy()
59{
60  if( m_bCreated )
61  {
62    m_bCreated    = false;
63    for( UInt uiDepth = 0; uiDepth < m_uiMaxDepth; uiDepth++ )
64    {
65      m_ppcYuv[ uiDepth ]->destroy(); delete m_ppcYuv[ uiDepth ]; m_ppcYuv[ uiDepth ] = 0;
66      m_ppcCU [ uiDepth ]->destroy(); delete m_ppcCU [ uiDepth ]; m_ppcCU [ uiDepth ] = 0;
67    }
68    delete [] m_ppcYuv; m_ppcYuv = 0;
69    delete [] m_ppcCU;  m_ppcCU  = 0;
70    m_cTmpPic.destroy();
71    m_uiMaxDepth          = 0;
72    m_uiOrgDepthBitDepth  = 0;
73    m_bDecoder            = false;
74  }
75}
76
77Void
78TComDepthMapGenerator::init( TComPrediction* pcPrediction, TComSPSAccess* pcSPSAccess, TComAUPicAccess* pcAUPicAccess )
79{
80  AOF( pcPrediction  );
81  AOF( pcSPSAccess   );
82  AOF( pcAUPicAccess );
83  uninit();
84  m_pcPrediction  = pcPrediction;
85  m_pcSPSAccess   = pcSPSAccess;
86  m_pcAUPicAccess = pcAUPicAccess;
87  m_bInit         = true;
88}
89
90Void
91TComDepthMapGenerator::uninit()
92{
93  if( m_bInit )
94  {
95    m_bInit         = false;
96    m_pcPrediction  = 0;
97    m_pcSPSAccess   = 0;
98    m_pcAUPicAccess = 0;
99  }
100}
101
102Void 
103TComDepthMapGenerator::initViewComponent( TComPic* pcPic )
104{
105  AOF  ( m_bCreated && m_bInit );
106  AOF  ( pcPic );
107  AOT  ( pcPic->getSPS()->getViewId() && !pcPic->getSPS()->isDepth() && pcPic->getPOC() && pcPic->getSPS()->getPredDepthMapGeneration() != m_pcSPSAccess->getPdm() );
108  m_bPDMAvailable = false;
109  m_uiCurrViewId  = pcPic->getSPS()->getViewId();
110
111  // update SPS list and AU pic list and set depth map generator in SPS
112  m_pcSPSAccess  ->addSPS( pcPic->getSPS() );
113  m_pcAUPicAccess->addPic( pcPic );
114  pcPic->getSPS()->setDepthMapGenerator( this );
115
116  // check whether we have depth data or don't use pred depth prediction
117  ROFVS( pcPic->getSPS()->getViewId() );
118  ROTVS( pcPic->getSPS()->isDepth  () );
119  ROFVS( m_pcSPSAccess->getPdm     () );
120
121  // set basic SPS parameters
122  const Int iDisparityDir = 1; // 1 or -1, depending on the usage of disparity vectors
123  TComSPS*  pcSPS         = pcPic->getSPS                 ();
124  Int       iVOI          = pcSPS->getViewOrderIdx        ();
125  UInt      uiPdmPrec     = pcSPS->getPdmPrecision        ();
126  UInt      uiCamPrec     = pcSPS->getCamParPrecision     ();
127  Bool      bInSlice      = pcSPS->hasCamParInSliceHeader ();
128  Int       iScaleVOI01   = ( 1 << ( uiPdmPrec + PDM_INTER_CALC_SHIFT + PDM_VIRT_DEPTH_PRECISION - 2 ) );
129
130  // check availability of base views and set base id list
131  std::vector<Int>  aiAbsDeltaVOI;
132  for( UInt uiBaseId = 0; uiBaseId < m_uiCurrViewId; uiBaseId++ )
133  {
134    TComSPS*  pcBaseSPS     = m_pcSPSAccess  ->getSPS( uiBaseId );
135    TComPic*  pcBasePic     = m_pcAUPicAccess->getPic( uiBaseId );
136    AOF( pcBaseSPS != 0 && pcBasePic != 0 );
137    Int       iDeltaVOI     = iVOI - pcBaseSPS->getViewOrderIdx();
138    Int       iAbsDeltaVOI  = ( iDeltaVOI < 0 ? -iDeltaVOI : iDeltaVOI ); 
139    AOT( iAbsDeltaVOI == 0 );
140    aiAbsDeltaVOI.push_back( iAbsDeltaVOI );
141  }
142  m_auiBaseIdList.clear();
143  while( (UInt)m_auiBaseIdList.size() < m_uiCurrViewId )
144  {
145    Int       iMinAbsDelta  = MAX_INT;
146    UInt      uiNextBaseId  = MAX_NUMBER_VIEWS;
147    for( UInt uiBaseId = 0; uiBaseId < m_uiCurrViewId; uiBaseId++ )
148    {
149      if( aiAbsDeltaVOI[ uiBaseId ] > 0 && aiAbsDeltaVOI[ uiBaseId ] <= iMinAbsDelta )
150      {
151        iMinAbsDelta  = aiAbsDeltaVOI[ uiBaseId ];
152        uiNextBaseId  = uiBaseId;
153      }
154    }
155    m_auiBaseIdList.push_back( uiNextBaseId );
156    aiAbsDeltaVOI[ uiNextBaseId ] = 0;
157  }
158
159  // check availability of prediction depth map
160  if( m_uiCurrViewId )
161  {
162    Bool      bCheckVId1  = ( m_uiCurrViewId > 1 && m_auiBaseIdList[0] == 0 );
163    UInt      uiBaseVId   = ( bCheckVId1 ? 1 : m_auiBaseIdList[0] );
164    TComPic*  pcBasePic   = m_pcAUPicAccess->getPic( uiBaseVId );
165    SliceType eSliceType  = pcBasePic->getCurrSlice()->getSliceType();
166    Bool      bNoRAPdm    = ( pcPic->getSPS()->getPredDepthMapGeneration() == 1 );
167    m_bPDMAvailable       = ( eSliceType != I_SLICE || !bNoRAPdm );
168  }
169
170  // update disparity depth conversion parameters
171  for( UInt uiBaseId = 0; uiBaseId < m_uiCurrViewId; uiBaseId++ )
172  {
173    TComSPS*  pcBaseSPS   = m_pcSPSAccess->getSPS( uiBaseId );
174    Int       iBaseVOI    = pcBaseSPS->getViewOrderIdx();
175
176    // disparity -> virtual depth
177    Int       iVNominator = ( 1 << PDM_LOG4_SCALE_DENOMINATOR ) + pcSPS->getPdmScaleNomDelta()[ uiBaseId ];
178    Int       iVDiv       = iVOI - iBaseVOI;
179    Int       iVAdd       = ( iVDiv > 0 ? iVDiv / 2 : -iVDiv / 2 );
180    Int       iVScalePred = ( iScaleVOI01 + iVAdd ) / iVDiv;
181    Int       iVShift     = PDM_INTER_CALC_SHIFT;
182    Int       iVScale     = Int( ( (Int64)iVNominator * (Int64)iVScalePred + (Int64)( ( 1 << PDM_LOG4_SCALE_DENOMINATOR ) >> 1 ) ) >> PDM_LOG4_SCALE_DENOMINATOR );
183    Int       iVOffset    = pcSPS->getPdmOffset()[ uiBaseId ] << PDM_OFFSET_SHIFT;
184    m_aaiConvParsDisparity2VirtDepth[ uiBaseId ][ 0 ] = iDisparityDir * iVScale;
185    m_aaiConvParsDisparity2VirtDepth[ uiBaseId ][ 1 ] = iDisparityDir * iVOffset + ( ( 1 << iVShift ) >> 1 );
186    m_aaiConvParsDisparity2VirtDepth[ uiBaseId ][ 2 ] = iVShift;
187
188    // virtual depth -> disparity
189    Int       iVInvAdd    = ( iVScale > 0 ? iVScale / 2 : -iVScale / 2 );
190    Int       iVInvScale  = Int( ( ( Int64(  1        ) << ( iVShift << 1 ) ) + iVInvAdd ) / Int64( iVScale ) );
191    Int       iVInvOffset = Int( ( ( Int64( -iVOffset ) <<   iVShift        ) + iVInvAdd ) / Int64( iVScale ) );
192    m_aaiConvParsVirtDepth2Disparity[ uiBaseId ][ 0 ] = iDisparityDir * iVInvScale;
193    m_aaiConvParsVirtDepth2Disparity[ uiBaseId ][ 1 ] = iDisparityDir * iVInvOffset + ( ( 1 << iVShift ) >> 1 );
194    m_aaiConvParsVirtDepth2Disparity[ uiBaseId ][ 2 ] = iVShift;
195
196    // coded depth -> virtual depth
197    Int       iCScale     = ( bInSlice ? pcPic->getCurrSlice()->getCodedScale () : pcSPS->getCodedScale () )[ uiBaseId ];
198    Int       iCOffset    = ( bInSlice ? pcPic->getCurrSlice()->getCodedOffset() : pcSPS->getCodedOffset() )[ uiBaseId ] << m_uiOrgDepthBitDepth;
199    Int       iCShift     = m_uiOrgDepthBitDepth + uiCamPrec + 1 - 2;
200    Int       iCVShift    = PDM_INTER_CALC_SHIFT;
201    Int       iTmpShift   = iVShift + iCShift - iCVShift; AOF( iTmpShift >= 0 )
202    Int       iCVScale    = Int( ( Int64( iVScale ) * Int64( iCScale  ) + Int64( ( 1 << iTmpShift ) >> 1 ) ) >> iTmpShift );
203    Int       iCVOffset   = Int( ( Int64( iVScale ) * Int64( iCOffset ) + Int64( ( 1 << iTmpShift ) >> 1 ) ) >> iTmpShift );
204    iTmpShift             = iVShift - iCVShift;           AOF( iTmpShift >= 0 )
205    iCVOffset            +=      ( iVOffset                             +      ( ( 1 << iTmpShift ) >> 1 ) ) >> iTmpShift;
206    m_aaiConvParsOrigDepth2VirtDepth[ uiBaseId ][ 0 ] = iCVScale;
207    m_aaiConvParsOrigDepth2VirtDepth[ uiBaseId ][ 1 ] = iCVOffset + ( ( 1 << iCVShift ) >> 1 );
208    m_aaiConvParsOrigDepth2VirtDepth[ uiBaseId ][ 2 ] = iCVShift;
209
210    // virtual depth -> coded depth
211    Int       iCVAdd      = ( iCVScale > 0 ? iCVScale / 2 : -iCVScale / 2 );
212    Int       iCVInvScale = Int( ( ( Int64(  1         ) << ( iCVShift << 1 ) ) + iCVAdd ) / Int64( iCVScale ) );
213    Int       iCVInvOffset= Int( ( ( Int64( -iCVOffset ) <<   iCVShift        ) + iCVAdd ) / Int64( iCVScale ) );
214    m_aaiConvParsVirtDepth2OrigDepth[ uiBaseId ][ 0 ] = iCVInvScale;
215    m_aaiConvParsVirtDepth2OrigDepth[ uiBaseId ][ 1 ] = iCVInvOffset + ( ( 1 << iCVShift ) >> 1 );
216    m_aaiConvParsVirtDepth2OrigDepth[ uiBaseId ][ 2 ] = iCVShift;
217  }
218
219  if( m_uiCurrViewId > 0 )
220  {
221    UInt      uiBaseId    = 0;
222    UInt      uiBaseVOI   = 0; // per definition
223    Int       iVNominator = ( 1 << PDM_LOG4_SCALE_DENOMINATOR ) + pcSPS->getPdmScaleNomDelta()[ uiBaseId ];
224    Int       iVDiv       = iVOI - uiBaseVOI;
225    Int       iVAdd       = ( iVDiv > 0 ? iVDiv / 2 : -iVDiv / 2 );
226    Int       iVScalePred = ( iScaleVOI01 + iVAdd ) / iVDiv;
227    Int       iVShift     = PDM_INTER_CALC_SHIFT;
228    Int       iVScale     = Int( ( (Int64)iVNominator * (Int64)iVScalePred + (Int64)( ( 1 << PDM_LOG4_SCALE_DENOMINATOR ) >> 1 ) ) >> PDM_LOG4_SCALE_DENOMINATOR );
229    Int       iVOffset    = pcSPS->getPdmOffset()[ uiBaseId ] << PDM_OFFSET_SHIFT;
230
231    // coded depth -> virtual depth (current view)
232    Int       iCScale     = ( bInSlice ? pcPic->getCurrSlice()->getInvCodedScale () : pcSPS->getInvCodedScale () )[ uiBaseId ];
233    Int       iCOffset    = ( bInSlice ? pcPic->getCurrSlice()->getInvCodedOffset() : pcSPS->getInvCodedOffset() )[ uiBaseId ] << m_uiOrgDepthBitDepth;
234    Int       iCShift     = m_uiOrgDepthBitDepth + uiCamPrec + 1 - 2;
235    Int       iCVShift    = PDM_INTER_CALC_SHIFT;
236    Int       iTmpShift   = iVShift + iCShift - iCVShift; AOF( iTmpShift >= 0 )
237    Int       iCVScale    = Int( ( Int64( -iVScale ) * Int64( iCScale  ) + Int64( ( 1 << iTmpShift ) >> 1 ) ) >> iTmpShift );
238    Int       iCVOffset   = Int( ( Int64( -iVScale ) * Int64( iCOffset ) + Int64( ( 1 << iTmpShift ) >> 1 ) ) >> iTmpShift );
239    iTmpShift             = iVShift - iCVShift;           AOF( iTmpShift >= 0 )
240    iCVOffset            +=      ( iVOffset                             +      ( ( 1 << iTmpShift ) >> 1 ) ) >> iTmpShift;
241    m_aaiConvParsOrigDepth2VirtDepth[ m_uiCurrViewId ][ 0 ] = iCVScale;
242    m_aaiConvParsOrigDepth2VirtDepth[ m_uiCurrViewId ][ 1 ] = iCVOffset + ( ( 1 << iCVShift ) >> 1 );
243    m_aaiConvParsOrigDepth2VirtDepth[ m_uiCurrViewId ][ 2 ] = iCVShift;
244
245    // virtual depth -> coded depth
246    Int       iCVAdd      = ( iCVScale > 0 ? iCVScale / 2 : -iCVScale / 2 );
247    Int       iCVInvScale = Int( ( ( Int64(  1         ) << ( iCVShift << 1 ) ) + iCVAdd ) / Int64( iCVScale ) );
248    Int       iCVInvOffset= Int( ( ( Int64( -iCVOffset ) <<   iCVShift        ) + iCVAdd ) / Int64( iCVScale ) );
249    m_aaiConvParsVirtDepth2OrigDepth[ m_uiCurrViewId ][ 0 ] = iCVInvScale;
250    m_aaiConvParsVirtDepth2OrigDepth[ m_uiCurrViewId ][ 1 ] = iCVInvOffset + ( ( 1 << iCVShift ) >> 1 );
251    m_aaiConvParsVirtDepth2OrigDepth[ m_uiCurrViewId ][ 2 ] = iCVShift;
252  }
253  else if( pcPic->getPOC() == 0 )
254  { // set dummy values
255    m_aaiConvParsOrigDepth2VirtDepth[ m_uiCurrViewId ][ 0 ] = 0;
256    m_aaiConvParsOrigDepth2VirtDepth[ m_uiCurrViewId ][ 1 ] = 0;
257    m_aaiConvParsOrigDepth2VirtDepth[ m_uiCurrViewId ][ 2 ] = 0;
258    m_aaiConvParsVirtDepth2OrigDepth[ m_uiCurrViewId ][ 0 ] = 0;
259    m_aaiConvParsVirtDepth2OrigDepth[ m_uiCurrViewId ][ 1 ] = 0;
260    m_aaiConvParsVirtDepth2OrigDepth[ m_uiCurrViewId ][ 2 ] = 0;
261  }
262
263
264#if 0 // print out for debugging
265  if( m_uiCurrViewId )
266  {
267    printf( "\n\ninit slice of view %d (VOI=%2d):\n===============================\n", m_uiCurrViewId, iVOI );
268    {
269      printf( "\n  disparity -> virtual depth:\n" );
270      for( UInt uiBaseId = 0; uiBaseId < m_uiCurrViewId; uiBaseId++ )
271      {
272        Int*    pP = m_aaiConvParsDisparity2VirtDepth[ uiBaseId ];
273        Double  dF = 1.0 / Double( 1 << pP[ 2 ] );
274        Double  dA = dF  * Double( pP[ 0 ] );
275        Double  dB = dF  * Double( pP[ 1 ] - ( ( 1 << pP[ 2 ] ) >> 1 ) );
276        printf( "    BId=%d:    a = %10.4lf    b = %10.4lf\n", uiBaseId, dA, dB );
277      }
278      printf( "\n  virtual depth -> disparity:\n" );
279      for( UInt uiBaseId = 0; uiBaseId < m_uiCurrViewId; uiBaseId++ )
280      {
281        Int*    pP = m_aaiConvParsVirtDepth2Disparity[ uiBaseId ];
282        Double  dF = 1.0 / Double( 1 << pP[ 2 ] );
283        Double  dA = dF  * Double( pP[ 0 ] );
284        Double  dB = dF  * Double( pP[ 1 ] - ( ( 1 << pP[ 2 ] ) >> 1 ) );
285        printf( "    BId=%d:    a = %10.4lf    b = %10.4lf\n", uiBaseId, dA, dB );
286      }
287      printf( "\n  original depth -> virtual depth:\n" );
288      for( UInt uiBaseId = 0; uiBaseId <= m_uiCurrViewId; uiBaseId++ )
289      {
290        Int*    pP = m_aaiConvParsOrigDepth2VirtDepth[ uiBaseId ];
291        Double  dF = 1.0 / Double( 1 << pP[ 2 ] );
292        Double  dA = dF  * Double( pP[ 0 ] );
293        Double  dB = dF  * Double( pP[ 1 ] - ( ( 1 << pP[ 2 ] ) >> 1 ) );
294        printf( "    VId=%d:    a = %10.4lf    b = %10.4lf\n", uiBaseId, dA, dB );
295      }
296      printf( "\n  virtual depth -> original depth:\n" );
297      for( UInt uiBaseId = 0; uiBaseId <= m_uiCurrViewId; uiBaseId++ )
298      {
299        Int*    pP = m_aaiConvParsVirtDepth2OrigDepth[ uiBaseId ];
300        Double  dF = 1.0 / Double( 1 << pP[ 2 ] );
301        Double  dA = dF  * Double( pP[ 0 ] );
302        Double  dB = dF  * Double( pP[ 1 ] - ( ( 1 << pP[ 2 ] ) >> 1 ) );
303        printf( "    VId=%d:    a = %10.4lf    b = %10.4lf\n", uiBaseId, dA, dB );
304      }
305      printf( "\n" );
306    }
307  }
308#endif
309}
310
311
312Bool
313TComDepthMapGenerator::predictDepthMap( TComPic* pcPic )
314{
315  AOF  ( m_bCreated && m_bInit );
316  AOF  ( pcPic );
317  ROTRS( pcPic->getSPS()->isDepth(),  true );
318  ROFRS( m_pcSPSAccess->getPdm(),     true );
319  AOF  ( pcPic->getPredDepthMap() );
320  AOF  ( pcPic->getSPS()->getViewId() == m_uiCurrViewId );
321
322#if PDM_OUTPUT_PRED_DEPTH_MAP
323  Char acFilenameBase[1024];
324  ::sprintf( acFilenameBase, "PDM_%s_Prd", ( m_bDecoder ? "Dec" : "Enc" ) );
325#endif
326
327  Bool bUndefined = true;
328  if( m_uiCurrViewId )
329  {
330    AOF( m_auiBaseIdList.size() );
331    UInt        uiBaseId    = m_auiBaseIdList[ 0 ];
332    TComPic*    pcBasePic   = m_pcAUPicAccess->getPic( uiBaseId );
333    AOF( pcBasePic );
334
335    if( m_uiCurrViewId == 1 )
336    {
337      if( pcBasePic->getPOC() == 0 )
338      {
339        xClearDepthMap( pcBasePic );
340      }
341#if PDM_OUTPUT_PRED_DEPTH_MAP
342      dumpDepthMap( pcBasePic, acFilenameBase );
343#endif
344    }
345
346    Bool  bLoadDepth  = ( m_pcSPSAccess->getPdm() == 2 );
347    if( m_pcSPSAccess->getPdm() > 2 )
348    {
349      bLoadDepth = ( pcBasePic->getCurrSlice()->getSliceType() == I_SLICE );
350    }
351
352    if( bLoadDepth)
353    { // load coded depth of base view
354      TComPic*  pcBaseDepth = m_pcAUPicAccess->getPic( uiBaseId, true );
355      AOF( pcBaseDepth );
356      AOF( pcBaseDepth->getPicYuvRec() );
357      AOF( pcBaseDepth->getPicYuvRec()->getWidth () == pcBasePic->getPredDepthMap()->getWidth () );
358      AOF( pcBaseDepth->getPicYuvRec()->getHeight() == pcBasePic->getPredDepthMap()->getHeight() );
359      Int       iWidth      = pcBasePic  ->getPredDepthMap()->getWidth    ();
360      Int       iHeight     = pcBasePic  ->getPredDepthMap()->getHeight   ();
361      Int       iDesStride  = pcBasePic  ->getPredDepthMap()->getStride   ();
362      Int       iSrcStride  = pcBaseDepth->getPicYuvRec   ()->getStride   ();
363      Pel*      pDesSamples = pcBasePic  ->getPredDepthMap()->getLumaAddr ( 0 );
364      Pel*      pSrcSamples = pcBaseDepth->getPicYuvRec   ()->getLumaAddr ( 0 );
365      for( Int iY = 0; iY < iHeight; iY++, pSrcSamples += iSrcStride, pDesSamples += iDesStride )
366      {
367        for( Int iX = 0; iX < iWidth; iX++ )
368        {
369          pDesSamples[ iX ] = xGetVirtDepthFromOrigDepth( uiBaseId, pSrcSamples[ iX ] );
370        }
371      }
372    }
373
374    // convert depth of base view to current view
375    bUndefined = xConvertDepthMapRef2Curr( pcPic, pcBasePic );
376
377#if PDM_OUTPUT_PRED_DEPTH_MAP
378    dumpDepthMap( pcPic, acFilenameBase );
379#endif
380  }
381  else
382  {
383    xClearDepthMap( pcPic );
384  }
385  return bUndefined;
386}
387
388
389Void
390TComDepthMapGenerator::updateDepthMap( TComPic* pcPic )
391{
392  AOF  ( m_bCreated && m_bInit );
393  AOF  ( pcPic );
394  ROTVS( pcPic->getSPS()->isDepth() );
395  ROFVS( m_pcSPSAccess->getPdm() == 1 || m_pcSPSAccess->getPdm() == 3 );
396  AOF  ( pcPic->getPredDepthMap() );
397  AOF  ( pcPic->getSPS()->getViewId() == m_uiCurrViewId );
398
399#if PDM_OUTPUT_PRED_DEPTH_MAP
400  Char acFilenameBase[1024];
401  ::sprintf( acFilenameBase, "PDM_%s_Upd", ( m_bDecoder ? "Dec" : "Enc" ) );
402#endif
403
404  // predict depth map using current coding symbols
405  xPredictDepthMap( pcPic );
406#if PDM_OUTPUT_PRED_DEPTH_MAP
407  if( m_uiCurrViewId )
408  {
409    dumpDepthMap( pcPic, acFilenameBase );
410  }
411#endif
412
413  // generate base depth map
414  if( m_uiCurrViewId == 1 )
415  {
416    TComPic* pcBasePic = m_pcAUPicAccess->getPic( 0 );
417    AOF( pcBasePic );
418    xConvertDepthMapCurr2Ref( pcBasePic, pcPic );
419#if PDM_OUTPUT_PRED_DEPTH_MAP
420    dumpDepthMap( pcBasePic, acFilenameBase );
421#endif
422  }
423}
424
425
426Void
427TComDepthMapGenerator::dumpDepthMap( TComPic* pcPic, char* pFilenameBase )
428{
429  AOF( m_bCreated && m_bInit );
430  AOF( pcPic );
431  AOF( pFilenameBase );
432  AOF( m_uiOrgDepthBitDepth == 8 + g_uiBitIncrement );
433  AOF( pcPic->getSPS()->getViewId() <= m_uiCurrViewId );
434
435  // convert to output format
436  Int         iMax        = ( 1 << m_uiOrgDepthBitDepth ) - 1;
437  UInt        uiViewId    = pcPic->getSPS()->getViewId();
438  TComPicYuv* pcPicYuv    = pcPic->getPredDepthMap();
439  Int         iWidth      = pcPicYuv->getWidth    ();
440  Int         iHeight     = pcPicYuv->getHeight   ();
441  Int         iSrcStride  = pcPicYuv->getStride   ();
442  Int         iDstStride  = m_cTmpPic.getStride   ();
443  Pel*        pSrcSamples = pcPicYuv->getLumaAddr ( 0 );
444  Pel*        pDstSamples = m_cTmpPic.getLumaAddr ( 0 );
445  Int         iMidOrgDpth = ( 1 << m_uiOrgDepthBitDepth ) >> 1;
446  AOF( m_cTmpPic.getWidth () == iWidth  );
447  AOF( m_cTmpPic.getHeight() == iHeight );
448  for( Int iY = 0; iY < iHeight; iY++, pSrcSamples += iSrcStride, pDstSamples += iDstStride )
449  {
450    for( Int iX = 0; iX < iWidth; iX++ )
451    {
452      Int iOrgDepth     = ( pSrcSamples[ iX ] != PDM_UNDEFINED_DEPTH ? xGetOrigDepthFromVirtDepth( uiViewId, pSrcSamples[ iX ] ) : iMidOrgDpth );
453      pDstSamples[ iX ] = Max( 0, Min( iMax, iOrgDepth ) );
454    }
455  }
456
457  // output
458  Char  acFilename[1024];
459  ::sprintf     ( acFilename, "%s_V%d.yuv", pFilenameBase, uiViewId );
460  m_cTmpPic.dump( acFilename, ( pcPic->getPOC() != 0 )  );
461}
462
463
464Void 
465TComDepthMapGenerator::covertOrgDepthMap( TComPic* pcPic )
466{
467  AOF  ( m_bCreated && m_bInit   );
468  AOF  ( pcPic );
469  ROFVS( pcPic->getOrgDepthMap() );
470  AOF  ( pcPic->getViewIdx() );
471
472  UInt  uiBaseId = pcPic->getViewIdx();
473  Int   iWidth   = pcPic->getOrgDepthMap()->getWidth    ();
474  Int   iHeight  = pcPic->getOrgDepthMap()->getHeight   ();
475  Int   iStride  = pcPic->getOrgDepthMap()->getStride   ();
476  Pel*  pSamples = pcPic->getOrgDepthMap()->getLumaAddr ( 0 );
477  for( Int iY = 0; iY < iHeight; iY++, pSamples += iStride )
478  {
479    for( Int iX = 0; iX < iWidth; iX++ )
480    {
481      pSamples[ iX ] = xGetVirtDepthFromOrigDepth( uiBaseId, pSamples[ iX ] );
482    }
483  }
484}
485
486
487Int
488TComDepthMapGenerator::getDisparity( TComPic* pcPic, Int iPosX, Int iPosY, UInt uiRefViewId )
489{
490  AOF( pcPic );
491  AOF( pcPic->getPredDepthMap() );
492  AOF( iPosX >= 0 && iPosX < pcPic->getPredDepthMap()->getWidth () );
493  AOF( iPosY >= 0 && iPosY < pcPic->getPredDepthMap()->getHeight() );
494  Pel*   piPdmMap    = pcPic->getPredDepthMap()->getLumaAddr( 0 );
495  Int    iStride     = pcPic->getPredDepthMap()->getStride  ();
496  Int    iPrdDepth   = piPdmMap[ iPosX + iPosY * iStride ];
497  Int    iDisparity  = xGetDisparityFromVirtDepth( uiRefViewId, iPrdDepth );
498  return iDisparity;
499}
500
501
502
503Int
504TComDepthMapGenerator::getPdmMergeCandidate( TComDataCU* pcCU, UInt uiPartIdx, Int* paiPdmRefIdx, TComMv* pacPdmMv )
505{
506  Int  iMaxNumInterPics  = 1;
507  Int  iMaxNumAllPics    = 2;
508
509  // inter-only
510  Bool abPdmAvailable[2] = {false,false};
511  for( Int iRefListId = 0; iRefListId < 2; iRefListId++ )
512  {
513    RefPicList  eRefPicList       = RefPicList( iRefListId );
514    Int         iNumRefPics       = pcCU->getSlice()->getNumRefIdx( eRefPicList );
515    TComMv      cMv;
516    for( Int iPdmRefIdx = 0, iInterPics = 0; iPdmRefIdx < iNumRefPics && iInterPics < iMaxNumInterPics; iPdmRefIdx++ )
517    {
518      if( pcCU->getSlice()->getRefPOC( eRefPicList, iPdmRefIdx ) != pcCU->getSlice()->getPOC() )
519      {
520        if( getPdmMvPred( pcCU, uiPartIdx, eRefPicList, iPdmRefIdx, cMv, true ) )
521        {
522          pcCU->clipMv( cMv );
523          abPdmAvailable[ iRefListId ] = true;
524          paiPdmRefIdx  [ iRefListId ] = iPdmRefIdx;
525          pacPdmMv      [ iRefListId ] = cMv;
526          break;
527        }
528        iInterPics++;
529      }
530    }
531  }
532  Int    iPdmInterDir = ( abPdmAvailable[0] ? 1 : 0 ) + ( abPdmAvailable[1] ? 2 : 0 );
533  if( 0==iPdmInterDir )
534  { // check all, including inter view references
535    for( Int iRefListId = 0; iRefListId < 2; iRefListId++ )
536    {
537      RefPicList  eRefPicList = RefPicList( iRefListId );
538      Int         iNumRefPics = Min( iMaxNumAllPics, pcCU->getSlice()->getNumRefIdx( eRefPicList ) );
539      TComMv      cMv;
540      for( Int iPdmRefIdx = 0; iPdmRefIdx < iNumRefPics; iPdmRefIdx++ )
541      {
542        if( getPdmMvPred( pcCU, uiPartIdx, eRefPicList, iPdmRefIdx, cMv, true ) )
543        {
544          pcCU->clipMv( cMv );
545          abPdmAvailable[ iRefListId ] = true;
546          paiPdmRefIdx  [ iRefListId ] = iPdmRefIdx;
547          pacPdmMv      [ iRefListId ] = cMv;
548          break;
549        }
550      }
551    }
552    iPdmInterDir = ( abPdmAvailable[0] ? 1 : 0 ) + ( abPdmAvailable[1] ? 2 : 0 );
553  }
554  return iPdmInterDir;
555}
556
557
558Bool 
559TComDepthMapGenerator::getPdmMvPred( TComDataCU* pcCU, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMv, Bool bMerge )
560{
561  AOF  ( m_bCreated && m_bInit );
562  AOF  ( iRefIdx >= 0 );
563  AOF  ( pcCU );
564  ROFRS( m_bPDMAvailable, false );
565
566  TComSlice*    pcSlice     = pcCU->getSlice ();
567  TComPic*      pcPic       = pcCU->getPic   ();
568  TComSPS*      pcSPS       = pcSlice->getSPS();
569  AOF  ( pcPic->getPredDepthMap() );
570  AOF  ( pcSPS->getViewId() == m_uiCurrViewId );
571 
572  TComPic*      pcRefPic    = pcSlice->getRefPic( eRefPicList, iRefIdx );
573  UInt          uiRefViewId = pcRefPic->getSPS()->getViewId();
574  Int           iRefPoc     = pcRefPic->getPOC();
575  Bool          bInterview  = ( uiRefViewId < m_uiCurrViewId );
576  AOT(  bInterview && iRefPoc != pcSlice->getPOC() );
577  AOT( !bInterview && iRefPoc == pcSlice->getPOC() );
578
579  Bool          bPdmIView   = ( ( pcSPS->getMultiviewMvPredMode() & PDM_USE_FOR_IVIEW ) == PDM_USE_FOR_IVIEW );
580  Bool          bPdmInter   = ( ( pcSPS->getMultiviewMvPredMode() & PDM_USE_FOR_INTER ) == PDM_USE_FOR_INTER );
581  Bool          bPdmMerge   = ( ( pcSPS->getMultiviewMvPredMode() & PDM_USE_FOR_MERGE ) == PDM_USE_FOR_MERGE );
582  ROTRS( ( bInterview && !bMerge ) && !bPdmIView, false );
583  ROTRS( (!bInterview && !bMerge ) && !bPdmInter, false );
584  ROTRS(                  bMerge   && !bPdmMerge, false );
585
586  //===== get predicted depth for middle position of current PU ===== 
587  Int  iPrdDepth, iCurrPosX, iCurrPosY;
588  Bool bAvailable  = xGetPredDepth( pcCU, uiPartIdx, iPrdDepth, &iCurrPosX, &iCurrPosY );
589  AOF( bAvailable );
590 
591  //===== inter-view motion vector prediction =====
592  if( bInterview )
593  {
594    Int         iDisparity  = xGetDisparityFromVirtDepth( uiRefViewId, iPrdDepth );
595    rcMv.set  ( iDisparity, 0 );
596    return      true;
597  }
598 
599  //===== inter motion vector prediction =====
600  for( UInt uiBId = 0; uiBId < m_uiCurrViewId; uiBId++ )
601  {
602    //--- get base CU/PU and check prediction mode ---
603    UInt        uiBaseId    = m_auiBaseIdList[ uiBId ];
604    TComPic*    pcBasePic   = m_pcAUPicAccess->getPic( uiBaseId );
605    TComPicYuv* pcBasePdm   = pcBasePic->getPredDepthMap();
606    TComPicYuv* pcBaseRec   = pcBasePic->getPicYuvRec   ();
607    Int         iDisparity  = xGetDisparityFromVirtDepth( uiBaseId, iPrdDepth );
608    Int         iBasePosX   = Clip3( 0, pcBasePdm->getWidth () - 1, iCurrPosX + ( ( iDisparity + 2 ) >> 2 ) );
609    Int         iBasePosY   = Clip3( 0, pcBasePdm->getHeight() - 1, iCurrPosY                               );
610    Int         iBaseCUAddr;
611    Int         iBaseAbsPartIdx;
612    pcBaseRec->getCUAddrAndPartIdx( iBasePosX, iBasePosY, iBaseCUAddr, iBaseAbsPartIdx );
613    TComDataCU* pcBaseCU    = pcBasePic->getCU( iBaseCUAddr );
614    if( pcBaseCU->getPredictionMode( iBaseAbsPartIdx ) != MODE_INTER && pcBaseCU->getPredictionMode( iBaseAbsPartIdx ) != MODE_SKIP )
615    {
616      continue;
617    }
618
619    for( UInt uiBaseRefListId = 0; uiBaseRefListId < 2; uiBaseRefListId++ )
620    {
621      RefPicList  eBaseRefPicList = RefPicList( uiBaseRefListId );
622      TComMvField cBaseMvField;
623      pcBaseCU->getMvField( pcBaseCU, iBaseAbsPartIdx, eBaseRefPicList, cBaseMvField );
624      Int         iBaseRefIdx     = cBaseMvField.getRefIdx();
625      Int         iBaseRefPoc     = ( iBaseRefIdx >= 0 ? pcBaseCU->getSlice()->getRefPic( eBaseRefPicList, iBaseRefIdx )->getPOC() : -(1<<30) );
626      if( iBaseRefIdx >= 0 && iBaseRefPoc == iRefPoc )
627      {
628        rcMv.set( cBaseMvField.getHor(), cBaseMvField.getVer() );
629        return true;
630      }
631    }
632  }
633  return false;
634}
635
636
637Bool  // first version
638TComDepthMapGenerator::getIViewOrgDepthMvPred( TComDataCU* pcCU, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMv )
639{
640  AOF  ( m_bCreated && m_bInit );
641  AOF  ( iRefIdx >= 0 );
642  AOF  ( pcCU );
643
644  TComSlice*    pcSlice     = pcCU->getSlice ();
645  TComPic*      pcPic       = pcCU->getPic   ();
646  TComSPS*      pcSPS       = pcSlice->getSPS();
647  AOF  ( pcSPS->getViewId() == m_uiCurrViewId );
648  ROFRS( pcPic->getOrgDepthMap(),      false );
649 
650  TComPic*      pcRefPic    = pcSlice->getRefPic( eRefPicList, iRefIdx );
651  UInt          uiRefViewId = pcRefPic->getSPS()->getViewId();
652  Int           iRefPoc     = pcRefPic->getPOC();
653  ROFRS( uiRefViewId < m_uiCurrViewId, false );
654  AOF  ( iRefPoc    == pcSlice->getPOC() );
655
656  //===== get predicted depth for middle position of current PU (first version) ===== 
657  UInt          uiPartAddr;
658  Int           iWidth;
659  Int           iHeight;
660  pcCU->getPartIndexAndSize( uiPartIdx, uiPartAddr, iWidth, iHeight );
661  TComPicYuv*   pcOrgDepthMap  = pcPic->getOrgDepthMap();
662  Pel*          piOrgDepthMap  = pcOrgDepthMap->getLumaAddr ( 0 );
663  Int           iCurrStride    = pcOrgDepthMap->getStride   ();
664  Int           iCurrPosX;
665  Int           iCurrPosY;
666  pcOrgDepthMap->getTopLeftSamplePos( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiPartAddr, iCurrPosX, iCurrPosY );
667  iCurrPosX                    += ( iWidth  - 1 ) >> 1;
668  iCurrPosY                    += ( iHeight - 1 ) >> 1;
669  Int           iPrdDepth       = piOrgDepthMap[ iCurrPosX + iCurrPosY * iCurrStride ];
670 
671  //===== get disparity vector =====
672  Int           iDisparity      = xGetDisparityFromVirtDepth( uiRefViewId, iPrdDepth );
673  rcMv.set    ( iDisparity, 0 );
674  return        true;
675}
676
677
678
679
680
681
682
683/*=======================================================*
684 *=====                                             =====*
685 *=====     p i c t u r e   o p e r a t i o n s     =====*
686 *=====                                             =====*
687 *=======================================================*/
688
689Bool
690TComDepthMapGenerator::xConvertDepthMapCurr2Ref( TComPic* pcRef, TComPic* pcCur )
691{
692  AOF( pcCur->getSPS()->getViewId() == m_uiCurrViewId );
693  AOF( pcCur->getSPS()->getViewId()  > pcRef->getSPS()->getViewId() );
694  AOF( pcCur->getPredDepthMap() );
695  AOF( pcRef->getPredDepthMap() );
696  AOF( pcRef->getPredDepthMap()->getWidth () == pcCur->getPredDepthMap()->getWidth () );
697  AOF( pcRef->getPredDepthMap()->getHeight() == pcCur->getPredDepthMap()->getHeight() );
698
699  xClearDepthMap( pcRef );
700  TComPicYuv* pcCurDepthMap =  pcCur->getPredDepthMap    ();
701  TComPicYuv* pcRefDepthMap =  pcRef->getPredDepthMap    ();
702  Int         iWidth        =  pcCurDepthMap->getWidth   ();
703  Int         iHeight       =  pcCurDepthMap->getHeight  ();
704  Int         iCurStride    =  pcCurDepthMap->getStride  ();
705  Int         iRefStride    =  pcRefDepthMap->getStride  ();
706  Pel*        pCurSamples   =  pcCurDepthMap->getLumaAddr( 0 );
707  Pel*        pRefSamples   =  pcRefDepthMap->getLumaAddr( 0 );
708  Int         iRefViewIdx   =  pcRef->getViewIdx();
709  for( Int iY = 0; iY < iHeight; iY++, pCurSamples += iCurStride, pRefSamples += iRefStride )
710  {
711    for( Int iXCur = 0; iXCur < iWidth; iXCur++ )
712    {
713      Int iDepth = pCurSamples[ iXCur ];
714      Int iDisp  = xGetDisparityFromVirtDepth( iRefViewIdx, iDepth );
715      Int iXRef  = iXCur + ( ( iDisp + 2 ) >> 2 );
716      if( iXRef >= 0 && iXRef < iWidth && iDepth > pRefSamples[ iXRef ] )
717      {
718        pRefSamples[ iXRef ] = iDepth;
719      }
720    }
721  }
722  Bool    bUndefined = xFillDepthMapHoles( pcRef );
723  pcRefDepthMap->setBorderExtension( false );
724  pcRefDepthMap->extendPicBorder   ();
725  return  bUndefined;
726}
727
728
729Bool
730TComDepthMapGenerator::xConvertDepthMapRef2Curr( TComPic* pcCur, TComPic* pcRef )
731{
732  AOF( pcCur->getSPS()->getViewId() == m_uiCurrViewId );
733  AOF( pcCur->getSPS()->getViewId()  > pcRef->getSPS()->getViewId() );
734  AOF( pcCur->getPredDepthMap() );
735  AOF( pcRef->getPredDepthMap() );
736  AOF( pcRef->getPredDepthMap()->getWidth () == pcCur->getPredDepthMap()->getWidth () );
737  AOF( pcRef->getPredDepthMap()->getHeight() == pcCur->getPredDepthMap()->getHeight() );
738
739  xClearDepthMap( pcCur );
740  TComPicYuv* pcRefDepthMap =  pcRef->getPredDepthMap    ();
741  TComPicYuv* pcCurDepthMap =  pcCur->getPredDepthMap    ();
742  Int         iWidth        =  pcRefDepthMap->getWidth   ();
743  Int         iHeight       =  pcRefDepthMap->getHeight  ();
744  Int         iRefStride    =  pcRefDepthMap->getStride  ();
745  Int         iCurStride    =  pcCurDepthMap->getStride  ();
746  Pel*        pRefSamples   =  pcRefDepthMap->getLumaAddr( 0 );
747  Pel*        pCurSamples   =  pcCurDepthMap->getLumaAddr( 0 );
748  Int         iRefViewIdx   =  pcRef->getViewIdx();
749  for( Int iY = 0; iY < iHeight; iY++, pRefSamples += iRefStride, pCurSamples += iCurStride )
750  {
751    for( Int iXRef = 0; iXRef < iWidth; iXRef++ )
752    {
753      Int iDepth = pRefSamples[ iXRef ];
754      Int iDisp  = xGetDisparityFromVirtDepth( iRefViewIdx, iDepth );
755      Int iXCur  = iXRef - ( ( iDisp + 2 ) >> 2 );
756      if( iXCur >= 0 && iXCur < iWidth && iDepth > pCurSamples[ iXCur ] )
757      {
758        pCurSamples[ iXCur ] = iDepth;
759      }
760    }
761  }
762  Bool    bUndefined = xFillDepthMapHoles( pcCur );
763  pcCurDepthMap->setBorderExtension( false );
764  pcCurDepthMap->extendPicBorder   ();
765  return  bUndefined;
766}
767
768
769Bool
770TComDepthMapGenerator::xPredictDepthMap( TComPic* pcPic )
771{
772  for( UInt uiCUAddr = 0; uiCUAddr < pcPic->getPicSym()->getNumberOfCUsInFrame(); uiCUAddr++ )
773  {
774    TComDataCU* pcCU = pcPic->getCU( uiCUAddr );
775    xPredictCUDepthMap( pcCU, 0, 0 );
776  }
777  Bool    bUndefined = xFillDepthMapHoles( pcPic );
778  pcPic->getPredDepthMap()->setBorderExtension( false );
779  pcPic->getPredDepthMap()->extendPicBorder   ();
780  return  bUndefined;
781}
782
783
784Bool
785TComDepthMapGenerator::xFillDepthMapHoles( TComPic* pcPic )
786{
787  Bool        bUndefined  = false;     
788  TComPicYuv* pcDepthMap  = pcPic->getPredDepthMap  ();
789  Int         iWidth      = pcDepthMap->getWidth    ();
790  Int         iHeight     = pcDepthMap->getHeight   ();
791  Int         iStride     = pcDepthMap->getStride   ();
792  Pel*        pDMSamples  = pcDepthMap->getLumaAddr ( 0 );
793  // horizontal
794  for( Int iY = 0; iY < iHeight && !bUndefined; iY++, pDMSamples += iStride )
795  {
796    for( Int iX = 0; iX < iWidth; iX++ )
797    {
798      if( pDMSamples[ iX ] == PDM_UNDEFINED_DEPTH )
799      {
800        Int  iE;
801        for( iE = iX + 1; iE < iWidth; iE++ )
802        {
803          if( pDMSamples[ iE ] != PDM_UNDEFINED_DEPTH )
804          {
805            break;
806          }
807        }
808        if( iX > 0 || iE < iWidth )
809        {
810          Int iDepth;
811          if     ( iX > 0 && iE < iWidth )  iDepth  = ( pDMSamples[ iX-1 ] < pDMSamples[ iE ] ? pDMSamples[ iX-1 ] : pDMSamples[ iE ] ); 
812          else if( iX > 0 )                 iDepth  =   pDMSamples[ iX-1 ]; 
813          else /*( iE < iWidth )*/          iDepth  =   pDMSamples[ iE   ]; 
814          for( Int iZ = iX; iZ < iE; iZ++ )
815          {
816            pDMSamples[ iZ ] = iDepth;
817          }
818        }
819        else
820        {
821          bUndefined = true;
822                  break;
823        }
824        iX = iE - 1;
825      }
826    }
827  }
828 
829  if( bUndefined && m_uiCurrViewId )
830  {
831    pDMSamples          = pcDepthMap->getLumaAddr( 0 );
832    Int  iMiddleOrgDpth = ( 1 << m_uiOrgDepthBitDepth ) >> 1;
833    Int  iMiddleDepth   = xGetVirtDepthFromOrigDepth( m_uiCurrViewId, iMiddleOrgDpth );
834    for( Int iY = 0; iY < iHeight; iY++, pDMSamples += iStride )
835    {
836      for( Int iX = 0; iX < iWidth; iX++ )
837      {
838        pDMSamples[ iX ] = iMiddleDepth;
839       }
840    }
841  }
842  return bUndefined;
843}
844
845
846Void
847TComDepthMapGenerator::xClearDepthMap( TComPic* pcPic, Int iVal )
848{
849  TComPicYuv* pcDepthMap  = pcPic->getPredDepthMap  ();
850  Int         iWidth      = pcDepthMap->getWidth    ();
851  Int         iHeight     = pcDepthMap->getHeight   ();
852  Int         iStride     = pcDepthMap->getStride   ();
853  Pel*        pDMSamples  = pcDepthMap->getLumaAddr ( 0 );
854  for( Int iY = 0; iY < iHeight; iY++, pDMSamples += iStride )
855  {
856    for( Int iX = 0; iX < iWidth; iX++ )
857    {
858      pDMSamples[ iX ] = iVal;
859    }
860  }
861  pcDepthMap->setBorderExtension( false );
862  pcDepthMap->extendPicBorder   ();
863}
864
865Void 
866TComDepthMapGenerator::xSetChroma( TComPicYuv* pcPic, Int iVal )
867{
868  Int   iWidth      = pcPic->getWidth   () >> 1;
869  Int   iHeight     = pcPic->getHeight  () >> 1;
870  Int   iStride     = pcPic->getCStride ();
871  Pel*  pCbSamples  = pcPic->getCbAddr  ( 0 );
872  Pel*  pCrSamples  = pcPic->getCrAddr  ( 0 );
873  for( Int iY = 0; iY < iHeight; iY++, pCbSamples += iStride, pCrSamples += iStride )
874  {
875    for( Int iX = 0; iX < iWidth; iX++ )
876    {
877      pCbSamples[ iX ] = pCrSamples[ iX ] = iVal;
878    }
879  }
880}
881
882
883
884
885
886
887
888/*===============================================*
889 *=====                                     =====*
890 *=====     C U   p r e d i c t i o n s     =====*
891 *=====                                     =====*
892 *===============================================*/
893
894Void
895TComDepthMapGenerator::xPredictCUDepthMap( TComDataCU* pcCU, UInt uiDepth, UInt uiAbsPartIdx )
896{
897  UInt  uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
898  UInt  uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
899  UInt  uiRPelX   = uiLPelX           + ( g_uiMaxCUWidth  >> uiDepth ) - 1;
900  UInt  uiBPelY   = uiTPelY           + ( g_uiMaxCUHeight >> uiDepth ) - 1;
901  Bool  bBoundary = ( uiRPelX >= pcCU->getSlice()->getSPS()->getWidth() || uiBPelY >= pcCU->getSlice()->getSPS()->getHeight() );
902  Bool  bSplit    = ( ( uiDepth < pcCU->getDepth( uiAbsPartIdx ) && uiDepth < ( g_uiMaxCUDepth - g_uiAddCUDepth ) ) || bBoundary );
903  if(   bSplit )
904  {
905    UInt uiQNumParts = ( pcCU->getPic()->getNumPartInCU() >> ( uiDepth << 1 ) ) >> 2;
906    for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++, uiAbsPartIdx += uiQNumParts )
907    {
908      uiLPelX       = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
909      uiTPelY       = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
910      Bool  bInside = ( uiLPelX < pcCU->getSlice()->getSPS()->getWidth() && uiTPelY < pcCU->getSlice()->getSPS()->getHeight() );
911      if(   bInside )
912      {
913        xPredictCUDepthMap( pcCU, uiDepth + 1, uiAbsPartIdx );
914      }
915    }
916    return;
917  }
918
919  //--- set sub-CU and sub-depth-map ---
920  TComDataCU* pcSubCU   = m_ppcCU [ uiDepth ];
921  TComYuv*    pcSubDM   = m_ppcYuv[ uiDepth ];
922  TComPicYuv* pcPicDM   = pcCU->getPic()->getPredDepthMap();
923  UInt        uiCUAddr  = pcCU->getAddr();
924  pcSubCU->copySubCU( pcCU, uiAbsPartIdx, uiDepth );
925
926  //--- update depth map ---
927  switch( pcSubCU->getPredictionMode( 0 ) )
928  {
929  case MODE_INTRA:
930    xIntraPredictCUDepthMap( pcSubCU, pcSubDM );
931    break;
932  case MODE_SKIP:
933  case MODE_INTER:
934    xInterPredictCUDepthMap( pcSubCU, pcSubDM );
935    break;
936  default:
937    AOT( true );
938    break;
939  }
940
941  //--- copy sub-depth-map ---
942  pcSubDM->copyToPicYuv( pcPicDM, uiCUAddr, uiAbsPartIdx );
943}
944
945
946Void
947TComDepthMapGenerator::xIntraPredictCUDepthMap( TComDataCU* pcCU, TComYuv* pcCUDepthMap )
948{
949  UInt  uiInitTrDepth = ( pcCU->getPartitionSize( 0 ) == SIZE_2Nx2N ? 0 : 1 );
950  UInt  uiNumPart     =   pcCU->getNumPartInter ();
951  UInt  uiNumQParts   =   pcCU->getTotalNumPart () >> 2;
952  for( UInt uiPU = 0; uiPU < uiNumPart; uiPU++ )
953  {
954    xIntraPredictBlkDepthMap( pcCU, pcCUDepthMap, uiPU * uiNumQParts, uiInitTrDepth );
955  }
956}
957
958
959Void
960TComDepthMapGenerator::xInterPredictCUDepthMap( TComDataCU* pcCU, TComYuv* pcCUDepthMap )
961{
962  for( UInt uiPartIdx = 0; uiPartIdx < pcCU->getNumPartInter(); uiPartIdx++ )
963  {
964    xInterPredictPUDepthMap( pcCU, pcCUDepthMap, uiPartIdx );
965  }
966}
967
968
969
970
971
972
973
974/*=====================================================================*
975 *=====                                                           =====*
976 *=====     P U -   a n d   B l o c k   p r e d i c t i o n s     =====*
977 *=====                                                           =====*
978 *=====================================================================*/
979
980Void
981TComDepthMapGenerator::xIntraPredictBlkDepthMap( TComDataCU* pcCU, TComYuv* pcCUDepthMap, UInt uiAbsPartIdx, UInt uiTrDepth )
982{
983  UInt uiFullDepth  = pcCU->getDepth( 0 ) + uiTrDepth;
984  UInt uiTrMode     = pcCU->getTransformIdx( uiAbsPartIdx );
985  if( uiTrMode == uiTrDepth )
986  {
987    UInt  uiWidth         = pcCU->getWidth ( 0 ) >> uiTrDepth;
988    UInt  uiHeight        = pcCU->getHeight( 0 ) >> uiTrDepth;
989    UInt  uiStride        = pcCUDepthMap->getStride  ();
990    Pel*  pDepthMap       = pcCUDepthMap->getLumaAddr( uiAbsPartIdx );
991    UInt  uiLumaPredMode  = pcCU->getLumaIntraDir    ( uiAbsPartIdx );
992    Bool  bAboveAvail     = false;
993    Bool  bLeftAvail      = false;
994    pcCU->getPattern()->initPattern   ( pcCU, uiTrDepth, uiAbsPartIdx, true );
995    pcCU->getPattern()->initAdiPattern( pcCU, uiAbsPartIdx, uiTrDepth, 
996                                        m_pcPrediction->getPredicBuf       (),
997                                        m_pcPrediction->getPredicBufWidth  (),
998                                        m_pcPrediction->getPredicBufHeight (),
999                                        bAboveAvail, bLeftAvail, true );
1000    m_pcPrediction->predIntraDepthAng ( pcCU->getPattern(), uiLumaPredMode, pDepthMap, uiStride, uiWidth, uiHeight ); // could be replaced with directional intra prediction
1001                                                                                                                      // using "predIntraLumaAng", but note:
1002                                                                                                                      //  - need to take care of neighbours with undefined depth
1003                                                                                                                      //  - special case for wedgelet mode (if available in normal views)
1004    // copy to picture array (for next intra prediction block)
1005    UInt  uiZOrderIdx     = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
1006    Pel*  pPicDepthMap    = pcCU->getPic()->getPredDepthMap()->getLumaAddr( pcCU->getAddr(), uiZOrderIdx );
1007    Int   iPicStride      = pcCU->getPic()->getPredDepthMap()->getStride  ();
1008    for( UInt uiY = 0; uiY < uiHeight; uiY++, pDepthMap += uiStride, pPicDepthMap += iPicStride )
1009    {
1010      for( UInt uiX = 0; uiX < uiWidth; uiX++ )
1011      {
1012        pPicDepthMap[ uiX ] = pDepthMap[ uiX ];
1013      }
1014    }
1015  }
1016  else
1017  {
1018    UInt uiNumQPart  = pcCU->getPic()->getNumPartInCU() >> ( ( uiFullDepth + 1 ) << 1 );
1019    for( UInt uiPart = 0; uiPart < 4; uiPart++ )
1020    {
1021      xIntraPredictBlkDepthMap( pcCU, pcCUDepthMap, uiAbsPartIdx + uiPart * uiNumQPart, uiTrDepth + 1 );
1022    }
1023  }
1024}
1025
1026
1027Void 
1028TComDepthMapGenerator::xInterPredictPUDepthMap( TComDataCU* pcCU, TComYuv* pcCUDepthMap, UInt uiPartIdx )
1029{
1030  if ( pcCU->getSlice()->getSPS()->getViewId() )
1031  {
1032    AOF( m_uiCurrViewId == pcCU->getSlice()->getSPS()->getViewId() );
1033    // check for interview prediction
1034    Int             iWidth;
1035    Int             iHeight;
1036    UInt            uiAbsPartIdx;
1037    pcCU->getPartIndexAndSize( uiPartIdx, uiAbsPartIdx, iWidth, iHeight );
1038    TComCUMvField*  aiCurrMvField[2]  = { pcCU->getCUMvField( REF_PIC_LIST_0 ),        pcCU->getCUMvField( REF_PIC_LIST_1 )        };
1039    Int             aiCurrRefIdx [2]  = { aiCurrMvField[0]->getRefIdx( uiAbsPartIdx ), aiCurrMvField[1]->getRefIdx( uiAbsPartIdx ) };
1040    Bool            abCurrIntView[2]  = { aiCurrRefIdx[0] >= 0 && pcCU->getSlice()->getRefPic( REF_PIC_LIST_0, aiCurrRefIdx[0] )->getSPS()->getViewId() != m_uiCurrViewId,
1041                                          aiCurrRefIdx[1] >= 0 && pcCU->getSlice()->getRefPic( REF_PIC_LIST_1, aiCurrRefIdx[1] )->getSPS()->getViewId() != m_uiCurrViewId };
1042    Bool            bUsesInterViewPrd = ( abCurrIntView[0] || abCurrIntView[1] );
1043    if( bUsesInterViewPrd )
1044    {
1045      xIViewPUDepthMapUpdate  ( pcCU, pcCUDepthMap, uiPartIdx );
1046    }
1047    else
1048    { 
1049#if PDM_NO_INTER_UPDATE
1050      xInterPUDepthMapPrediction( pcCU, pcCUDepthMap, uiPartIdx );
1051#else
1052      xInterPUDepthMapUpdate  ( pcCU, pcCUDepthMap, uiPartIdx );
1053#endif
1054    }
1055  }
1056  else
1057  {
1058    xInterPUDepthMapPrediction( pcCU, pcCUDepthMap, uiPartIdx );
1059  }
1060}
1061
1062
1063Void 
1064TComDepthMapGenerator::xIViewPUDepthMapUpdate( TComDataCU* pcCU, TComYuv* pcCUDepthMap, UInt uiPartIdx )
1065{
1066  // get width, height, and part address
1067  Int   iWidth;
1068  Int   iHeight;
1069  UInt  uiAbsPartIdx;
1070  pcCU->getPartIndexAndSize( uiPartIdx, uiAbsPartIdx, iWidth, iHeight );
1071
1072  // get depth values
1073  Int   iDepthValue   = PDM_UNDEFINED_DEPTH;
1074  Int   aiPrdDepth[2] = { PDM_UNDEFINED_DEPTH, PDM_UNDEFINED_DEPTH };
1075  for( Int iRefListId = 0; iRefListId < 2; iRefListId++ )
1076  {
1077    RefPicList      eRefPicList = RefPicList( iRefListId );
1078    TComCUMvField*  pcCUMvField = pcCU->getCUMvField( eRefPicList );
1079    Int             iRefIdx     = pcCUMvField->getRefIdx( uiAbsPartIdx );
1080    UInt            uiBaseId    = ( iRefIdx >= 0 ? pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getSPS()->getViewId() : MAX_NUMBER_VIEWS ); 
1081    Bool            bInterview  = ( iRefIdx >= 0 && uiBaseId < m_uiCurrViewId );
1082    if( bInterview )
1083    {
1084      Int           iMvX        = pcCUMvField->getMv( uiAbsPartIdx ).getHor();
1085      aiPrdDepth[ iRefListId ]  = xGetVirtDepthFromDisparity( uiBaseId, iMvX );
1086    }
1087  }
1088  if( aiPrdDepth[ 0 ] != PDM_UNDEFINED_DEPTH && aiPrdDepth[ 1 ] != PDM_UNDEFINED_DEPTH )
1089  {
1090    iDepthValue = ( aiPrdDepth[ 0 ] + aiPrdDepth[ 1 ] + 1 ) >> 2;
1091  }
1092  else
1093  {
1094    iDepthValue = ( aiPrdDepth[ 0 ] != PDM_UNDEFINED_DEPTH ? aiPrdDepth[ 0 ] : aiPrdDepth[ 1 ] );
1095    AOT( iDepthValue == PDM_UNDEFINED_DEPTH );
1096  }
1097  iDepthValue   = Max( 0, Min( PDM_MAX_ABS_VIRT_DEPTH, iDepthValue ) );
1098
1099  // set depth map for PU
1100  Pel*  pDMSamples  = pcCUDepthMap->getLumaAddr( uiAbsPartIdx );
1101  Int   iStride     = pcCUDepthMap->getStride  ();
1102  for( Int iY = 0; iY < iHeight; iY++, pDMSamples += iStride )
1103  {
1104    for( Int iX = 0; iX < iWidth; iX++)
1105    {
1106      pDMSamples[ iX ] = (Pel)iDepthValue;
1107    }
1108  }
1109}
1110
1111
1112Void
1113TComDepthMapGenerator::xInterPUDepthMapUpdate( TComDataCU* pcCU, TComYuv* pcCUDepthMap, UInt uiPartIdx )
1114{
1115  const Int       iMaxAbsDeltaMvY   = 8 << 2;
1116
1117  //===== determine block parameters for current access unit and current view =====
1118  Int             iWidth;
1119  Int             iHeight;
1120  UInt            uiAbsPartIdx;
1121  pcCU->getPartIndexAndSize ( uiPartIdx, uiAbsPartIdx, iWidth, iHeight );
1122  UInt            uiCurrViewId      = pcCU->getSlice()->getSPS()->getViewId(); 
1123  Int             iNum4x4BlksY      = iHeight >> 2;
1124  Int             iNum4x4BlksX      = iWidth  >> 2;
1125  TComPicYuv*     pcCurrDepthMap    = pcCU->getPic()->getPredDepthMap();
1126  Pel*            piCurrDepthMap    = pcCurrDepthMap->getLumaAddr();
1127  Int             iCurrStride       = pcCurrDepthMap->getStride();
1128  TComCUMvField*  aiCurrMvField[2]  = { pcCU->getCUMvField( REF_PIC_LIST_0 ),        pcCU->getCUMvField( REF_PIC_LIST_1 )        };
1129  Int             aiCurrRefIdx [2]  = { aiCurrMvField[0]->getRefIdx( uiAbsPartIdx ), aiCurrMvField[1]->getRefIdx( uiAbsPartIdx ) };
1130  Int             iMinCurrListId    = ( aiCurrRefIdx [0] < 0 ? 1 : 0 );
1131  Int             iMaxCurrListId    = ( aiCurrRefIdx [1] < 0 ? 0 : 1 );
1132  Int             iCurrPUPosX;
1133  Int             iCurrPUPosY;
1134  pcCurrDepthMap->getTopLeftSamplePos( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiAbsPartIdx, iCurrPUPosX, iCurrPUPosY );
1135  AOT( uiCurrViewId    != m_uiCurrViewId );
1136  AOT( iMinCurrListId  >  iMaxCurrListId );
1137  AOT( aiCurrRefIdx[0] >= 0 && pcCU->getSlice()->getRefPic( REF_PIC_LIST_0, aiCurrRefIdx[0] )->getSPS()->getViewId() != uiCurrViewId );
1138  AOT( aiCurrRefIdx[1] >= 0 && pcCU->getSlice()->getRefPic( REF_PIC_LIST_1, aiCurrRefIdx[1] )->getSPS()->getViewId() != uiCurrViewId );
1139
1140  //===== determine parameters for current access unit and base view =====
1141  AOF( m_auiBaseIdList.size() );
1142  UInt            uiBaseId          = m_auiBaseIdList[ 0 ];
1143  TComPic*        pcBasePic         = m_pcAUPicAccess->getPic( uiBaseId );
1144  AOF( pcBasePic );
1145  TComPicYuv*     pcBaseDepthMap    = pcBasePic->getPredDepthMap();
1146  TComPicYuv*     pcBaseRecPic      = pcBasePic->getPicYuvRec   ();
1147  Pel*            piBaseDepthMap    = pcBaseDepthMap->getLumaAddr();
1148  Int             iBaseStride       = pcBaseDepthMap->getStride();
1149
1150  //===== initialize 4x4 block arrays =====
1151  for( Int i4x4BlkY = 0; i4x4BlkY < iNum4x4BlksY; i4x4BlkY++ )
1152  {
1153    for( Int i4x4BlkX = 0; i4x4BlkX < iNum4x4BlksX; i4x4BlkX++ )
1154    {
1155      m_aabDepthSet[ i4x4BlkY ][ i4x4BlkX ] = false;
1156      m_aai4x4Depth[ i4x4BlkY ][ i4x4BlkX ] = PDM_UNDEFINED_DEPTH;
1157    }
1158  }
1159  Int iNum4x4Set = 0;
1160
1161  //===== determine depth based on 4x4 blocks =====
1162  for( Int i4x4BlkY = 0; i4x4BlkY < iNum4x4BlksY; i4x4BlkY++ )
1163  {
1164    for( Int i4x4BlkX = 0; i4x4BlkX < iNum4x4BlksX; i4x4BlkX++ )
1165    {
1166      // position parameters
1167      Int               iCurrBlkPosX        = iCurrPUPosX + ( i4x4BlkX << 2 );
1168      Int               iCurrBlkPosY        = iCurrPUPosY + ( i4x4BlkY << 2 );
1169      Int               iCurrSamplePosX     = iCurrBlkPosX + 1;
1170      Int               iCurrSamplePosY     = iCurrBlkPosY + 1;
1171      Int               iCurrPredDepth      = piCurrDepthMap[ iCurrSamplePosY * iCurrStride + iCurrSamplePosX ];
1172      Int               iCurrPredDisp       = xGetDisparityFromVirtDepth( uiBaseId, iCurrPredDepth );
1173      Int               iBaseSamplePosX     = iCurrSamplePosX + ( ( iCurrPredDisp + 2 ) >> 2 );
1174      Int               iBaseSamplePosY     = iCurrSamplePosY;
1175      iBaseSamplePosX                       = Clip3( 0, pcBaseDepthMap->getWidth () - 1, iBaseSamplePosX );
1176      iBaseSamplePosY                       = Clip3( 0, pcBaseDepthMap->getHeight() - 1, iBaseSamplePosY );
1177
1178      // check for occlusion
1179      if( piBaseDepthMap[ iBaseSamplePosY * iBaseStride + iBaseSamplePosX ] != iCurrPredDepth )
1180      {
1181        continue;
1182      }
1183
1184      // determine base motion data and check prediction mode
1185      Int               iBaseCUAddr;
1186      Int               iBaseAbsPartIdx;
1187      pcBaseRecPic->getCUAddrAndPartIdx( iBaseSamplePosX, iBaseSamplePosY, iBaseCUAddr, iBaseAbsPartIdx );
1188      TComDataCU*       pcBaseCU            = pcBasePic->getCU( iBaseCUAddr );
1189      if( pcBaseCU->getPredictionMode( iBaseAbsPartIdx ) != MODE_INTER && pcBaseCU->getPredictionMode( iBaseAbsPartIdx ) != MODE_SKIP )
1190      {
1191        continue;
1192      }
1193
1194      // check whether base was inter-view predicted
1195      TComCUMvField*    aiBaseMvField[2]    = { pcBaseCU->getCUMvField( REF_PIC_LIST_0 ),       pcBaseCU->getCUMvField( REF_PIC_LIST_1 )       };
1196      Int               aiBaseRefIdx [2]    = { aiBaseMvField[0]->getRefIdx( iBaseAbsPartIdx ), aiBaseMvField[1]->getRefIdx( iBaseAbsPartIdx ) };
1197      Bool              abBaseIntView[2]    = { aiBaseRefIdx[0] >= 0 && pcBaseCU->getSlice()->getRefPic( REF_PIC_LIST_0, aiBaseRefIdx[0] )->getSPS()->getViewId() != uiBaseId,
1198                                                aiBaseRefIdx[1] >= 0 && pcBaseCU->getSlice()->getRefPic( REF_PIC_LIST_1, aiBaseRefIdx[1] )->getSPS()->getViewId() != uiBaseId };
1199      if( abBaseIntView[0] || abBaseIntView[1] )
1200      { // current depth is reliable
1201        m_aai4x4Depth[i4x4BlkY][i4x4BlkX]   = iCurrPredDepth;
1202        m_aabDepthSet[i4x4BlkY][i4x4BlkX]   = true;
1203        iNum4x4Set++;
1204        continue;
1205      }
1206     
1207      // determine depth candidates using an approximate 4-point relationship (if appropriate)
1208      std::vector<Int>  aiDepthCand;
1209      Int               iMinBaseListId      = ( aiBaseRefIdx [0] < 0 ? 1 : 0 );
1210      Int               iMaxBaseListId      = ( aiBaseRefIdx [1] < 0 ? 0 : 1 );
1211      AOT( iMinBaseListId > iMaxBaseListId );
1212      for( Int iCurrRefListId  = iMinCurrListId; iCurrRefListId <= iMaxCurrListId; iCurrRefListId++ )
1213      {
1214        RefPicList      eCurrRefPicList     = RefPicList( iCurrRefListId );
1215        Int             iCurrRefPoc         = pcCU->getSlice()->getRefPOC( eCurrRefPicList, aiCurrRefIdx[ iCurrRefListId ] );
1216        TComPic*        pcCurrRefPic        = pcCU->getSlice()->getRefPic( eCurrRefPicList, aiCurrRefIdx[ iCurrRefListId ] );
1217        TComPicYuv*     pcCurrRefDMap       = pcCurrRefPic->getPredDepthMap();
1218        Pel*            piCurrRefDMap       = pcCurrRefDMap->getLumaAddr();
1219        Int             iCurrRefStride      = pcCurrRefDMap->getStride();
1220        TComMv&         rcCurrMv            = aiCurrMvField[ iCurrRefListId ]->getMv( uiAbsPartIdx );
1221        Int             iCurrRefSamplePosX  = iCurrSamplePosX + ( ( rcCurrMv.getHor() + 2 ) >> 2 );
1222        Int             iCurrRefSamplePosY  = iCurrSamplePosY + ( ( rcCurrMv.getVer() + 2 ) >> 2 );
1223        Int             iCurrRefSamplePosXC = Clip3( 0, pcCurrRefDMap->getWidth () - 1, iCurrRefSamplePosX );
1224        Int             iCurrRefSamplePosYC = Clip3( 0, pcCurrRefDMap->getHeight() - 1, iCurrRefSamplePosY );
1225        Int             iCurrRefDepth       = piCurrRefDMap[ iCurrRefSamplePosYC * iCurrRefStride + iCurrRefSamplePosXC ];
1226
1227        for( Int iBaseRefListId = iMinBaseListId; iBaseRefListId <= iMaxBaseListId; iBaseRefListId++ )
1228        {
1229          RefPicList    eBaseRefPicList     = RefPicList( iBaseRefListId );
1230          Int           iBaseRefPoc         = pcBaseCU->getSlice()->getRefPOC( eBaseRefPicList, aiBaseRefIdx[ iBaseRefListId ] );
1231
1232          if( iCurrRefPoc == iBaseRefPoc )
1233          {
1234            // location and depth for path currView/currAU -> currView/refAU -> baseView/refAU
1235            Int         iCurrRefDisp        = xGetDisparityFromVirtDepth( uiBaseId, iCurrRefDepth );
1236            Int         iBaseRefSamplePosX  = iCurrRefSamplePosX + ( ( iCurrRefDisp + 2 ) >> 2 );
1237            Int         iBaseRefSamplePosY  = iCurrRefSamplePosY;
1238            TComPic*    pcBaseRefPic        = pcBaseCU->getSlice()->getRefPic( eBaseRefPicList, aiBaseRefIdx[ iBaseRefListId ] );
1239            TComPicYuv* pcBaseRefDMap       = pcBaseRefPic->getPredDepthMap();
1240            Pel*        piBaseRefDMap       = pcBaseRefDMap->getLumaAddr();
1241            Int         iBaseRefStride      = pcBaseRefDMap->getStride();
1242            iBaseRefSamplePosX              = Clip3( 0, pcBaseRefDMap->getWidth () - 1, iBaseRefSamplePosX );
1243            iBaseRefSamplePosY              = Clip3( 0, pcBaseRefDMap->getHeight() - 1, iBaseRefSamplePosY );
1244            Int         iBaseRefDepth       = piBaseRefDMap[ iBaseRefSamplePosY * iBaseRefStride + iBaseRefSamplePosX ];
1245
1246            // location and depth for path currView/currAU ->baseView/currAU -> baseView/refAU
1247            TComMv&     rcBaseMv            = aiBaseMvField[ iBaseRefListId ]->getMv( iBaseAbsPartIdx );
1248            Int         iAbsDeltaMvY        = ( rcBaseMv.getAbsVer() > rcCurrMv.getVer() ? rcBaseMv.getAbsVer() - rcCurrMv.getVer() : rcCurrMv.getVer() - rcBaseMv.getAbsVer() );
1249
1250            // check reliability (occlusion in reference access unit / vertical motion vector difference)
1251            if( iBaseRefDepth != iCurrRefDepth || iAbsDeltaMvY > iMaxAbsDeltaMvY )
1252            {
1253              continue;
1254            }
1255
1256            // determine new depth
1257            Int         iCurrCandDisp       = iCurrRefDisp + rcCurrMv.getHor() - rcBaseMv.getHor();
1258            Int         iCurrCandDepth      = xGetVirtDepthFromDisparity( uiBaseId, iCurrCandDisp );
1259            aiDepthCand.push_back( iCurrCandDepth );
1260          } // iCurrRefPoc == iBaseRefPoc
1261        } // iBaseRefListId
1262      } // iCurrRefListId
1263     
1264      // set depth for 4x4 block
1265      if( aiDepthCand.size() )
1266      { // get depth with minimum change (probably most reliable)
1267        Int             iMinAbsDepthChange  = (1<<30);
1268        Int             iDepthForMinChange  = (1<<30);
1269        for( UInt uiCandId = 0; uiCandId < (UInt)aiDepthCand.size(); uiCandId++ )
1270        {
1271          Int           iAbsDeltaDepth      = ( aiDepthCand[uiCandId] > iCurrPredDepth ? aiDepthCand[uiCandId] > iCurrPredDepth : iCurrPredDepth - aiDepthCand[uiCandId] );
1272          if( iAbsDeltaDepth < iMinAbsDepthChange )
1273          {
1274            iMinAbsDepthChange              = iAbsDeltaDepth;
1275            iDepthForMinChange              = aiDepthCand[uiCandId];
1276          }
1277        }
1278        m_aai4x4Depth[i4x4BlkY][i4x4BlkX]   = Min( Max( 0, iDepthForMinChange ), PDM_MAX_ABS_VIRT_DEPTH );
1279        m_aabDepthSet[i4x4BlkY][i4x4BlkX]   = true;
1280        iNum4x4Set++;
1281      }
1282    } // i4x4BlkX
1283  } // i4x4BlkY
1284
1285  //===== fall back (take original depth for 4x4 blocks) ====
1286  if( iNum4x4Set < Max( 1, ( iNum4x4BlksY * iNum4x4BlksX ) >> 2 ) )
1287  {
1288    iNum4x4Set = 0;
1289    for( Int i4x4BlkY = 0; i4x4BlkY < iNum4x4BlksY; i4x4BlkY++ )
1290    {
1291      for( Int i4x4BlkX = 0; i4x4BlkX < iNum4x4BlksX; i4x4BlkX++ )
1292      {
1293        Int             iCurrSamplePosX     = iCurrPUPosX + ( i4x4BlkX << 2 ) + 1;
1294        Int             iCurrSamplePosY     = iCurrPUPosY + ( i4x4BlkY << 2 ) + 1;
1295        m_aai4x4Depth[i4x4BlkY][i4x4BlkX]   = piCurrDepthMap[ iCurrSamplePosY * iCurrStride + iCurrSamplePosX ];
1296        m_aabDepthSet[i4x4BlkY][i4x4BlkX]   = true;
1297        iNum4x4Set++;
1298      }
1299    }
1300  }
1301
1302#if PDM_ONE_DEPTH_PER_PU
1303  //===== set average in 4x4 depth array =====
1304  Int   iSum        = 0;
1305  for( Int i4x4BlkY = 0; i4x4BlkY < iNum4x4BlksY; i4x4BlkY++ )
1306  {
1307    for( Int i4x4BlkX = 0; i4x4BlkX < iNum4x4BlksX; i4x4BlkX++ )
1308    {
1309      if( m_aabDepthSet[ i4x4BlkY ][ i4x4BlkX ] )
1310      {
1311        iSum += m_aai4x4Depth[ i4x4BlkY ][ i4x4BlkX ];
1312      }
1313    }
1314  }
1315  Int   iDepth      = ( iSum + ( iNum4x4Set >> 1 ) ) / iNum4x4Set;
1316  iNum4x4Set        = iNum4x4BlksY * iNum4x4BlksX;
1317  for( Int i4x4BlkY = 0; i4x4BlkY < iNum4x4BlksY; i4x4BlkY++ )
1318  {
1319    for( Int i4x4BlkX = 0; i4x4BlkX < iNum4x4BlksX; i4x4BlkX++ )
1320    {
1321      m_aai4x4Depth[ i4x4BlkY ][ i4x4BlkX ] = iDepth;
1322      m_aabDepthSet[ i4x4BlkY ][ i4x4BlkX ] = true;
1323    }
1324  }
1325#endif
1326 
1327  //===== complete depth arrays =====
1328  while( iNum4x4BlksY * iNum4x4BlksX - iNum4x4Set )
1329  {
1330    for( Int i4x4BlkY = 0; i4x4BlkY < iNum4x4BlksY; i4x4BlkY++ )
1331    {
1332      for( Int i4x4BlkX = 0; i4x4BlkX < iNum4x4BlksX; i4x4BlkX++ )
1333      {
1334        if( !m_aabDepthSet[ i4x4BlkY ][ i4x4BlkX ] )
1335        { // could also use minimum of neighbours (occlusions)
1336          Int iNumNeighbours  = 0;
1337          Int iSumNeighbours  = 0;
1338          if( i4x4BlkY > 0              && m_aabDepthSet[ i4x4BlkY-1 ][ i4x4BlkX   ] ) { iSumNeighbours += m_aai4x4Depth[ i4x4BlkY-1 ][ i4x4BlkX   ]; iNumNeighbours++; }
1339          if( i4x4BlkY < iNum4x4BlksY-1 && m_aabDepthSet[ i4x4BlkY+1 ][ i4x4BlkX   ] ) { iSumNeighbours += m_aai4x4Depth[ i4x4BlkY+1 ][ i4x4BlkX   ]; iNumNeighbours++; }
1340          if( i4x4BlkX > 0              && m_aabDepthSet[ i4x4BlkY   ][ i4x4BlkX-1 ] ) { iSumNeighbours += m_aai4x4Depth[ i4x4BlkY   ][ i4x4BlkX-1 ]; iNumNeighbours++; }
1341          if( i4x4BlkX < iNum4x4BlksX-1 && m_aabDepthSet[ i4x4BlkY   ][ i4x4BlkX+1 ] ) { iSumNeighbours += m_aai4x4Depth[ i4x4BlkY   ][ i4x4BlkX+1 ]; iNumNeighbours++; }
1342          if( iNumNeighbours )
1343          {
1344            m_aai4x4Depth[ i4x4BlkY ][ i4x4BlkX ] = ( iSumNeighbours + ( iNumNeighbours >> 1 ) ) / iNumNeighbours;
1345            m_aabDepthSet[ i4x4BlkY ][ i4x4BlkX ] = true;
1346            iNum4x4Set++;
1347          }
1348        }
1349      }
1350    }
1351  }
1352
1353  //===== set depth values =====
1354  Pel* piDepthMap = pcCUDepthMap->getLumaAddr( uiAbsPartIdx );
1355  Int  iCUStride  = pcCUDepthMap->getStride  ();
1356  for( Int iRow = 0; iRow < iHeight; iRow++, piDepthMap += iCUStride )
1357  {
1358    for( Int iCol = 0; iCol < iWidth; iCol++ )
1359    {
1360      piDepthMap[ iCol ] = m_aai4x4Depth[ iRow >> 2 ][ iCol >> 2 ];
1361    }
1362  }
1363}
1364
1365
1366Void
1367TComDepthMapGenerator::xInterPUDepthMapPrediction( TComDataCU* pcCU, TComYuv* pcCUDepthMap, UInt uiPartIdx )
1368{
1369  m_pcPrediction->motionCompensation( pcCU, pcCUDepthMap, REF_PIC_LIST_X, (Int)uiPartIdx, true ); 
1370}
1371
1372
1373Bool
1374TComDepthMapGenerator::xGetPredDepth( TComDataCU* pcCU, UInt uiPartIdx, Int& riPrdDepth, Int* piPosX, Int* piPosY )
1375{
1376  AOF  ( m_bCreated && m_bInit );
1377  AOF  ( pcCU );
1378  ROFRS( m_bPDMAvailable, false );
1379
1380  TComSlice*    pcSlice     = pcCU->getSlice ();
1381  TComPic*      pcPic       = pcCU->getPic   ();
1382  TComSPS*      pcSPS       = pcSlice->getSPS();
1383  AOF  ( pcPic->getPredDepthMap() );
1384  AOF  ( pcSPS->getViewId() == m_uiCurrViewId );
1385 
1386  //===== get predicted depth and disprity for middle position of current PU ===== 
1387  UInt          uiPartAddr;
1388  Int           iWidth;
1389  Int           iHeight;
1390  pcCU->getPartIndexAndSize( uiPartIdx, uiPartAddr, iWidth, iHeight );
1391  TComPicYuv*   pcPredDepthMap  = pcPic->getPredDepthMap();
1392  Pel*          piPredDepthMap  = pcPredDepthMap->getLumaAddr ( 0 );
1393  Int           iCurrStride     = pcPredDepthMap->getStride   ();
1394  Int           iCurrPosX;
1395  Int           iCurrPosY;
1396  pcPredDepthMap->getTopLeftSamplePos( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiPartAddr, iCurrPosX, iCurrPosY );
1397  iCurrPosX  += ( iWidth  - 1 ) >> 1;
1398  iCurrPosY  += ( iHeight - 1 ) >> 1;
1399  riPrdDepth  = piPredDepthMap[ iCurrPosX + iCurrPosY * iCurrStride ];
1400  if( piPosX )
1401  {
1402    *piPosX   = iCurrPosX;
1403  }
1404  if( piPosY )
1405  {
1406    *piPosY   = iCurrPosY;
1407  }
1408  return        true;
1409}
1410
Note: See TracBrowser for help on using the repository browser.