📄 umc_avi_splitter_base.cpp
字号:
break; default: m_info.m_audio_info.channels = 0; break; } } // Wrong way, but for DEBUG it's OK if (0 == m_info.m_audio_info.bitPerSample) { pASInfo->bitPerSample = 16; } if (UMC_OK != umcRes) { vm_debug_trace(4, VM_STRING("BaseAVISplitter FillAudioInfo failed\n")); } return umcRes;}UMC::StatusUMC::BaseAVISplitter::ExtractAudioInfo(const vm_var32 cuiStreamInd, FifoBuffer* pFifo){ Status umcRes = UMC_OK; AudioStreamType AStrmType = UNDEF_AUDIO; if (NULL == pFifo) { umcRes = UMC_NULL_PTR; } AVISplitStrmStruct& rCurStream = m_pStreams[cuiStreamInd]; if (UMC_OK == umcRes) { umcRes = SelectAudioStream(cuiStreamInd, AStrmType); } if (UMC_OK == umcRes && UNDEF_AUDIO != AStrmType) { // Someone don't like to set up uiSuggestedBufferSize field // in audio stream header, so we should wolk such situation around. if (0 == rCurStream.sStrmHdr.uiSuggestedBufferSize) { rCurStream.sStrmHdr.uiSuggestedBufferSize = rCurStream.sStrmHdr.uiLength * rCurStream.sStrmHdr.uiSampleSize; if (m_pStreams[cuiStreamInd].sStrmHdr.uiSuggestedBufferSize < rCurStream.sStrmHdr.uiSuggestedBufferSize) { rCurStream.sStrmHdr.uiSuggestedBufferSize = m_pStreams[cuiStreamInd].sStrmHdr.uiSuggestedBufferSize; } } assert(0 != rCurStream.sStrmHdr.uiSuggestedBufferSize); umcRes = pFifo->Init(rCurStream.sStrmHdr.uiSuggestedBufferSize, UMC_DVSPL_AUDIOFIFO_LEN); } if (UMC_OK != umcRes) { vm_debug_trace(4, VM_STRING("BaseAVISplitter ExtractAudioInfo failed\n")); } return umcRes;}UMC::StatusUMC::BaseAVISplitter::GetInfo(SplitterInfo* pIinfo){ Status umcRes = UMC_OK; if (NULL == pIinfo) { umcRes = UMC_NULL_PTR; } if (UMC_OK == umcRes && NULL != m_pStreams) { m_info.number_audio_tracks = (vm_byte)m_uiAudioStreamCount; m_info.number_video_tracks = (vm_byte)m_uiVideoStreamCount; m_info.m_video_info.duration = (m_sAviHdr.uiMicroSecPerFrame * m_sAviHdr.uiTotalFrames) * 10e-7; *pIinfo = m_info; } else { umcRes = UMC_NOT_INITIALIZED; } return umcRes;}UMC::StatusUMC::BaseAVISplitter::SetPosition(double pos){ Status umcRes = UMC_NOT_IMPLEMENTED; if (UMC_OK == umcRes) { umcRes = m_NewPosMailBox.Put(pos); } return umcRes;}UMC::StatusUMC::BaseAVISplitter::GetPosition(double& pos){ Status umcRes = UMC_OK; if (0 == m_uiVideoStreamCount && 0 == m_uiAudioStreamCount) { umcRes = UMC_NOT_INITIALIZED; } if (UMC_OK == umcRes && 0 != m_uiVideoStreamCount) { pos = (double)m_pVideoStreams[0].m_Channel.GetCurFrameInd() / m_pStreams[m_pVideoStreams[0].m_iStreamInd].sStrmHdr.uiLength; } else if (UMC_OK == umcRes && m_uiAudioStreamCount) { pos = (double)m_pAudioStreams[0].m_Channel.GetCurFrameInd() / m_pStreams[m_pAudioStreams[0].m_iStreamInd].sStrmHdr.uiLength; } return umcRes;}// JumpToNewPos function is called from file reading thread as soon as// position change request is receivedUMC::StatusUMC::BaseAVISplitter::JumpToNewPos(double dfPos, vm_var32 uiType, vm_var32 uiIdx){ Status umcRes = UMC_OK; if (UMC_OK == umcRes && VIDEO_SPLITTER == uiType && VIDEO_SPLITTER & m_info.m_splitter_flags) { vm_var32 uiNewVideoFrame = (vm_var32)(dfPos * m_pStreams[m_pVideoStreams[uiIdx].m_iStreamInd].sStrmHdr.uiLength); umcRes = m_pVideoStreams[0].m_Channel.JumpToFrame(uiNewVideoFrame); } if (UMC_OK == umcRes && AUDIO_SPLITTER == uiType && AUDIO_SPLITTER & m_info.m_splitter_flags) { UMC::WAVEFORMATEX* pWavFmt = (UMC::WAVEFORMATEX*)m_pStreams[m_pAudioStreams[uiIdx].m_iStreamInd].pbStrmFmt; double dfTime = ((double)m_pVideoStreams[0].m_Channel.GetCurFrameInd()) * m_pStreams[m_pVideoStreams[uiIdx].m_iStreamInd].sStrmHdr.uiScale / m_pStreams[m_pVideoStreams[uiIdx].m_iStreamInd].sStrmHdr.uiRate; assert(0 != pWavFmt->nSamplesPerSec); assert(0 != pWavFmt->wBitsPerSample); assert(0 != m_pStreams[m_pAudioStreams[uiIdx].m_iStreamInd].sStrmHdr.uiSampleSize); vm_sizet ullAudioStreamPos = (vm_sizet)(dfTime * pWavFmt->nSamplesPerSec * (pWavFmt->nChannels * pWavFmt->wBitsPerSample / 8)); umcRes = m_pAudioStreams[0].m_Channel.JumpToBytePos(ullAudioStreamPos); } assert(UMC_OK == umcRes); return umcRes;}UMC::StatusUMC::AVIStream::PickFrame(){ Status umcRes = UMC_OK; unsigned char* pucNewBuf = NULL; vm_var32 uiNewBufSize = 0; // Check if we have free buffer in video fifo if (UMC_OK == umcRes) { umcRes = m_Fifo.GetInBuf(&pucNewBuf); } // Read new frame to video FIFO if (UMC_OK == umcRes) { umcRes = m_Channel.ReadFrame(pucNewBuf, m_Fifo.GetBufSize(), uiNewBufSize); } // Release FIFo buffer - now it's ready to be read out from FIFO if (NULL != pucNewBuf) { Status umcTmpRes = m_Fifo.ReleaseInBuf(uiNewBufSize, m_Channel.GetCurFrameInd()); assert(UMC_OK == umcTmpRes); } return umcRes;}voidUMC::BaseAVISplitter::CopyChunkToFifo(vm_var32 uiType, vm_var32 uiIdx){ Status umcVRes = UMC_OK; Status umcARes = UMC_OK; vm_debug_trace(4, VM_STRING("BaseAVISplitter CopyChunkToFifo start\n")); if (VIDEO_SPLITTER == uiType) { if(0 == (m_info.m_splitter_flags & VIDEO_SPLITTER ) ) { umcVRes = UMC_END_OF_STREAM; } while (UMC_OK == umcVRes && 0 == (FLAGS_AVISPL_STOPFILERD & m_uiFlags)) { if (VIDEO_SPLITTER & m_info.m_splitter_flags && UMC_OK == umcVRes) { umcVRes = m_pVideoStreams[uiIdx].PickFrame(); // Signal to others video is running if (UMC_OK == umcVRes) { m_pVideoStreams[uiIdx].m_uiThreadState = AVI_SPL_THREAD_RUNNING; } else if (UMC_END_OF_STREAM == umcVRes) { m_pVideoStreams[uiIdx].m_uiThreadState = AVI_SPL_THREAD_EOF; } } // check if we have position change request double dfNewPos = 0; if (UMC_OK == m_NewPosMailBox.Get(dfNewPos)) { Status tmpRes = JumpToNewPos(dfNewPos, uiType, uiIdx); if (UMC_OK != tmpRes) { umcVRes = umcARes = tmpRes; } } // I'm not sure if we can make any error check here if (!(VIDEO_SPLITTER & m_info.m_splitter_flags) || UMC_FAILED_TO_ALLOCATE_BUFFER == umcVRes || UMC_END_OF_STREAM == umcVRes) { vm_time_sleep(10); } if (UMC_FAILED_TO_ALLOCATE_BUFFER == umcVRes) { umcVRes = UMC_OK; } } } if (AUDIO_SPLITTER == uiType) { if(0 == (m_info.m_splitter_flags & AUDIO_SPLITTER) ) { umcARes = UMC_END_OF_STREAM; } while ((UMC_OK == umcARes) && 0 == (FLAGS_AVISPL_STOPFILERD & m_uiFlags)) { if (AUDIO_SPLITTER & m_info.m_splitter_flags && UMC_OK == umcARes) { umcARes = m_pAudioStreams[uiIdx].PickFrame(); // Signal to others video is running if (UMC_OK == umcARes) { m_pAudioStreams[uiIdx].m_uiThreadState = AVI_SPL_THREAD_RUNNING; } else if (UMC_END_OF_STREAM == umcARes) { m_pAudioStreams[uiIdx].m_uiThreadState = AVI_SPL_THREAD_EOF; } } // check if we have position change request double dfNewPos = 0; if (UMC_OK == m_NewPosMailBox.Get(dfNewPos)) { Status tmpRes = JumpToNewPos(dfNewPos, uiType, uiIdx); if (UMC_OK != tmpRes) { umcVRes = umcARes = tmpRes; } } // I'm not sure if we can make any error check here if ((!(AUDIO_SPLITTER & m_info.m_splitter_flags) || UMC_FAILED_TO_ALLOCATE_BUFFER == umcARes || UMC_END_OF_STREAM == umcARes)) { vm_time_sleep(10); } if (UMC_FAILED_TO_ALLOCATE_BUFFER == umcARes) { umcARes = UMC_OK; } } vm_debug_trace(4, VM_STRING("BaseAVISplitter::CopyChunkToFifo Audio exit\n")); } vm_debug_trace(4, VM_STRING("BaseAVISplitter CopyChunkToFifo stop\n"));}unsigned intUMC::BaseAVISplitter::FileReadThreadProc(void* pvParam){ assert(NULL != pvParam); ThreadData Data = *(ThreadData*)pvParam; delete pvParam; // was allocated before thread start - must be deleted! UMC::BaseAVISplitter* pthis = DynamicCast<UMC::BaseAVISplitter>(Data.pthis); if (pthis) { pthis->CopyChunkToFifo(Data.iType, Data.uiIndex); return 0; } return 0;}UMC::StatusUMC::BaseAVISplitter::GetNextVideoData(MediaData* pMData, vm_var32 uiIndex){ Status umcRes = UMC_OK; if (NULL == pMData) { umcRes = UMC_NULL_PTR; } else if (uiIndex > m_uiVideoStreamCount) { umcRes = UMC_OPERATION_FAILED; } else if (NULL == m_pStreams && VIDEO_SPLITTER & m_info.m_splitter_flags) { umcRes = UMC_NOT_INITIALIZED; }// m_ObjAccessMut.Lock(); m_pVideoStreams[uiIndex].m_Fifo.ReleaseOutBuf(); if (UMC_OK == umcRes && 0 == m_pVideoStreams[uiIndex].m_Fifo.GetFilledBufNum() && AVI_SPL_THREAD_EOF == m_pVideoStreams[uiIndex].m_uiThreadState) { vm_debug_trace(4, VM_STRING("BaseAVISplitter Video Stream End\n")); umcRes = UMC_END_OF_STREAM; } if (UMC_OK == umcRes) { vm_byte *pbBuffer; vm_var32 uiSize; vm_sizet ullIndex; umcRes = m_pVideoStreams[uiIndex].m_Fifo.GetOutBuf(&pbBuffer, uiSize, ullIndex); if (UMC_TIMEOUT == umcRes || UMC_FAILED_TO_ALLOCATE_BUFFER == umcRes) { umcRes = UMC_END_OF_STREAM; vm_debug_trace(4, VM_STRING("BaseAVISplitter Video FIFO buffer unavailable\n")); } else { // Check if output buffer is 32bit aligned assert(0 == (reinterpret_cast<long>(pbBuffer) & 0x3)); pMData->SetBufferPointer(pbBuffer, uiSize); pMData->SetTime((double)(vm_var64s)ullIndex / m_info.m_video_info.framerate); } }// m_ObjAccessMut.Unlock(); // We can't return any other value assert(UMC_OK == umcRes || UMC_END_OF_STREAM == umcRes); if (UMC_OK != umcRes) { vm_debug_trace(4, VM_STRING("BaseAVISplitter GetNextVideoData failed\n")); } else { vm_debug_trace(0, VM_STRING("BaseAVISplitter GetNextVideoData passed\n")); } return umcRes;}UMC::StatusUMC::BaseAVISplitter::GetNextAudioData(MediaData* pMData, vm_var32 uiIndex){ Status umcRes = UMC_OK; if (NULL == pMData) { umcRes = UMC_NULL_PTR; } else if (uiIndex > m_uiAudioStreamCount) { umcRes = UMC_OPERATION_FAILED; } else if (NULL == m_pStreams && AUDIO_SPLITTER & m_info.m_splitter_flags) { umcRes = UMC_NOT_INITIALIZED; }// m_ObjAccessMut.Lock(); m_pAudioStreams[uiIndex].m_Fifo.ReleaseOutBuf(); if (UMC_OK == umcRes && 0 == m_pAudioStreams[uiIndex].m_Fifo.GetFilledBufNum() && AVI_SPL_THREAD_EOF == m_pAudioStreams[uiIndex].m_uiThreadState) { umcRes = UMC_END_OF_STREAM; } if (UMC_OK == umcRes) { vm_byte *pbBuffer; vm_var32 uiSize; vm_sizet ullIndex; umcRes = m_pAudioStreams[uiIndex].m_Fifo.GetOutBuf(&pbBuffer, uiSize, ullIndex); if (UMC_TIMEOUT == umcRes || UMC_FAILED_TO_ALLOCATE_BUFFER == umcRes) { umcRes = UMC_END_OF_STREAM; } else { // Check if output buffer is 32bit aligned assert(0 == (reinterpret_cast<long>(pbBuffer) & 0x3)); pMData->SetBufferPointer(pbBuffer, uiSize); } } if (UMC_OK == umcRes) { double dfTime = m_dfCurAudioTime; pMData->SetTime(m_dfCurAudioTime); if (-1 != m_dfCurAudioTime) { unsigned short usBlockAlign = (unsigned short)(m_info.m_audio_info.bitPerSample >> 3); m_dfCurAudioTime +=
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -