#pragma once #include #include #include #include #include #include "dtsc.h" #include "theora.h" #include "vorbis.h" #include "socket.h" 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 & currentSegment); 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; }; }