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+
47+namespace 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+ */
57+static 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+ */
95+static 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+ */
124+static 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+ */
199+int32_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+ */
214+void_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+ */
255+bool_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+ */
275+bool_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+ */
311+int32_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+ */
330+MB_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