📄 umc_linear_buffer.cpp
字号:
/*
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright (c) 2003-2007 Intel Corporation. All Rights Reserved.
//
//
*/
#include "umc_linear_buffer.h"
#include "umc_automatic_mutex.h"
namespace UMC
{
enum
{
ALIGN_VALUE = 128
};
MediaBuffer *CreateLinearBuffer(void)
{
return new LinearBuffer();
} // MediaBuffer *CreateLinearBuffer(void)
LinearBuffer::LinearBuffer(void)
{
// reset variables
m_pbAllocatedBuffer = NULL;
m_midAllocatedBuffer = MID_INVALID;
m_lAllocatedBufferSize = 0;
m_pbBuffer = NULL;
m_lBufferSize = 0;
m_pbFree = NULL;
m_lFreeSize = 0;
m_pbUsed = NULL;
m_lUsedSize = 0;
m_lDummySize = 0;
m_pSamples = NULL;
m_pFreeSampleInfo = NULL;
m_bEndOfStream = false;
m_bQuit = false;
// reset mutex
vm_mutex_set_invalid(&m_synchro);
// reset time of dummy sample
memset(&m_Dummy, 0, sizeof(m_Dummy));
m_Dummy.m_dTime = -1.0;
} // LinearBuffer::LinearBuffer(void)
LinearBuffer::~LinearBuffer(void)
{
Close();
// destroy mutex
if (1 == vm_mutex_is_valid(&m_synchro))
vm_mutex_destroy(&m_synchro);
} // LinearBuffer::~LinearBuffer(void)
Status LinearBuffer::Close(void)
{
// stop all waiting(s)
// actually, this method does nothing
Stop();
// delete buffer
if (m_pbAllocatedBuffer)
m_pMemoryAllocator->Unlock(m_midAllocatedBuffer);
if (MID_INVALID != m_midAllocatedBuffer)
m_pMemoryAllocator->Free(m_midAllocatedBuffer);
m_midAllocatedBuffer = MID_INVALID;
// delete sample list
while (m_pSamples)
{
SampleInfo *pTemp = m_pSamples;
m_pSamples = m_pSamples->m_pNext;
delete pTemp;
}
// delete free sample list
while (m_pFreeSampleInfo)
{
SampleInfo *pTemp = m_pFreeSampleInfo;
m_pFreeSampleInfo = m_pFreeSampleInfo->m_pNext;
delete pTemp;
}
// reset variables
m_pbAllocatedBuffer = NULL;
m_lAllocatedBufferSize = 0;
m_pbBuffer = NULL;
m_lBufferSize = 0;
m_pbFree = NULL;
m_lFreeSize = 0;
m_pbUsed = NULL;
m_lUsedSize = 0;
m_lDummySize = 0;
m_pSamples = NULL;
m_pFreeSampleInfo = NULL;
m_bEndOfStream = false;
m_bQuit = false;
// reset time of dummy sample
m_Dummy.m_dTime = -1.0;
// call the parent's method
MediaBuffer::Close();
return UMC_OK;
} // Status LinearBuffer::Close(void)
Status LinearBuffer::Init(MediaReceiverParams *init)
{
size_t lAllocate, lMaxSampleSize;
Ipp32u l, lFramesNumber;
MediaBufferParams *pParams = DynamicCast<MediaBufferParams> (init);
Status umcRes;
// check error(s)
if (NULL == pParams)
return UMC_ERR_NULL_PTR;
if ((0 == pParams->m_numberOfFrames) ||
(0 == pParams->m_prefInputBufferSize) ||
(0 == pParams->m_prefOutputBufferSize))
return UMC_ERR_INIT;
// release the object before initialization
Close();
// call the parent's method
umcRes = MediaBuffer::Init(init);
if (UMC_OK != umcRes)
return umcRes;
m_Params = *pParams;
// init mutex
if (0 == vm_mutex_is_valid(&m_synchro))
{
if (VM_OK != vm_mutex_init(&m_synchro))
return UMC_ERR_INIT;
}
// allocate buffer (one more)
lMaxSampleSize = IPP_MAX(pParams->m_prefInputBufferSize, pParams->m_prefOutputBufferSize);
lAllocate = lMaxSampleSize * (IPP_MAX(pParams->m_numberOfFrames, 3) + 1);
if (UMC_OK != m_pMemoryAllocator->Alloc(&m_midAllocatedBuffer, lAllocate + ALIGN_VALUE, UMC_ALLOC_PERSISTENT, 16))
return UMC_ERR_ALLOC;
m_pbAllocatedBuffer = (Ipp8u *) m_pMemoryAllocator->Lock(m_midAllocatedBuffer);
if (NULL == m_pbAllocatedBuffer)
return UMC_ERR_ALLOC;
m_lAllocatedBufferSize = lAllocate + ALIGN_VALUE;
// align buffer & reserve one sample
m_pbBuffer = align_pointer<Ipp8u *> (m_pbAllocatedBuffer + lMaxSampleSize, ALIGN_VALUE);
m_lBufferSize = lAllocate - lMaxSampleSize;
m_pbFree = m_pbBuffer;
m_lFreeSize = m_lBufferSize;
m_pbUsed = m_pbBuffer;
m_lUsedSize = 0;
// allocate sample info
lFramesNumber = (IPP_MAX(pParams->m_prefInputBufferSize, pParams->m_prefOutputBufferSize) *
pParams->m_numberOfFrames) /
IPP_MIN(pParams->m_prefInputBufferSize, pParams->m_prefOutputBufferSize);
for (l = 0; l < lFramesNumber; l++)
{
SampleInfo *pTemp;
pTemp = new SampleInfo();
if (NULL == pTemp)
return UMC_ERR_ALLOC;
pTemp->m_pNext = m_pFreeSampleInfo;
m_pFreeSampleInfo = pTemp;
}
// save preferended size(s)
m_lInputSize = pParams->m_prefInputBufferSize;
m_lOutputSize = pParams->m_prefOutputBufferSize;
return UMC_OK;
} // Status LinearBuffer::Init(MediaReceiverParams *init)
Status LinearBuffer::LockInputBuffer(MediaData* in)
{
AutomaticMutex guard(m_synchro);
size_t lFreeSize;
bool bAtEnd = false;
// check error(s)
if (NULL == in)
return UMC_ERR_NULL_PTR;
if (NULL == m_pbFree)
return UMC_ERR_NOT_INITIALIZED;
// get free size
if (m_pbFree >= m_pbBuffer + (m_lBufferSize - m_lFreeSize))
{
lFreeSize = m_pbBuffer + m_lBufferSize - m_pbFree;
bAtEnd = true;
}
else
lFreeSize = m_lFreeSize;
// check free size
if (lFreeSize < m_lInputSize)
{
if (false == bAtEnd)
return UMC_ERR_NOT_ENOUGH_BUFFER;
// free space at end is too small
else
{
// when used data is present,
// concatenate dummy bytes to last sample info
if (m_pSamples)
{
SampleInfo *pTemp;
// find last sample info
pTemp = m_pSamples;
while (pTemp->m_pNext)
pTemp = pTemp->m_pNext;
pTemp->m_lBufferSize += lFreeSize;
// update variable(s)
m_pbFree = m_pbBuffer;
m_lFreeSize -= lFreeSize;
m_lDummySize = lFreeSize;
m_lUsedSize += lFreeSize;
// need to Unlock to avoid double locking of
// the mutex
guard.Unlock();
// and call again to lock space at the
// beginning of the buffer
return LockInputBuffer(in);
}
// when there is no used data,
// simply move pointer(s)
else
{
m_pbFree = m_pbBuffer;
m_pbUsed = m_pbBuffer;
lFreeSize = m_lFreeSize;
}
}
}
// check free sample info
if (NULL == m_pFreeSampleInfo)
{
// when needed - allocate one more
if (m_lUsedSize - m_lDummySize < m_lOutputSize)
{
m_pFreeSampleInfo = new SampleInfo();
if (m_pFreeSampleInfo)
m_pFreeSampleInfo->m_pNext = NULL;
else
return UMC_ERR_NOT_ENOUGH_BUFFER;
}
else
return UMC_ERR_NOT_ENOUGH_BUFFER;
}
// set free pointer
in->SetBufferPointer(m_pbFree, lFreeSize);
in->SetDataSize(0);
return UMC_OK;
} // Status LinearBuffer::LockInputBuffer(MediaData* in)
Status LinearBuffer::UnLockInputBuffer(MediaData* in, Status StreamStatus)
{
AutomaticMutex guard(m_synchro);
size_t lFreeSize;
SampleInfo *pTemp;
// check END OF STREAM
if (UMC_OK != StreamStatus)
m_bEndOfStream = true;
// check error(s)
if (NULL == in)
return UMC_ERR_NULL_PTR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -