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 */ 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 */ 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 */ 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 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 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