mistserver/lib/ogg.h

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