📄 umc_cyclic_buffer.cpp
字号:
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_lUsedSize >= m_pbBuffer + m_lBufferSize) 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_NOT_ENOUGH_DATA; // set used pointer out->SetBufferPointer(m_pbUsed, 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; // check error(s) if ((NULL == out) || (NULL == m_pbUsed)) return UMC_NULL_PTR; // when END OF STREAM if (m_bEndOfStream) m_bQuit = false; // when 0 bytes to unlock if (0 == (out->GetBufferSize() - out->GetDataSize())) //if (0 == ((unsigned char*)out->GetDataPointer() - (unsigned char*)out->GetBufferPointer())) return UMC_OK; // get used size if (m_pbUsed + m_lUsedSize >= m_pbBuffer + m_lBufferSize) 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_NOT_ENOUGH_BUFFER; // check used data lToSkip = out->GetBufferSize() - out->GetDataSize();// lToSkip = (unsigned char*)out->GetDataPointer() - (unsigned char*)out->GetBufferPointer(); if (lToSkip > lUsedSize) return UMC_OPERATION_FAILED; // skip data while (lToSkip) { size_t lFreeSizeInc; pTemp = m_pSamples; // when skipped data placed before buffer if (m_pbUsed < m_pbBuffer) { if (lToSkip < pTemp->m_lDataSize) lFreeSizeInc = 0; else lFreeSizeInc = max(m_pbUsed + pTemp->m_lBufferSize - m_pbBuffer, 0); } // when skipped data 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 current data potion if (lToSkip < pTemp->m_lDataSize) { m_pbUsed += lToSkip; m_lUsedSize -= lToSkip; m_lFreeSize += lFreeSizeInc; pTemp->m_lBufferSize -= lToSkip; pTemp->m_lDataSize -= lToSkip; // update time only then time from consumer is greater if (out->GetTime() > pTemp->m_dTime) pTemp->m_dTime = out->GetTime(); lToSkip = 0; } // when data to skip is greater then 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; } } 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); return Init(&m_Params);} // Status LinearBuffer::Reset(void)SampleBuffer::SampleBuffer(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_pSamples = NULL; m_bEndOfStream = false; m_bQuit = false; // reset mutex vm_mutex_set_invalid(&m_synchro);} // SampleBuffer::SampleBuffer(void)SampleBuffer::~SampleBuffer(void){ Close(); // destroy mutex if (VM_OK == vm_mutex_is_valid(&m_synchro)) { vm_mutex_destroy(&m_synchro); vm_mutex_set_invalid(&m_synchro); }} // SampleBuffer::~SampleBuffer(void)Status SampleBuffer::Close(void){ // stop all waiting(s) Stop(); // delete buffer if (m_pbAllocatedBuffer) delete[] m_pbAllocatedBuffer; // 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_pSamples = NULL; m_bEndOfStream = false; m_bQuit = false; return UMC_OK;} // Status SampleBuffer::Close(void)Status SampleBuffer::Init(MediaReceiverParams *init){ size_t lAllocate, lMaxSampleSize; 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 lMaxSampleSize = max(pParams->m_prefInputBufferSize, pParams->m_prefOutputBufferSize) + ALIGN_VALUE + sizeof(SampleInfo); lAllocate = lMaxSampleSize * max(pParams->m_numberOfFrames, 3); 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 m_pbBuffer = align_pointer<vm_byte *> (m_pbAllocatedBuffer, ALIGN_VALUE); m_lBufferSize = lAllocate; m_pbFree = m_pbBuffer; m_lFreeSize = m_lBufferSize; m_pbUsed = m_pbBuffer; m_lUsedSize = 0; // save preferred size(s) m_lInputSize = pParams->m_prefInputBufferSize; m_lOutputSize = pParams->m_prefOutputBufferSize; return UMC_OK;} // Status SampleBuffer::Init(MediaReceiverParams *init)Status SampleBuffer::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 + ALIGN_VALUE + sizeof(SampleInfo)) { 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; return UMC_NOT_ENOUGH_BUFFER; } // when no used data, // simple move pointer(s) else { m_pbFree = m_pbBuffer; m_pbUsed = m_pbBuffer; lFreeSize = m_lFreeSize; } } } // set free pointer in->SetBufferPointer(m_pbFree, lFreeSize - ALIGN_VALUE - sizeof(SampleInfo)); in->SetDataSize(0); return UMC_OK;} // Status SampleBuffer::LockInputBuffer(MediaData* in)Status SampleBuffer::UnLockInputBuffer(MediaData* in, Status StreamStatus){ AutomaticMutex guard(m_synchro); size_t lFreeSize; SampleInfo *pTemp; vm_byte *pb; // 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) return UMC_NOT_ENOUGH_BUFFER; // check used data if (in->GetDataSize() + ALIGN_VALUE + sizeof(SampleInfo) > lFreeSize) return UMC_OPERATION_FAILED; // get new sample info //pb = m_pbFree + in->GetDataSize(); pb = align_pointer<vm_byte *> (m_pbFree + in->GetDataSize(), ALIGN_VALUE); pTemp = reinterpret_cast<SampleInfo *> (pb); // fill sample info in->GetTime(pTemp->m_dTime, pTemp->m_dTimeAux); pTemp->m_lBufferSize = align_value<size_t> (pb + sizeof(SampleInfo) - m_pbFree, ALIGN_VALUE); pTemp->m_lDataSize = in->GetDataSize(); pTemp->m_pbData = m_pbFree; 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_lDataSize; return UMC_OK;} // Status SampleBuffer::UnLockInputBuffer(MediaData* in, Status StreamStatus)Status SampleBuffer::LockOutputBuffer(MediaData* out){ AutomaticMutex guard(m_synchro); // 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)) { // reset variables m_pbFree = m_pbBuffer; m_lFreeSize = m_lBufferSize; m_pbUsed = m_pbBuffer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -