blob: 2ddea806f3d95ca803d11081e4d2bafa17600415 [file] [log] [blame]
/*************************************************************************************
* INTEL CONFIDENTIAL
* Copyright 2011 Intel Corporation All Rights Reserved.
* The source code contained or described herein and all documents related
* to the source code ("Material") are owned by Intel Corporation or its
* suppliers or licensors. Title to the Material remains with Intel
* Corporation or its suppliers and licensors. The Material contains trade
* secrets and proprietary and confidential information of Intel or its
* suppliers and licensors. The Material is protected by worldwide copyright
* and trade secret laws and treaty provisions. No part of the Material may
* be used, copied, reproduced, modified, published, uploaded, posted,
* transmitted, distributed, or disclosed in any way without Intel's prior
* express written permission.
*
* No license under any patent, copyright, trade secret or other intellectual
* property right is granted to or conferred upon you by disclosure or delivery
* of the Materials, either expressly, by implication, inducement, estoppel or
* otherwise. Any license under such intellectual property rights must be express
* and approved by Intel in writing.
************************************************************************************/
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
*************************************************************************
* @file VideoEditorBuffer.cpp
* @brief StageFright shell Buffer
*************************************************************************
*/
#undef M4OSA_TRACE_LEVEL
#define M4OSA_TRACE_LEVEL 1
#include "VideoEditorBuffer.h"
#include "utils/Log.h"
#define VIDEOEDITOR_BUFFEPOOL_MAX_NAME_SIZE 40
#define VIDEOEDITOR_SAFE_FREE(p) \
{ \
if(M4OSA_NULL != p) \
{ \
free(p); \
p = M4OSA_NULL; \
} \
}
/**
************************************************************************
M4OSA_ERR VIDEOEDITOR_BUFFER_allocatePool(VIDEOEDITOR_BUFFER_Pool** ppool,
* M4OSA_UInt32 nbBuffers)
* @brief Allocate a pool of nbBuffers buffers
*
* @param ppool : IN The buffer pool to create
* @param nbBuffers : IN The number of buffers in the pool
* @param poolName : IN a name given to the pool
* @return Error code
************************************************************************
*/
M4OSA_ERR VIDEOEDITOR_BUFFER_allocatePool(VIDEOEDITOR_BUFFER_Pool** ppool,
M4OSA_UInt32 nbBuffers, M4OSA_Char* poolName)
{
M4OSA_ERR lerr = M4NO_ERROR;
VIDEOEDITOR_BUFFER_Pool* pool;
ALOGV("VIDEOEDITOR_BUFFER_allocatePool : ppool = 0x%x nbBuffers = %d ",
ppool, nbBuffers);
pool = M4OSA_NULL;
pool = (VIDEOEDITOR_BUFFER_Pool*)M4OSA_32bitAlignedMalloc(
sizeof(VIDEOEDITOR_BUFFER_Pool), VIDEOEDITOR_BUFFER_EXTERNAL,
(M4OSA_Char*)("VIDEOEDITOR_BUFFER_allocatePool: pool"));
if (M4OSA_NULL == pool)
{
lerr = M4ERR_ALLOC;
goto VIDEOEDITOR_BUFFER_allocatePool_Cleanup;
}
ALOGV("VIDEOEDITOR_BUFFER_allocatePool : Allocating Pool buffers");
pool->pNXPBuffer = M4OSA_NULL;
pool->pNXPBuffer = (VIDEOEDITOR_BUFFER_Buffer*)M4OSA_32bitAlignedMalloc(
sizeof(VIDEOEDITOR_BUFFER_Buffer)*nbBuffers,
VIDEOEDITOR_BUFFER_EXTERNAL,
(M4OSA_Char*)("BUFFER_allocatePool: pNXPBuffer"));
if(M4OSA_NULL == pool->pNXPBuffer)
{
lerr = M4ERR_ALLOC;
goto VIDEOEDITOR_BUFFER_allocatePool_Cleanup;
}
ALOGV("VIDEOEDITOR_BUFFER_allocatePool : Allocating Pool name buffer");
pool->poolName = M4OSA_NULL;
pool->poolName = (M4OSA_Char*)M4OSA_32bitAlignedMalloc(
VIDEOEDITOR_BUFFEPOOL_MAX_NAME_SIZE,VIDEOEDITOR_BUFFER_EXTERNAL,
(M4OSA_Char*)("VIDEOEDITOR_BUFFER_allocatePool: poolname"));
if(pool->poolName == M4OSA_NULL)
{
lerr = M4ERR_ALLOC;
goto VIDEOEDITOR_BUFFER_allocatePool_Cleanup;
}
ALOGV("VIDEOEDITOR_BUFFER_allocatePool : Assigning Pool name buffer");
memset((void *)pool->poolName, 0,VIDEOEDITOR_BUFFEPOOL_MAX_NAME_SIZE);
if (strlen((const char *)poolName) < VIDEOEDITOR_BUFFEPOOL_MAX_NAME_SIZE) {
memcpy((void *)pool->poolName, (void *)poolName,
strlen((const char *)poolName));
}
pool->NB = nbBuffers;
VIDEOEDITOR_BUFFER_allocatePool_Cleanup:
if(M4NO_ERROR != lerr)
{
VIDEOEDITOR_SAFE_FREE(pool->pNXPBuffer);
VIDEOEDITOR_SAFE_FREE(pool->poolName);
VIDEOEDITOR_SAFE_FREE(pool);
}
*ppool = pool;
ALOGV("VIDEOEDITOR_BUFFER_allocatePool END");
return lerr;
}
/**
************************************************************************
M4OSA_ERR VIDEOEDITOR_BUFFER_freePool_Ext(VIDEOEDITOR_BUFFER_Pool* ppool)
* @brief Deallocate a buffer pool
*
* @param ppool : IN The buffer pool to free
* @return Error code
************************************************************************
*/
M4OSA_ERR VIDEOEDITOR_BUFFER_freePool_Ext(VIDEOEDITOR_BUFFER_Pool* ppool)
{
M4OSA_ERR err;
M4OSA_UInt32 j = 0;
ALOGV("VIDEOEDITOR_BUFFER_freePool_Ext : ppool = 0x%x", ppool);
err = M4NO_ERROR;
for (j = 0; j < ppool->NB; j++)
{
if(M4OSA_NULL != ppool->pNXPBuffer[j].mBuffer)
{
ppool->pNXPBuffer[j].mBuffer->release();
ppool->pNXPBuffer[j].state = VIDEOEDITOR_BUFFER_kEmpty;
ppool->pNXPBuffer[j].mBuffer = M4OSA_NULL;
ppool->pNXPBuffer[j].size = 0;
ppool->pNXPBuffer[j].buffCTS = -1;
}
}
if(ppool != M4OSA_NULL)
{
SAFE_FREE(ppool->pNXPBuffer);
SAFE_FREE(ppool->poolName);
SAFE_FREE(ppool);
}
return(err);
}
/**
************************************************************************
M4OSA_ERR VIDEOEDITOR_BUFFER_getBuffer(VIDEOEDITOR_BUFFER_Pool* ppool,
* VIDEOEDITOR_BUFFER_Buffer** pNXPBuffer)
* @brief Returns a buffer in a given state
*
* @param ppool : IN The buffer pool
* @param desiredState : IN The buffer state
* @param pNXPBuffer : IN The selected buffer
* @return Error code
************************************************************************
*/
M4OSA_ERR VIDEOEDITOR_BUFFER_getBuffer(VIDEOEDITOR_BUFFER_Pool* ppool,
VIDEOEDITOR_BUFFER_State desiredState,
VIDEOEDITOR_BUFFER_Buffer** pNXPBuffer)
{
M4OSA_ERR err = M4NO_ERROR;
M4OSA_Bool bFound = M4OSA_FALSE;
M4OSA_UInt32 i, ibuf;
ALOGV("VIDEOEDITOR_BUFFER_getBuffer from %s in state=%d",
ppool->poolName, desiredState);
ibuf = 0;
for (i=0; i < ppool->NB; i++)
{
bFound = (ppool->pNXPBuffer[i].state == desiredState);
if (bFound)
{
ibuf = i;
break;
}
}
if(!bFound)
{
ALOGV("VIDEOEDITOR_BUFFER_getBuffer No buffer available in state %d",
desiredState);
*pNXPBuffer = M4OSA_NULL;
return M4ERR_NO_BUFFER_AVAILABLE;
}
/* case where a buffer has been found */
*pNXPBuffer = &(ppool->pNXPBuffer[ibuf]);
ALOGV("VIDEOEDITOR_BUFFER_getBuffer: idx = %d", ibuf);
return(err);
}
/**
************************************************************************
void VIDEOEDITOR_BUFFER_getBufferForDecoder(VIDEOEDITOR_BUFFER_Pool* ppool,
* VIDEOEDITOR_BUFFER_Buffer** pNXPBuffer)
* @brief Returns a buffer in a given state
*
* @param ppool : IN The buffer pool
* @param desiredState : IN The buffer state
* @param pNXPBuffer : IN The selected buffer
* @return Error code
************************************************************************
*/
void VIDEOEDITOR_BUFFER_getBufferForDecoder(VIDEOEDITOR_BUFFER_Pool* ppool)
{
M4OSA_Bool bFound = M4OSA_FALSE;
M4OSA_UInt32 i, ibuf;
M4_MediaTime candidateTimeStamp = (M4_MediaTime)0x7ffffff;
ibuf = 0;
for (i=0; i < ppool->NB; i++)
{
bFound = (ppool->pNXPBuffer[i].state == VIDEOEDITOR_BUFFER_kEmpty);
if (bFound)
{
break;
}
}
if(!bFound)
{
for(i = 0; i< ppool->NB; i++)
{
if(ppool->pNXPBuffer[i].state == VIDEOEDITOR_BUFFER_kFilled)
{
if(ppool->pNXPBuffer[i].buffCTS <= candidateTimeStamp)
{
bFound = M4OSA_TRUE;
candidateTimeStamp = ppool->pNXPBuffer[i].buffCTS;
ibuf = i;
}
}
}
if(M4OSA_TRUE == bFound)
{
if(M4OSA_NULL != ppool->pNXPBuffer[ibuf].mBuffer) {
ppool->pNXPBuffer[ibuf].mBuffer->release();
ppool->pNXPBuffer[ibuf].state = VIDEOEDITOR_BUFFER_kEmpty;
ppool->pNXPBuffer[ibuf].mBuffer = M4OSA_NULL;
ppool->pNXPBuffer[ibuf].size = 0;
ppool->pNXPBuffer[ibuf].buffCTS = -1;
}
}
}
}
M4OSA_ERR VIDEOEDITOR_BUFFER_initPoolBuffers_Ext(VIDEOEDITOR_BUFFER_Pool* pool,
M4OSA_UInt32 lSize)
{
M4OSA_ERR err = M4NO_ERROR;
M4OSA_UInt32 index, i, j;
/**
* Initialize all the buffers in the pool */
for(index = 0; index < pool->NB; index++)
{
pool->pNXPBuffer[index].mBuffer = M4OSA_NULL;
pool->pNXPBuffer[index].size = 0;
pool->pNXPBuffer[index].state = VIDEOEDITOR_BUFFER_kEmpty;
pool->pNXPBuffer[index].idx = index;
pool->pNXPBuffer[index].buffCTS = -1;
}
return err;
}
M4OSA_ERR VIDEOEDITOR_BUFFER_getOldestBuffer(VIDEOEDITOR_BUFFER_Pool *pool,
VIDEOEDITOR_BUFFER_State desiredState,
VIDEOEDITOR_BUFFER_Buffer** pNXPBuffer)
{
M4OSA_ERR err = M4NO_ERROR;
M4OSA_UInt32 index, j;
M4_MediaTime candidateTimeStamp = (M4_MediaTime)0x7ffffff;
M4OSA_Bool bFound = M4OSA_FALSE;
*pNXPBuffer = M4OSA_NULL;
for(index = 0; index< pool->NB; index++)
{
if(pool->pNXPBuffer[index].state == desiredState)
{
if(pool->pNXPBuffer[index].buffCTS <= candidateTimeStamp)
{
bFound = M4OSA_TRUE;
candidateTimeStamp = pool->pNXPBuffer[index].buffCTS;
*pNXPBuffer = &(pool->pNXPBuffer[index]);
}
}
}
if(M4OSA_FALSE == bFound)
{
ALOGV("VIDEOEDITOR_BUFFER_getOldestBuffer WARNING no buffer available");
err = M4ERR_NO_BUFFER_AVAILABLE;
}
return err;
}