129 lines
4.5 KiB
C++
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 ¤tSegment);
|
|
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
|