📄 umc_mpeg2_spl_av.cpp
字号:
m_pVideoAuxData = NULL; // it is an parallelization things // it gives benefits only on MT systems if (0) if (1 < vm_sys_info_get_cpu_num()) { m_pVideoAuxData = new SampleBuffer(); // non-critical error if (m_pVideoAuxData) { MediaBufferParams params; params.m_prefInputBufferSize = sizeof(MediaDataEx::_MediaDataEx); params.m_numberOfFrames = 100; params.m_prefOutputBufferSize = sizeof(MediaDataEx::_MediaDataEx); err = m_pVideoAuxData->Init(¶ms); //lock buffer start codes //it must give memory at the first time if (UMC_OK == err) err = m_pVideoAuxData->LockInputBuffer(&m_startCodesData); // non-critical error if (UMC_OK != err) { delete m_pVideoAuxData; m_pVideoAuxData = NULL; err = UMC_OK; } } } return err;}Status MPEG2AVSplitter::FindIPicturePositionMPEG2(int size,unsigned char* LastBytes, int &ipos, int& iIFrameStart){ Status err = UMC_OK; int iIFrame = 0; iIFrameStart = -1; int i; for (i = ipos;size>0;i++) { err = m_pDataReader->GetByte(&(LastBytes[i%6])); size --; if (err != UMC_OK) return err; // looking for I picture start if ((LastBytes[(i-5)%6]==0)&& (LastBytes[(i-4)%6]==0)&& (LastBytes[(i-3)%6]==1)&& (LastBytes[(i-2)%6]==0)&& (((LastBytes[i%6]>>3)&0x07)==1) ) { iIFrameStart = i - 1; } } ipos = i; return err;}Status MPEG2AVSplitter::FillBufferMPEG2Video(ElementaryStream* pES, int full_size, int swapFlag){ Status ret = UMC_OK, retBuff = UMC_OK; unsigned int get_size = full_size; unsigned int uiStartCodeMax = MAX_CODE_COUNT; bool breakIfSeq = !m_bSequenceFound; // means init stage when true, for FLAG_VSPL_COMPATIBLE mode // doesn't break parsing on 1st picture_start_code when false int flagInit = !m_bSequenceFound && !(m_lFlagsReq & FLAG_VSPL_VIDEO_FRAME_REQ); m_uiEndian = 0; // mpeg2 video must be not swapped! (problem with CloseProcessing) get_size = full_size > PORTION_TO_READ?PORTION_TO_READ:full_size; while(!m_bStop && full_size > 0) { if(retBuff == UMC_OK || m_lockedVideoBuffer.GetBufferSize() >= PORTION_TO_READ) { //read data m_readVideoStream.SetBufferPointer(m_pTmpDataBuffAct, PORTION_TO_READ); ret = m_pDataReader->GetData(m_readVideoStream.GetBufferPointer(), &get_size); //break immediately if data reader error if(ret != UMC_OK) return ret; m_readVideoStream.SetDataSize(get_size); //Will check all MPEG2 start codes in lockedData //untill next PIC START CODE would be found do { bool isSeqFound = false; ret = FindMPEG2StartCode(&m_readVideoStream,//input buffer //pointer and remaining size //will be updated &m_lockedVideoBuffer,//output frame(may be swapped) //if all ok m_InfoFromPrevPES, //previous 3 bytes needed //to not lose a start code //on the bounds &m_pStartCodes[m_uiStartCodePos],//StartCodes structure will //be filled inside uiStartCodeMax, //limit of structure m_uiStartCodeOff, breakIfSeq, isSeqFound, flagInit); if(isSeqFound) { isSeqFound = false; if(!m_bSequenceFound) { m_bSequenceFound = true; unsigned char* ptr = (unsigned char*)m_readVideoStream.GetBufferPointer(); unsigned int count = 0; while(count < m_readVideoStream.GetDataSize() - 3) { if( ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 1 && ptr[3] == 0xb3) { break; } ptr ++; count++; } ret = ParseMPEG2SeqHeader(pES, ptr, m_readVideoStream.GetDataSize()); if (m_InfoFromPrevPES.m_bStartInPrevPES) { m_lockedVideoBuffer.SetTime(m_InfoFromPrevPES.m_video_pts, m_InfoFromPrevPES.m_video_dts); } else { m_lockedVideoBuffer.SetTime(m_dCurrVideoPts, m_dCurrVideoDts); } vm_debug_trace(0,VM_STRING("MPEG2 SEQ founnd, PTS = %lf\n"),m_lockedVideoBuffer.GetTime()); } } breakIfSeq = !m_bSequenceFound; if(!m_bSequenceFound && ret == UMC_OK) { int tail = (m_splitter_flags & FLAG_VSPL_COMPATIBLE) ? 0 : 4; m_readVideoStream.SetBufferPointer(((unsigned char*)m_readVideoStream.GetBufferPointer()) + tail, m_readVideoStream.GetDataSize() - tail); m_lockedVideoBuffer.SetDataSize(0); uiStartCodeMax = MAX_CODE_COUNT; m_uiStartCodePos = 0; m_uiStartCodeOff = 0; } else if(!m_bStop && (ret == UMC_OK) && m_lockedVideoBuffer.GetDataSize() > 0) { if(m_splitter_flags & FLAG_VSPL_COMPATIBLE) // done by flagInit m_lFlagsReq &= ~FLAG_VSPL_VIDEO_FRAME_REQ; if(m_lFlagsReq & FLAG_VSPL_VIDEO_FRAME_REQ) { m_lFlagsReq &= ~FLAG_VSPL_VIDEO_FRAME_REQ; m_uiStartCodeOff = m_lockedVideoBuffer.GetDataSize(); m_uiStartCodePos += uiStartCodeMax; uiStartCodeMax = MAX_CODE_COUNT - m_uiStartCodePos; VM_ASSERT(uiStartCodeMax > 0); VM_ASSERT(m_uiStartCodePos < MAX_CODE_COUNT); } else { flagInit = 0; //first portion was with seq. header // !MPEG2 DECODER DOESN'T WORK WITH SWAPPED DATA ANYMORE! // //align buffer size on 16 bytes //if(swapFlag == 2)//TBD need to check swap flag //{ // unsigned char * from, * to; // int size, sizea; // size = m_lockedVideoBuffer.GetDataSize(); // sizea = (size + 3) & ~3; // from = (unsigned char*)m_lockedVideoBuffer.GetBufferPointer() + size; // to = (unsigned char*)m_lockedVideoBuffer.GetBufferPointer() + sizea; // while(from < to) { *from = 0; from++; } // m_lockedVideoBuffer.SetDataSize(sizea);//? 15->3 // //if start code was find make buffer size [16->]4 bytes aligned // //and swap data if needed // Swap4Bytes((unsigned char*)m_lockedVideoBuffer.GetBufferPointer(), sizea); //} if(UMC_OK == retBuff && m_pVideoAuxData) { Ipp32u i; MediaDataEx::_MediaDataEx *stCodes; stCodes = new MediaDataEx::_MediaDataEx; if(!stCodes) return UMC_ALLOC; int num_codes = 0; m_startCodesData.SetDataSize(sizeof(MediaDataEx::_MediaDataEx)); stCodes->count = m_uiStartCodePos + uiStartCodeMax; stCodes->index = 0; stCodes->bstrm_pos = 0; for(i = 0; i < stCodes->count; i++) { if(m_pStartCodes[i].m_startCode >= 0x00000100 && m_pStartCodes[i].m_startCode <= 0x000001AF) { stCodes->offsets[num_codes] = m_pStartCodes[i].m_StartCodePos; stCodes->values[num_codes] = m_pStartCodes[i].m_startCode; num_codes++; } } stCodes->count = num_codes; memcpy(m_startCodesData.GetBufferPointer(), &stCodes, sizeof(MediaDataEx::_MediaDataEx*)); retBuff = m_pVideoAuxData->UnLockInputBuffer(&m_startCodesData); } vm_debug_trace(0,VM_STRING("MPEG2 Picture complete, PTS = %lf\n"),m_lockedVideoBuffer.GetTime()); retBuff = m_pVideoBuffer->UnLockInputBuffer(&m_lockedVideoBuffer); m_uiVideoFrameCount++; StoreLastPositionAndPTS(m_lockedVideoBuffer.GetTime(), m_pDataReader->GetPosition() - m_readVideoStream.GetDataSize()); /*vm_status vmSts = VM_TIMEOUT; do { vmSts = vm_semaphore_timedwait(&m_eVideoFrameCount, 1000); } while((VM_TIMEOUT == vmSts) && !m_bFlagStop && !m_bReposHappend && !m_bPrepareForReposition);*/ do { retBuff = m_pVideoBuffer->LockInputBuffer(&m_lockedVideoBuffer); if(retBuff == UMC_NOT_ENOUGH_BUFFER) vm_time_sleep(5); } while(!m_bStop && retBuff == UMC_NOT_ENOUGH_BUFFER); if(UMC_OK == retBuff && m_pVideoAuxData) do { retBuff = m_pVideoAuxData->LockInputBuffer(&m_startCodesData); if(retBuff == UMC_NOT_ENOUGH_BUFFER) vm_time_sleep(5); } while(!m_bStop && retBuff == UMC_NOT_ENOUGH_BUFFER); if (m_InfoFromPrevPES.m_bStartInPrevPES) { m_lockedVideoBuffer.SetTime(m_InfoFromPrevPES.m_video_pts, m_InfoFromPrevPES.m_video_dts); } else { m_lockedVideoBuffer.SetTime(m_dCurrVideoPts, m_dCurrVideoDts); } m_dPrevVideoPts = -1; uiStartCodeMax = MAX_CODE_COUNT; m_uiStartCodePos = 0; m_uiStartCodeOff = 0; } } else { m_uiStartCodeOff = m_lockedVideoBuffer.GetDataSize(); m_uiStartCodePos += uiStartCodeMax; uiStartCodeMax = MAX_CODE_COUNT - m_uiStartCodePos; VM_ASSERT(uiStartCodeMax > 0); VM_ASSERT(m_uiStartCodePos < MAX_CODE_COUNT); } } while(!m_bStop && ret == UMC_OK); full_size -= get_size; get_size = full_size > PORTION_TO_READ?PORTION_TO_READ:full_size; } else { //video buffer is full with frames, need to wait vm_time_sleep(5); } } return ret;}Status MPEG2AVSplitter::FillBufferMPEG4Video(ElementaryStream* pES, int full_size, int swapFlag){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -