📄 demux.h
字号:
/////////////////
//Wenson Chen.
//Innofidei Inc.
//2007/Dec/01 IP MUX
//2008 May MODE2 with RTP support
/*++ CDemuxer
Copyright (C) 2007-2008 Innofidei, Inc.
Module Name: Demux.h
Function:
Audio and Video Demux
--*/
#ifndef DEMUX_H
#define DEMUX_H
//Features switch
//Comment the below line to save CPU if you are not interesting in RTP
//#define RTP_OUTPUT_SUPPORT
#define NAL_FRAG_THRESH 1430
#define RTP_HDR_LEN 12
#define RTP_PT_H264 96
#define RTP_PT_AACP 97
#include "BaseElements.h"
struct API CDemuxer:public CFrameHeader
{
int XPE_pos;
int XPE_total_len;
bool XPE_State; //true if there has been some packet in XPE_pl, waiting for the last one
CFrameHeader lastFrameHeader;//To Save the latest updating sequence number of all control tables
bool CombineMode2Fragment(LPBYTE lpIn, WORD& wUnitLen);
BYTE XPE_pl[4096]; //temp buf storing XPE payload
bool serviceMode; //false if stream mode, true if file mode
public:
CDemuxer(WORD videoPort=6700, WORD audioPort=6702);
int Demultiplex(LPBYTE lpIn, DWORD);
//Position in a video frame of a piece of NAL data
//Normally, the I-frame is up to 20 or more KB, A NAL unit can be the First NAL unit or the last or neither
enum NAL_FRAGMENT_POS_IND
{
FRAME_MID = 0,//Neither the BEGIN or TAIL
FRAME_TAIL = 1,//This Piece of NAL data ends a frame
FRAME_BEGIN = 2,//This Piece of NAL data begins a frame
WHOLE_FRAME = 3,//This is a complete frame NAL data. normaly A P-frame
};
protected:
//The current subframe ID
BYTE m_subFrameId;
CNIT m_Nit; //Network Information
CESG m_Esg; //ESG Basic Description Table
CEBFragment m_eb; //Emergency Message
CMCT m_Cmct; //Continual Multiplex Configuration Table
CMCT m_Smct; // Short time Multiplex Configuration Table
CCA m_ca; //Conditional Acception
#ifdef USE_SCT
CSCT m_Sct; // Continual Service Configuration Table
CSCT m_stSct; // Short time Service Configuration Table
#endif
protected:
#ifdef RTP_OUTPUT_SUPPORT
WORD m_videoSeq, m_audioSeq;
WORD m_VideoPort, m_AudioPort;
#endif
CSubframe tSubFrame[7];
private:
DWORD ParseSubframe(int subId, LPBYTE lpIn);
void ParseVideoSegment(LPBYTE lpIn, DWORD ts, DWORD dwSegLen);
void ParseDataSegment(LPBYTE lpIn, DWORD dwSegLen);
void ParseAudioSegment(LPBYTE lpIn, DWORD ts, DWORD dwSegLen);
virtual void OnVideoSegmentHeader(CVideoDataSegHeader &){}
virtual void OnDataSegmentHeader(CDataDataSegHeader &){}
virtual void OnAudioSegmentHeader(CAudioDataSegHeader &){}
//
enum
{
VIDEO, //0: video seg
AUDIO, //1: audio seg
DATA, //2: data(includes RTP) seg
UNKNOWN //3: unknown type
};
virtual int OnAVMode2Fragment(DWORD ts, LPBYTE & lpStart, LPBYTE lpEnd, int data_type=UNKNOWN);
void RecoverMode2Fragment(LPBYTE lpIn, DWORD dwSegLen, int data_type=UNKNOWN);
void ParseCMct();
void ParseSMct();
void ParseXpePayload(LPBYTE, WORD length, bool is_file_mode=false/*false=streaming*/);
void ParseProgramGuideInfo(LPBYTE lpIn, WORD wUnitLen);
void ParseXpe(LPBYTE lpIn, WORD wUnitLen);
public:
#ifdef RTP_OUTPUT_SUPPORT
//This function is called for each RTP packet for Audio, Video and ECM
//The subclass can filter the RTP packet by overide this interface.
virtual void OnAvRtpPacket(LPBYTE pRtpHeader, size_t rtp_packet_len_with_header)=0;
void NalToRtp(WORD &seq, DWORD ts, LPBYTE nal, DWORD nalSize);
#else
virtual void OnAudioAacFrame(DWORD ts, LPBYTE data, WORD wDataLen)=0; //For One-Frame AAC
virtual void OnVideoNalData(DWORD ts, LPBYTE data, WORD wDataLen, NAL_FRAGMENT_POS_IND)=0; //For NAL fragment
int RtpToNal(DWORD ts, BYTE * buf, int len,NAL_FRAGMENT_POS_IND);
void RtpToAacFrame(DWORD ts, LPBYTE data, WORD len); //For AAC Audio
#endif
//This virtual function is called when the subclass wants the NAL or AAC data instead of RTP packet
virtual void OnVideoUnit(DWORD ts, LPBYTE data, WORD wUnitLen); //For Video Unit in Mode2
virtual void OnAudioUnit(DWORD ts, LPBYTE data, WORD wUnitLen); //For Video Unit in Mode2
virtual void OnDataUnit(BYTE type, LPBYTE lpIn, WORD wUnitLen);
virtual bool OnMode1DataUnit(BYTE type, LPBYTE lpIn, WORD wUnitLen);
//CA
virtual void OnEcmPacket(LPBYTE data, size_t len, int CAS_ID); //For ECM, max len of ECM is 255, CAS_ID is in the range [0, 2]
virtual void OnEmmPacket(LPBYTE data, size_t len, int CAS_ID);
//This virtual function is called after we have demuxed all control tables in the Control Channel(TS0)
virtual bool OnNitParsed();
virtual bool OnCmctParsed();//ProcessMct() will be called then OnContinusServiceInfo will be called inside.
virtual bool OnSmctParsed();
virtual bool OnEsgParsed();
virtual bool OnCaParsed();
virtual bool OnEbParsed();//The user has to combine before display the message
virtual void OnTS0Parsed();//After all the control table being parsed
//This virtual function is called in Every Second when we are receiving services other than Control channel
//The user can compare the header to know which controlTable has been channged
virtual void OnFrameHeaderInfo(CFrameHeader& former);
virtual void OnContinusServiceInfo(CService& rService);
virtual void OnShortServiceInfo(CService& rService);
virtual void OnProgramGuide(CProgramGuide&pf);
virtual void OnESGData(LPBYTE pIn, DWORD len);
virtual void OnFileModeXpe(LPBYTE dest, WORD length);
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -