📄 umc_mpeg2ts_spl.cpp
字号:
if (m_uiMAXGOPLength==0) m_uiMAXGOPLength = 200000; m_dCurrVideoPts=-1.0; m_dCurrVideoDts=-1.0; int ii = CheckIfNewES(false, pid, -1); pCurrES = &m_pESArray[ii]; end = p_start; saved_start = p_start; start = p_start; video_start = 0; posIFrame = 0; posPackege = 0; memset (LastBytes,0xff,sizeof(LastBytes)); while(!m_bStop) { unsigned int id=0; unsigned short length; if ((start>=end)&&(posIFrame==0)) { // Interval [saved_start, end] was checked and I frame hasn't been found if (bFirstFrame) return UMC_END_OF_STREAM; // the first frame has been unpacked. if (end-m_uiMAXGOPLength <= 0) { bFirstFrame=true; err = m_pDataReader->SetPosition((vm_sizet)(0)); if (err != UMC_OK) return err; } else { // Step back on m_uiMAXGOPLength err = m_pDataReader->SetPosition(end-m_uiMAXGOPLength); if (err != UMC_OK) return err; } memset (LastBytes,0xff,sizeof(LastBytes)); err = MoveToNextSyncWord(); if (err != UMC_OK || m_bStop) return err; vm_debug_trace (-1,VM_STRING("steps back: %d, %d, %d, %d\n"),(int)start,(int)end,(int)saved_start,(int)video_start); start = m_pDataReader->GetPosition(); end = (video_start>0)?video_start:saved_start; saved_start = start; video_start = 0; if (start>=end) continue; } else if ((start>=end)&&(posIFrame>0)) { // I frame was found, interval was checked break; } unsigned char byte_code; unsigned short short_code; unsigned int int_code; PacketPosition = m_pDataReader->GetPosition(); if (err != UMC_OK) return err; err = CheckTSSyncByte(byte_code); if(err != UMC_OK) return err; err = m_pDataReader->GetByte(&byte_code); if(err != UMC_OK) return err; VM_ASSERT (byte_code == ID_TS_SYNC_BYTE); if (byte_code != ID_TS_SYNC_BYTE) return err; // TS packet CurrentPackSize = m_uiRegularPackSize-1; err = m_pDataReader->GetShort(&short_code); if(err != UMC_OK) return err; CurrentPackSize -= 2; payload_unit_start_indicator = ((short_code >> 14) & 1); id = (short_code & ((1 << 13) - 1)); err = m_pDataReader->GetByte(&byte_code); if(err != UMC_OK) return err; CurrentPackSize --; adaptation_field_control = ((byte_code >> 4) & ((1 << 2) - 1)); start = m_pDataReader->GetPosition(); if (start>=end) continue; if (id == pid) { // video packet was found double timeStamp; int gotBytes = 0; int size; int iIFrameStart; PrevPacketPosition = CurrPacketPosition; CurrPacketPosition = PacketPosition; if (adaptation_field_control==3) { unsigned int hlen; err = m_pDataReader->GetByte(&byte_code); if(err != UMC_OK) return err; hlen = (unsigned int)byte_code; err = m_pDataReader->MovePosition(hlen); if(err != UMC_OK) return err; CurrentPackSize -= (hlen+1); } else if(adaptation_field_control==2) { err = m_pDataReader->MovePosition(CurrentPackSize); if(err != UMC_OK) return err; CurrentPackSize = 0; } if (CurrentPackSize) { if(payload_unit_start_indicator) { prevDTS = currDTS; prevPTS = currPTS; err = m_pDataReader->GetUInt(&int_code); if(err != UMC_OK) return err; VM_ASSERT ((int_code>>8)==0x000001); err = m_pDataReader->GetShort(&short_code); if(err != UMC_OK) return err; CurrentPackSize -= 6; err = MPEG2PESPacketHeader(&timeStamp, &currDTS, gotBytes); if (err != UMC_OK) return err; GetVideoTime(&currPTS, timeStamp); CurrentPackSize -= (gotBytes); } vm_sizet pos = m_pDataReader->GetPosition(); if (err != UMC_OK) return err; if (video_start==0) video_start = pos + 6; // when we step back, start code on the edge should not be lost size = ((CurrentPackSize) < (int)(end - pos))? (CurrentPackSize) : (int)(end - pos); switch (pCurrES->m_videoStreamInfo.stream_type) { case MPEG1_VIDEO: case MPEG2_VIDEO: err = FindIPicturePositionMPEG2(size, LastBytes, i, iIFrameStart); break; default: return UMC::UMC_NOT_IMPLEMENTED; } if (iIFrameStart>0) { // I frame was found in this PES packet if (i-iIFrameStart<=size) { //I picture starts in this PES packet posIFrame = pos + size - (i-iIFrameStart); posPackege = CurrPacketPosition; } else { //I picture starts in prev. PES packet posIFrame = PrevPESEndPosition + size - (i-iIFrameStart); posPackege = PrevPacketPosition; } if (i-iIFrameStart<=size-4) { //I picture start code starts in this PES packet m_dCurrVideoPts=currPTS; m_dCurrVideoDts=currDTS; } else { //I picture start code starts in prev PES packet m_dCurrVideoPts=prevPTS; m_dCurrVideoDts=prevDTS; } } start = pos + size; PrevPESEndPosition = pos + size; } }// if PID==id else { err = m_pDataReader->MovePosition(CurrentPackSize); if (err != UMC_OK) return err; } err = MoveToNextSyncWord(); if (err != UMC_OK) return err; }// end of while //curr_position = m_pDataReader->SetPosition((vm_sizet)curr_position); return UMC_OK;}Status MPEG2TSSplitter::MPEG2TSPack(){ unsigned char next_sync_byte;// int transport_error_indicator; int payload_unit_start_indicator;// int transport_priority; unsigned int PID;// int transport_scrambling_control; int adaptation_field_control;// int continuity_counter;// int data_byte;// int pointer_field; int num_add_byte = 0; int retSize; int i; int len_of_af = 0;// long code; unsigned short short_code; unsigned char byte_code; UMC::Status err; unsigned char syncByte; err = m_pDataReader->GetByte(&syncByte); if(err != UMC_OK) return err; VM_ASSERT(syncByte == ID_TS_SYNC_BYTE); err = m_pDataReader->CheckByte(&next_sync_byte, m_uiNextSyncBytePos-1); if(err != UMC_OK) return err; if(next_sync_byte != ID_TS_SYNC_BYTE) { //try to find next sync byte if error case while(next_sync_byte != ID_TS_SYNC_BYTE && !m_bStop) { num_add_byte++; err = m_pDataReader->CheckByte(&next_sync_byte, m_uiRegularPackSize-1 + num_add_byte); if(err != UMC_OK ||m_bStop ) return err; } } else { num_add_byte = 0; if((err != UMC_OK)) { return err; } } m_uiCurrentPackSize = m_uiRegularPackSize + num_add_byte - 1; err = m_pDataReader->GetShort(&short_code); if(err != UMC_OK) return err; m_uiCurrentPackSize -= 2; payload_unit_start_indicator = ((short_code >> 14) & 1); PID = (short_code & ((1 << 13) - 1)); err = m_pDataReader->GetByte(&byte_code); if(err != UMC_OK) return err; m_uiCurrentPackSize --; adaptation_field_control = ((byte_code >> 4) & ((1 << 2) - 1)); switch(PID) { case ID_TS_PROGRAM_ASSOCIATTION_TABLE://Program association table if(adaptation_field_control == 3 || adaptation_field_control == 2) { //get size of adaptation field control err = m_pDataReader->GetByte((unsigned char*)&len_of_af ); if(err != UMC_OK) return err; //and skip it //TBD implement err = m_pDataReader->MovePosition( len_of_af); if(err != UMC_OK) return err; len_of_af ++; m_uiCurrentPackSize -= len_of_af; } retSize = ProgramAssociationSection(payload_unit_start_indicator); m_uiCurrentPackSize -= retSize; err = m_pDataReader->MovePosition( m_uiCurrentPackSize); if(err != UMC_OK) return err; m_uiCurrentPackSize = 0; break; case ID_TS_CONDITIONAL_ACCESS_TABLE://Conditional Access table case ID_TS_PROGRAM_MAP_TABLE: //Program map table case ID_TS_NULL_PACKET: //null packet //splitter currently skip these packets //TBD implement err = m_pDataReader->MovePosition( m_uiCurrentPackSize); if(err != UMC_OK) return err; m_uiCurrentPackSize = 0; break; default: { int found = 0; //TBD check if program exist and chosen //fill audio or video buffer if(m_uiChoosedProgram == 0 && m_iChoosedVideo != -1 && m_inESCount > 0) { int i; for(i = 0; i < m_inESCount; i++) { if(m_pESArray[i].m_uiStreamID == m_iChoosedVideo) { m_uiChoosedProgram = m_pESArray[i].m_uiProgramNum; break; } } } else if(m_uiChoosedProgram == 0 && m_inESCount > 0) { for(i = 0; i < m_inESCount; i++) { if(m_pESArray[i].m_uiProgramNum > 0 && m_pESArray[i].m_uiProgramNum < ID_TS_NULL_PACKET) { m_uiChoosedProgram = m_pESArray[i].m_uiProgramNum; break; } } } for(i = 0; i < m_inESCount; i++) { if(m_pESArray[i].m_uiPMSecID == PID) { if(adaptation_field_control == 3 || adaptation_field_control == 2) { err = m_pDataReader->GetByte((unsigned char*)&len_of_af ); if(err != UMC_OK) return err; err = m_pDataReader->MovePosition( len_of_af); if(err != UMC_OK) return err; len_of_af ++; m_uiCurrentPackSize -= len_of_af; } retSize = TSProgramMapSection(payload_unit_start_indicator, i); if(m_pESArray[i].m_videoStreamInfo.stream_type == UNDEF_VIDEO) { m_bIgnoreVideo = true; m_lFlags &= ~VIDEO_SPLITTER; m_splitter_flags &= ~VIDEO_SPLITTER; } if(m_pESArray[i].m_audioStreamInfo.stream_type == UNDEF_AUDIO) { m_bIgnoreAudio = true; m_lFlags &= ~AUDIO_SPLITTER; m_splitter_flags &= ~AUDIO_SPLITTER; } m_uiCurrentPackSize -= retSize; err = m_pDataReader->MovePosition(m_uiCurrentPackSize); if(err != UMC_OK) return err; m_uiCurrentPackSize = 0; found = 1; break; } else if((m_pESArray[i].m_uiStreamID == PID) && //video (m_uiChoosedProgram == m_pESArray[i].m_uiProgramNum)) { if(m_bIgnoreVideo) { break; } m_dCurrVideoPts = -1; m_dCurrVideoDts = -1; err = AdaptationField(adaptation_field_control); if(err != UMC_OK) return err; found = 1; if(m_uiCurrentPackSize) { if(payload_unit_start_indicator) { //pes packet come err = MPEG2PESPack(m_uiCurrentPackSize, i, PID);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -