mistserver/lib/ogg.h
2021-10-19 22:29:40 +02:00

129 lines
4.5 KiB
C++

#pragma once
#include "dtsc.h"
#include "socket.h"
#include "theora.h"
#include "vorbis.h"
#include <cstdlib>
#include <deque>
#include <sstream>
#include <string>
#include <vector>
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;
};
}// namespace OGG