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