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 57 LOGV("VIDEOEDITOR_BUFFER_allocatePool : ppool = 0x%x nbBuffers = %d ", 58 ppool, nbBuffers); 59 60 pool = M4OSA_NULL; 61 pool = (VIDEOEDITOR_BUFFER_Pool*)M4OSA_32bitAlignedMalloc( 62 sizeof(VIDEOEDITOR_BUFFER_Pool), VIDEOEDITOR_BUFFER_EXTERNAL, 63 (M4OSA_Char*)("VIDEOEDITOR_BUFFER_allocatePool: pool")); 64 if (M4OSA_NULL == pool) 65 { 66 lerr = M4ERR_ALLOC; 67 goto VIDEOEDITOR_BUFFER_allocatePool_Cleanup; 68 } 69 70 LOGV("VIDEOEDITOR_BUFFER_allocatePool : Allocating Pool buffers"); 71 pool->pNXPBuffer = M4OSA_NULL; 72 pool->pNXPBuffer = (VIDEOEDITOR_BUFFER_Buffer*)M4OSA_32bitAlignedMalloc( 73 sizeof(VIDEOEDITOR_BUFFER_Buffer)*nbBuffers, 74 VIDEOEDITOR_BUFFER_EXTERNAL, 75 (M4OSA_Char*)("BUFFER_allocatePool: pNXPBuffer")); 76 if(M4OSA_NULL == pool->pNXPBuffer) 77 { 78 lerr = M4ERR_ALLOC; 79 goto VIDEOEDITOR_BUFFER_allocatePool_Cleanup; 80 } 81 82 LOGV("VIDEOEDITOR_BUFFER_allocatePool : Allocating Pool name buffer"); 83 pool->poolName = M4OSA_NULL; 84 pool->poolName = (M4OSA_Char*)M4OSA_32bitAlignedMalloc( 85 VIDEOEDITOR_BUFFEPOOL_MAX_NAME_SIZE,VIDEOEDITOR_BUFFER_EXTERNAL, 86 (M4OSA_Char*)("VIDEOEDITOR_BUFFER_allocatePool: poolname")); 87 if(pool->poolName == M4OSA_NULL) 88 { 89 lerr = M4ERR_ALLOC; 90 goto VIDEOEDITOR_BUFFER_allocatePool_Cleanup; 91 } 92 93 LOGV("VIDEOEDITOR_BUFFER_allocatePool : Assigning Pool name buffer"); 94 95 memset((void *)pool->poolName, 0,VIDEOEDITOR_BUFFEPOOL_MAX_NAME_SIZE); 96 memcpy((void *)pool->poolName, (void *)poolName, 97 VIDEOEDITOR_BUFFEPOOL_MAX_NAME_SIZE-1); 98 99 pool->NB = nbBuffers; 100 101 VIDEOEDITOR_BUFFER_allocatePool_Cleanup: 102 if(M4NO_ERROR != lerr) 103 { 104 VIDEOEDITOR_SAFE_FREE(pool->pNXPBuffer); 105 VIDEOEDITOR_SAFE_FREE(pool->poolName); 106 VIDEOEDITOR_SAFE_FREE(pool); 107 } 108 *ppool = pool; 109 LOGV("VIDEOEDITOR_BUFFER_allocatePool END"); 110 111 return lerr; 112 } 113 114 /** 115 ************************************************************************ 116 M4OSA_ERR VIDEOEDITOR_BUFFER_freePool(VIDEOEDITOR_BUFFER_Pool* ppool) 117 * @brief Deallocate a buffer pool 118 * 119 * @param ppool : IN The buffer pool to free 120 * @return Error code 121 ************************************************************************ 122 */ 123 M4OSA_ERR VIDEOEDITOR_BUFFER_freePool(VIDEOEDITOR_BUFFER_Pool* ppool) 124 { 125 M4OSA_ERR err; 126 M4OSA_UInt32 j = 0; 127 128 LOGV("VIDEOEDITOR_BUFFER_freePool : ppool = 0x%x", ppool); 129 130 err = M4NO_ERROR; 131 132 for (j = 0; j < ppool->NB; j++) 133 { 134 if(M4OSA_NULL != ppool->pNXPBuffer[j].pData) 135 { 136 free(ppool->pNXPBuffer[j].pData); 137 ppool->pNXPBuffer[j].pData = M4OSA_NULL; 138 } 139 } 140 141 if(ppool != M4OSA_NULL) 142 { 143 SAFE_FREE(ppool->pNXPBuffer); 144 SAFE_FREE(ppool->poolName); 145 SAFE_FREE(ppool); 146 } 147 148 return(err); 149 } 150 151 /** 152 ************************************************************************ 153 M4OSA_ERR VIDEOEDITOR_BUFFER_getBuffer(VIDEOEDITOR_BUFFER_Pool* ppool, 154 * VIDEOEDITOR_BUFFER_Buffer** pNXPBuffer) 155 * @brief Returns a buffer in a given state 156 * 157 * @param ppool : IN The buffer pool 158 * @param desiredState : IN The buffer state 159 * @param pNXPBuffer : IN The selected buffer 160 * @return Error code 161 ************************************************************************ 162 */ 163 M4OSA_ERR VIDEOEDITOR_BUFFER_getBuffer(VIDEOEDITOR_BUFFER_Pool* ppool, 164 VIDEOEDITOR_BUFFER_State desiredState, 165 VIDEOEDITOR_BUFFER_Buffer** pNXPBuffer) 166 { 167 M4OSA_ERR err = M4NO_ERROR; 168 M4OSA_Bool bFound = M4OSA_FALSE; 169 M4OSA_UInt32 i, ibuf; 170 171 LOGV("VIDEOEDITOR_BUFFER_getBuffer from %s in state=%d", 172 ppool->poolName, desiredState); 173 174 ibuf = 0; 175 176 for (i=0; i < ppool->NB; i++) 177 { 178 bFound = (ppool->pNXPBuffer[i].state == desiredState); 179 if (bFound) 180 { 181 ibuf = i; 182 break; 183 } 184 } 185 186 if(!bFound) 187 { 188 LOGV("VIDEOEDITOR_BUFFER_getBuffer No buffer available in state %d", 189 desiredState); 190 *pNXPBuffer = M4OSA_NULL; 191 return M4ERR_NO_BUFFER_AVAILABLE; 192 } 193 194 /* case where a buffer has been found */ 195 *pNXPBuffer = &(ppool->pNXPBuffer[ibuf]); 196 197 LOGV("VIDEOEDITOR_BUFFER_getBuffer: idx = %d", ibuf); 198 199 return(err); 200 } 201 202 M4OSA_ERR VIDEOEDITOR_BUFFER_initPoolBuffers(VIDEOEDITOR_BUFFER_Pool* pool, 203 M4OSA_UInt32 lSize) 204 { 205 M4OSA_ERR err = M4NO_ERROR; 206 M4OSA_UInt32 index, j; 207 208 /** 209 * Initialize all the buffers in the pool */ 210 for(index = 0; index < pool->NB; index++) 211 { 212 pool->pNXPBuffer[index].pData = M4OSA_NULL; 213 pool->pNXPBuffer[index].pData = (M4OSA_Void*)M4OSA_32bitAlignedMalloc( 214 lSize, VIDEOEDITOR_BUFFER_EXTERNAL, 215 (M4OSA_Char*)("BUFFER_initPoolBuffers: Buffer data")); 216 if(M4OSA_NULL == pool->pNXPBuffer[index].pData) 217 { 218 for (j = 0; j < index; j++) 219 { 220 if(M4OSA_NULL != pool->pNXPBuffer[j].pData) 221 { 222 free(pool->pNXPBuffer[j].pData); 223 pool->pNXPBuffer[j].pData = M4OSA_NULL; 224 } 225 } 226 err = M4ERR_ALLOC; 227 return err; 228 } 229 pool->pNXPBuffer[index].size = 0; 230 pool->pNXPBuffer[index].state = VIDEOEDITOR_BUFFER_kEmpty; 231 pool->pNXPBuffer[index].idx = index; 232 pool->pNXPBuffer[index].buffCTS = -1; 233 } 234 return err; 235 } 236 237 M4OSA_ERR VIDEOEDITOR_BUFFER_getOldestBuffer(VIDEOEDITOR_BUFFER_Pool *pool, 238 VIDEOEDITOR_BUFFER_State desiredState, 239 VIDEOEDITOR_BUFFER_Buffer** pNXPBuffer) 240 { 241 M4OSA_ERR err = M4NO_ERROR; 242 M4OSA_UInt32 index, j; 243 M4_MediaTime candidateTimeStamp = (M4_MediaTime)0x7ffffff; 244 M4OSA_Bool bFound = M4OSA_FALSE; 245 246 *pNXPBuffer = M4OSA_NULL; 247 for(index = 0; index< pool->NB; index++) 248 { 249 if(pool->pNXPBuffer[index].state == desiredState) 250 { 251 if(pool->pNXPBuffer[index].buffCTS <= candidateTimeStamp) 252 { 253 bFound = M4OSA_TRUE; 254 candidateTimeStamp = pool->pNXPBuffer[index].buffCTS; 255 *pNXPBuffer = &(pool->pNXPBuffer[index]); 256 } 257 } 258 } 259 if(M4OSA_FALSE == bFound) 260 { 261 LOGV("VIDEOEDITOR_BUFFER_getOldestBuffer WARNING no buffer available"); 262 err = M4ERR_NO_BUFFER_AVAILABLE; 263 } 264 return err; 265 } 266