1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 /**
17 *************************************************************************
18 * @file VideoEditorBuffer.c
19 * @brief StageFright shell Buffer
20 *************************************************************************
21 */
22 #undef M4OSA_TRACE_LEVEL
23 #define M4OSA_TRACE_LEVEL 1
24
25 #include "VideoEditorBuffer.h"
26 #include "utils/Log.h"
27
28 #define VIDEOEDITOR_BUFFEPOOL_MAX_NAME_SIZE 40
29
30 #define VIDEOEDITOR_SAFE_FREE(p) \
31 { \
32 if(M4OSA_NULL != p) \
33 { \
34 free(p); \
35 p = M4OSA_NULL; \
36 } \
37 }
38
39 /**
40 ************************************************************************
41 M4OSA_ERR VIDEOEDITOR_BUFFER_allocatePool(VIDEOEDITOR_BUFFER_Pool** ppool,
42 * M4OSA_UInt32 nbBuffers)
43 * @brief Allocate a pool of nbBuffers buffers
44 *
45 * @param ppool : IN The buffer pool to create
46 * @param nbBuffers : IN The number of buffers in the pool
47 * @param poolName : IN a name given to the pool
48 * @return Error code
49 ************************************************************************
50 */
VIDEOEDITOR_BUFFER_allocatePool(VIDEOEDITOR_BUFFER_Pool ** ppool,M4OSA_UInt32 nbBuffers,M4OSA_Char * poolName)51 M4OSA_ERR VIDEOEDITOR_BUFFER_allocatePool(VIDEOEDITOR_BUFFER_Pool** ppool,
52 M4OSA_UInt32 nbBuffers, M4OSA_Char* poolName)
53 {
54 M4OSA_ERR lerr = M4NO_ERROR;
55 VIDEOEDITOR_BUFFER_Pool* pool;
56 M4OSA_UInt32 index;
57
58 ALOGV("VIDEOEDITOR_BUFFER_allocatePool : ppool = 0x%x nbBuffers = %d ",
59 ppool, nbBuffers);
60
61 pool = M4OSA_NULL;
62 pool = (VIDEOEDITOR_BUFFER_Pool*)M4OSA_32bitAlignedMalloc(
63 sizeof(VIDEOEDITOR_BUFFER_Pool), VIDEOEDITOR_BUFFER_EXTERNAL,
64 (M4OSA_Char*)("VIDEOEDITOR_BUFFER_allocatePool: pool"));
65 if (M4OSA_NULL == pool)
66 {
67 lerr = M4ERR_ALLOC;
68 goto VIDEOEDITOR_BUFFER_allocatePool_Cleanup;
69 }
70
71 ALOGV("VIDEOEDITOR_BUFFER_allocatePool : Allocating Pool buffers");
72 pool->pNXPBuffer = M4OSA_NULL;
73 pool->pNXPBuffer = (VIDEOEDITOR_BUFFER_Buffer*)M4OSA_32bitAlignedMalloc(
74 sizeof(VIDEOEDITOR_BUFFER_Buffer)*nbBuffers,
75 VIDEOEDITOR_BUFFER_EXTERNAL,
76 (M4OSA_Char*)("BUFFER_allocatePool: pNXPBuffer"));
77 if(M4OSA_NULL == pool->pNXPBuffer)
78 {
79 lerr = M4ERR_ALLOC;
80 goto VIDEOEDITOR_BUFFER_allocatePool_Cleanup;
81 }
82
83 for (index = 0; index < nbBuffers; index++)
84 {
85 pool->pNXPBuffer[index].pData = M4OSA_NULL;
86 }
87
88 ALOGV("VIDEOEDITOR_BUFFER_allocatePool : Allocating Pool name buffer");
89 pool->poolName = M4OSA_NULL;
90 pool->poolName = (M4OSA_Char*)M4OSA_32bitAlignedMalloc(
91 VIDEOEDITOR_BUFFEPOOL_MAX_NAME_SIZE,VIDEOEDITOR_BUFFER_EXTERNAL,
92 (M4OSA_Char*)("VIDEOEDITOR_BUFFER_allocatePool: poolname"));
93 if(pool->poolName == M4OSA_NULL)
94 {
95 lerr = M4ERR_ALLOC;
96 goto VIDEOEDITOR_BUFFER_allocatePool_Cleanup;
97 }
98
99 ALOGV("VIDEOEDITOR_BUFFER_allocatePool : Assigning Pool name buffer");
100
101 memset((void *)pool->poolName, 0,VIDEOEDITOR_BUFFEPOOL_MAX_NAME_SIZE);
102 memcpy((void *)pool->poolName, (void *)poolName,
103 VIDEOEDITOR_BUFFEPOOL_MAX_NAME_SIZE-1);
104
105 pool->NB = nbBuffers;
106
107 VIDEOEDITOR_BUFFER_allocatePool_Cleanup:
108 if(M4NO_ERROR != lerr)
109 {
110 VIDEOEDITOR_SAFE_FREE(pool->pNXPBuffer);
111 VIDEOEDITOR_SAFE_FREE(pool->poolName);
112 VIDEOEDITOR_SAFE_FREE(pool);
113 }
114 *ppool = pool;
115 ALOGV("VIDEOEDITOR_BUFFER_allocatePool END");
116
117 return lerr;
118 }
119
120 /**
121 ************************************************************************
122 M4OSA_ERR VIDEOEDITOR_BUFFER_freePool(VIDEOEDITOR_BUFFER_Pool* ppool)
123 * @brief Deallocate a buffer pool
124 *
125 * @param ppool : IN The buffer pool to free
126 * @return Error code
127 ************************************************************************
128 */
VIDEOEDITOR_BUFFER_freePool(VIDEOEDITOR_BUFFER_Pool * ppool)129 M4OSA_ERR VIDEOEDITOR_BUFFER_freePool(VIDEOEDITOR_BUFFER_Pool* ppool)
130 {
131 M4OSA_ERR err;
132 M4OSA_UInt32 j = 0;
133
134 ALOGV("VIDEOEDITOR_BUFFER_freePool : ppool = 0x%x", ppool);
135
136 err = M4NO_ERROR;
137
138 for (j = 0; j < ppool->NB; j++)
139 {
140 if(M4OSA_NULL != ppool->pNXPBuffer[j].pData)
141 {
142 free(ppool->pNXPBuffer[j].pData);
143 ppool->pNXPBuffer[j].pData = M4OSA_NULL;
144 }
145 }
146
147 if(ppool != M4OSA_NULL)
148 {
149 SAFE_FREE(ppool->pNXPBuffer);
150 SAFE_FREE(ppool->poolName);
151 SAFE_FREE(ppool);
152 }
153
154 return(err);
155 }
156
157 /**
158 ************************************************************************
159 M4OSA_ERR VIDEOEDITOR_BUFFER_getBuffer(VIDEOEDITOR_BUFFER_Pool* ppool,
160 * VIDEOEDITOR_BUFFER_Buffer** pNXPBuffer)
161 * @brief Returns a buffer in a given state
162 *
163 * @param ppool : IN The buffer pool
164 * @param desiredState : IN The buffer state
165 * @param pNXPBuffer : IN The selected buffer
166 * @return Error code
167 ************************************************************************
168 */
VIDEOEDITOR_BUFFER_getBuffer(VIDEOEDITOR_BUFFER_Pool * ppool,VIDEOEDITOR_BUFFER_State desiredState,VIDEOEDITOR_BUFFER_Buffer ** pNXPBuffer)169 M4OSA_ERR VIDEOEDITOR_BUFFER_getBuffer(VIDEOEDITOR_BUFFER_Pool* ppool,
170 VIDEOEDITOR_BUFFER_State desiredState,
171 VIDEOEDITOR_BUFFER_Buffer** pNXPBuffer)
172 {
173 M4OSA_ERR err = M4NO_ERROR;
174 M4OSA_Bool bFound = M4OSA_FALSE;
175 M4OSA_UInt32 i, ibuf;
176
177 ALOGV("VIDEOEDITOR_BUFFER_getBuffer from %s in state=%d",
178 ppool->poolName, desiredState);
179
180 ibuf = 0;
181
182 for (i=0; i < ppool->NB; i++)
183 {
184 bFound = (ppool->pNXPBuffer[i].state == desiredState);
185 if (bFound)
186 {
187 ibuf = i;
188 break;
189 }
190 }
191
192 if(!bFound)
193 {
194 ALOGV("VIDEOEDITOR_BUFFER_getBuffer No buffer available in state %d",
195 desiredState);
196 *pNXPBuffer = M4OSA_NULL;
197 return M4ERR_NO_BUFFER_AVAILABLE;
198 }
199
200 /* case where a buffer has been found */
201 *pNXPBuffer = &(ppool->pNXPBuffer[ibuf]);
202
203 ALOGV("VIDEOEDITOR_BUFFER_getBuffer: idx = %d", ibuf);
204
205 return(err);
206 }
207
VIDEOEDITOR_BUFFER_initPoolBuffers(VIDEOEDITOR_BUFFER_Pool * pool,M4OSA_UInt32 lSize)208 M4OSA_ERR VIDEOEDITOR_BUFFER_initPoolBuffers(VIDEOEDITOR_BUFFER_Pool* pool,
209 M4OSA_UInt32 lSize)
210 {
211 M4OSA_ERR err = M4NO_ERROR;
212 M4OSA_UInt32 index, j;
213
214 /**
215 * Initialize all the buffers in the pool */
216 for(index = 0; index < pool->NB; index++)
217 {
218 pool->pNXPBuffer[index].pData = M4OSA_NULL;
219 pool->pNXPBuffer[index].pData = (M4OSA_Void*)M4OSA_32bitAlignedMalloc(
220 lSize, VIDEOEDITOR_BUFFER_EXTERNAL,
221 (M4OSA_Char*)("BUFFER_initPoolBuffers: Buffer data"));
222 if(M4OSA_NULL == pool->pNXPBuffer[index].pData)
223 {
224 for (j = 0; j < index; j++)
225 {
226 if(M4OSA_NULL != pool->pNXPBuffer[j].pData)
227 {
228 free(pool->pNXPBuffer[j].pData);
229 pool->pNXPBuffer[j].pData = M4OSA_NULL;
230 }
231 }
232 err = M4ERR_ALLOC;
233 return err;
234 }
235 pool->pNXPBuffer[index].size = 0;
236 pool->pNXPBuffer[index].state = VIDEOEDITOR_BUFFER_kEmpty;
237 pool->pNXPBuffer[index].idx = index;
238 pool->pNXPBuffer[index].buffCTS = -1;
239 }
240 return err;
241 }
242
VIDEOEDITOR_BUFFER_getOldestBuffer(VIDEOEDITOR_BUFFER_Pool * pool,VIDEOEDITOR_BUFFER_State desiredState,VIDEOEDITOR_BUFFER_Buffer ** pNXPBuffer)243 M4OSA_ERR VIDEOEDITOR_BUFFER_getOldestBuffer(VIDEOEDITOR_BUFFER_Pool *pool,
244 VIDEOEDITOR_BUFFER_State desiredState,
245 VIDEOEDITOR_BUFFER_Buffer** pNXPBuffer)
246 {
247 M4OSA_ERR err = M4NO_ERROR;
248 M4OSA_UInt32 index, j;
249 M4_MediaTime candidateTimeStamp = (M4_MediaTime)0x7ffffff;
250 M4OSA_Bool bFound = M4OSA_FALSE;
251
252 *pNXPBuffer = M4OSA_NULL;
253 for(index = 0; index< pool->NB; index++)
254 {
255 if(pool->pNXPBuffer[index].state == desiredState)
256 {
257 if(pool->pNXPBuffer[index].buffCTS <= candidateTimeStamp)
258 {
259 bFound = M4OSA_TRUE;
260 candidateTimeStamp = pool->pNXPBuffer[index].buffCTS;
261 *pNXPBuffer = &(pool->pNXPBuffer[index]);
262 }
263 }
264 }
265 if(M4OSA_FALSE == bFound)
266 {
267 ALOGV("VIDEOEDITOR_BUFFER_getOldestBuffer WARNING no buffer available");
268 err = M4ERR_NO_BUFFER_AVAILABLE;
269 }
270 return err;
271 }
272