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