#pragma once #include "dtsc.h" #include "socket.h" #include "theora.h" #include "vorbis.h" #include #include #include #include #include namespace OGG{ class oggSegment{ public: oggSegment(); std::string dataString; int isKeyframe; long long unsigned int lastKeyFrameSeen; long long unsigned int framesSinceKeyFrame; unsigned int frameNumber; long long unsigned int timeStamp; }; enum oggCodec{THEORA, VORBIS, OPUS}; enum HeaderType{Plain = 0, Continued = 1, BeginOfStream = 2, EndOfStream = 4}; std::deque decodeXiphSize(char *data, size_t len); class Page{ public: Page(); Page(const Page &rhs); void operator=(const Page &rhs); bool read(std::string &newData); bool read(FILE *inFile); bool getSegment(unsigned int index, std::string &ret); const char *getSegment(unsigned int index); unsigned long getSegmentLen(unsigned int index); void setMagicNumber(); char getVersion(); void setVersion(char newVal = 0); char getHeaderType(); void setHeaderType(char newVal); long long unsigned int getGranulePosition(); void setGranulePosition(long long unsigned int newVal); long unsigned int getBitstreamSerialNumber(); void setBitstreamSerialNumber(long unsigned int newVal); long unsigned int getCRCChecksum(); void setCRCChecksum(long unsigned int newVal); long unsigned int getPageSequenceNumber(); void setPageSequenceNumber(long unsigned int newVal); char getPageSegments(); // get the amount of page segments inline void setPageSegments(char newVal); // set the amount of page segments int getPayloadSize(); const std::deque &getAllSegments(); bool possiblyContinued(); std::string toPrettyString(size_t indent = 0); long unsigned int calcChecksum(); bool verifyChecksum(); unsigned int calcPayloadSize(); // void clear(); void clear(char HeaderType, long long unsigned int GranPos, long unsigned int BSN, long unsigned int PSN); void prepareNext(bool continueMe = false); // prepare the page to become the next page bool setPayload(char *newData, unsigned int length); // probably obsolete unsigned int addSegment(const std::string &content); // add a segment to the page, returns added bytes unsigned int addSegment(const char *content, unsigned int length); // add a segment to the page, returns added bytes void sendTo(Socket::Connection &destination, int calcGranule = -2); // combines all data and sends it to socket unsigned int setNextSegmentTableEntry(unsigned int entrySize); // returns the size that could not be added to the table unsigned int overFlow(); // returns the amount of bytes that don't fit in this page from the segments; long long unsigned int calculateGranule(oggSegment ¤tSegment); bool shouldSend(); void vorbisStuff(); // process most recent segment long long unsigned int totalFrames; int granules; OGG::oggCodec codec; std::deque oggSegments; // used for ogg output unsigned int pageSequenceNumber; unsigned int framesSeen; unsigned int lastKeyFrame; unsigned int firstSample; // for vorbis, to handle "when to send the page" unsigned int sampleRate; // for vorbis, to handle the sampleRate int prevBlockFlag; char blockSize[2]; std::deque vorbisModes; // modes for vorbis unsigned int split; // KFGShift for theora private: char data[282]; // Fulldata std::deque segments; }; class oggTrack{ public: oggTrack() : KFGShift(0), lastTime(0), parsedHeaders(false), lastPageOffset(0), nxtSegment(0){} oggCodec codec; std::string name; std::string contBuffer; // buffer for continuing pages long long unsigned int dtscID; char KFGShift; double lastTime; long long unsigned int lastGran; bool parsedHeaders; long long unsigned int lastPageOffset; unsigned int nxtSegment; double msPerFrame; Page myPage; // Codec specific elements // theora // theora::header idHeader;//needed to determine keyframe //bullshit? // vorbis std::deque vModes; char channels; long long unsigned int blockSize[2]; // unsigned long getBlockSize(unsigned int vModeIndex); }; class headerPages{ public: std::map DTSCID2OGGSerial; std::map DTSCID2seqNum; std::string parsedPages; }; }// namespace OGG