141 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			141 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #pragma once
 | |
| #include <cstdlib>
 | |
| #include <string>
 | |
| #include <vector>
 | |
| #include <deque>
 | |
| #include <sstream>
 | |
| #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<unsigned int> 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<std::string> & 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<oggSegment> 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<vorbis::mode> vorbisModes;//modes for vorbis
 | |
|       unsigned int split;             //KFGShift for theora
 | |
|     private:
 | |
|       char data[282];//Fulldata
 | |
|       std::deque<std::string> 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<vorbis::mode> vModes;
 | |
|       char channels;
 | |
|       long long unsigned int blockSize[2];
 | |
|       //unsigned long getBlockSize(unsigned int vModeIndex);
 | |
|   };
 | |
| 
 | |
|   class headerPages {
 | |
|     public:
 | |
|       std::map <long long unsigned int, unsigned int> DTSCID2OGGSerial;
 | |
|       std::map <long long unsigned int, unsigned int> DTSCID2seqNum;
 | |
|       std::string parsedPages;
 | |
|   };
 | |
| }
 | |
| 
 | |
| 
 | 
