#pragma once #include <string> #include <iostream> #include <iomanip> #include <cstdio> #include <stdint.h> #include <sstream> #include <deque> #include <algorithm> #include "json.h" /// Contains all MP4 format related code. namespace MP4 { class Box{ public: Box(char * datapointer = 0, bool manage = true); ~Box(); std::string getType(); bool isType(const char* boxType); bool read(std::string & newData); uint64_t boxedSize(); uint64_t payloadSize(); char * asBox(); char * payload(); void clear(); std::string toPrettyString(int indent = 0); protected: //integer functions void setInt8(char newData, size_t index); char getInt8(size_t index); void setInt16(short newData, size_t index); short getInt16(size_t index); void setInt24(uint32_t newData, size_t index); uint32_t getInt24(size_t index); void setInt32(uint32_t newData, size_t index); uint32_t getInt32(size_t index); void setInt64(uint64_t newData, size_t index); uint64_t getInt64(size_t index); //string functions void setString(std::string newData, size_t index); void setString(char* newData, size_t size, size_t index); char * getString(size_t index); size_t getStringLen(size_t index); //box functions Box & getBox(size_t index); size_t getBoxLen(size_t index); void setBox(Box & newEntry, size_t index); //data functions bool reserve(size_t position, size_t current, size_t wanted); //internal variables char * data; ///< Holds the data of this box int data_size; ///< Currently reserved size bool managed; ///< If false, will not attempt to resize/free the data pointer. int payloadOffset; ///<The offset of the payload with regards to the data }; //Box Class struct afrt_runtable{ uint32_t firstFragment; uint64_t firstTimestamp; uint32_t duration; uint32_t discontinuity; }; //fragmentRun /// AFRT Box class class AFRT: public Box{ public: AFRT(); void setVersion(char newVersion); uint32_t getVersion(); void setUpdate(uint32_t newUpdate); uint32_t getUpdate(); void setTimeScale(uint32_t newScale); uint32_t getTimeScale(); uint32_t getQualityEntryCount(); void setQualityEntry(std::string & newQuality, uint32_t no); const char * getQualityEntry(uint32_t no); uint32_t getFragmentRunCount(); void setFragmentRun(afrt_runtable newRun, uint32_t no); afrt_runtable getFragmentRun(uint32_t no); std::string toPrettyString(int indent = 0); }; //AFRT Box struct asrt_runtable{ uint32_t firstSegment; uint32_t fragmentsPerSegment; }; /// ASRT Box class class ASRT: public Box{ public: ASRT(); void setVersion(char newVersion); uint32_t getVersion(); void setUpdate(uint32_t newUpdate); uint32_t getUpdate(); uint32_t getQualityEntryCount(); void setQualityEntry(std::string & newQuality, uint32_t no); const char* getQualityEntry(uint32_t no); uint32_t getSegmentRunEntryCount(); void setSegmentRun(uint32_t firstSegment, uint32_t fragmentsPerSegment, uint32_t no); asrt_runtable getSegmentRun(uint32_t no); std::string toPrettyString(int indent = 0); }; //ASRT Box /// ABST Box class class ABST: public Box{ public: ABST(); void setVersion(char newVersion); char getVersion(); void setFlags(uint32_t newFlags); uint32_t getFlags(); void setBootstrapinfoVersion(uint32_t newVersion); uint32_t getBootstrapinfoVersion(); void setProfile(char newProfile); char getProfile(); void setLive(bool newLive); bool getLive(); void setUpdate(bool newUpdate); bool getUpdate(); void setTimeScale(uint32_t newTimeScale); uint32_t getTimeScale(); void setCurrentMediaTime(uint64_t newTime); uint64_t getCurrentMediaTime(); void setSmpteTimeCodeOffset(uint64_t newTime); uint64_t getSmpteTimeCodeOffset(); void setMovieIdentifier(std::string & newIdentifier); char * getMovieIdentifier(); uint32_t getServerEntryCount(); void setServerEntry(std::string & entry, uint32_t no); const char * getServerEntry(uint32_t no); uint32_t getQualityEntryCount(); void setQualityEntry(std::string & entry, uint32_t no); const char * getQualityEntry(uint32_t no); void setDrmData(std::string newDrm); char * getDrmData(); void setMetaData(std::string newMetaData); char * getMetaData(); uint32_t getSegmentRunTableCount(); void setSegmentRunTable(ASRT & table, uint32_t no); ASRT & getSegmentRunTable(uint32_t no); uint32_t getFragmentRunTableCount(); void setFragmentRunTable(AFRT & table, uint32_t no); AFRT & getFragmentRunTable(uint32_t no); std::string toPrettyString(uint32_t indent = 0); }; //ABST Box class MFHD: public Box{ public: MFHD(); void setSequenceNumber(uint32_t newSequenceNumber); uint32_t getSequenceNumber(); std::string toPrettyString(int indent = 0); }; //MFHD Box class MOOF: public Box{ public: MOOF(); uint32_t getContentCount(); void setContent(Box & newContent, uint32_t no); Box & getContent(uint32_t no); std::string toPrettyString(int indent = 0); }; //MOOF Box class TRAF: public Box{ public: TRAF(); uint32_t getContentCount(); void setContent(Box & newContent, uint32_t no); Box & getContent(uint32_t no); std::string toPrettyString(int indent = 0); }; //TRAF Box struct trunSampleInformation{ uint32_t sampleDuration; uint32_t sampleSize; uint32_t sampleFlags; uint32_t sampleOffset; }; enum trunflags{ trundataOffset = 0x00000001, trunfirstSampleFlags = 0x00000004, trunsampleDuration = 0x00000100, trunsampleSize = 0x00000200, trunsampleFlags = 0x00000400, trunsampleOffsets = 0x00000800 }; enum sampleflags{ noIPicture = 0x01000000, isIPicture = 0x02000000, noDisposable = 0x00400000, isDisposable = 0x00800000, isRedundant = 0x00100000, noRedundant = 0x00200000, noKeySample = 0x00010000, isKeySample = 0x00000000, MUST_BE_PRESENT = 0x1 }; std::string prettySampleFlags(uint32_t flag); class TRUN: public Box{ public: TRUN(); void setFlags(uint32_t newFlags); uint32_t getFlags(); void setDataOffset(uint32_t newOffset); uint32_t getDataOffset(); void setFirstSampleFlags(uint32_t newSampleFlags); uint32_t getFirstSampleFlags(); uint32_t getSampleInformationCount(); void setSampleInformation(trunSampleInformation newSample, uint32_t no); trunSampleInformation getSampleInformation(uint32_t no); std::string toPrettyString(uint32_t indent = 0); }; enum tfhdflags{ tfhdBaseOffset = 0x000001, tfhdSampleDesc = 0x000002, tfhdSampleDura = 0x000008, tfhdSampleSize = 0x000010, tfhdSampleFlag = 0x000020, tfhdNoDuration = 0x010000, }; class TFHD: public Box{ public: TFHD(); void setFlags(uint32_t newFlags); uint32_t getFlags(); void setTrackID(uint32_t newID); uint32_t getTrackID(); void setBaseDataOffset(uint64_t newOffset); uint64_t getBaseDataOffset(); void setSampleDescriptionIndex(uint32_t newIndex); uint32_t getSampleDescriptionIndex(); void setDefaultSampleDuration(uint32_t newDuration); uint32_t getDefaultSampleDuration(); void setDefaultSampleSize(uint32_t newSize); uint32_t getDefaultSampleSize(); void setDefaultSampleFlags(uint32_t newFlags); uint32_t getDefaultSampleFlags(); std::string toPrettyString(uint32_t indent = 0); }; struct afraentry{ uint64_t time; uint64_t offset; }; struct globalafraentry{ uint64_t time; uint32_t segment; uint32_t fragment; uint64_t afraoffset; uint64_t offsetfromafra; }; class AFRA: public Box{ public: AFRA(); void setVersion(uint32_t newVersion); uint32_t getVersion(); void setFlags(uint32_t newFlags); uint32_t getFlags(); void setLongIDs(bool newVal); bool getLongIDs(); void setLongOffsets(bool newVal); bool getLongOffsets(); void setGlobalEntries(bool newVal); bool getGlobalEntries(); void setTimeScale(uint32_t newVal); uint32_t getTimeScale(); uint32_t getEntryCount(); void setEntry(afraentry newEntry, uint32_t no); afraentry getEntry(uint32_t no); uint32_t getGlobalEntryCount(); void setGlobalEntry(globalafraentry newEntry, uint32_t no); globalafraentry getGlobalEntry(uint32_t no); std::string toPrettyString(uint32_t indent = 0); }; class AVCC: public Box{ public: AVCC(); void setVersion(uint32_t newVersion); uint32_t getVersion(); void setProfile(uint32_t newProfile); uint32_t getProfile(); void setCompatibleProfiles(uint32_t newCompatibleProfiles); uint32_t getCompatibleProfiles(); void setLevel(uint32_t newLevel); uint32_t getLevel(); void setSPSNumber(uint32_t newSPSNumber); uint32_t getSPSNumber(); void setSPS(std::string newSPS); uint32_t getSPSLen(); char* getSPS(); void setPPSNumber(uint32_t newPPSNumber); uint32_t getPPSNumber(); void setPPS(std::string newPPS); uint32_t getPPSLen(); char* getPPS(); std::string asAnnexB(); void setPayload(std::string newPayload); std::string toPrettyString(uint32_t indent = 0); }; class SDTP: public Box{ public: SDTP(); void setVersion(uint32_t newVersion); uint32_t getVersion(); void setValue(uint32_t newValue, size_t index); uint32_t getValue(size_t index); }; }