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-2014, 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 
43 //! \ingroup TLibCommon
44 //! \{
45 
46 // ====================================================================================================================
47 // Public member functions
48 // ====================================================================================================================
49 
50 // --------------------------------------------------------------------------------------------------------------------
51 // Create / destroy
52 // --------------------------------------------------------------------------------------------------------------------
53 
create(UInt uiNumPartition)54 Void TComCUMvField::create( UInt uiNumPartition )
55 {
56   assert(m_pcMv     == NULL);
57   assert(m_pcMvd    == NULL);
58   assert(m_piRefIdx == NULL);
59 
60   m_pcMv     = new TComMv[ uiNumPartition ];
61   m_pcMvd    = new TComMv[ uiNumPartition ];
62   m_piRefIdx = new Char  [ uiNumPartition ];
63 
64   m_uiNumPartition = uiNumPartition;
65 }
66 
destroy()67 Void TComCUMvField::destroy()
68 {
69   assert(m_pcMv     != NULL);
70   assert(m_pcMvd    != NULL);
71   assert(m_piRefIdx != NULL);
72 
73   delete[] m_pcMv;
74   delete[] m_pcMvd;
75   delete[] m_piRefIdx;
76 
77   m_pcMv     = NULL;
78   m_pcMvd    = NULL;
79   m_piRefIdx = NULL;
80 
81   m_uiNumPartition = 0;
82 }
83 
84 // --------------------------------------------------------------------------------------------------------------------
85 // Clear / copy
86 // --------------------------------------------------------------------------------------------------------------------
87 
clearMvField()88 Void TComCUMvField::clearMvField()
89 {
90   for ( Int i = 0; i < m_uiNumPartition; i++ )
91   {
92     m_pcMv [ i ].setZero();
93     m_pcMvd[ i ].setZero();
94   }
95   assert( sizeof( *m_piRefIdx ) == 1 );
96   memset( m_piRefIdx, NOT_VALID, m_uiNumPartition * sizeof( *m_piRefIdx ) );
97 }
98 
copyFrom(TComCUMvField const * pcCUMvFieldSrc,Int iNumPartSrc,Int iPartAddrDst)99 Void TComCUMvField::copyFrom( TComCUMvField const * pcCUMvFieldSrc, Int iNumPartSrc, Int iPartAddrDst )
100 {
101   Int iSizeInTComMv = sizeof( TComMv ) * iNumPartSrc;
102 
103   memcpy( m_pcMv     + iPartAddrDst, pcCUMvFieldSrc->m_pcMv,     iSizeInTComMv );
104   memcpy( m_pcMvd    + iPartAddrDst, pcCUMvFieldSrc->m_pcMvd,    iSizeInTComMv );
105   memcpy( m_piRefIdx + iPartAddrDst, pcCUMvFieldSrc->m_piRefIdx, sizeof( *m_piRefIdx ) * iNumPartSrc );
106 }
107 
copyTo(TComCUMvField * pcCUMvFieldDst,Int iPartAddrDst) const108 Void TComCUMvField::copyTo( TComCUMvField* pcCUMvFieldDst, Int iPartAddrDst ) const
109 {
110   copyTo( pcCUMvFieldDst, iPartAddrDst, 0, m_uiNumPartition );
111 }
112 
copyTo(TComCUMvField * pcCUMvFieldDst,Int iPartAddrDst,UInt uiOffset,UInt uiNumPart) const113 Void TComCUMvField::copyTo( TComCUMvField* pcCUMvFieldDst, Int iPartAddrDst, UInt uiOffset, UInt uiNumPart ) const
114 {
115   Int iSizeInTComMv = sizeof( TComMv ) * uiNumPart;
116   Int iOffset = uiOffset + iPartAddrDst;
117 
118   memcpy( pcCUMvFieldDst->m_pcMv     + iOffset, m_pcMv     + uiOffset, iSizeInTComMv );
119   memcpy( pcCUMvFieldDst->m_pcMvd    + iOffset, m_pcMvd    + uiOffset, iSizeInTComMv );
120   memcpy( pcCUMvFieldDst->m_piRefIdx + iOffset, m_piRefIdx + uiOffset, sizeof( *m_piRefIdx ) * uiNumPart );
121 }
122 
123 // --------------------------------------------------------------------------------------------------------------------
124 // Set
125 // --------------------------------------------------------------------------------------------------------------------
126 
127 template <typename T>
setAll(T * p,T const & val,PartSize eCUMode,Int iPartAddr,UInt uiDepth,Int iPartIdx)128 Void TComCUMvField::setAll( T *p, T const & val, PartSize eCUMode, Int iPartAddr, UInt uiDepth, Int iPartIdx  )
129 {
130   Int i;
131   p += iPartAddr;
132   Int numElements = m_uiNumPartition >> ( 2 * uiDepth );
133 
134   switch( eCUMode )
135   {
136     case SIZE_2Nx2N:
137       for ( i = 0; i < numElements; i++ )
138       {
139         p[ i ] = val;
140       }
141       break;
142 
143     case SIZE_2NxN:
144       numElements >>= 1;
145       for ( i = 0; i < numElements; i++ )
146       {
147         p[ i ] = val;
148       }
149       break;
150 
151     case SIZE_Nx2N:
152       numElements >>= 2;
153       for ( i = 0; i < numElements; i++ )
154       {
155         p[ i                   ] = val;
156         p[ i + 2 * numElements ] = val;
157       }
158       break;
159 
160     case SIZE_NxN:
161       numElements >>= 2;
162       for ( i = 0; i < numElements; i++)
163       {
164         p[ i ] = val;
165       }
166       break;
167     case SIZE_2NxnU:
168     {
169       Int iCurrPartNumQ = numElements>>2;
170       if( iPartIdx == 0 )
171       {
172         T *pT  = p;
173         T *pT2 = p + iCurrPartNumQ;
174         for (i = 0; i < (iCurrPartNumQ>>1); i++)
175         {
176           pT [i] = val;
177           pT2[i] = val;
178         }
179       }
180       else
181       {
182         T *pT  = p;
183         for (i = 0; i < (iCurrPartNumQ>>1); i++)
184         {
185           pT[i] = val;
186         }
187 
188         pT = p + iCurrPartNumQ;
189         for (i = 0; i < ( (iCurrPartNumQ>>1) + (iCurrPartNumQ<<1) ); i++)
190         {
191           pT[i] = val;
192         }
193       }
194       break;
195     }
196   case SIZE_2NxnD:
197     {
198       Int iCurrPartNumQ = numElements>>2;
199       if( iPartIdx == 0 )
200       {
201         T *pT  = p;
202         for (i = 0; i < ( (iCurrPartNumQ>>1) + (iCurrPartNumQ<<1) ); i++)
203         {
204           pT[i] = val;
205         }
206         pT = p + ( numElements - iCurrPartNumQ );
207         for (i = 0; i < (iCurrPartNumQ>>1); i++)
208         {
209           pT[i] = val;
210         }
211       }
212       else
213       {
214         T *pT  = p;
215         T *pT2 = p + iCurrPartNumQ;
216         for (i = 0; i < (iCurrPartNumQ>>1); i++)
217         {
218           pT [i] = val;
219           pT2[i] = val;
220         }
221       }
222       break;
223     }
224   case SIZE_nLx2N:
225     {
226       Int iCurrPartNumQ = numElements>>2;
227       if( iPartIdx == 0 )
228       {
229         T *pT  = p;
230         T *pT2 = p + (iCurrPartNumQ<<1);
231         T *pT3 = p + (iCurrPartNumQ>>1);
232         T *pT4 = p + (iCurrPartNumQ<<1) + (iCurrPartNumQ>>1);
233 
234         for (i = 0; i < (iCurrPartNumQ>>2); i++)
235         {
236           pT [i] = val;
237           pT2[i] = val;
238           pT3[i] = val;
239           pT4[i] = val;
240         }
241       }
242       else
243       {
244         T *pT  = p;
245         T *pT2 = p + (iCurrPartNumQ<<1);
246         for (i = 0; i < (iCurrPartNumQ>>2); i++)
247         {
248           pT [i] = val;
249           pT2[i] = val;
250         }
251 
252         pT  = p + (iCurrPartNumQ>>1);
253         pT2 = p + (iCurrPartNumQ<<1) + (iCurrPartNumQ>>1);
254         for (i = 0; i < ( (iCurrPartNumQ>>2) + iCurrPartNumQ ); i++)
255         {
256           pT [i] = val;
257           pT2[i] = val;
258         }
259       }
260       break;
261     }
262   case SIZE_nRx2N:
263     {
264       Int iCurrPartNumQ = numElements>>2;
265       if( iPartIdx == 0 )
266       {
267         T *pT  = p;
268         T *pT2 = p + (iCurrPartNumQ<<1);
269         for (i = 0; i < ( (iCurrPartNumQ>>2) + iCurrPartNumQ ); i++)
270         {
271           pT [i] = val;
272           pT2[i] = val;
273         }
274 
275         pT  = p + iCurrPartNumQ + (iCurrPartNumQ>>1);
276         pT2 = p + numElements - iCurrPartNumQ + (iCurrPartNumQ>>1);
277         for (i = 0; i < (iCurrPartNumQ>>2); i++)
278         {
279           pT [i] = val;
280           pT2[i] = val;
281         }
282       }
283       else
284       {
285         T *pT  = p;
286         T *pT2 = p + (iCurrPartNumQ>>1);
287         T *pT3 = p + (iCurrPartNumQ<<1);
288         T *pT4 = p + (iCurrPartNumQ<<1) + (iCurrPartNumQ>>1);
289         for (i = 0; i < (iCurrPartNumQ>>2); i++)
290         {
291           pT [i] = val;
292           pT2[i] = val;
293           pT3[i] = val;
294           pT4[i] = val;
295         }
296       }
297       break;
298     }
299     default:
300       assert(0);
301       break;
302   }
303 }
304 
setAllMv(TComMv const & mv,PartSize eCUMode,Int iPartAddr,UInt uiDepth,Int iPartIdx)305 Void TComCUMvField::setAllMv( TComMv const & mv, PartSize eCUMode, Int iPartAddr, UInt uiDepth, Int iPartIdx )
306 {
307   setAll(m_pcMv, mv, eCUMode, iPartAddr, uiDepth, iPartIdx);
308 }
309 
setAllMvd(TComMv const & mvd,PartSize eCUMode,Int iPartAddr,UInt uiDepth,Int iPartIdx)310 Void TComCUMvField::setAllMvd( TComMv const & mvd, PartSize eCUMode, Int iPartAddr, UInt uiDepth, Int iPartIdx )
311 {
312   setAll(m_pcMvd, mvd, eCUMode, iPartAddr, uiDepth, iPartIdx);
313 }
314 
setAllRefIdx(Int iRefIdx,PartSize eCUMode,Int iPartAddr,UInt uiDepth,Int iPartIdx)315 Void TComCUMvField::setAllRefIdx ( Int iRefIdx, PartSize eCUMode, Int iPartAddr, UInt uiDepth, Int iPartIdx )
316 {
317   setAll(m_piRefIdx, static_cast<Char>(iRefIdx), eCUMode, iPartAddr, uiDepth, iPartIdx);
318 }
319 
setAllMvField(TComMvField const & mvField,PartSize eCUMode,Int iPartAddr,UInt uiDepth,Int iPartIdx)320 Void TComCUMvField::setAllMvField( TComMvField const & mvField, PartSize eCUMode, Int iPartAddr, UInt uiDepth, Int iPartIdx )
321 {
322   setAllMv    ( mvField.getMv(),     eCUMode, iPartAddr, uiDepth, iPartIdx );
323   setAllRefIdx( mvField.getRefIdx(), eCUMode, iPartAddr, uiDepth, iPartIdx );
324 }
325 
326 /**Subsampling of the stored prediction mode, reference index and motion vector
327  * \param pePredMode Pointer to prediction modes
328  * \param scale      Factor by which to subsample motion information
329  */
compress(Char * pePredMode,Int scale)330 Void TComCUMvField::compress(Char* pePredMode, Int scale)
331 {
332   Int N = scale * scale;
333   assert( N > 0 && N <= m_uiNumPartition);
334 
335   for ( Int uiPartIdx = 0; uiPartIdx < m_uiNumPartition; uiPartIdx += N )
336   {
337     TComMv cMv(0,0);
338     Int iRefIdx = 0;
339 
340     cMv = m_pcMv[ uiPartIdx ];
341     PredMode predMode = static_cast<PredMode>( pePredMode[ uiPartIdx ] );
342     iRefIdx = m_piRefIdx[ uiPartIdx ];
343     for ( Int i = 0; i < N; i++ )
344     {
345       m_pcMv[ uiPartIdx + i ] = cMv;
346       pePredMode[ uiPartIdx + i ] = predMode;
347       m_piRefIdx[ uiPartIdx + i ] = iRefIdx;
348     }
349   }
350 }
351 //! \}
352