📄 umc_mpeg2_spl_base.cpp
字号:
Status MPEG2SplitterBase::SwitchToNextVideoFrame(){ return UMC_OK;}Status MPEG2SplitterBase::SwitchToNextAudioFrame(){ return UMC_OK;}Status MPEG2SplitterBase::CheckNextVideoData(MediaData* data, vm_var32 track_idx){ if (track_idx != 0) return UMC_OPERATION_FAILED; // MPEG-2 splitter does not support more than 1 video track; Status ret = GetNextVideoData(data, track_idx); if(UMC_OK == ret) m_uiVideoFrameCount++; m_VideoPrevData.SetBufferPointer(0, 0); if(ret == UMC_OK && m_pVideoAuxData) { m_VideoPrevAuxData.SetBufferPointer(0, 0); } return ret;}Status MPEG2SplitterBase::CheckNextAudioData(MediaData* data, vm_var32 track_idx){ Status ret = GetNextAudioData(data, track_idx); if(UMC_OK == ret) m_uiAudioFrameCount[m_uiCurrOutBuffNum]++; m_AudioPrevData[m_uiCurrOutBuffNum].SetBufferPointer(0, 0); return ret;}Status MPEG2SplitterBase::GetNextData(MediaData* data, vm_var32* stream_id){ Status umcRes = UMC_OK; if(m_splitter_flags & FLAG_VSPL_NO_INTERNAL_THREAD) { while(!m_bStop && (umcRes == UMC_OK) && (m_uiVideoFrameCount < 1) && (m_uiAudioFrameCount[0] < 1) && (m_uiAudioFrameCount[1] < 1)) { umcRes = ProcessPackets(1); } } if(UMC_OK == umcRes) { if(m_uiVideoFrameCount > 0) { umcRes = GetNextVideoData(data, *stream_id); *stream_id = m_iChoosedVideo; } else if(m_uiAudioFrameCount[0] > 0) { umcRes = GetNextAudioData(data, *stream_id); *stream_id = m_iChoosedAudio[0]; } else if(m_uiAudioFrameCount[1] > 0) { umcRes = GetNextAudioData(data, 1); *stream_id = m_iChoosedAudio[1]; } } return umcRes;}Status MPEG2SplitterBase::GetNextVideoData(MediaData* data, vm_var32 track_idx){ if (track_idx != 0) return UMC_OPERATION_FAILED; // MPEG-2 splitter does not support more than 1 video track; UMC::Status ret = UMC_OK; if(!(m_splitter_flags & VIDEO_SPLITTER)) return UMC_OPERATION_FAILED; if(m_VideoPrevData.GetBufferSize()) { ret = m_pVideoBuffer->UnLockOutputBuffer(&m_VideoPrevData); if(ret == UMC_OK && m_pVideoAuxData) { ret = m_pVideoAuxData->UnLockOutputBuffer(&m_VideoPrevAuxData); MediaDataEx::_MediaDataEx* ptr = m_VideoPrevData.GetExData(); if(ptr) delete ptr; } } if(UMC_OK == ret) { ret = WaitForVideoFrame(); if(ret != UMC_OK && m_bReadingFinished) { m_VideoPrevData.SetBufferPointer(0, 0); m_VideoPrevAuxData.SetBufferPointer(0, 0); ret = UMC_END_OF_STREAM; } if(UMC_OK == ret) { ret = GetVideoFrame((MediaDataEx*)data); m_uiVideoFrameCount--; } if(UMC_OK == ret) ret = SwitchToNextVideoFrame(); } else { m_VideoPrevData.SetBufferPointer(0, 0); m_VideoPrevAuxData.SetBufferPointer(0, 0); } vm_debug_trace(-1,VM_STRING("GetVideoFrame = %f\n"),data->GetTime()); if(UMC_OK == ret && m_pVideoBuffer->m_bDirty) { if(data->GetTime() != -1) m_pVideoBuffer->m_bDirty = false; return UMC_WAIT_FOR_REPOSITION; } //vm_debug_trace(-1,VM_STRING("GetVideoFrame = %f\n"),data->GetTime()); if (UMC_OK == ret) ret = CheckFrameType(data,m_frame_types )? ret:UMC_WAIT_FOR_REPOSITION; return ret;}Status MPEG2SplitterBase::GetNextAudioData(MediaData* data, vm_var32 track_idx){ UMC::Status ret = UMC_OK; if(!(m_splitter_flags & AUDIO_SPLITTER)) return UMC_OPERATION_FAILED; if((track_idx != 0) && (track_idx != 1)) return UMC_OPERATION_FAILED; if((track_idx == 0) && !m_pAudioBuffer[0]) return UMC_OPERATION_FAILED; if((track_idx == 1) && !m_pAudioBuffer[1]) return UMC_OPERATION_FAILED; m_uiCurrOutBuffNum = track_idx; if(m_AudioPrevData[m_uiCurrOutBuffNum].GetBufferSize()) { ret = m_pAudioBuffer[m_uiCurrOutBuffNum]->UnLockOutputBuffer(&m_AudioPrevData[m_uiCurrOutBuffNum]); } if(UMC_OK == ret) { ret = WaitForAudioFrame(); if(ret != UMC_OK && m_bReadingFinished) { m_AudioPrevData[m_uiCurrOutBuffNum].SetBufferPointer(0, 0); ret = UMC_END_OF_STREAM; } if(UMC_OK == ret) { ret = GetAudioFrame(data); m_uiAudioFrameCount[m_uiCurrOutBuffNum]--; } if(UMC_OK == ret) ret = SwitchToNextAudioFrame(); } else { m_AudioPrevData[m_uiCurrOutBuffNum].SetBufferPointer(0, 0); } if(UMC_OK == ret && m_pAudioBuffer[m_uiCurrOutBuffNum]->m_bDirty) { if(data->GetTime() != -1) m_pAudioBuffer[m_uiCurrOutBuffNum]->m_bDirty = false; return UMC_WAIT_FOR_REPOSITION; } return ret;}//private functionsvoid MPEG2SplitterBase::Swap2Bytes(unsigned char* ptr, int size){ int i; unsigned char tmp; for(i = 0; i < size; i+= 2) { tmp = ptr[i+1]; ptr[i+1] = ptr[i]; ptr[i] = tmp; }}//independent pointersvoid MPEG2SplitterBase::Swap2Bytes(unsigned char* inptr, unsigned char* outptr, int size){ int i;#ifdef _ICL#pragma vector always#pragma ivdep#endif for(i = 0; i < size; i+= 2) { outptr[i+1] = inptr[i]; outptr[i] = inptr[i+1]; }}void MPEG2SplitterBase::Swap4Bytes(unsigned char* ptr, int size){ int i; unsigned char tmp; for(i = 0; i < size; i+= 4) { tmp = ptr[i+3]; ptr[i+3] = ptr[i+0]; ptr[i+0] = tmp; tmp = ptr[i+2]; ptr[i+2] = ptr[i+1]; ptr[i+1] = tmp; }}void MPEG2SplitterBase::Swap4Bytes(unsigned char* inptr, unsigned char* outptr, int size){ int i;#ifdef _ICL#pragma vector always#pragma ivdep#endif for(i = 0; i < size; i+= 4) { outptr[i+3] = inptr[i+0]; outptr[i+2] = inptr[i+1]; outptr[i+1] = inptr[i+2]; outptr[i+0] = inptr[i+3]; }}unsigned int MPEG2SplitterBase::SingleSplitterThread(){ Status ret; bool IgnoreAudio = m_bIgnoreAudio ; ret= UMC_WAIT_FOR_REPOSITION; vm_debug_trace(-1,VM_STRING("=== >>> === MPEG2SplitterBase forward thread is started\n")); FlushBuffers(); ret = MoveToNextSyncWord(); m_bReadingFinished = false; if(m_dRate != 1.0) m_bIgnoreAudio = true; m_frame_types = (m_dRate >= 4.0)? SPL_FT_I:SPL_FT_ANY; ret = ProcessPackets(); m_bReadingFinished = true; m_bIgnoreAudio = IgnoreAudio;#ifdef _DEBUG m_pDataReader->MovePosition(0);#endif if(!m_bStop) { if(m_pAudioBuffer[0]) { MediaData data; data.SetBufferPointer(0, 0); m_pAudioBuffer[0]->UnLockInputBuffer(&data, UMC_END_OF_STREAM); m_uiAudioFrameCount[0]++; } if(m_pAudioBuffer[1]) { MediaData data; data.SetBufferPointer(0, 0); m_pAudioBuffer[1]->UnLockInputBuffer(&data, UMC_END_OF_STREAM); m_uiAudioFrameCount[1]++; } } //wait to not exit earlier than Init() complited m_eInitComplete.Wait(); vm_debug_trace(-1,VM_STRING("=== <<< === MPEG2SplitterBase forward thread exited\n")); return 0;}unsigned int MPEG2SplitterBase::SingleReverseSplitterThread(){ Status ret; bool IgnoreAudio = m_bIgnoreAudio ; ret= UMC_WAIT_FOR_REPOSITION; vm_debug_trace(-1,VM_STRING("=== >>> === MPEG2SplitterBase backward thread is started\n")); FlushBuffers(); m_bIgnoreAudio = true; ret = MoveToNextSyncWord(); m_bReadingFinished = false; ret = PlayBack(m_iChoosedVideo); m_bIgnoreAudio = IgnoreAudio; m_bReadingFinished = true;#ifdef _DEBUG m_pDataReader->MovePosition(0);#endif if(!m_bStop) { if(m_pAudioBuffer[0]) { MediaData data; data.SetBufferPointer(0, 0); m_pAudioBuffer[0]->UnLockInputBuffer(&data, UMC_END_OF_STREAM); m_uiAudioFrameCount[0]++; } if(m_pAudioBuffer[1]) { MediaData data; data.SetBufferPointer(0, 0); m_pAudioBuffer[1]->UnLockInputBuffer(&data, UMC_END_OF_STREAM); m_uiAudioFrameCount[1]++; } } //wait to not exit earlier than Init() complited m_eInitComplete.Wait(); vm_debug_trace(-1,VM_STRING("=== <<< === MPEG2SplitterBase backward thread exited\n")); return 0;}UMC::Status MPEG2SplitterBase::SetRate(double rate){ m_dRate = rate; return UMC_OK;}void MPEG2SplitterBase::StoreLastPositionAndPTS(double time, vm_sizet byte_offset){ if (time != -1.0) { m_uiLastPosition = byte_offset; m_dLastPts = time; if (m_dFirstPts == -1.0) m_dFirstPts = m_dLastPts; }}UMC::Status MPEG2SplitterBase::SetPosition(double start_time, double end_time){ double new_pos = -1.; // default wrong value if (m_uiLastPosition != 0 && m_dLastPts != -1.0) { double lp = (double)((signed int)m_uiLastPosition); new_pos = lp*start_time/m_dLastPts; } return SetPosition(new_pos);}bool MPEG2SplitterBase::CheckFrameType(MediaData* data, SPL_FRAME_TYPES type){ unsigned char *frame = (unsigned char *)data->GetDataPointer(); SPL_FRAME_TYPES spl_ft = SPL_FT_UNKNOWN; int i; for(i = 0; i < m_inESCount; i++) { if(m_pESArray[i].m_uiStreamID == m_iChoosedVideo) { break; } } if (m_inESCount==i) return true; switch(m_pESArray[i].m_videoStreamInfo.stream_type) { case MPEG1_VIDEO: case MPEG2_VIDEO: if (frame[3]==0 && frame[2]==0 && frame[1]==1&&m_uiEndian==2 ||frame[0]==0 && frame[1]==0 && frame[2]==1&&m_uiEndian!=2 ) { spl_ft=SPL_FT_ANY; } else { int ind = (m_uiEndian==2)? 2:3; int ft = (frame[ind]>>3)&0x07; switch(ft) { case 1: spl_ft=SPL_FT_I; vm_debug_trace(-1,VM_STRING("========I frame\n")); break; case 2: spl_ft=SPL_FT_P; vm_debug_trace(-1,VM_STRING("P frame\n")); break; case 3: spl_ft=SPL_FT_B; vm_debug_trace(-1,VM_STRING("B frame\n")); break; case 4: spl_ft=SPL_FT_D; vm_debug_trace(-1,VM_STRING("D frame\n")); break; default: spl_ft=SPL_FT_UNKNOWN; vm_debug_trace(-1,VM_STRING("UNKNOWN\n")); break; } break; } case MPEG4_VIDEO: case H261_VIDEO : case H263_VIDEO : case H264_VIDEO : break; } return !!(spl_ft&type);}Status MPEG2SplitterBase::PlayBack(unsigned int pid){ Status err = UMC_OK; vm_sizet p_end; vm_sizet p_start; // position of I frame start code. vm_sizet p_pack_start; // position of PS packet start which contains I frame start code. //m_bSaveStatistic = false; m_uiMAXGOPLength = 0; double prevCurrVideoPts=-1.0; double diffPTS=0.0; p_end = m_pDataReader->GetPosition(); if (p_end == 0) return UMC_OK; err = InitProcessing(); m_pVideoBuffer->m_bDirty = false; if(err == UMC_OK && m_bStop == 0) { do { err = GetPrevGop(pid,p_end,p_start,p_pack_start); // looks for prev. GOP start: (p_start,p_pack_start) if (err != UMC_OK || m_bStop) break; VM_ASSERT(p_start<p_end); if (m_uiMAXGOPLength< (p_end - p_pack_start) ||m_uiMAXGOPLength>(p_end - p_pack_start)*5/4) m_uiMAXGOPLength = (p_end - p_pack_start)*5/4; vm_debug_trace(-1,VM_STRING("m_uiMAXGOPLength=%d\n"),m_uiMAXGOPLength); if (m_dCurrVideoPts<0 && diffPTS>0.0 && prevCurrVideoPts>0.0) m_dCurrVideoPts= prevCurrVideoPts - diffPTS; if (m_dCurrVideoPts>0.0) { if (m_dCurrVideoPts< prevCurrVideoPts && prevCurrVideoPts>0.0) diffPTS = prevCurrVideoPts-m_dCurrVideoPts; prevCurrVideoPts=m_dCurrVideoPts; } else { prevCurrVideoPts = -1.0; diffPTS = 0.0; } vm_debug_trace(-1,VM_STRING("Splitter: packet start=%d, start = %d, end = %d, pts = %f, dts = %f\n"), (int)p_start,(int)p_pack_start,(int)p_end,(float)m_dCurrVideoPts,(float)m_dCurrVideoDts); err = ProcessPackets_back(pid, p_pack_start, p_start, p_end); p_end = p_start; }while((err == UMC_OK) && (m_bStop == 0) ); } m_pVideoBuffer->m_bDirty = true; vm_debug_trace(-1,VM_STRING("PlayBack - err=%d, m_bStop=%d\n"),err,m_bStop); //m_bSaveStatistic = true; err = CloseProcessing(); return err;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -