#ifndef FLVPARSER_H #define FLVPARSER_H #include #include #include #include class FlvParser { public: FlvParser(); virtual ~FlvParser(); int Parse(uint8_t *pBuf, int nBufLen, int &nUsedLen); int DumpH264(const std::string filepath); int DumpAAC(const std::string filepath); int DumpFlv(const std::string filepath); private: struct FlvHeader { int nVersion; int bHaveAudio; int bHaveVideo; int nHeaderSize; uint8_t *pFlvHeader; }; typedef struct FlvHeader *pFlvHeader; struct TagHeader { int nTagType; int nDataSize; int nTimeSamp; int nTimeSampExt; int nStreamID; uint32_t nTotalTS; TagHeader() : nTagType(0), nDataSize(0), nTimeSamp(0), nTimeSampExt(0), nStreamID(0) {}; ~TagHeader() {}; }; class Tag { public: Tag() : _pTagData(nullptr), _pTagHeader(nullptr), _pMedia(nullptr) {} void Init(TagHeader *pHeader, uint8_t *pBuf, int nLeftLen); TagHeader _header; uint8_t *_pTagHeader; uint8_t *_pTagData; uint8_t *_pMedia; int _nMediaLen; }; class VideoTag : public Tag { public: VideoTag(TagHeader *pHeader, uint8_t *pBuf, int nLeftLen, FlvParser *pParser); int _nFrameType; int _nCodecType; int ParseH264Tag(FlvParser *pParser); int ParseH264Configuration(FlvParser *pParser, uint8_t *pTagData); int ParseNalu(FlvParser *pParser, uint8_t *pTagData); }; class AudioTag : public Tag { public: AudioTag(TagHeader *pHeader, uint8_t *pBuf, int nLeftLen, FlvParser *pParser); int _nSoundType; int _nSoundRate; int _nSoundSize; int _nSoundFormat; static int _aacProfile; static int _sampleRateIndex; static int _channelConfig; int ParseAACTag(FlvParser *pParser); int ParseAudioSpecificConfig(FlvParser *pParser, uint8_t *pTagData); int ParseAACRaw(FlvParser *pParser, uint8_t *pTagData); }; class MetaTag : public Tag { public: MetaTag(TagHeader *pHeader, uint8_t *pBuf, int nLeftLen, FlvParser *pParser); double hexStr2Double(const unsigned char *hex, const unsigned int length); int parseMeta(FlvParser *pParser); void printMeta(); uint8_t m_amf1_type; uint32_t m_amf1_size; uint8_t m_amf2_type; unsigned char *m_meta; unsigned int m_length; double m_duration; // 视频时长 double m_width; // 视频宽度 double m_height; // 视频高度 double m_videodatarate; // 视频码率(kbps) double m_framerate; // 视频帧率 double m_videocodecid; // 视频编码格式编号 double m_audiodatarate; // 音频码率 double m_audiosamplerate; // 音频采样率 double m_audiosamplesize; // 音频采样位数(通常是16bit) bool m_stereo; // 是否立体声(多声道) double m_audiocodecid; // 音频编码格式 // std::string m_major_brand; std::string m_minor_version; std::string m_compatible_brand; std::string m_encoder; double m_filesize; }; struct FlvStat { int nMetaNum; int nVideoNum; int nAudioNum; int nMaxTimeStamp; int nLengthSize; FlvStat() : nMetaNum(0), nVideoNum(0), nAudioNum(0), nMaxTimeStamp(0), nLengthSize(0) {} ~FlvStat() {}; }; void SetStat(); void SetVideoStat(Tag *pTag); friend class Tag; public: static uint32_t SolveU32(uint8_t *pBuf) { return (pBuf[0] << 24 | pBuf[1] << 16 | pBuf[2] << 8 | pBuf[3]); } static uint32_t SolveU24(uint8_t *pBuf) { return (pBuf[0] << 16 | pBuf[1] << 8 | pBuf[0]); } static u_int32_t SolveU16(uint8_t *pBuf) { return (pBuf[0] << 8 | pBuf[1]); } static uint32_t SolveU8(uint8_t *pBuf) { return (pBuf[0]); } static void WriteU64(uint64_t &x, int length, int value) { uint64_t mask = 0xFFFFFFFFFFFFFFFF >> (64 - length); x = (x << length) | ((uint64_t)value & mask); } void PrintInfo(); private: FlvParser::FlvHeader *CreateHeader(uint8_t *pBuf); void DestroyHeader(FlvHeader *pHeader); Tag *CreateTag(uint8_t *pBuf, int nLeftSize); void DestroyTag(Tag *pTag); private: FlvHeader *_pFlvHeader; std::vector _vpTag; FlvStat _sStat; int _nNaluUnitLength; }; #endif // !FLVPARSER_H