1 /*!
2 * \copy
3 * Copyright (c) 2008-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 * memmgr_nal_unit.c
33 *
34 * Abstract
35 * memory manager utils for NAL Unit list available
36 *
37 * History
38 * 07/10/2008 Created
39 *
40 *****************************************************************************/
41 #include "memmgr_nal_unit.h"
42 #include "memory_align.h"
43 #include "error_code.h"
44
45 namespace WelsDec {
46
MemInitNalList(PAccessUnit * ppAu,const uint32_t kuiSize,CMemoryAlign * pMa)47 int32_t MemInitNalList (PAccessUnit* ppAu, const uint32_t kuiSize, CMemoryAlign* pMa) {
48 uint32_t uiIdx = 0;
49 uint8_t* pBase = NULL, *pPtr = NULL;
50 const uint32_t kuiSizeAu = sizeof (SAccessUnit);
51 const uint32_t kuiSizeNalUnitPtr = kuiSize * sizeof (PNalUnit);
52 const uint32_t kuiSizeNalUnit = sizeof (SNalUnit);
53 const uint32_t kuiCountSize = (kuiSizeAu + kuiSizeNalUnitPtr + kuiSize * kuiSizeNalUnit) * sizeof (uint8_t);
54
55 if (kuiSize == 0)
56 return ERR_INFO_INVALID_PARAM;
57
58 if (*ppAu != NULL) {
59 MemFreeNalList (ppAu, pMa);
60 }
61
62 pBase = (uint8_t*)pMa->WelsMallocz (kuiCountSize, "Access Unit");
63 if (pBase == NULL)
64 return ERR_INFO_OUT_OF_MEMORY;
65 pPtr = pBase;
66 *ppAu = (PAccessUnit)pPtr;
67 pPtr += kuiSizeAu;
68 (*ppAu)->pNalUnitsList = (PNalUnit*)pPtr;
69 pPtr += kuiSizeNalUnitPtr;
70 do {
71 (*ppAu)->pNalUnitsList[uiIdx] = (PNalUnit)pPtr;
72 pPtr += kuiSizeNalUnit;
73 ++ uiIdx;
74 } while (uiIdx < kuiSize);
75
76 (*ppAu)->uiCountUnitsNum = kuiSize;
77 (*ppAu)->uiAvailUnitsNum = 0;
78 (*ppAu)->uiActualUnitsNum = 0;
79 (*ppAu)->uiStartPos = 0;
80 (*ppAu)->uiEndPos = 0;
81 (*ppAu)->bCompletedAuFlag = false;
82
83 return ERR_NONE;
84 }
85
MemFreeNalList(PAccessUnit * ppAu,CMemoryAlign * pMa)86 int32_t MemFreeNalList (PAccessUnit* ppAu, CMemoryAlign* pMa) {
87 if (ppAu != NULL) {
88 PAccessUnit pAu = *ppAu;
89 if (pAu != NULL) {
90 pMa->WelsFree (pAu, "Access Unit");
91 *ppAu = NULL;
92 }
93 }
94 return ERR_NONE;
95 }
96
97
ExpandNalUnitList(PAccessUnit * ppAu,const int32_t kiOrgSize,const int32_t kiExpSize,CMemoryAlign * pMa)98 int32_t ExpandNalUnitList (PAccessUnit* ppAu, const int32_t kiOrgSize, const int32_t kiExpSize, CMemoryAlign* pMa) {
99 if (kiExpSize <= kiOrgSize)
100 return ERR_INFO_INVALID_PARAM;
101 else {
102 PAccessUnit pTmp = NULL;
103 int32_t iIdx = 0;
104 int32_t iRet = ERR_NONE;
105 if ((iRet = MemInitNalList (&pTmp, kiExpSize, pMa)) != ERR_NONE) // request new list with expanding
106 return iRet;
107
108 do {
109 memcpy (pTmp->pNalUnitsList[iIdx], (*ppAu)->pNalUnitsList[iIdx], sizeof (SNalUnit)); //confirmed_safe_unsafe_usage
110 ++ iIdx;
111 } while (iIdx < kiOrgSize);
112
113 pTmp->uiCountUnitsNum = kiExpSize;
114 pTmp->uiAvailUnitsNum = (*ppAu)->uiAvailUnitsNum;
115 pTmp->uiActualUnitsNum = (*ppAu)->uiActualUnitsNum;
116 pTmp->uiEndPos = (*ppAu)->uiEndPos;
117 pTmp->bCompletedAuFlag = (*ppAu)->bCompletedAuFlag;
118
119 MemFreeNalList (ppAu, pMa); // free old list
120 *ppAu = pTmp;
121 return ERR_NONE;
122 }
123 }
124
125 /*
126 * MemGetNextNal
127 * Get next NAL Unit for using.
128 * Need expand NAL Unit list if exceeding count number of available NAL Units withing an Access Unit
129 */
MemGetNextNal(PAccessUnit * ppAu,CMemoryAlign * pMa)130 PNalUnit MemGetNextNal (PAccessUnit* ppAu, CMemoryAlign* pMa) {
131 PAccessUnit pAu = *ppAu;
132 PNalUnit pNu = NULL;
133
134 if (pAu->uiAvailUnitsNum >= pAu->uiCountUnitsNum) { // need expand list
135 const uint32_t kuiExpandingSize = pAu->uiCountUnitsNum + (MAX_NAL_UNIT_NUM_IN_AU >> 1);
136 if (ExpandNalUnitList (ppAu, pAu->uiCountUnitsNum, kuiExpandingSize, pMa))
137 return NULL; // out of memory
138 pAu = *ppAu;
139 }
140
141 pNu = pAu->pNalUnitsList[pAu->uiAvailUnitsNum++]; // ready for next nal position
142
143 memset (pNu, 0, sizeof (SNalUnit)); // Please do not remove this for cache intend!!
144
145 return pNu;
146 }
147
148 } // namespace WelsDec
149