📄 mpgparse.cpp
字号:
(p1[1] == 0x00) && (p1[2] == 0x01) && (p1[3] == 0xBA))) { IsDVD = 0; } if (!( (p2[0] == 0x00) && (p2[1] == 0x00) && (p2[2] == 0x01) && (p2[3] == 0xBA))) { IsDVD = 0; } if (!( (p3[0] == 0x00) && (p3[1] == 0x00) && (p3[2] == 0x01) && (p3[3] == 0xBA))) { IsDVD = 0; } if (!( (p4[0] == 0x00) && (p4[1] == 0x00) && (p4[2] == 0x01) && (p4[3] == 0xBA))) { IsDVD = 0; } if (!( (p5[0] == 0x00) && (p5[1] == 0x00) && (p5[2] == 0x01) && (p5[3] == 0xBA))) { IsDVD = 0; } DEBUGMSG (1, ("IsDVDStream: IsDVD = %d\n", (int)IsDVD)); if (IsDVD) { RMint32 i; m_CallbackTable.fseek (file, 0, SEEK_SET, m_CallbackTable.context); for (i=0; i<512; i++) { n = m_CallbackTable.fread (file, pBuffer, 2048, m_CallbackTable.context); if (n == 2048) { RMuint8 *pSystemHeader; pSystemHeader = pBuffer + 14; // try to find a navigation pack if (!( (pSystemHeader[0] == 0x00) && (pSystemHeader[1] == 0x00) && (pSystemHeader[2] == 0x01) && (pSystemHeader[3] == 0xBB))) { IsDVD = 0; continue; } RMuint8 *pPCIPacketHeader = pSystemHeader + 24; if (!( (pPCIPacketHeader[0] == 0x00) && (pPCIPacketHeader[1] == 0x00) && (pPCIPacketHeader[2] == 0x01) && (pPCIPacketHeader[3] == 0xBF) && (pPCIPacketHeader[6] == 0x00))) { IsDVD = 0; continue; } RMuint8 *pDSIPacketHeader = pPCIPacketHeader + 6 + 1 + 979; if (!( (pDSIPacketHeader[0] == 0x00) && (pDSIPacketHeader[1] == 0x00) && (pDSIPacketHeader[2] == 0x01) && (pDSIPacketHeader[3] == 0xBF) && (pDSIPacketHeader[6] == 0x01))) { IsDVD = 0; continue; } IsDVD = 1; break; } } } } m_CallbackTable.fclose (file, m_CallbackTable.context); return IsDVD;}RMint32 MPEGDemux::IsVCDStream (RMint8 *filename){ DEBUGMSG (1, ("IsVCDStream (%s)\n", filename)); RMuint32 file = m_CallbackTable.fopen (filename, m_CallbackTable.context); if (file == 0) return 0; RMint32 n; RMuint8 riffhdr[64]; n = m_CallbackTable.fread (file, riffhdr, sizeof(riffhdr), m_CallbackTable.context); // header must be at least 44 bytes long if (n < 44) { m_CallbackTable.fclose (file, m_CallbackTable.context); return 0; } if ((riffhdr[0] != 'R') || (riffhdr[1] != 'I') || (riffhdr[2] != 'F') || (riffhdr[3] != 'F')) { m_CallbackTable.fclose (file, m_CallbackTable.context); return 0; } if ((riffhdr[ 8] != 'C') || (riffhdr[ 9] != 'D') || (riffhdr[10] != 'X') || (riffhdr[11] != 'A') || (riffhdr[12] != 'f') || (riffhdr[13] != 'm') || (riffhdr[14] != 't') || (riffhdr[15] != ' ')) { m_CallbackTable.fclose (file, m_CallbackTable.context); return 0; } m_CallbackTable.fclose (file, m_CallbackTable.context); // 44 should be the file offset to the vcd data sectors return 44;}RMint32 MPEGDemux::IsMPEG124ElementaryStream (RMint8 *filename, RMuint32 *pmpeg12){ RMint32 IsMPEG12Elementary, i; DEBUGMSG (1, ("IsMPEG12ElementaryStream (%s)\n", filename)); // look for start codes and check that there is no system start // start code IsMPEG12Elementary = 0; RMuint32 file = m_CallbackTable.fopen (filename, m_CallbackTable.context); if (file == 0) return IsMPEG12Elementary; RMuint8 *pBuffer = 0; RMuint8 *pDetectionBuffer = 0; RMuint32 length = 1024*8; m_CallbackTable.getDetectionBuffer (&pDetectionBuffer, &length, m_CallbackTable.context); ASSERT (pDetectionBuffer); pBuffer = pDetectionBuffer; ASSERT (pBuffer); if (pBuffer) { RMuint32 n; DEBUGMSG (1, ("IsMPEG12ElementaryStream: m_CallbackTable.fread\n")); n = m_CallbackTable.fread (file, pBuffer, 1024*8, m_CallbackTable.context); for (i=0; i<n-6; i++) { if ((pBuffer[0] == 0x00) && (pBuffer[1] == 0x00) && (pBuffer[2] == 0x01)) { IsMPEG12Elementary++; } pBuffer++; } } m_CallbackTable.fclose (file, m_CallbackTable.context); DEBUGMSG (1, ("IsMPEG12ElementaryStream: IsMPEG12Elementary = %d\n", (int)IsMPEG12Elementary)); if (IsMPEG12Elementary > 20) { // now take a closer look at the buffer to see if this is an // mpeg-1/mpeg-2 or a mpeg-4 stream // do it a very cheesy way ... pBuffer = pDetectionBuffer; if ((pBuffer[0] == 0x00) && (pBuffer[1] == 0x00) && (pBuffer[2] == 0x01) && (pBuffer[3] <= 0x2f)) { // mpeg-4 *pmpeg12 = 0; m_CallbackTable.info (MSG_MSG_MPEG4_ELEMENTARY, 0, m_CallbackTable.context); } else if ((pBuffer[0] == 0x00) && (pBuffer[1] == 0x00) && (pBuffer[2] == 0x01) && (pBuffer[3] == 0xb0)) { // mpeg-4 *pmpeg12 = 0; m_CallbackTable.info (MSG_MSG_MPEG4_ELEMENTARY, 0, m_CallbackTable.context); } else { // mpeg-1/2 *pmpeg12 = 1; m_CallbackTable.info (MSG_MSG_MPEG12_ELEMENTARY, 0, m_CallbackTable.context); } return 1; } return 0;}RMint32 MPEGDemux::reformat_vcdsectors (RMuint8 *p, RMint32 l){ while (l >= 2352) { memset (p, 0xff, 24); memset (p+24+2324, 0xff, 4); p += 2352; l -= 2352; } return l;}RMint32 MPEGDemux::demux (RMuint8 *p, RMuint32 l){ switch (m_DemuxType) { case PROGRAM_DEMUX: case DVD_DEMUX: m_ProgramDemux.Demux (p, l); break; case DAT_DEMUX: reformat_vcdsectors (p, l/2352*2352); case SYSTEM_DEMUX: m_MPEG1Demux.Demux (p, l); break; case NO_DEMUX: m_CallbackTable.addref (p, m_CallbackTable.context); m_CallbackTable.putpayload (p, l, 0xe0, 0, 0, 0, 0, 0, m_CallbackTable.context); m_CallbackTable.release (p, m_CallbackTable.context); break; default: ASSERT (0); break; } return 0;}void MPEGDemux::MPEG1DemuxCallback (RMuint8 *pData, RMuint32 Length, RMuint8 PacketId, RMint64 Scr, RMint64 Pts, RMint64 Dts, RMuint8 Flags, RMint64 offset){ ASSERT (m_CallbackTable.putpayload); if (m_BytesToSkip == 0) { m_CallbackTable.putpayload (pData, Length, PacketId, 0, Scr, Pts, Dts, Flags, m_CallbackTable.context); } else { // video only if ((PacketId & 0xf0) == 0xe0) { if ((m_IFrameSubState == MPG_LOOKING_FOR_SEQUENCE_HEADER) || (m_IFrameSubState == MPG_LOOKING_FOR_1ST_PICTURE_HEADER)) { if (Flags == 0) return; } RMint32 l; RMuint32 sendit; ASSERT (m_BytesToSkip); sendit = 0; l = iframe_parser (pData, Length, &sendit); if (m_IFrameSubState == MPG_FOUND_2ND_PICTURE_HEADER) Flags = 0; ASSERT (l <= Length); if (sendit) { DEBUGMSG (((Flags & PTS_VALID_FLAG) == 0), ("(IFrame) m_CallbackTable.putpayload (%d)\n", (RMint32)(Length-l))); DEBUGMSG ((Flags & PTS_VALID_FLAG), ("(IFrame) m_CallbackTable.putpayload (%d) pts=%d\n", (RMint32)(Length-l), (RMint32)Pts)); m_CallbackTable.putpayload (pData, Length - l, PacketId, 0, Scr, Pts, Dts, Flags, m_CallbackTable.context); } } }}void MPEGDemux::PESDemuxCallback (RMuint8 *pData, RMuint32 Length, RMuint8 StreamId, RMuint8 SubStreamId, RMint64 Scr, RMint64 Pts, RMint64 Dts, RMuint8 Flags, RMint64 offset){ ASSERT (m_CallbackTable.putpayload); if (m_BytesToSkip == 0) { m_CallbackTable.putpayload (pData, Length, StreamId, SubStreamId, Scr, Pts, Dts, Flags, m_CallbackTable.context); } else { if ((StreamId & 0xf0) == 0xe0) { //////////////////////////////////////////////////////////////////////// // this is a shortcut to avoid parsing everything // XXX WARNING: // for this shortcut to work, every I frame MUST have a PTS. // In addition, every frame follwing the I frame (in decode // order) must also have a PTS. if ((m_IFrameSubState == MPG_LOOKING_FOR_SEQUENCE_HEADER) || (m_IFrameSubState == MPG_LOOKING_FOR_1ST_PICTURE_HEADER)) { if (Flags == 0) { return; } } else if (m_IFrameSubState == MPG_LOOKING_FOR_2ND_PICTURE_HEADER) { if (Flags == 0) { // just send it m_CallbackTable.putpayload (pData, Length, StreamId, SubStreamId, Scr, Pts, Dts, Flags, m_CallbackTable.context); return; } } // end shortcut /////////////////////////////////////////////////////////////////////////// RMint32 l; RMuint32 sendit; ASSERT (m_BytesToSkip); sendit = 0; l = iframe_parser (pData, Length, &sendit); if (m_IFrameSubState == MPG_FOUND_2ND_PICTURE_HEADER) Flags = 0; ASSERT (l <= Length); if (sendit) { DEBUGMSG (((Flags & PTS_VALID_FLAG) == 0), ("(IFrame) m_CallbackTable.putpayload (%d)\n", Length-l)); DEBUGMSG ((Flags & PTS_VALID_FLAG), ("(IFrame) m_CallbackTable.putpayload (%d) pts=%d\n", Length-l, (RMint32)Pts)); m_CallbackTable.putpayload (pData, Length-l, StreamId, SubStreamId, Scr, Pts, Dts, Flags, m_CallbackTable.context); } } }}void MPEGDemux::AC3DTSInfoCallback (RMuint8 numberOfFrameHeaders, RMuint16 firstAccessUnitPointer){ AC3DTS_INFO info; info.nFrameHeaders = numberOfFrameHeaders; info.FirstAccessUnitPointer = firstAccessUnitPointer; m_CallbackTable.info (MSG_MSG_AC3DTS_INFO, &info, m_CallbackTable.context);}void MPEGDemux::LPCMInfoCallback (RMuint8 numberOfFrameHeaders, RMuint16 firstAccessUnitPointer, RMuint32 frequency, RMuint8 numberOfChannels, RMuint8 quantizationWordLength){ LPCM_INFO info; info.nFrameHeaders = numberOfFrameHeaders; info.FirstAccessUnitPointer = firstAccessUnitPointer; info.Frequency = frequency; info.NumberOfChannels = numberOfChannels + 1; info.QuantizationWordLength = quantizationWordLength; m_CallbackTable.info (MSG_MSG_LPCM_INFO, &info, m_CallbackTable.context);}RMint32 MPEGDemux::iframe_parser (RMuint8 *p, RMint32 len, RMuint32 *sendit){ if (m_IFrameSubState == MPG_LOOKING_FOR_2ND_PICTURE_HEADER) *sendit |= 1; else if (m_IFrameSubState == MPG_FOUND_2ND_PICTURE_HEADER) { m_MPEG1Demux.Reset (); m_MPEG1Demux.ResetState (); return len; } else if (m_IFrameSubState == MPG_ERROR_SAME_IFRAME_DURING_REVERSE) { m_MPEG1Demux.Reset (); m_MPEG1Demux.ResetState (); return len; } while (len) { switch (m_IFrameState) { case 0: // found 0xxxxxxxxx looking for 0x00xxxxxx if (*p == 0) m_IFrameState++; break; case 1: // found 0x00xxxxxx looking for 0x0000xxxx if (*p == 0) m_IFrameState++; else m_IFrameState = 0; break; case 2: // found 0x0000xxxx looking for 0x000001xx if (*p == 1) m_IFrameState++; else if (*p == 0); else m_IFrameState = 0; break; case 3: // found 0x000001xx if (m_IFrameSubState == MPG_LOOKING_FOR_SEQUENCE_HEADER) { // sequence header OR group of pictures header if ((*p == 0xb8) || (*p == 0xb3)) { DEBUGMSG ((*p == 0xb8), ("FOUND GOP HEADER\n")); DEBUGMSG ((*p == 0xb3), ("FOUND SEQUENCE HEADER\n")); m_IFrameSubState = MPG_LOOKING_FOR_1ST_PICTURE_HEADER; *sendit |= 1; } } else if (m_IFrameSubState == MPG_LOOKING_FOR_1ST_PICTURE_HEADER) { if (*p == 0x00) { DEBUGMSG (1, ("FOUND START PICTURE HEADER (%d)\n", (RMint32)m_CurrentPosition)); m_IFrameSubState = MPG_LOOKING_FOR_2ND_PICTURE_HEADER; *sendit |= 1; if (m_BytesToSkip < 0) { if (m_IFramePosition == -1) m_IFramePosition = m_CurrentPosition; else if (m_CurrentPosition >= m_IFramePosition) { *sendit = 0; DEBUGMSG (1, ("MPG_ERROR_SAME_IFRAME_DURING_REVERSE\n")); m_IFrameSubState = MPG_ERROR_SAME_IFRAME_DURING_REVERSE; } else m_IFramePosition = m_CurrentPosition; } else { m_IFramePosition = m_CurrentPosition; } DEBUGMSG (1, ("m_IFramePosition = %d\n", (RMint32)m_IFramePosition)); } } else if (m_IFrameSubState == MPG_LOOKING_FOR_2ND_PICTURE_HEADER) { if (*p == 0x00) { m_ReverseErrorLoop = 0; DEBUGMSG (1, ("FOUND END PICTURE HEADER\n")); m_IFrameSubState = MPG_FOUND_2ND_PICTURE_HEADER; return len; } } m_IFrameState = 0; break; default: ASSERT (0); break; } len--; p++; } return len;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -