📄 umc_mpeg2_spl_base.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_mpeg2_spl_base.h"#include "umc_splitter_ex.h"#include "umc_mpeg4_pure_detect.h"#include "vm_debug.h"#include "ipps.h"#include "umc_audio_buffer.h"using namespace UMC;//public constructor/destructorMPEG2SplitterBase::MPEG2SplitterBase(){ m_pVideoBuffer = NULL; m_pDataReader = NULL; m_pVideoAuxData = NULL; m_pESArray = NULL; m_bStop = true; m_bReadingFinished = false; m_bIgnoreVideo = false; m_bIgnoreAudio = false;// m_bReposHappend = true; m_dCurrAudioPts = -1; m_dCurrVideoPts = -1; m_dCurrVideoDts = -1; m_dPrevVideoPts = -1; m_dDiffVideoPts = -1; m_dBaseVideoPts = -1; m_dRate = 1; m_uiOutputAudioSize = 0; m_splitter_flags = 0; m_eInitAudio.Init(1, 0); m_eInitVideo.Init(1, 0); m_eInitComplete.Init(1, 0); vm_semaphore_set_invalid(&m_eVideoFrameCount); memset(&m_systemStreamInfo, 0, sizeof(SystemStreamInfo)); m_inESCount = 0; m_lFlags = 0; m_lFlagsReq = 0; m_uiOutputAudioSize = 0; m_MPEGASyncWord = 0; m_uiEndian = 2; //4 bytes swap for video by default// m_bPrepareForReposition = false; m_iChoosedVideo = -1;//it is -1, not 0 initially because m_iChoosedAudio[0] = -1;//ElementaryStream::m_uiStreamID = 0 //by default m_iChoosedAudio[1] = -1;//ElementaryStream::m_uiStreamID = 0 //by default m_pAudioBuffer[0] = NULL; m_pAudioBuffer[1] = NULL; m_uiCurrInputBuffNum = 0; m_uiCurrOutBuffNum = 0; m_uiVideoFrameCount = 0; m_uiAudioFrameCount[0] = 0; m_uiAudioFrameCount[1] = 0; m_uiLastPosition = 0; m_dLastPts = -1.0; //ResetStatistic(); m_uiMAXGOPLength=0; //m_bSaveStatistic=true; m_dFirstPts = -1.0; m_frame_types = SPL_FT_ANY;}/*void MPEG2SplitterBase::ResetStatistic(){ m_uiPosPacketWithGOPStart=0; m_uiPosCurrPacket=0; m_uiPosLastIFrame =0; m_uiPosPrevPacket=0; m_uiPosPrevFrame=0;}*/MPEG2SplitterBase::~MPEG2SplitterBase(){ Close();}//Splitter interfaceStatus MPEG2SplitterBase::Init(SplitterParams& init){ UMC::Status umcSts = UMC_OK; m_frame_types = SPL_FT_ANY; //memset(&m_sSplInfo, 0, sizeof(SplitterInfo)); m_pDataReader = init.m_pDataReader; if(!m_pDataReader) { //only external data reader supported return UMC_NULL_PTR; } m_inESCount = 0; m_pESArray = new ElementaryStream[MAX_ES_COUNT]; if(!m_pESArray) return UMC_ALLOC; if(init.m_uiSelectedVideoPID == SELECT_ANY_VIDEO_PID) { m_iChoosedVideo = -1; } else if(init.m_uiSelectedVideoPID == SELECT_ALL_VIDEO_PIDS) { assert(0); } else m_iChoosedVideo = init.m_uiSelectedVideoPID; if(init.m_uiSelectedAudioPID == SELECT_ANY_AUDIO_PID) { m_iChoosedAudio[0] = -1; m_iChoosedAudio[1] = 0; } else if(init.m_uiSelectedAudioPID == SELECT_ALL_AUDIO_PIDS) { m_iChoosedAudio[0] = -1; m_iChoosedAudio[1] = -1; } else { m_iChoosedAudio[0] = init.m_uiSelectedAudioPID; m_iChoosedAudio[1] = 0; } m_lFlagsReq = m_lFlags = init.m_lFlags; m_bStop = false; m_bIgnoreAudio = false; m_bIgnoreVideo = false; //just for double check, if UNDEF_VIDEO & UNDEF_AUDIO != 0// m_sSplInfo.m_video_info.stream_type = UNDEF_VIDEO;// m_sSplInfo.m_audio_info.stream_type = UNDEF_AUDIO; m_splitter_flags = init.m_lFlags; m_bReadingFinished = false;// m_bReposHappend = false;// m_bPrepareForReposition = false; m_eWaitNewPosition.Init(1, 0); m_eInitComplete.Reset(); vm_semaphore_init(&m_eVideoFrameCount, 25); memset(&m_systemStreamInfo, 0, sizeof(m_systemStreamInfo)); umcSts = DetectSequence(); if((UMC_OK == umcSts) && (m_lFlags & VIDEO_SPLITTER) && !m_bIgnoreVideo) { umcSts = InitVideoFrameBuffer(); } else { m_bIgnoreVideo = true; m_lFlags &= ~VIDEO_SPLITTER; m_splitter_flags &= ~VIDEO_SPLITTER; } if((UMC_OK == umcSts) && (m_lFlags & AUDIO_SPLITTER) && !m_bIgnoreAudio) { umcSts = InitAudioFrameBuffer(); } else { m_bIgnoreAudio = true; m_lFlags &= ~AUDIO_SPLITTER; m_splitter_flags &= ~AUDIO_SPLITTER; } if(0 != (m_lFlags & FLAG_VSPL_4BYTE_ACCESS)) { //requires 4 bytes data swap m_uiEndian = 2; } else { //requires original data m_uiEndian = 0; } if(!(m_splitter_flags & FLAG_VSPL_NO_INTERNAL_THREAD)) { if(UMC_OK == umcSts && (!m_bIgnoreVideo || !m_bIgnoreAudio)) { umcSts = SplitterThread.Create((vm_thread_callback)SplitterThreadProc,(void *)this); //umcSts = SplitterThread.Create((vm_thread_callback)SplitterReverseThreadProc,(void *)this); //vm_time_sleep(100); } else { umcSts = UMC_END_OF_STREAM; } if(SplitterThread.IsValid()) SplitterThread.SetPriority(VM_THREAD_PRIORITY_HIGHEST); //m_bIgnoreVideo = true; if(UMC_OK == umcSts) { MpegSplitterParams* MpegParam = DynamicCast<MpegSplitterParams, SplitterParams>(&init); if( !MpegParam ) return UMC_OPERATION_FAILED; MediaDataEx * data = MpegParam->m_mediaData; if(((m_lFlags & FLAG_VSPL_VIDEO_HEADER_REQ) || (m_lFlags & FLAG_VSPL_VIDEO_FRAME_REQ)) && m_lFlags & VIDEO_SPLITTER && !m_bIgnoreVideo) { if(!data) { umcSts = UMC_NULL_PTR; } if(UMC_OK == umcSts && IfFrameRequared()) umcSts = GetNextVideoData(data, 0); if(UMC_OK != umcSts && m_bIgnoreVideo) { m_lFlags &= ~VIDEO_SPLITTER; m_splitter_flags &= ~VIDEO_SPLITTER; data->SetBufferPointer(NULL, 0); umcSts = UMC_OK; } } else { if(!data) { umcSts = UMC_NULL_PTR; } if(umcSts == UMC_OK) { data->SetBufferPointer(NULL, 0); } } } if((UMC_OK == umcSts) && (m_lFlags & AUDIO_SPLITTER) && !m_bIgnoreAudio) { int timeout = 0; while(UMC_TIMEOUT == m_eInitAudio.Wait(1000) && !m_bIgnoreAudio) { timeout ++; //wait for while to have a chance to find audio #ifdef _DEBUG if(timeout > 3) #else if(timeout > 1) #endif { m_splitter_flags &= ~AUDIO_SPLITTER; m_lFlags &= ~AUDIO_SPLITTER; m_bIgnoreAudio = 1; break; } } } } else { InitProcessing(); } m_eInitComplete.Set(); if(m_bStop) umcSts = UMC_END_OF_STREAM; if(UMC_OK != umcSts) Close(); return umcSts;}bool MPEG2SplitterBase::IfFrameRequared(){ return true;}Status MPEG2SplitterBase::InitVideoFrameBuffer(){ MediaBufferParams params; m_pVideoBuffer = new SampleBuffer; if(!m_pVideoBuffer) return UMC_ALLOC;//#if defined(SMALL_MEMORY_USE) params.m_prefInputBufferSize = 1024*1024; params.m_numberOfFrames = 4; params.m_prefOutputBufferSize = 1024*1024;/*#else // defined(_WIN32_WCE) params.m_prefInputBufferSize = 1024*1024; params.m_numberOfFrames = 16; params.m_prefOutputBufferSize = 1024*1024;#endif // defined(_WIN32_WCE)*/ return m_pVideoBuffer->Init(¶ms);}Status MPEG2SplitterBase::InitAudioFrameBuffer(){ Status umcRes; MediaBufferParams params; m_pAudioBuffer[0] = new AudioBuffer; if(!m_pAudioBuffer[0]) return UMC_ALLOC; params.m_prefInputBufferSize = 16*1024; params.m_numberOfFrames = 64; params.m_prefOutputBufferSize = 16*1024; umcRes = m_pAudioBuffer[0]->Init(¶ms); if((UMC_OK == umcRes) && (0 != m_iChoosedAudio[0])) { m_pAudioBuffer[1] = new AudioBuffer; if(!m_pAudioBuffer[1]) return UMC_ALLOC; umcRes = m_pAudioBuffer[1]->Init(¶ms); } return umcRes;}Status MPEG2SplitterBase::DetectSequence(){ unsigned char code1; unsigned int code2; Status umcSts = UMC_OK; umcSts = m_pDataReader->CheckByte(&code1, 0); if(UMC_OK != umcSts) return UMC_NOT_INITIALIZED; umcSts = m_pDataReader->CheckUInt(&code2, 0); if(UMC_OK != umcSts) return UMC_NOT_INITIALIZED; //search some MPEG2 PS start code, it can start from bunch of zeros before if(0 == code2) { int check_counter = 1; while(0 == code2) { umcSts = m_pDataReader->CheckUInt(&code2,check_counter); if(UMC_OK != umcSts) return UMC_NOT_INITIALIZED; check_counter++; } umcSts = m_pDataReader->CheckUInt(&code2,check_counter); if(UMC_OK != umcSts) return UMC_NOT_INITIALIZED; if((code2 & 0x0000fff0) == 0x0000fff0) { m_pDataReader->MovePosition(check_counter+2); if(UMC_OK != umcSts) return UMC_NOT_INITIALIZED; umcSts = m_pDataReader->CheckUInt(&code2,0); if(UMC_OK != umcSts) return UMC_NOT_INITIALIZED; } } //check if transport stream, 0x47 is sync byte for it if(code1 == ID_TS_SYNC_BYTE) { m_systemStreamInfo.stream_type = MPEG2_TRANSPORT_STREAM; //m_sSplInfo.m_video_info.stream_type = MPEG2_VIDEO; } //check if program stream else if(code2 == ID_PS_PACK_START_CODE || (code2&0xFFFFFFFC) == 0x000001BC) { m_systemStreamInfo.stream_type = MPEG2_PROGRAMM_STREAM; //m_sSplInfo.m_video_info.stream_type = MPEG2_VIDEO; } //check if PES stream, //0x000001C0 < audio < 0x000001DF //0x000001E0 < audio < 0x000001EF else if(((code2 >= 0x000001C0) && (code2 <= 0x000001DF)) || ((code2 >= 0x000001E0) && (code2 <= 0x000001EF))) { m_systemStreamInfo.stream_type = MPEG2_PES_PACKETS_STREAM; //m_sSplInfo.m_video_info.stream_type = MPEG2_VIDEO ; } //check if MPEG2 Sequence or Picture start code else if(code2 == SEQUENCE_HEADER_CODE || (code2 & (~0xff)) == PICTURE_START_CODE) { vm_var32 size = 32*1024; unsigned char * pData; ParseMP4Header* mp4_dec = new ParseMP4Header; pData = ippsMalloc_8u(size); if(!pData) return UMC_ALLOC; m_pDataReader->CheckData(pData, &size, 0); if(mp4_dec->Init(pData, size) == UMC_OK) { m_systemStreamInfo.stream_type = MPEG4_PURE_VIDEO_STREAM; m_pESArray[0].m_videoStreamInfo.stream_type = MPEG4_VIDEO ; m_pESArray[0].m_videoStreamInfo.stream_subtype = UNDEF_VIDEO_SUBTYPE; m_splitter_flags &= ~AUDIO_SPLITTER; m_pESArray[0].m_audioStreamInfo.stream_type = UNDEF_AUDIO; m_bIgnoreAudio = true; m_splitter_flags |= VIDEO_SPLITTER; m_inESCount = 1; mp4_dec->GetdecInfo(m_pESArray[0].m_videoStreamInfo.clip_info.width, m_pESArray[0].m_videoStreamInfo.clip_info.height); } else { m_systemStreamInfo.stream_type = MPEG2_PURE_VIDEO_STREAM; m_pESArray[0].m_videoStreamInfo.stream_type = MPEG2_VIDEO ; m_pESArray[0].m_audioStreamInfo.stream_type = UNDEF_AUDIO; m_bIgnoreAudio = true; m_splitter_flags |= VIDEO_SPLITTER; m_splitter_flags &= ~AUDIO_SPLITTER; m_inESCount = 1; } ippsFree(pData); delete mp4_dec; return UMC_OK; } else if(((code2 & 0xfffffc00) == 0x00008000)) { //H.263 pure video m_systemStreamInfo.stream_type = H263_PURE_VIDEO_STREAM; m_pESArray[0].m_videoStreamInfo.stream_type = H263_VIDEO; m_splitter_flags |= VIDEO_SPLITTER; m_splitter_flags &= ~AUDIO_SPLITTER; m_pESArray[0].m_audioStreamInfo.stream_type = UNDEF_AUDIO; m_bIgnoreAudio = true; m_inESCount = 1; } else if(((code2 & 0xfffff000) == 0x00010000)) { //H.261 pure video m_systemStreamInfo.stream_type = H261_PURE_VIDEO_STREAM; m_pESArray[0].m_videoStreamInfo.stream_type = H261_VIDEO; m_splitter_flags |= VIDEO_SPLITTER; m_splitter_flags &= ~AUDIO_SPLITTER; m_pESArray[0].m_audioStreamInfo.stream_type = UNDEF_AUDIO; m_bIgnoreAudio = true; m_inESCount = 1; } //pure H.264 video else if(code2 == 0x00000001) { m_systemStreamInfo.stream_type = H264_PURE_VIDEO_STREAM; m_pESArray[0].m_videoStreamInfo.stream_type = H264_VIDEO; m_splitter_flags |= VIDEO_SPLITTER; m_splitter_flags &= ~AUDIO_SPLITTER; m_pESArray[0].m_audioStreamInfo.stream_type = UNDEF_AUDIO; m_bIgnoreAudio = true; m_inESCount = 1; } //maybe audio stream, mp3 for example //Checking for MP3 and ID3 headers else if(((code2 & 0xfff00000) == 0xfff00000) || ((code2 & 0xffffff00) == 0x49443300) || ((code2 == 0))) { unsigned char aux_byte1; unsigned char aux_byte2; unsigned char aux_byte3; int shift = 0; if ((code2 & 0xffffff00) == 0x49443300) { vm_byte byte; for ( int i = 6; i < 10; i++ ) { if ( UMC_OK != m_pDataReader->CheckByte( &byte, i ) ) { break; } shift <<= 7; shift += byte; } shift += 10; //Search a little further to handle errors in ID3 header size for ( int j = 0; j < 256; j++ ) { if ( UMC_OK != m_pDataReader->CheckUInt( &code2, shift ) ) { break; } if ( (code2 & 0xfff00000) == 0xfff00000 ) { break; } shift++; } m_pDataReader->CheckUInt(&code2, shift); if (!(code2 & 0xfff00000)) return UMC_BAD_STREAM; } m_pDataReader->CheckByte(&aux_byte1, shift+1); m_pDataReader->CheckByte(&aux_byte2, shift+2); m_pDataReader->CheckByte(&aux_byte3, shift+3); int id = (aux_byte1&0x08)>>3; int la = ((aux_byte1&0x06)>>1); int br = (aux_byte2&0xf0) >> 4; int fr = (aux_byte2&0x0c)>>2; int md = (aux_byte3&0xc0)>>6; m_pDataReader->MovePosition(shift); if((la == 0) && (id == 1)) { //AAC_AUDIO specific process
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -