source: 3DVCSoftware/branches/HTM-15.2-dev/source/Lib/TLibCommon/TComMotionInfo.cpp @ 1365

Last change on this file since 1365 was 1360, checked in by tech, 9 years ago

Update to HM-16.7.

  • Property svn:eol-style set to native
File size: 14.1 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-2015, 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     TComMotionInfo.cpp
35    \brief    motion information handling classes
36*/
37
38#include <memory.h>
39#include "TComMotionInfo.h"
40#include "assert.h"
41#include <stdlib.h>
42#if NH_3D_SPIVMP
43#include "TComDataCU.h"
44#include "TComPic.h"
45#endif
46#if NH_MV
47#include <iomanip>
48#endif
49//! \ingroup TLibCommon
50//! \{
51
52// ====================================================================================================================
53// Public member functions
54// ====================================================================================================================
55
56// --------------------------------------------------------------------------------------------------------------------
57// Create / destroy
58// --------------------------------------------------------------------------------------------------------------------
59
60Void TComCUMvField::create( UInt uiNumPartition )
61{
62  assert(m_pcMv     == NULL);
63  assert(m_pcMvd    == NULL);
64  assert(m_piRefIdx == NULL);
65
66  m_pcMv     = new TComMv[ uiNumPartition ];
67  m_pcMvd    = new TComMv[ uiNumPartition ];
68  m_piRefIdx = new SChar [ uiNumPartition ];
69
70  m_uiNumPartition = uiNumPartition;
71}
72
73Void TComCUMvField::destroy()
74{
75  assert(m_pcMv     != NULL);
76  assert(m_pcMvd    != NULL);
77  assert(m_piRefIdx != NULL);
78
79  delete[] m_pcMv;
80  delete[] m_pcMvd;
81  delete[] m_piRefIdx;
82
83  m_pcMv     = NULL;
84  m_pcMvd    = NULL;
85  m_piRefIdx = NULL;
86
87  m_uiNumPartition = 0;
88}
89
90// --------------------------------------------------------------------------------------------------------------------
91// Clear / copy
92// --------------------------------------------------------------------------------------------------------------------
93
94Void TComCUMvField::clearMvField()
95{
96  for ( Int i = 0; i < m_uiNumPartition; i++ )
97  {
98    m_pcMv [ i ].setZero();
99    m_pcMvd[ i ].setZero();
100  }
101  assert( sizeof( *m_piRefIdx ) == 1 );
102  memset( m_piRefIdx, NOT_VALID, m_uiNumPartition * sizeof( *m_piRefIdx ) );
103}
104
105Void TComCUMvField::copyFrom( TComCUMvField const * pcCUMvFieldSrc, Int iNumPartSrc, Int iPartAddrDst )
106{
107  Int iSizeInTComMv = sizeof( TComMv ) * iNumPartSrc;
108
109  memcpy( m_pcMv     + iPartAddrDst, pcCUMvFieldSrc->m_pcMv,     iSizeInTComMv );
110  memcpy( m_pcMvd    + iPartAddrDst, pcCUMvFieldSrc->m_pcMvd,    iSizeInTComMv );
111  memcpy( m_piRefIdx + iPartAddrDst, pcCUMvFieldSrc->m_piRefIdx, sizeof( *m_piRefIdx ) * iNumPartSrc );
112}
113
114Void TComCUMvField::copyTo( TComCUMvField* pcCUMvFieldDst, Int iPartAddrDst ) const
115{
116  copyTo( pcCUMvFieldDst, iPartAddrDst, 0, m_uiNumPartition );
117}
118
119Void TComCUMvField::copyTo( TComCUMvField* pcCUMvFieldDst, Int iPartAddrDst, UInt uiOffset, UInt uiNumPart ) const
120{
121  Int iSizeInTComMv = sizeof( TComMv ) * uiNumPart;
122  Int iOffset = uiOffset + iPartAddrDst;
123
124  memcpy( pcCUMvFieldDst->m_pcMv     + iOffset, m_pcMv     + uiOffset, iSizeInTComMv );
125  memcpy( pcCUMvFieldDst->m_pcMvd    + iOffset, m_pcMvd    + uiOffset, iSizeInTComMv );
126  memcpy( pcCUMvFieldDst->m_piRefIdx + iOffset, m_piRefIdx + uiOffset, sizeof( *m_piRefIdx ) * uiNumPart );
127}
128
129// --------------------------------------------------------------------------------------------------------------------
130// Set
131// --------------------------------------------------------------------------------------------------------------------
132
133template <typename T>
134Void TComCUMvField::setAll( T *p, T const & val, PartSize eCUMode, Int iPartAddr, UInt uiDepth, Int iPartIdx  )
135{
136  Int i;
137  p += iPartAddr;
138  Int numElements = m_uiNumPartition >> ( 2 * uiDepth );
139
140  switch( eCUMode )
141  {
142    case SIZE_2Nx2N:
143      for ( i = 0; i < numElements; i++ )
144      {
145        p[ i ] = val;
146      }
147      break;
148
149    case SIZE_2NxN:
150      numElements >>= 1;
151      for ( i = 0; i < numElements; i++ )
152      {
153        p[ i ] = val;
154      }
155      break;
156
157    case SIZE_Nx2N:
158      numElements >>= 2;
159      for ( i = 0; i < numElements; i++ )
160      {
161        p[ i                   ] = val;
162        p[ i + 2 * numElements ] = val;
163      }
164      break;
165
166    case SIZE_NxN:
167      numElements >>= 2;
168      for ( i = 0; i < numElements; i++)
169      {
170        p[ i ] = val;
171      }
172      break;
173    case SIZE_2NxnU:
174    {
175      Int iCurrPartNumQ = numElements>>2;
176      if( iPartIdx == 0 )
177      {
178        T *pT  = p;
179        T *pT2 = p + iCurrPartNumQ;
180        for (i = 0; i < (iCurrPartNumQ>>1); i++)
181        {
182          pT [i] = val;
183          pT2[i] = val;
184        }
185      }
186      else
187      {
188        T *pT  = p;
189        for (i = 0; i < (iCurrPartNumQ>>1); i++)
190        {
191          pT[i] = val;
192        }
193
194        pT = p + iCurrPartNumQ;
195        for (i = 0; i < ( (iCurrPartNumQ>>1) + (iCurrPartNumQ<<1) ); i++)
196        {
197          pT[i] = val;
198        }
199      }
200      break;
201    }
202  case SIZE_2NxnD:
203    {
204      Int iCurrPartNumQ = numElements>>2;
205      if( iPartIdx == 0 )
206      {
207        T *pT  = p;
208        for (i = 0; i < ( (iCurrPartNumQ>>1) + (iCurrPartNumQ<<1) ); i++)
209        {
210          pT[i] = val;
211        }
212        pT = p + ( numElements - iCurrPartNumQ );
213        for (i = 0; i < (iCurrPartNumQ>>1); i++)
214        {
215          pT[i] = val;
216        }
217      }
218      else
219      {
220        T *pT  = p;
221        T *pT2 = p + iCurrPartNumQ;
222        for (i = 0; i < (iCurrPartNumQ>>1); i++)
223        {
224          pT [i] = val;
225          pT2[i] = val;
226        }
227      }
228      break;
229    }
230  case SIZE_nLx2N:
231    {
232      Int iCurrPartNumQ = numElements>>2;
233      if( iPartIdx == 0 )
234      {
235        T *pT  = p;
236        T *pT2 = p + (iCurrPartNumQ<<1);
237        T *pT3 = p + (iCurrPartNumQ>>1);
238        T *pT4 = p + (iCurrPartNumQ<<1) + (iCurrPartNumQ>>1);
239
240        for (i = 0; i < (iCurrPartNumQ>>2); i++)
241        {
242          pT [i] = val;
243          pT2[i] = val;
244          pT3[i] = val;
245          pT4[i] = val;
246        }
247      }
248      else
249      {
250        T *pT  = p;
251        T *pT2 = p + (iCurrPartNumQ<<1);
252        for (i = 0; i < (iCurrPartNumQ>>2); i++)
253        {
254          pT [i] = val;
255          pT2[i] = val;
256        }
257
258        pT  = p + (iCurrPartNumQ>>1);
259        pT2 = p + (iCurrPartNumQ<<1) + (iCurrPartNumQ>>1);
260        for (i = 0; i < ( (iCurrPartNumQ>>2) + iCurrPartNumQ ); i++)
261        {
262          pT [i] = val;
263          pT2[i] = val;
264        }
265      }
266      break;
267    }
268  case SIZE_nRx2N:
269    {
270      Int iCurrPartNumQ = numElements>>2;
271      if( iPartIdx == 0 )
272      {
273        T *pT  = p;
274        T *pT2 = p + (iCurrPartNumQ<<1);
275        for (i = 0; i < ( (iCurrPartNumQ>>2) + iCurrPartNumQ ); i++)
276        {
277          pT [i] = val;
278          pT2[i] = val;
279        }
280
281        pT  = p + iCurrPartNumQ + (iCurrPartNumQ>>1);
282        pT2 = p + numElements - iCurrPartNumQ + (iCurrPartNumQ>>1);
283        for (i = 0; i < (iCurrPartNumQ>>2); i++)
284        {
285          pT [i] = val;
286          pT2[i] = val;
287        }
288      }
289      else
290      {
291        T *pT  = p;
292        T *pT2 = p + (iCurrPartNumQ>>1);
293        T *pT3 = p + (iCurrPartNumQ<<1);
294        T *pT4 = p + (iCurrPartNumQ<<1) + (iCurrPartNumQ>>1);
295        for (i = 0; i < (iCurrPartNumQ>>2); i++)
296        {
297          pT [i] = val;
298          pT2[i] = val;
299          pT3[i] = val;
300          pT4[i] = val;
301        }
302      }
303      break;
304    }
305    default:
306      assert(0);
307      break;
308  }
309}
310
311Void TComCUMvField::setAllMv( TComMv const & mv, PartSize eCUMode, Int iPartAddr, UInt uiDepth, Int iPartIdx )
312{
313  setAll(m_pcMv, mv, eCUMode, iPartAddr, uiDepth, iPartIdx);
314}
315
316Void TComCUMvField::setAllMvd( TComMv const & mvd, PartSize eCUMode, Int iPartAddr, UInt uiDepth, Int iPartIdx )
317{
318  setAll(m_pcMvd, mvd, eCUMode, iPartAddr, uiDepth, iPartIdx);
319}
320
321Void TComCUMvField::setAllRefIdx ( Int iRefIdx, PartSize eCUMode, Int iPartAddr, UInt uiDepth, Int iPartIdx )
322{
323  setAll(m_piRefIdx, static_cast<SChar>(iRefIdx), eCUMode, iPartAddr, uiDepth, iPartIdx);
324}
325
326Void TComCUMvField::setAllMvField( TComMvField const & mvField, PartSize eCUMode, Int iPartAddr, UInt uiDepth, Int iPartIdx )
327{
328  setAllMv    ( mvField.getMv(),     eCUMode, iPartAddr, uiDepth, iPartIdx );
329  setAllRefIdx( mvField.getRefIdx(), eCUMode, iPartAddr, uiDepth, iPartIdx );
330}
331
332#if NH_3D_SPIVMP
333Void TComCUMvField::setMvFieldSP( TComDataCU* pcCU, UInt uiAbsPartIdx, TComMvField cMvField, Int iWidth, Int iHeight  )
334{
335  uiAbsPartIdx += pcCU->getZorderIdxInCtu();
336  Int iStartPelX = g_auiRasterToPelX[g_auiZscanToRaster[uiAbsPartIdx]];
337  Int iStartPelY = g_auiRasterToPelY[g_auiZscanToRaster[uiAbsPartIdx]];
338  Int iEndPelX = iStartPelX + iWidth;
339  Int iEndPelY = iStartPelY + iHeight; 
340
341  for (Int i=iStartPelY; i<iEndPelY; i+=pcCU->getPic()->getMinCUHeight())
342  {
343    for (Int j=iStartPelX; j < iEndPelX; j += pcCU->getPic()->getMinCUWidth())
344    {
345      Int iCurrRaster = i / pcCU->getPic()->getMinCUHeight() * pcCU->getPic()->getNumPartInCtuWidth() + j/pcCU->getPic()->getMinCUWidth();
346      Int uiPartAddr = g_auiRasterToZscan[iCurrRaster];
347      uiPartAddr -= pcCU->getZorderIdxInCtu(); 
348
349      m_pcMv[uiPartAddr] = cMvField.getMv();
350      m_piRefIdx[uiPartAddr] = cMvField.getRefIdx();
351    }
352  }
353}
354#endif
355
356/**Subsampling of the stored prediction mode, reference index and motion vector
357 * \param pePredMode Pointer to prediction modes
358 * \param scale      Factor by which to subsample motion information
359 */
360Void TComCUMvField::compress(SChar* pePredMode, Int scale)
361{
362  Int N = scale * scale;
363  assert( N > 0 && N <= m_uiNumPartition);
364
365  for ( Int uiPartIdx = 0; uiPartIdx < m_uiNumPartition; uiPartIdx += N )
366  {
367    TComMv cMv(0,0);
368    Int iRefIdx = 0;
369
370    cMv = m_pcMv[ uiPartIdx ];
371    PredMode predMode = static_cast<PredMode>( pePredMode[ uiPartIdx ] );
372    iRefIdx = m_piRefIdx[ uiPartIdx ];
373    for ( Int i = 0; i < N; i++ )
374    {
375      m_pcMv[ uiPartIdx + i ] = cMv;
376      pePredMode[ uiPartIdx + i ] = predMode;
377      m_piRefIdx[ uiPartIdx + i ] = iRefIdx;
378    }
379  }
380}
381
382#if NH_MV
383Void TComCUMvField::print(SChar* pePredMode)
384{
385  for ( Int uiPartIdx = 0; uiPartIdx < m_uiNumPartition; uiPartIdx += 1 )
386  {
387    PredMode predMode = static_cast<PredMode>( pePredMode[ uiPartIdx ] );
388
389    if ( predMode == MODE_INTRA)
390    {
391      std::cout << std::setfill(' ') << "(" 
392        << std::setw(3) <<  "   "    << ","
393        << std::setw(3) <<  "   "    << ","
394        << std::setw(3) <<  "   "    << ")";
395    }
396    else
397    {
398      ;
399      std::cout << std::setfill(' ') << "(" 
400        << std::setw(3) <<  (Int) m_piRefIdx[ uiPartIdx ]        << ","
401        << std::setw(3) <<  m_pcMv[ uiPartIdx ].getHor()   << ","
402        << std::setw(3) <<  m_pcMv[ uiPartIdx ].getVer()   << ")";
403    }   
404  }
405}
406
407#if NH_3D_MLC
408Void TComMotionCand::print( Int i )
409{
410  if (i == 0  )
411  {
412
413    std::cout << std::setfill(' ')                          << std::setw( 15 )
414      << "Num"                                              << std::setw( 15 )
415      << "Avai"                                             << std::setw( 15 )
416      << "Dir "                                             << std::setw( 15 )
417      <<  "L0 RefIdx"                                       << std::setw( 15 )
418      <<  "L0 Hor"                                          << std::setw( 15 )
419      <<  "L0 Ver"                                          << std::setw( 15 )
420      <<  "L1 RefIdx"                                       << std::setw( 15 )
421      <<  "L1 Hor"                                          << std::setw( 15 )
422      <<  "L1 Ver"                                          << std::setw( 15 )
423      << "VspFlag"                                          << std::setw( 15 )
424      << "SPIVMPFlag"                                       
425      << std::endl; 
426  }
427
428  std::cout << std::setfill(' ')                                  << std::setw( 15 )
429    << i                                                          << std::setw( 15 )
430    << m_bAvailable                                               << std::setw( 15 )
431    << (UInt) m_uDir                                              << std::setw( 15 )
432    << ((m_uDir & 1) ? m_cMvField[0].getRefIdx()       : MIN_INT) << std::setw( 15 )
433    << ((m_uDir & 1) ? m_cMvField[0].getMv().getHor()  : MIN_INT) << std::setw( 15 )
434    << ((m_uDir & 1) ? m_cMvField[0].getMv().getVer()  : MIN_INT) << std::setw( 15 )
435    << ((m_uDir & 2) ? m_cMvField[1].getRefIdx()       : MIN_INT) << std::setw( 15 )
436    << ((m_uDir & 2) ? m_cMvField[1].getMv().getHor()  : MIN_INT) << std::setw( 15 )
437    << ((m_uDir & 2) ? m_cMvField[1].getMv().getVer()  : MIN_INT) << std::setw( 15 )
438    << m_iVspFlag                                                 << std::setw( 15 )
439    << m_bSPIVMPFlag                                              << std::setw( 15 )
440    << std::endl;
441}
442#endif
443#endif
444//! \}
Note: See TracBrowser for help on using the repository browser.