History

Initial Commit

Ethan Hugg committed 12 years ago

Commit 70e5e621 parent bd509b2308 files · +97095 −-5Browse files

Showing the changes to codec/decoder/core/src/fmo.cpp (1 of 308 files). Show all

Unified · Split

codec/decoder/core/src/fmo.cpp+355−0
@@ -0,0 +1,355 @@
1/*!
2 * \copy
3 * Copyright (c) 2009-2013, Cisco Systems
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 *
32 * \file fmo.c
33 *
34 * \brief Flexible Macroblock Ordering implementation
35 *
36 * \date 2/4/2009 Created
37 *
38 *************************************************************************************
39 */
40#include <string.h>
41
42#include "fmo.h"
43#include "macros.h"
44#include "utils.h"
45#include "mem_align.h"
46
47namespace WelsDec {
48
49/*!
50 * \brief Generate MB allocated map for interleaved slice group (TYPE 0)
51 *
52 * \param pFmo fmo context
53 * \param pPps pps context
54 *
55 * \return 0 - successful; none 0 - failed
56 */
57static inline int32_t FmoGenerateMbAllocMapType0( PFmo pFmo, PPps pPps )
58{
59 uint32_t uiNumSliceGroups = 0;
60 int32_t iMbNum = 0;
61 int32_t i = 0;
62
63 WELS_VERIFY_RETURN_IF( 1, ( NULL == pFmo || NULL == pPps ) )
64 uiNumSliceGroups = pPps->uiNumSliceGroups;
65 iMbNum = pFmo->iCountMbNum;
66 WELS_VERIFY_RETURN_IF( 1, ( NULL == pFmo->pMbAllocMap || iMbNum <= 0 || uiNumSliceGroups >= MAX_SLICEGROUP_IDS ) )
67
68 do
69 {
70 uint8_t uiGroup = 0;
71 do {
72 const int32_t kiRunIdx = pPps->uiRunLength[uiGroup];
73 int32_t j = 0;
74 do {
75 pFmo->pMbAllocMap[i+j] = uiGroup;
76 ++ j;
77 } while(j < kiRunIdx && i + j < iMbNum);
78 i += kiRunIdx;
79 ++ uiGroup;
80 } while(uiGroup < uiNumSliceGroups && i < iMbNum);
81 }while(i < iMbNum);
82
83 return 0; // well here
84}
85
86/*!
87 * \brief Generate MB allocated map for dispersed slice group (TYPE 1)
88 *
89 * \param pFmo fmo context
90 * \param pPps pps context
91 * \param iMbWidth MB width
92 *
93 * \return 0 - successful; none 0 - failed
94 */
95static inline int32_t FmoGenerateMbAllocMapType1( PFmo pFmo, PPps pPps, const int32_t kiMbWidth )
96{
97 uint32_t uiNumSliceGroups = 0;
98 int32_t iMbNum = 0;
99 int16_t i = 0;
100 WELS_VERIFY_RETURN_IF( 1, ( NULL == pFmo || NULL == pPps ) )
101 uiNumSliceGroups = pPps->uiNumSliceGroups;
102 iMbNum = pFmo->iCountMbNum;
103 WELS_VERIFY_RETURN_IF( 1, ( NULL == pFmo->pMbAllocMap || iMbNum <= 0 || kiMbWidth == 0 || uiNumSliceGroups >= MAX_SLICEGROUP_IDS ) )
104
105 do
106 {
107 pFmo->pMbAllocMap[i] = (uint8_t)(((i % kiMbWidth)+(((i / kiMbWidth)*uiNumSliceGroups)>>1)) % uiNumSliceGroups);
108 ++ i;
109 }while (i < iMbNum);
110
111 return 0; // well here
112}
113
114/*!
115 * \brief Generate MB allocated map for various type of slice group cases (TYPE 0, .., 6)
116 *
117 * \param pFmo fmo context
118 * \param pPps pps context
119 * \param kiMbWidth MB width
120 * \param kiMbHeight MB height
121 *
122 * \return 0 - successful; none 0 - failed
123 */
124static inline int32_t FmoGenerateSliceGroup( PFmo pFmo, const PPps kpPps, const int32_t kiMbWidth, const int32_t kiMbHeight )
125{
126 int32_t iNumMb = 0;
127 int32_t iErr = 0;
128 bool_t bResolutionChanged = false;
129
130 // the cases we would not like
131 WELS_VERIFY_RETURN_IF( 1, ( NULL == pFmo || NULL == kpPps ) )
132
133 iNumMb = pFmo->iCountMbNum;
134
135 iNumMb = kiMbWidth * kiMbHeight;
136
137 if ( 0 == iNumMb )
138 return 1;
139
140
141 WelsFree(pFmo->pMbAllocMap, "_fmo->pMbAllocMap");
142 pFmo->pMbAllocMap = (uint8_t *)WelsMalloc( iNumMb * sizeof(uint8_t), "_fmo->pMbAllocMap" );
143 WELS_VERIFY_RETURN_IF( 1, (NULL == pFmo->pMbAllocMap) ) // out of memory
144
145 pFmo->iCountMbNum = iNumMb;
146
147 if ( kpPps->uiNumSliceGroups < 2 && iNumMb > 0) // only one slice group, exactly it is single slice based
148 {
149 memset ( pFmo->pMbAllocMap, 0, iNumMb * sizeof(int8_t)); // for safe
150
151 pFmo->iSliceGroupCount = 1;
152
153 return 0;
154 }
155
156 if ( bResolutionChanged || ((int32_t)kpPps->uiSliceGroupMapType != pFmo->iSliceGroupType)
157 || ((int32_t)kpPps->uiNumSliceGroups != pFmo->iSliceGroupCount) )
158 {
159 switch ( kpPps->uiSliceGroupMapType )
160 {
161 case 0:
162 iErr = FmoGenerateMbAllocMapType0( pFmo, kpPps );
163 break;
164 case 1:
165 iErr = FmoGenerateMbAllocMapType1( pFmo, kpPps, kiMbWidth );
166 break;
167 case 2:
168 case 3:
169 case 4:
170 case 5:
171 case 6:
172 // Reserve for others slice group type
173 iErr = 1;
174 break;
175 default:
176 return 1;
177 }
178 }
179
180 if ( 0 == iErr ) // well now
181 {
182 pFmo->iSliceGroupCount = kpPps->uiNumSliceGroups;
183 pFmo->iSliceGroupType = kpPps->uiSliceGroupMapType;
184 }
185
186 return iErr;
187}
188
189/*!
190 * \brief Initialize Wels Flexible Macroblock Ordering (FMO)
191 *
192 * \param pFmo Wels fmo to be initialized
193 * \param pPps pps argument
194 * \param kiMbWidth mb width
195 * \param kiMbHeight mb height
196 *
197 * \return 0 - successful; none 0 - failed;
198 */
199int32_t InitFmo( PFmo pFmo, PPps pPps, const int32_t kiMbWidth, const int32_t kiMbHeight )
200{
201 return FmoGenerateSliceGroup( pFmo, pPps, kiMbWidth, kiMbHeight );
202}
203
204
205/*!
206 * \brief Uninitialize Wels Flexible Macroblock Ordering (FMO) list
207 *
208 * \param pFmo Wels base fmo ptr to be uninitialized
209 * \param kiCnt count number of PPS per list
210 * \param kiAvail count available number of PPS in list
211 *
212 * \return NONE
213 */
214void_t UninitFmoList( PFmo pFmo, const int32_t kiCnt, const int32_t kiAvail )
215{
216 PFmo pIter = pFmo;
217 int32_t i = 0;
218 int32_t iFreeNodes = 0;
219
220 if ( NULL == pIter || kiAvail <= 0 || kiCnt < kiAvail )
221 return;
222
223 while ( i < kiCnt ) {
224 if ( pIter != NULL && pIter->bActiveFlag )
225 {
226 if ( NULL != pIter->pMbAllocMap )
227 {
228 WelsFree( pIter->pMbAllocMap, "pIter->pMbAllocMap" );
229
230 pIter->pMbAllocMap = NULL;
231 }
232 pIter->iSliceGroupCount = 0;
233 pIter->iSliceGroupType = -1;
234 pIter->iCountMbNum = 0;
235 pIter->bActiveFlag = false;
236 ++ iFreeNodes;
237 if ( iFreeNodes >= kiAvail )
238 break;
239 }
240 ++ pIter;
241 ++ i;
242 }
243}
244
245/*!
246 * \brief detect parameter sets are changed or not
247 *
248 * \param pFmo fmo context
249 * \param kiCountNumMb (iMbWidth * iMbHeight) in Sps
250 * \param iSliceGroupType slice group type if fmo is exactly enabled
251 * \param iSliceGroupCount slice group count if fmo is exactly enabled
252 *
253 * \return true - changed or not initialized yet; false - not change at all
254 */
255bool_t FmoParamSetsChanged( PFmo pFmo, const int32_t kiCountNumMb, const int32_t kiSliceGroupType, const int32_t kiSliceGroupCount )
256{
257 WELS_VERIFY_RETURN_IF( false, (NULL == pFmo) )
258
259 return ( (!pFmo->bActiveFlag)
260 || (kiCountNumMb != pFmo->iCountMbNum)
261 || (kiSliceGroupType != pFmo->iSliceGroupType)
262 || (kiSliceGroupCount != pFmo->iSliceGroupCount) );
263}
264
265/*!
266 * \brief update/insert FMO parameter unit
267 *
268 * \param _fmo FMO context
269 * \param _sps PSps
270 * \param _pps PPps
271 * \param pActiveFmoNum int32_t* [in/out]
272 *
273 * \return true - update/insert successfully; false - failed;
274 */
275bool_t FmoParamUpdate( PFmo pFmo, PSps pSps, PPps pPps, int32_t *pActiveFmoNum )
276{
277 const uint32_t kuiMbWidth = pSps->iMbWidth;
278 const uint32_t kuiMbHeight= pSps->iMbHeight;
279
280 if ( FmoParamSetsChanged( pFmo,
281 kuiMbWidth * kuiMbHeight,
282 pPps->uiSliceGroupMapType,
283 pPps->uiNumSliceGroups ) )
284 {
285
286 if ( InitFmo( pFmo, pPps, kuiMbWidth, kuiMbHeight ) )
287 {
288 return false;
289 }
290 else
291 {
292 if ( !pFmo->bActiveFlag && *pActiveFmoNum < MAX_PPS_COUNT )
293 {
294 ++ (*pActiveFmoNum);
295 pFmo->bActiveFlag = true;
296 }
297 }
298 }
299
300 return true;
301}
302
303/*!
304 * \brief Convert kMbXy to slice group idc correspondingly
305 *
306 * \param pFmo Wels fmo context
307 * \param kMbXy kMbXy to be converted
308 *
309 * \return slice group idc - successful; -1 - failed;
310 */
311int32_t FmoMbToSliceGroup( PFmo pFmo, const MB_XY_T kiMbXy )
312{
313 const int32_t kiMbNum = pFmo->iCountMbNum;
314 const uint8_t* kpMbMap = pFmo->pMbAllocMap;
315
316 if ( kiMbXy < 0 || kiMbXy >= kiMbNum || kpMbMap == NULL)
317 return -1;
318
319 return kpMbMap[ kiMbXy ];
320}
321
322/*!
323 * \brief Get successive mb to be processed with given current kMbXy
324 *
325 * \param pFmo Wels fmo context
326 * \param kMbXy current kMbXy
327 *
328 * \return iNextMb - successful; -1 - failed;
329 */
330MB_XY_T FmoNextMb( PFmo pFmo, const MB_XY_T kiMbXy )
331{
332 const int32_t kiTotalMb = pFmo->iCountMbNum;
333 const uint8_t* kpMbMap = pFmo->pMbAllocMap;
334 MB_XY_T iNextMb = kiMbXy;
335 const uint8_t kuiSliceGroupIdc = (uint8_t)FmoMbToSliceGroup( pFmo, kiMbXy );
336
337 if (kuiSliceGroupIdc == (uint8_t)(-1))
338 return -1;
339
340 do {
341 ++ iNextMb;
342 if (iNextMb >= kiTotalMb){
343 iNextMb = -1;
344 break;
345 }
346 if (kpMbMap[iNextMb] == kuiSliceGroupIdc){
347 break;
348 }
349 } while( 1 );
350
351 // -1: No further MB in this slice (could be end of picture)
352 return iNextMb;
353}
354
355} // namespace WelsDec

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t