#pragma once #include <string> #include <iostream> #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); long long int boxedSize(); long long int 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(long newData, size_t index); long getInt24(size_t index); void setInt32(long newData, size_t index); long getInt32(size_t index); void setInt64(long long int newData, size_t index); long long int 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{ long firstFragment; long long int firstTimestamp; long duration; long discontinuity; }; //fragmentRun /// AFRT Box class class AFRT: public Box{ public: AFRT(); void setVersion(char newVersion); long getVersion(); void setUpdate(long newUpdate); long getUpdate(); void setTimeScale(long newScale); long getTimeScale(); long getQualityEntryCount(); void setQualityEntry(std::string & newQuality, long no); const char * getQualityEntry(long no); long getFragmentRunCount(); void setFragmentRun(afrt_runtable newRun, long no); afrt_runtable getFragmentRun(long no); std::string toPrettyString(int indent = 0); }; //AFRT Box struct asrt_runtable{ long firstSegment; long fragmentsPerSegment; }; /// ASRT Box class class ASRT: public Box{ public: ASRT(); void setVersion(char newVersion); long getVersion(); void setUpdate(long newUpdate); long getUpdate(); long getQualityEntryCount(); void setQualityEntry(std::string & newQuality, long no); const char* getQualityEntry(long no); long getSegmentRunEntryCount(); void setSegmentRun(long firstSegment, long fragmentsPerSegment, long no); asrt_runtable getSegmentRun(long 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(long newFlags); long getFlags(); void setBootstrapinfoVersion(long newVersion); long getBootstrapinfoVersion(); void setProfile(char newProfile); char getProfile(); void setLive(bool newLive); bool getLive(); void setUpdate(bool newUpdate); bool getUpdate(); void setTimeScale(long newTimeScale); long getTimeScale(); void setCurrentMediaTime(long long int newTime); long long int getCurrentMediaTime(); void setSmpteTimeCodeOffset(long long int newTime); long long int getSmpteTimeCodeOffset(); void setMovieIdentifier(std::string & newIdentifier); char * getMovieIdentifier(); long getServerEntryCount(); void setServerEntry(std::string & entry, long no); const char * getServerEntry(long no); long getQualityEntryCount(); void setQualityEntry(std::string & entry, long no); const char * getQualityEntry(long no); void setDrmData(std::string newDrm); char * getDrmData(); void setMetaData(std::string newMetaData); char * getMetaData(); long getSegmentRunTableCount(); void setSegmentRunTable(ASRT & table, long no); ASRT & getSegmentRunTable(long no); long getFragmentRunTableCount(); void setFragmentRunTable(AFRT & table, long no); AFRT & getFragmentRunTable(long no); std::string toPrettyString(long indent = 0); }; //ABST Box class MFHD: public Box{ public: MFHD(); void setSequenceNumber(long newSequenceNumber); long getSequenceNumber(); std::string toPrettyString(int indent = 0); }; //MFHD Box class MOOF: public Box{ public: MOOF(); long getContentCount(); void setContent(Box & newContent, long no); Box & getContent(long no); std::string toPrettyString(int indent = 0); }; //MOOF Box class TRAF: public Box{ public: TRAF(); long getContentCount(); void setContent(Box & newContent, long no); Box & getContent(long no); std::string toPrettyString(int indent = 0); }; //TRAF Box struct trunSampleInformation{ long sampleDuration; long sampleSize; long sampleFlags; long 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(long flag); class TRUN: public Box{ public: TRUN(); void setFlags(long newFlags); long getFlags(); void setDataOffset(long newOffset); long getDataOffset(); void setFirstSampleFlags(long newSampleFlags); long getFirstSampleFlags(); long getSampleInformationCount(); void setSampleInformation(trunSampleInformation newSample, long no); trunSampleInformation getSampleInformation(long no); std::string toPrettyString(long indent = 0); }; enum tfhdflags{ tfhdBaseOffset = 0x000001, tfhdSampleDesc = 0x000002, tfhdSampleDura = 0x000008, tfhdSampleSize = 0x000010, tfhdSampleFlag = 0x000020, tfhdNoDuration = 0x010000, }; class TFHD: public Box{ public: TFHD(); void setFlags(long newFlags); long getFlags(); void setTrackID(long newID); long getTrackID(); void setBaseDataOffset(long long newOffset); long long getBaseDataOffset(); void setSampleDescriptionIndex(long newIndex); long getSampleDescriptionIndex(); void setDefaultSampleDuration(long newDuration); long getDefaultSampleDuration(); void setDefaultSampleSize(long newSize); long getDefaultSampleSize(); void setDefaultSampleFlags(long newFlags); long getDefaultSampleFlags(); std::string toPrettyString(long indent = 0); }; struct afraentry{ long long time; long long offset; }; struct globalafraentry{ long long time; long segment; long fragment; long long afraoffset; long long offsetfromafra; }; class AFRA: public Box{ public: AFRA(); void setVersion(long newVersion); long getVersion(); void setFlags(long newFlags); long getFlags(); void setLongIDs(bool newVal); bool getLongIDs(); void setLongOffsets(bool newVal); bool getLongOffsets(); void setGlobalEntries(bool newVal); bool getGlobalEntries(); void setTimeScale(long newVal); long getTimeScale(); long getEntryCount(); void setEntry(afraentry newEntry, long no); afraentry getEntry(long no); long getGlobalEntryCount(); void setGlobalEntry(globalafraentry newEntry, long no); globalafraentry getGlobalEntry(long no); std::string toPrettyString(long indent = 0); }; class AVCC: public Box{ public: AVCC(); void setVersion(long newVersion); long getVersion(); void setProfile(long newProfile); long getProfile(); void setCompatibleProfiles(long newCompatibleProfiles); long getCompatibleProfiles(); void setLevel(long newLevel); long getLevel(); void setSPSNumber(long newSPSNumber); long getSPSNumber(); void setSPS(std::string newSPS); long getSPSLen(); char* getSPS(); void setPPSNumber(long newPPSNumber); long getPPSNumber(); void setPPS(std::string newPPS); long getPPSLen(); char* getPPS(); std::string asAnnexB(); void setPayload(std::string newPayload); std::string toPrettyString(long indent = 0); }; class SDTP: public Box{ public: SDTP(); void setVersion(long newVersion); long getVersion(); void setValue(long newValue, size_t index); long getValue(size_t index); }; }