📄 umc_linear_buffer.cpp
字号:
if (NULL == m_pbFree)
return UMC_ERR_NOT_INITIALIZED;
// when no data is given
if (0 == in->GetDataSize())
return UMC_OK;
// get free size
if (m_pbFree + m_lFreeSize >= m_pbBuffer + m_lBufferSize)
lFreeSize = m_pbBuffer + m_lBufferSize - m_pbFree;
else
lFreeSize = m_lFreeSize;
// check free size
if ((lFreeSize < m_lInputSize) ||
(NULL == m_pFreeSampleInfo))
return UMC_ERR_NOT_ENOUGH_BUFFER;
// check used data
if (in->GetDataSize() > lFreeSize)
return UMC_ERR_FAILED;
// get new sample info
pTemp = m_pFreeSampleInfo;
m_pFreeSampleInfo = m_pFreeSampleInfo->m_pNext;
//
// fill sample info
//
// handle data gaps
if ((m_pSamples) || (in->GetTime() > m_Dummy.m_dTime))
pTemp->m_dTime = in->GetTime();
else
pTemp->m_dTime = m_Dummy.m_dTime;
pTemp->m_lBufferSize =
pTemp->m_lDataSize = in->GetDataSize();
pTemp->m_pNext = NULL;
// add sample to end of queue
if (m_pSamples)
{
SampleInfo *pWork = m_pSamples;
while (pWork->m_pNext)
pWork = pWork->m_pNext;
pWork->m_pNext = pTemp;
}
else
m_pSamples = pTemp;
// update variable(s)
m_pbFree += pTemp->m_lBufferSize;
if (m_pbBuffer + m_lBufferSize == m_pbFree)
m_pbFree = m_pbBuffer;
m_lFreeSize -= pTemp->m_lBufferSize;
m_lUsedSize += pTemp->m_lBufferSize;
return UMC_OK;
} // Status LinearBuffer::UnLockInputBuffer(MediaData* in, Status StreamStatus)
Status LinearBuffer::LockOutputBuffer(MediaData* out)
{
AutomaticMutex guard(m_synchro);
size_t lUsedSize;
// check error(s)
if (NULL == out)
return UMC_ERR_NULL_PTR;
if (NULL == m_pbUsed)
return UMC_ERR_NOT_INITIALIZED;
// when END OF STREAM
if (m_bEndOfStream)
{
// time to exit
if ((m_bQuit) || (0 == m_lUsedSize - m_lDummySize))
{
// add sample info(s) to list of free sample info(s)
if (m_pFreeSampleInfo)
{
SampleInfo *pTemp = m_pFreeSampleInfo;
while (pTemp->m_pNext)
pTemp = pTemp->m_pNext;
pTemp->m_pNext = m_pSamples;
m_pSamples = NULL;
}
else
{
m_pFreeSampleInfo = m_pSamples;
m_pSamples = NULL;
}
// reset variables
m_pbFree = m_pbBuffer;
m_lFreeSize = m_lBufferSize;
m_pbUsed = m_pbBuffer;
m_lUsedSize = 0;
m_lDummySize = 0;
return UMC_ERR_END_OF_STREAM;
}
// set the last "lock output" request
else
m_bQuit = true;
}
// when used pointer is wrapped around
if (m_pbBuffer + m_lBufferSize == m_pbUsed)
m_pbUsed = m_pbBuffer;
// when used space at end is small (move it to beginning)
if ((m_pbUsed + m_lUsedSize >= m_pbBuffer + m_lBufferSize) &&
(m_pbBuffer + m_lBufferSize < m_pbUsed + m_lOutputSize + m_lDummySize))
{
size_t lBytesAtEnd;
lBytesAtEnd = m_pbBuffer + m_lBufferSize - m_pbUsed - m_lDummySize;
// copy remain byte(s) before the buffer
memcpy(m_pbBuffer - lBytesAtEnd, m_pbUsed, lBytesAtEnd);
// update variable(s)
m_pbUsed = m_pbBuffer - lBytesAtEnd;
m_lFreeSize += lBytesAtEnd + m_lDummySize;
m_lUsedSize -= m_lDummySize;
m_lDummySize = 0;
// remove dummy bytes from sample info
{
SampleInfo *pTemp = m_pSamples;
while (pTemp)
{
if (pTemp->m_lBufferSize != pTemp->m_lDataSize)
{
pTemp->m_lBufferSize = pTemp->m_lDataSize;
break;
}
pTemp = pTemp->m_pNext;
}
}
}
// get used size
if (m_pbUsed >= m_pbBuffer + (m_lBufferSize - m_lUsedSize))
lUsedSize = m_pbBuffer + m_lBufferSize - m_pbUsed - m_lDummySize;
else
lUsedSize = m_lUsedSize;
// check used size
if ((lUsedSize < m_lOutputSize) && (false == m_bEndOfStream))
return UMC_ERR_NOT_ENOUGH_DATA;
// set used pointer
out->SetBufferPointer(m_pbUsed, lUsedSize);
out->SetDataSize(lUsedSize);
out->SetTime(m_pSamples->m_dTime);
return UMC_OK;
} // Status LinearBuffer::LockOutputBuffer(MediaData* out)
Status LinearBuffer::UnLockOutputBuffer(MediaData* out)
{
AutomaticMutex guard(m_synchro);
size_t lUsedSize, lToSkip;
SampleInfo *pTemp;
bool bSingleMemoryPiece = true;
// check error(s)
if (NULL == out)
return UMC_ERR_NULL_PTR;
if (NULL == m_pbUsed)
return UMC_ERR_NOT_INITIALIZED;
// drop the "last lock output" event,
// because data was used
if (m_bEndOfStream)
m_bQuit = false;
// when 0 bytes to unlock
if (0 == (out->GetBufferSize() - out->GetDataSize()))
return UMC_OK;
// get used size
if (m_pbUsed >= m_pbBuffer + (m_lBufferSize - m_lUsedSize))
lUsedSize = m_pbBuffer + m_lBufferSize - m_pbUsed - m_lDummySize;
else
lUsedSize = m_lUsedSize;
// check used size
if ((lUsedSize < m_lOutputSize) && (false == m_bEndOfStream))
return UMC_ERR_NOT_ENOUGH_BUFFER;
// check used data
lToSkip = out->GetBufferSize() - out->GetDataSize();
if (lToSkip > lUsedSize)
return UMC_ERR_FAILED;
// skip data
while (lToSkip)
{
size_t lFreeSizeInc;
pTemp = m_pSamples;
// when skipped data is placed before the buffer
if (m_pbUsed < m_pbBuffer)
{
if (lToSkip < pTemp->m_lDataSize)
lFreeSizeInc = 0;
else
lFreeSizeInc = IPP_MAX(m_pbUsed + pTemp->m_lBufferSize - m_pbBuffer, 0);
}
// when skipped data is placed in middle of buffer
else
{
if (lToSkip < pTemp->m_lDataSize)
lFreeSizeInc = lToSkip;
else
lFreeSizeInc = pTemp->m_lBufferSize;
}
// when data to skip is smaller then the current data potion
if (lToSkip < pTemp->m_lDataSize)
{
// update timestamp. We keep the timestamp only for the first
// frame in memory piece.
if (bSingleMemoryPiece)
pTemp->m_dTime = -1.0;
m_pbUsed += lToSkip;
m_lUsedSize -= lToSkip;
m_lFreeSize += lFreeSizeInc;
pTemp->m_lBufferSize -= lToSkip;
pTemp->m_lDataSize -= lToSkip;
lToSkip = 0;
}
// when data to skip is greater then the current data potion
else
{
if (pTemp->m_lBufferSize != pTemp->m_lDataSize)
m_lDummySize = 0;
m_pbUsed += pTemp->m_lBufferSize;
m_lUsedSize -= pTemp->m_lBufferSize;
m_lFreeSize += lFreeSizeInc;
lToSkip -= pTemp->m_lDataSize;
// update sample queue(s)
m_pSamples = m_pSamples->m_pNext;
pTemp->m_pNext = m_pFreeSampleInfo;
m_pFreeSampleInfo = pTemp;
pTemp = m_pSamples;
// we skip several memory pieces
bSingleMemoryPiece = false;
}
}
return UMC_OK;
} // Status LinearBuffer::UnLockOutputBuffer(MediaData* out)
Status LinearBuffer::Stop(void)
{
return UMC_OK;
} // Status LinearBuffer::Stop(void)
Status LinearBuffer::Reset(void)
{
AutomaticMutex guard(m_synchro);
// reset variables
m_pbFree = m_pbBuffer;
m_lFreeSize = m_lBufferSize;
m_pbUsed = m_pbBuffer;
m_lUsedSize = 0;
// move all samples to the free list
while (m_pSamples)
{
SampleInfo *pTemp = m_pSamples;
m_pSamples = m_pSamples->m_pNext;
pTemp->m_pNext = m_pFreeSampleInfo;
m_pFreeSampleInfo = pTemp;
}
m_bEndOfStream = false;
m_bQuit = false;
return UMC_OK;
} // Status LinearBuffer::Reset(void)
} // namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -