📄 umc_cyclic_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-2005 Intel Corporation. All Rights Reserved.////*/#include "umc_media_data.h"#include "umc_cyclic_buffer.h"#include "umc_automatic_mutex.h"#include "umc_video_data.h"#include "vm_thread.h"#include "vm_debug.h"#include "vm_time.h"namespace UMC{enum{ ALIGN_VALUE = 128};LinearBuffer::LinearBuffer(void){ // 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 mutex vm_mutex_set_invalid(&m_synchro);} // 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) Stop(); // delete buffer if (m_pbAllocatedBuffer) delete [] m_pbAllocatedBuffer; // 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; return UMC_OK;} // Status LinearBuffer::Close(void)Status LinearBuffer::Init(MediaReceiverParams *init){ size_t lAllocate, lMaxSampleSize; vm_var32 l, lFramesNumber; MediaBufferParams *pParams = DynamicCast<MediaBufferParams> (init); // check error(s) if (NULL == pParams) return UMC_NULL_PTR; if ((0 == pParams->m_numberOfFrames) || (0 == pParams->m_prefInputBufferSize) || (0 == pParams->m_prefOutputBufferSize)) return UMC_FAILED_TO_INITIALIZE; Close(); m_Params = *pParams; // init mutex if (0 == vm_mutex_is_valid(&m_synchro)) { if (VM_OK != vm_mutex_init(&m_synchro)) return UMC_FAILED_TO_INITIALIZE; } // allocate buffer (one more) lMaxSampleSize = max(pParams->m_prefInputBufferSize, pParams->m_prefOutputBufferSize); lAllocate = lMaxSampleSize * (max(pParams->m_numberOfFrames, 3) + 1); m_pbAllocatedBuffer = new vm_byte[lAllocate + ALIGN_VALUE]; if (NULL == m_pbAllocatedBuffer) return UMC_FAILED_TO_ALLOCATE_BUFFER; m_lAllocatedBufferSize = lAllocate + ALIGN_VALUE; // align buffer & reserve one sample m_pbBuffer = align_pointer<vm_byte *> (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 = (max(pParams->m_prefInputBufferSize, pParams->m_prefOutputBufferSize) * pParams->m_numberOfFrames) / min(pParams->m_prefInputBufferSize, pParams->m_prefOutputBufferSize); for (l = 0;l < lFramesNumber;l++) { SampleInfo *pTemp; pTemp = new SampleInfo(); if (NULL == pTemp) return UMC_FAILED_TO_ALLOCATE_BUFFER; 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) || (NULL == m_pbFree)) return UMC_NULL_PTR; // get free size if (m_pbFree + m_lFreeSize >= m_pbBuffer + m_lBufferSize) { 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_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 lock of // mutex guard.Unlock(); // and call again to lock space at the // beginning of the buffer return LockInputBuffer(in); } // when no used data, // simple 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_NOT_ENOUGH_BUFFER; } else return UMC_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 error(s) if ((NULL == in) || (NULL == m_pbFree)) return UMC_NULL_PTR; // check END OF STREAM if (UMC_OK != StreamStatus) m_bEndOfStream = true; // when no data 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_NOT_ENOUGH_BUFFER; // check used data if (in->GetDataSize() > lFreeSize) return UMC_OPERATION_FAILED; // get new sample info pTemp = m_pFreeSampleInfo; m_pFreeSampleInfo = m_pFreeSampleInfo->m_pNext; // fill sample info pTemp->m_dTime = in->GetTime(); 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) || (NULL == m_pbUsed)) return UMC_NULL_PTR; // 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; m_bEndOfStream = false; m_bQuit = false; return UMC_END_OF_STREAM; } // last "lock output" request else m_bQuit = true; } // when used pointer is wrap 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) to before 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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -