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;
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
 |