Shared Memory updates
This commit is contained in:
parent
330b9f871d
commit
0e5d838a20
24 changed files with 2420 additions and 612 deletions
176
lib/dtsc.h
176
lib/dtsc.h
|
@ -16,8 +16,8 @@
|
|||
namespace DTSC {
|
||||
bool isFixed(JSON::Value & metadata);
|
||||
|
||||
/// This enum holds all possible datatypes for DTSC packets.
|
||||
enum datatype{
|
||||
///\brief This enum holds all possible datatypes for DTSC packets.
|
||||
enum datatype {
|
||||
AUDIO, ///< Stream Audio data
|
||||
VIDEO, ///< Stream Video data
|
||||
META, ///< Stream Metadata
|
||||
|
@ -30,50 +30,98 @@ namespace DTSC {
|
|||
extern char Magic_Packet[]; ///< The magic bytes for a DTSC packet
|
||||
extern char Magic_Packet2[]; ///< The magic bytes for a DTSC packet version 2
|
||||
|
||||
/// A simple structure used for ordering byte seek positions.
|
||||
///\brief A simple structure used for ordering byte seek positions.
|
||||
struct seekPos {
|
||||
bool operator < (const seekPos& rhs) const {
|
||||
if (seekTime < rhs.seekTime){
|
||||
///\brief Less-than comparison for seekPos structures.
|
||||
///\param rhs The seekPos to compare with.
|
||||
///\return Whether this object is smaller than rhs.
|
||||
bool operator < (const seekPos & rhs) const {
|
||||
if (seekTime < rhs.seekTime) {
|
||||
return true;
|
||||
}else{
|
||||
if (seekTime == rhs.seekTime){
|
||||
if (trackID < rhs.trackID){
|
||||
} else {
|
||||
if (seekTime == rhs.seekTime) {
|
||||
if (trackID < rhs.trackID) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
long long unsigned int seekTime;
|
||||
long long unsigned int bytePos;
|
||||
unsigned int trackID;
|
||||
long long unsigned int seekTime;///< Stores the timestamp of the DTSC packet referenced by this structure.
|
||||
long long unsigned int bytePos;///< Stores the byteposition of the DTSC packet referenced by this structure.
|
||||
unsigned int trackID;///< Stores the track the DTSC packet referenced by this structure is associated with.
|
||||
};
|
||||
|
||||
enum packType{
|
||||
DTSC_INVALID,
|
||||
DTSC_HEAD,
|
||||
DTSC_V1,
|
||||
DTSC_V2
|
||||
};
|
||||
|
||||
/// DTSC::Packets can currently be three types:
|
||||
/// DTSC_HEAD packets are the "DTSC" header string, followed by 4 bytes len and packed content.
|
||||
/// DTSC_V1 packets are "DTPD", followed by 4 bytes len and packed content.
|
||||
/// DTSC_V2 packets are "DTP2", followed by 4 bytes len, 4 bytes trackID, 8 bytes time, and packed content.
|
||||
/// The len is always without the first 8 bytes counted.
|
||||
class Packet {
|
||||
public:
|
||||
Packet();
|
||||
Packet(const Packet & rhs);
|
||||
Packet(const char * data_, unsigned int len, bool noCopy = false);
|
||||
~Packet();
|
||||
void null();
|
||||
void operator = (const Packet & rhs);
|
||||
operator bool() const;
|
||||
packType getVersion();
|
||||
void reInit(const char * data_, unsigned int len, bool noCopy = false);
|
||||
void getString(const char * identifier, char *& result, int & len);
|
||||
void getString(const char * identifier, std::string & result);
|
||||
void getInt(const char * identifier, int & result);
|
||||
int getInt(const char * identifier);
|
||||
void getFlag(const char * identifier, bool & result);
|
||||
bool getFlag(const char * identifier);
|
||||
bool hasMember(const char * identifier);
|
||||
long long unsigned int getTime();
|
||||
long int getTrackId();
|
||||
char * getData();
|
||||
int getDataLen();
|
||||
JSON::Value toJSON();
|
||||
protected:
|
||||
bool master;
|
||||
packType version;
|
||||
char * findIdentifier(const char * identifier);
|
||||
void resize(unsigned int size);
|
||||
char * data;
|
||||
unsigned int bufferLen;
|
||||
unsigned int dataLen;
|
||||
};
|
||||
|
||||
/// A simple structure used for ordering byte seek positions.
|
||||
struct livePos {
|
||||
livePos(){
|
||||
livePos() {
|
||||
seekTime = 0;
|
||||
trackID = 0;
|
||||
}
|
||||
livePos(const livePos & rhs){
|
||||
livePos(const livePos & rhs) {
|
||||
seekTime = rhs.seekTime;
|
||||
trackID = rhs.trackID;
|
||||
}
|
||||
void operator = (const livePos& rhs) {
|
||||
void operator = (const livePos & rhs) {
|
||||
seekTime = rhs.seekTime;
|
||||
trackID = rhs.trackID;
|
||||
}
|
||||
bool operator == (const livePos& rhs) {
|
||||
bool operator == (const livePos & rhs) {
|
||||
return seekTime == rhs.seekTime && trackID == rhs.trackID;
|
||||
}
|
||||
bool operator != (const livePos& rhs) {
|
||||
bool operator != (const livePos & rhs) {
|
||||
return seekTime != rhs.seekTime || trackID != rhs.trackID;
|
||||
}
|
||||
bool operator < (const livePos& rhs) const {
|
||||
if (seekTime < rhs.seekTime){
|
||||
bool operator < (const livePos & rhs) const {
|
||||
if (seekTime < rhs.seekTime) {
|
||||
return true;
|
||||
}else{
|
||||
if (seekTime > rhs.seekTime){
|
||||
} else {
|
||||
if (seekTime > rhs.seekTime) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +133,7 @@ namespace DTSC {
|
|||
|
||||
/// A part from the DTSC::Stream ringbuffer.
|
||||
/// Holds information about a buffer that will stay consistent
|
||||
class Ring{
|
||||
class Ring {
|
||||
public:
|
||||
Ring(livePos v);
|
||||
livePos b;
|
||||
|
@ -96,7 +144,9 @@ namespace DTSC {
|
|||
volatile int playCount;
|
||||
};
|
||||
|
||||
class Part{
|
||||
|
||||
///\brief Basic class for storage of data associated with single DTSC packets, a.k.a. parts.
|
||||
class Part {
|
||||
public:
|
||||
long getSize();
|
||||
void setSize(long newSize);
|
||||
|
@ -104,12 +154,21 @@ namespace DTSC {
|
|||
void setDuration(short newDuration);
|
||||
long getOffset();
|
||||
void setOffset(long newOffset);
|
||||
char* getData();
|
||||
char * getData();
|
||||
void toPrettyString(std::stringstream & str, int indent = 0);
|
||||
private:
|
||||
///\brief Data storage for this packet.
|
||||
///
|
||||
/// - 3 bytes: MSB storage of the payload size of this packet in bytes.
|
||||
/// - 2 bytes: MSB storage of the duration of this packet in milliseconds.
|
||||
/// - 4 bytes: MSB storage of the presentation time offset of this packet in milliseconds.
|
||||
char data[9];
|
||||
};
|
||||
|
||||
class Key{
|
||||
///\brief Basic class for storage of data associated with keyframes.
|
||||
///
|
||||
/// When deleting this object, make sure to remove all DTSC::Part associated with it, if any. If you fail doing this, it *will* cause data corruption.
|
||||
class Key {
|
||||
public:
|
||||
long long unsigned int getBpos();
|
||||
void setBpos(long long unsigned int newBpos);
|
||||
|
@ -121,12 +180,21 @@ namespace DTSC {
|
|||
void setParts(short newParts);
|
||||
long getTime();
|
||||
void setTime(long newTime);
|
||||
char* getData();
|
||||
char * getData();
|
||||
void toPrettyString(std::stringstream & str, int indent = 0);
|
||||
private:
|
||||
///\brief Data storage for this packet.
|
||||
///
|
||||
/// - 5 bytes: MSB storage of the position of the first packet of this keyframe within the file.
|
||||
/// - 3 bytes: MSB storage of the duration of this keyframe.
|
||||
/// - 2 bytes: MSB storage of the number of this keyframe.
|
||||
/// - 2 bytes: MSB storage of the amount of parts in this keyframe.
|
||||
/// - 4 bytes: MSB storage of the timestamp associated with this keyframe's first packet.
|
||||
char data[16];
|
||||
};
|
||||
|
||||
class Fragment{
|
||||
///\brief Basic class for storage of data associated with fragments.
|
||||
class Fragment {
|
||||
public:
|
||||
long getDuration();
|
||||
void setDuration(long newDuration);
|
||||
|
@ -136,26 +204,28 @@ namespace DTSC {
|
|||
void setNumber(short newNumber);
|
||||
long getSize();
|
||||
void setSize(long newSize);
|
||||
char* getData();
|
||||
char * getData();
|
||||
void toPrettyString(std::stringstream & str, int indent = 0);
|
||||
private:
|
||||
char data[11];
|
||||
};
|
||||
|
||||
class readOnlyTrack{
|
||||
class readOnlyTrack {
|
||||
public:
|
||||
readOnlyTrack();
|
||||
readOnlyTrack(JSON::Value & trackRef);
|
||||
int getSendLen();
|
||||
void send(Socket::Connection & conn);
|
||||
void writeTo(char *& p);
|
||||
std::string getIdentifier();
|
||||
std::string getWritableIdentifier();
|
||||
JSON::Value toJSON();
|
||||
long long unsigned int fragLen;
|
||||
Fragment* fragments;
|
||||
Fragment * fragments;
|
||||
long long unsigned int keyLen;
|
||||
Key* keys;
|
||||
Key * keys;
|
||||
long long unsigned int partLen;
|
||||
Part* parts;
|
||||
Part * parts;
|
||||
int trackID;
|
||||
int firstms;
|
||||
int lastms;
|
||||
|
@ -175,6 +245,7 @@ namespace DTSC {
|
|||
//vorbis and theora only
|
||||
std::string idHeader;
|
||||
std::string commentHeader;
|
||||
void toPrettyString(std::stringstream & str, int indent = 0, int verbosity = 0);
|
||||
};
|
||||
|
||||
class Track : public readOnlyTrack {
|
||||
|
@ -182,32 +253,42 @@ namespace DTSC {
|
|||
Track();
|
||||
Track(const readOnlyTrack & rhs);
|
||||
Track(JSON::Value & trackRef);
|
||||
inline operator bool() const {return parts.size();}
|
||||
inline operator bool() const {
|
||||
return parts.size();
|
||||
}
|
||||
void update(DTSC::Packet & pack);
|
||||
void update(JSON::Value & pack);
|
||||
int getSendLen();
|
||||
void send(Socket::Connection & conn);
|
||||
void writeTo(char *& p);
|
||||
JSON::Value toJSON();
|
||||
std::deque<Fragment> fragments;
|
||||
std::deque<Key> keys;
|
||||
std::deque<Part> parts;
|
||||
Key & getKey(unsigned int keyNum);
|
||||
void reset();
|
||||
void toPrettyString(std::stringstream & str, int indent = 0, int verbosity = 0);
|
||||
};
|
||||
|
||||
class readOnlyMeta {
|
||||
public:
|
||||
readOnlyMeta();
|
||||
readOnlyMeta(JSON::Value & meta);
|
||||
inline operator bool() const {return vod || live;}
|
||||
std::map<int,readOnlyTrack> tracks;
|
||||
inline operator bool() const {
|
||||
return vod || live;
|
||||
}
|
||||
std::map<int, readOnlyTrack> tracks;
|
||||
bool vod;
|
||||
bool live;
|
||||
bool merged;
|
||||
long long int moreheader;
|
||||
long long int bufferWindow;
|
||||
unsigned int getSendLen();
|
||||
void send(Socket::Connection & conn);
|
||||
void writeTo(char * p);
|
||||
JSON::Value toJSON();
|
||||
bool isFixed();
|
||||
void toPrettyString(std::stringstream & str, int indent = 0, int verbosity = 0);
|
||||
};
|
||||
|
||||
class Meta : public readOnlyMeta {
|
||||
|
@ -215,16 +296,20 @@ namespace DTSC {
|
|||
Meta();
|
||||
Meta(const readOnlyMeta & meta);
|
||||
Meta(JSON::Value & meta);
|
||||
std::map<int,Track> tracks;
|
||||
std::map<int, Track> tracks;
|
||||
void update(DTSC::Packet & pack);
|
||||
void update(JSON::Value & pack);
|
||||
unsigned int getSendLen();
|
||||
void send(Socket::Connection & conn);
|
||||
void writeTo(char * p);
|
||||
JSON::Value toJSON();
|
||||
void reset();
|
||||
bool isFixed();
|
||||
void toPrettyString(std::stringstream & str, int indent = 0, int verbosity = 0);
|
||||
};
|
||||
|
||||
/// A simple wrapper class that will open a file and allow easy reading/writing of DTSC data from/to it.
|
||||
class File{
|
||||
class File {
|
||||
public:
|
||||
File();
|
||||
File(const File & rhs);
|
||||
|
@ -241,8 +326,7 @@ namespace DTSC {
|
|||
bool reachedEOF();
|
||||
void seekNext();
|
||||
void parseNext();
|
||||
std::string & getPacket();
|
||||
JSON::Value & getJSON();
|
||||
DTSC::Packet & getPacket();
|
||||
bool seek_time(unsigned int ms);
|
||||
bool seek_time(unsigned int ms, int trackNo, bool forceSeek = false);
|
||||
bool seek_bpos(int bpos);
|
||||
|
@ -254,11 +338,10 @@ namespace DTSC {
|
|||
private:
|
||||
long int endPos;
|
||||
void readHeader(int pos);
|
||||
std::string strbuffer;
|
||||
JSON::Value jsonbuffer;
|
||||
DTSC::Packet myPack;
|
||||
JSON::Value metaStorage;
|
||||
readOnlyMeta metadata;
|
||||
std::map<int,std::string> trackMapping;
|
||||
std::map<int, std::string> trackMapping;
|
||||
long long int currtime;
|
||||
long long int lastreadpos;
|
||||
int currframe;
|
||||
|
@ -274,7 +357,7 @@ namespace DTSC {
|
|||
/// Holds temporary data for a DTSC stream and provides functions to utilize it.
|
||||
/// Optionally also acts as a ring buffer of a certain requested size.
|
||||
/// If ring buffering mode is enabled, it will automatically grow in size to always contain at least one keyframe.
|
||||
class Stream{
|
||||
class Stream {
|
||||
public:
|
||||
Stream();
|
||||
virtual ~Stream();
|
||||
|
@ -302,17 +385,18 @@ namespace DTSC {
|
|||
void endStream();
|
||||
void waitForMeta(Socket::Connection & sourceSocket);
|
||||
void waitForPause(Socket::Connection & sourceSocket);
|
||||
protected:
|
||||
protected:
|
||||
void cutOneBuffer();
|
||||
void resetStream();
|
||||
std::map<livePos,JSON::Value> buffers;
|
||||
std::map<int,std::set<livePos> > keyframes;
|
||||
std::map<livePos, JSON::Value> buffers;
|
||||
std::map<int, std::set<livePos> > keyframes;
|
||||
virtual void addPacket(JSON::Value & newPack);
|
||||
virtual void addMeta(JSON::Value & newMeta);
|
||||
datatype datapointertype;
|
||||
unsigned int buffercount;
|
||||
unsigned int buffertime;
|
||||
std::map<int,std::string> trackMapping;
|
||||
std::map<int, std::string> trackMapping;
|
||||
virtual void deletionCallback(livePos deleting);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue