removed readOnlyMeta (was not really in use)

This commit is contained in:
Thulinma 2015-03-06 16:52:59 +01:00
parent 12b0d9a930
commit e8d1578a33
3 changed files with 85 additions and 652 deletions

View file

@ -645,11 +645,13 @@ DTSC::File::File(std::string filename, bool create) {
currframe = 0;
}
/// Returns the header metadata for this file as JSON::Value.
DTSC::readOnlyMeta & DTSC::File::getMeta() {
DTSC::Meta & DTSC::File::getMeta() {
return metadata;
}
/// (Re)writes the given string to the header area if the size is the same as the existing header.
/// Forces a write if force is set to true.
bool DTSC::File::writeHeader(std::string & header, bool force) {
@ -704,30 +706,30 @@ void DTSC::File::readHeader(int pos) {
} else {
DEBUG_MSG(DLVL_ERROR, "Could not read header @ %d", pos);
}
metadata = readOnlyMeta();
metadata = Meta();
return;
}
if (memcmp(buffer, DTSC::Magic_Header, 4) != 0) {
DEBUG_MSG(DLVL_ERROR, "Invalid header - %.4s != %.4s @ %i", (char *)buffer, DTSC::Magic_Header, pos);
metadata = readOnlyMeta();
metadata = Meta();
return;
}
if (fread(buffer, 4, 1, F) != 1) {
DEBUG_MSG(DLVL_ERROR, "Could not read header size @ %i", pos);
metadata = readOnlyMeta();
metadata = Meta();
return;
}
long packSize = ntohl(((unsigned long *)buffer)[0]);
long packSize = ntohl(((unsigned long *)buffer)[0]) + 8;
std::string strBuffer;
strBuffer.resize(packSize);
if (packSize) {
fseek(F, pos, SEEK_SET);
if (fread((void *)strBuffer.c_str(), packSize, 1, F) != 1) {
DEBUG_MSG(DLVL_ERROR, "Could not read header packet @ %i", pos);
metadata = readOnlyMeta();
metadata = Meta();
return;
}
JSON::fromDTMI(strBuffer, metaStorage);
metadata = readOnlyMeta(metaStorage);//make readonly
metadata = Meta(DTSC::Packet(strBuffer.data(), strBuffer.size(),true));
}
//if there is another header, read it and replace metadata with that one.
if (metadata.moreheader) {
@ -836,7 +838,7 @@ void DTSC::File::seekNext() {
insert = true;
} else {
long tid = myPack.getTrackId();
for (unsigned int i = 0; i != metadata.tracks[tid].keyLen; i++) {
for (unsigned int i = 0; i != metadata.tracks[tid].keys.size(); i++) {
if ((unsigned long long)metadata.tracks[tid].keys[i].getTime() > myPack.getTime()) {
tmpPos.seekTime = metadata.tracks[tid].keys[i].getTime();
tmpPos.bytePos = metadata.tracks[tid].keys[i].getBpos();
@ -965,8 +967,8 @@ bool DTSC::File::seek_time(unsigned int ms, unsigned int trackNo, bool forceSeek
tmpPos.bytePos = 0;
tmpPos.seekTime = 0;
}
DTSC::readOnlyTrack & trackRef = metadata.tracks[trackNo];
for (unsigned int i = 0; i < trackRef.keyLen; i++) {
DTSC::Track & trackRef = metadata.tracks[trackNo];
for (unsigned int i = 0; i < trackRef.keys.size(); i++) {
long keyTime = trackRef.keys[i].getTime();
if (keyTime > ms) {
break;
@ -1066,8 +1068,8 @@ bool DTSC::File::atKeyframe() {
return true;
}
long long int bTime = myPack.getTime();
DTSC::readOnlyTrack & trackRef = metadata.tracks[myPack.getTrackId()];
for (unsigned int i = 0; i < trackRef.keyLen; i++) {
DTSC::Track & trackRef = metadata.tracks[myPack.getTrackId()];
for (unsigned int i = 0; i < trackRef.keys.size(); i++) {
if (trackRef.keys[i].getTime() >= bTime) {
return (trackRef.keys[i].getTime() == bTime);
}
@ -1089,31 +1091,3 @@ DTSC::File::~File() {
}
free(buffer);
}
bool DTSC::isFixed(JSON::Value & metadata) {
if (metadata.isMember("is_fixed")) {
return true;
}
if (!metadata.isMember("tracks")) {
return false;
}
for (JSON::ObjIter it = metadata["tracks"].ObjBegin(); it != metadata["tracks"].ObjEnd(); it++) {
if (it->second["type"].asString() == "meta") {
continue;
}
if (!it->second["keys"].isString()) {
return false;
}
//Check for bpos: last element bpos != 0
std::string keyRef = it->second["keys"].asStringRef();
if (keyRef.size() < 16) {
return false;
}
int offset = keyRef.size() - 17;
if (!(keyRef[offset] | keyRef[offset + 1] | keyRef[offset + 2] | keyRef[offset + 3] | keyRef[offset + 4])) {
return false;
}
}
return true;
}

View file

@ -20,7 +20,6 @@
#define DTSC_CON 0xFF
namespace DTSC {
bool isFixed(JSON::Value & metadata);
///\brief This enum holds all possible datatypes for DTSC packets.
enum datatype {
@ -252,27 +251,33 @@ namespace DTSC {
char data[11];
};
///\brief Basic class for storage of a read-only track
class readOnlyTrack {
///\brief Class for storage of track data
class Track {
public:
readOnlyTrack();
readOnlyTrack(JSON::Value & trackRef);
Track();
Track(JSON::Value & trackRef);
Track(Scan & trackRef);
inline operator bool() const {
return (partLen && keySizes.size() && (keySizes.size() == keyLen));
return (parts.size() && keySizes.size() && (keySizes.size() == keys.size()));
}
void update(long long packTime, long long packOffset, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 5000);
int getSendLen();
void send(Socket::Connection & conn);
void writeTo(char *& p);
JSON::Value toJSON();
std::deque<Fragment> fragments;
std::deque<Key> keys;
std::deque<unsigned long> keySizes;
std::deque<Part> parts;
Key & getKey(unsigned int keyNum);
unsigned int timeToKeynum(unsigned int timestamp);
unsigned int timeToFragnum(unsigned int timestamp);
void reset();
void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0);
std::string getIdentifier();
std::string getWritableIdentifier();
JSON::Value toJSON();
long long unsigned int fragLen;
Fragment * fragments;
long long unsigned int keyLen;
Key * keys;
std::vector<unsigned long> keySizes;
long long unsigned int partLen;
Part * parts;
unsigned int trackID;
unsigned long long firstms;
unsigned long long lastms;
@ -289,62 +294,19 @@ namespace DTSC {
int width;
int height;
int fpks;
void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0);
};
///\brief Class for storage of track data
class Track : public readOnlyTrack {
public:
Track();
Track(const readOnlyTrack & rhs);
Track(JSON::Value & trackRef);
Track(Scan & trackRef);
inline operator bool() const {
return (parts.size() && keySizes.size() && (keySizes.size() == keys.size()));
}
void update(long long packTime, long long packOffset, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 5000);
int getSendLen();
void send(Socket::Connection & conn);
void writeTo(char *& p);
JSON::Value toJSON();
std::deque<Fragment> fragments;
std::deque<Key> keys;
std::deque<unsigned long> keySizes;
std::deque<Part> parts;
Key & getKey(unsigned int keyNum);
void reset();
void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0);
};
///\brief Class for storage of read-only meta data
class readOnlyMeta {
public:
readOnlyMeta();
readOnlyMeta(JSON::Value & meta);
inline operator bool() const {
return vod || live;
}
std::map<unsigned 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::ostream & str, int indent = 0, int verbosity = 0);
};
///\brief Class for storage of meta data
class Meta : public readOnlyMeta {
class Meta{
/// \todo Make toJSON().toNetpacked() shorter
public:
Meta();
Meta(const DTSC::Packet & source);
Meta(const readOnlyMeta & meta);
Meta(JSON::Value & meta);
inline operator bool() const { //returns if the object contains valid meta data BY LOOKING AT vod/live FLAGS
return vod || live;
}
void reinit(const DTSC::Packet & source);
void update(DTSC::Packet & pack, unsigned long segment_size = 5000);
void updatePosOverride(DTSC::Packet & pack, unsigned long bpos);
@ -355,10 +317,14 @@ namespace DTSC {
void writeTo(char * p);
JSON::Value toJSON();
void reset();
bool isFixed();
void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0);
//members:
std::map<unsigned int, Track> tracks;
bool vod;
bool live;
bool merged;
long long int moreheader;
long long int bufferWindow;
};
/// A simple wrapper class that will open a file and allow easy reading/writing of DTSC data from/to it.
@ -370,7 +336,7 @@ namespace DTSC {
File & operator = (const File & rhs);
operator bool() const;
~File();
readOnlyMeta & getMeta();
Meta & getMeta();
long long int getLastReadPos();
bool writeHeader(std::string & header, bool force = false);
long long int addHeader(std::string & header);
@ -393,7 +359,7 @@ namespace DTSC {
void readHeader(int pos);
DTSC::Packet myPack;
JSON::Value metaStorage;
readOnlyMeta metadata;
Meta metadata;
std::map<unsigned int, std::string> trackMapping;
long long int currtime;
long long int lastreadpos;

View file

@ -949,75 +949,6 @@ namespace DTSC {
str << std::string(indent, ' ') << "Fragment " << getNumber() << ": Dur(" << getDuration() << "), Len(" << (int)getLength() << "), Size(" << getSize() << ")" << std::endl;
}
///\brief Constructs an empty readOnlyTrack
readOnlyTrack::readOnlyTrack() {
fragments = NULL;
fragLen = 0;
keys = NULL;
keyLen = 0;
parts = NULL;
partLen = 0;
missedFrags = 0;
firstms = 0;
lastms = 0;
bps = 0;
rate = 0;
size = 0;
channels = 0;
width = 0;
height = 0;
fpks = 0;
}
///\brief Constructs a readOnlyTrack from a JSON::Value
readOnlyTrack::readOnlyTrack(JSON::Value & trackRef) {
if (trackRef.isMember("fragments") && trackRef["fragments"].isString()) {
fragments = (Fragment *)trackRef["fragments"].asStringRef().data();
fragLen = trackRef["fragments"].asStringRef().size() / 11;
} else {
fragments = 0;
fragLen = 0;
}
if (trackRef.isMember("keys") && trackRef["keys"].isString()) {
keys = (Key *)trackRef["keys"].asStringRef().data();
keyLen = trackRef["keys"].asStringRef().size() / 16;
} else {
keys = 0;
keyLen = 0;
}
if (trackRef.isMember("parts") && trackRef["parts"].isString()) {
parts = (Part *)trackRef["parts"].asStringRef().data();
partLen = trackRef["parts"].asStringRef().size() / 9;
} else {
parts = 0;
partLen = 0;
}
trackID = trackRef["trackid"].asInt();
firstms = trackRef["firstms"].asInt();
lastms = trackRef["lastms"].asInt();
bps = trackRef["bps"].asInt();
missedFrags = trackRef["missed_frags"].asInt();
codec = trackRef["codec"].asStringRef();
type = trackRef["type"].asStringRef();
init = trackRef["init"].asStringRef();
if (type == "audio") {
rate = trackRef["rate"].asInt();
size = trackRef["size"].asInt();
channels = trackRef["channels"].asInt();
}
if (type == "video") {
width = trackRef["width"].asInt();
height = trackRef["height"].asInt();
fpks = trackRef["fpks"].asInt();
}
if (trackRef.isMember("keysizes") && trackRef["keysizes"].isString()) {
std::string tmp = trackRef["keysizes"].asStringRef();
for (unsigned int i = 0; i < tmp.size(); i += 4){
keySizes.push_back((((long unsigned)tmp[i]) << 24) | (((long unsigned)tmp[i+1]) << 16) | (((long unsigned int)tmp[i+2]) << 8) | tmp[i+3]);
}
}
}
///\brief Constructs an empty track
Track::Track() {
trackID = 0;
@ -1033,36 +964,6 @@ namespace DTSC {
fpks = 0;
}
///\brief Constructs a track from a readOnlyTrack
Track::Track(const readOnlyTrack & rhs) {
trackID = rhs.trackID;
firstms = rhs.firstms;
lastms = rhs.lastms;
bps = rhs.bps;
missedFrags = rhs.missedFrags;
init = rhs.init;
codec = rhs.codec;
type = rhs.type;
rate = rhs.rate;
size = rhs.size;
channels = rhs.channels;
width = rhs.width;
height = rhs.height;
fpks = rhs.fpks;
if (rhs.fragments && rhs.fragLen) {
fragments = std::deque<Fragment>(rhs.fragments, rhs.fragments + rhs.fragLen);
}
if (rhs.keys && rhs.keyLen) {
keys = std::deque<Key>(rhs.keys, rhs.keys + rhs.keyLen);
}
if (rhs.parts && rhs.partLen) {
parts = std::deque<Part>(rhs.parts, rhs.parts + rhs.partLen);
}
for(std::vector<long unsigned>::const_iterator it = rhs.keySizes.begin(); it != rhs.keySizes.end(); it++){
keySizes.push_back(*it);
}
}
///\brief Constructs a track from a JSON::Value
Track::Track(JSON::Value & trackRef) {
if (trackRef.isMember("fragments") && trackRef["fragments"].isString()) {
@ -1225,30 +1126,26 @@ namespace DTSC {
return keys[keyNum - keys[0].getNumber()];
}
///\brief Returns a unique identifier for a track
std::string readOnlyTrack::getIdentifier() {
std::stringstream result;
if (type == "") {
result << "metadata_" << trackID;
return result.str();
unsigned int Track::timeToKeynum(unsigned int timestamp){
unsigned int result = 0;
for (std::deque<Key>::iterator it = keys.begin(); it != keys.end(); it++){
if (it->getTime() >= timestamp){
break;
}
result = it->getNumber();
}
result << type << "_";
result << codec << "_";
if (type == "audio") {
result << channels << "ch_";
result << rate << "hz";
} else if (type == "video") {
result << width << "x" << height << "_";
result << (double)fpks / 1000 << "fps";
}
return result.str();
return result;
}
///\brief Returns a writable identifier for a track, to prevent overwrites on readout
std::string readOnlyTrack::getWritableIdentifier() {
std::stringstream result;
result << getIdentifier() << "_" << trackID;
return result.str();
unsigned int Track::timeToFragnum(unsigned int timestamp){
unsigned long long int totalTime = firstms;
for (unsigned int i = 0; i<fragments.size(); i++){
if (timestamp <= totalTime){
return i;
}
totalTime += fragments[i].getDuration();
}
return fragments.size()-1;
}
///\brief Resets a track, clears all meta values
@ -1262,92 +1159,6 @@ namespace DTSC {
lastms = 0;
}
///\brief Creates an empty read-only meta object
readOnlyMeta::readOnlyMeta() {
vod = false;
live = false;
merged = false;
moreheader = 0;
merged = false;
bufferWindow = 0;
}
///\brief Creates a read-only meta object from a given JSON::Value
readOnlyMeta::readOnlyMeta(JSON::Value & meta) {
vod = meta.isMember("vod") && meta["vod"];
live = meta.isMember("live") && meta["live"];
merged = meta.isMember("merged") && meta["merged"];
bufferWindow = 0;
if (meta.isMember("buffer_window")) {
bufferWindow = meta["buffer_window"].asInt();
}
for (JSON::ObjIter it = meta["tracks"].ObjBegin(); it != meta["tracks"].ObjEnd(); it++) {
if (it->second.isMember("trackid") && it->second["trackid"]) {
tracks[it->second["trackid"].asInt()] = readOnlyTrack(it->second);
}
}
if (meta.isMember("moreheader")) {
moreheader = meta["moreheader"].asInt();
} else {
moreheader = 0;
}
}
///\brief Converts a read-only track to a human readable string
///\param str The stringstream to append to
///\param indent the amount of indentation needed
///\param verbosity How verbose the output needs to be
void readOnlyTrack::toPrettyString(std::ostream & str, int indent, int verbosity) {
str << std::string(indent, ' ') << "Track " << getWritableIdentifier() << std::endl;
str << std::string(indent + 2, ' ') << "ID: " << trackID << std::endl;
str << std::string(indent + 2, ' ') << "Firstms: " << firstms << std::endl;
str << std::string(indent + 2, ' ') << "Lastms: " << lastms << std::endl;
str << std::string(indent + 2, ' ') << "Bps: " << bps << std::endl;
if (missedFrags) {
str << std::string(indent + 2, ' ') << "missedFrags: " << missedFrags << std::endl;
}
str << std::string(indent + 2, ' ') << "Codec: " << codec << std::endl;
str << std::string(indent + 2, ' ') << "Type: " << type << std::endl;
str << std::string(indent + 2, ' ') << "Init: ";
for (unsigned int i = 0; i < init.size(); ++i) {
str << std::hex << std::setw(2) << std::setfill('0') << (int)init[i];
}
str << std::dec << std::endl;
if (type == "audio") {
str << std::string(indent + 2, ' ') << "Rate: " << rate << std::endl;
str << std::string(indent + 2, ' ') << "Size: " << size << std::endl;
str << std::string(indent + 2, ' ') << "Channel: " << channels << std::endl;
} else if (type == "video") {
str << std::string(indent + 2, ' ') << "Width: " << width << std::endl;
str << std::string(indent + 2, ' ') << "Height: " << height << std::endl;
str << std::string(indent + 2, ' ') << "Fpks: " << fpks << std::endl;
}
str << std::string(indent + 2, ' ') << "Fragments: " << fragLen << std::endl;
if (fragments && verbosity & 0x01) {
for (unsigned int i = 0; i < fragLen; i++) {
fragments[i].toPrettyString(str, indent + 4);
}
}
str << std::string(indent + 2, ' ') << "Keys: " << keyLen << std::endl;
if (keys && verbosity & 0x02) {
for (unsigned int i = 0; i < keyLen; i++) {
keys[i].toPrettyString(str, indent + 4);
}
}
str << std::string(indent + 2, ' ') << "KeySizes: " << keySizes.size() << std::endl;
if (keySizes.size() && verbosity & 0x02){
for (unsigned int i = 0; i < keySizes.size(); i++){
str << std::string(indent + 4, ' ') << "[" << i << "] " << keySizes[i] << std::endl;
}
}
str << std::string(indent + 2, ' ') << "Parts: " << partLen << std::endl;
if (parts && verbosity & 0x04) {
for (unsigned int i = 0; i < partLen; i++) {
parts[i].toPrettyString(str, indent + 4);
}
}
}
///\brief Creates an empty meta object
Meta::Meta() {
vod = false;
@ -1357,18 +1168,6 @@ namespace DTSC {
bufferWindow = 0;
}
///\brief Creates a meta object from a read-only meta object
Meta::Meta(const readOnlyMeta & rhs) {
vod = rhs.vod;
live = rhs.live;
merged = rhs.merged;
bufferWindow = rhs.bufferWindow;
for (std::map<unsigned int, readOnlyTrack>::const_iterator it = rhs.tracks.begin(); it != rhs.tracks.end(); it++) {
tracks[it->first] = it->second;
}
moreheader = rhs.moreheader;
}
Meta::Meta(const DTSC::Packet & source) {
reinit(source);
}
@ -1541,24 +1340,31 @@ namespace DTSC {
return result;
}
///\brief Determines the "packed" size of a read-only track
int readOnlyTrack::getSendLen() {
int result = 146 + init.size() + codec.size() + type.size() + getWritableIdentifier().size();
result += fragLen * 11;
result += keyLen * 16;
if (keySizes.size()){
result += 11 + (keySizes.size() * 4) + 4;
///\brief Returns a unique identifier for a track
std::string Track::getIdentifier() {
std::stringstream result;
if (type == "") {
result << "metadata_" << trackID;
return result.str();
}
result += partLen * 9;
result << type << "_";
result << codec << "_";
if (type == "audio") {
result += 49;
result << channels << "ch_";
result << rate << "hz";
} else if (type == "video") {
result += 48;
result << width << "x" << height << "_";
result << (double)fpks / 1000 << "fps";
}
if (missedFrags) {
result += 23;
}
return result;
return result.str();
}
///\brief Returns a writable identifier for a track, to prevent overwrites on readout
std::string Track::getWritableIdentifier() {
std::stringstream result;
result << getIdentifier() << "_" << trackID;
return result.str();
}
///\brief Determines the "packed" size of a track
@ -1596,135 +1402,6 @@ namespace DTSC {
writePointer(p, src.data(), src.size());
}
///\brief Writes a read-only track to a pointer
void readOnlyTrack::writeTo(char *& p) {
std::string iden = getWritableIdentifier();
writePointer(p, convertShort(iden.size()), 2);
writePointer(p, iden);
writePointer(p, "\340", 1);//Begin track object
writePointer(p, "\000\011fragments\002", 12);
writePointer(p, convertInt(fragLen * 11), 4);
writePointer(p, (char *)fragments, fragLen * 11);
writePointer(p, "\000\004keys\002", 7);
writePointer(p, convertInt(keyLen * 16), 4);
writePointer(p, (char *)keys, keyLen * 16);
writePointer(p, "\000\010keysizes\002,", 11);
writePointer(p, convertInt(keySizes.size() * 4), 4);
std::string tmp;
tmp.reserve(keySizes.size() * 4);
for (unsigned int i = 0; i < keySizes.size(); i++){
tmp += ((char)keySizes[i] >> 24);
tmp += ((char)keySizes[i] >> 16);
tmp += ((char)keySizes[i] >> 8);
tmp += ((char)keySizes[i]);
}
writePointer(p, tmp.data(), tmp.size());
writePointer(p, "\000\005parts\002", 8);
writePointer(p, convertInt(partLen * 9), 4);
writePointer(p, (char *)parts, partLen * 9);
writePointer(p, "\000\007trackid\001", 10);
writePointer(p, convertLongLong(trackID), 8);
if (missedFrags) {
writePointer(p, "\000\014missed_frags\001", 15);
writePointer(p, convertLongLong(missedFrags), 8);
}
writePointer(p, "\000\007firstms\001", 10);
writePointer(p, convertLongLong(firstms), 8);
writePointer(p, "\000\006lastms\001", 9);
writePointer(p, convertLongLong(lastms), 8);
writePointer(p, "\000\003bps\001", 6);
writePointer(p, convertLongLong(bps), 8);
writePointer(p, "\000\004init\002", 7);
writePointer(p, convertInt(init.size()), 4);
writePointer(p, init);
writePointer(p, "\000\005codec\002", 8);
writePointer(p, convertInt(codec.size()), 4);
writePointer(p, codec);
writePointer(p, "\000\004type\002", 7);
writePointer(p, convertInt(type.size()), 4);
writePointer(p, type);
if (type == "audio") {
writePointer(p, "\000\004rate\001", 7);
writePointer(p, convertLongLong(rate), 8);
writePointer(p, "\000\004size\001", 7);
writePointer(p, convertLongLong(size), 8);
writePointer(p, "\000\010channels\001", 11);
writePointer(p, convertLongLong(channels), 8);
} else if (type == "video") {
writePointer(p, "\000\005width\001", 8);
writePointer(p, convertLongLong(width), 8);
writePointer(p, "\000\006height\001", 9);
writePointer(p, convertLongLong(height), 8);
writePointer(p, "\000\004fpks\001", 7);
writePointer(p, convertLongLong(fpks), 8);
}
writePointer(p, "\000\000\356", 3);//End this track Object
}
///\brief Writes a read-only track to a socket
void readOnlyTrack::send(Socket::Connection & conn) {
conn.SendNow(convertShort(getWritableIdentifier().size()), 2);
conn.SendNow(getWritableIdentifier());
conn.SendNow("\340", 1);//Begin track object
conn.SendNow("\000\011fragments\002", 12);
conn.SendNow(convertInt(fragLen * 11), 4);
conn.SendNow((char *)fragments, fragLen * 11);
conn.SendNow("\000\004keys\002", 7);
conn.SendNow(convertInt(keyLen * 16), 4);
conn.SendNow((char *)keys, keyLen * 16);
conn.SendNow("\000\010keysizes\002,", 11);
conn.SendNow(convertInt(keySizes.size() * 4), 4);
std::string tmp;
tmp.reserve(keySizes.size() * 4);
for (unsigned int i = 0; i < keySizes.size(); i++){
tmp += ((char)keySizes[i] >> 24);
tmp += ((char)keySizes[i] >> 16);
tmp += ((char)keySizes[i] >> 8);
tmp += ((char)keySizes[i]);
}
conn.SendNow(tmp.data(), tmp.size());
conn.SendNow("\000\005parts\002", 8);
conn.SendNow(convertInt(partLen * 9), 4);
conn.SendNow((char *)parts, partLen * 9);
conn.SendNow("\000\007trackid\001", 10);
conn.SendNow(convertLongLong(trackID), 8);
if (missedFrags) {
conn.SendNow("\000\014missed_frags\001", 15);
conn.SendNow(convertLongLong(missedFrags), 8);
}
conn.SendNow("\000\007firstms\001", 10);
conn.SendNow(convertLongLong(firstms), 8);
conn.SendNow("\000\006lastms\001", 9);
conn.SendNow(convertLongLong(lastms), 8);
conn.SendNow("\000\003bps\001", 6);
conn.SendNow(convertLongLong(bps), 8);
conn.SendNow("\000\004init\002", 7);
conn.SendNow(convertInt(init.size()), 4);
conn.SendNow(init);
conn.SendNow("\000\005codec\002", 8);
conn.SendNow(convertInt(codec.size()), 4);
conn.SendNow(codec);
conn.SendNow("\000\004type\002", 7);
conn.SendNow(convertInt(type.size()), 4);
conn.SendNow(type);
if (type == "audio") {
conn.SendNow("\000\004rate\001", 7);
conn.SendNow(convertLongLong(rate), 8);
conn.SendNow("\000\004size\001", 7);
conn.SendNow(convertLongLong(size), 8);
conn.SendNow("\000\010channels\001", 11);
conn.SendNow(convertLongLong(channels), 8);
} else if (type == "video") {
conn.SendNow("\000\005width\001", 8);
conn.SendNow(convertLongLong(width), 8);
conn.SendNow("\000\006height\001", 9);
conn.SendNow(convertLongLong(height), 8);
conn.SendNow("\000\004fpks\001", 7);
conn.SendNow(convertLongLong(fpks), 8);
}
conn.SendNow("\000\000\356", 3);//End this track Object
}
///\brief Writes a track to a pointer
void Track::writeTo(char *& p) {
writePointer(p, convertShort(getWritableIdentifier().size()), 2);
@ -1865,77 +1542,6 @@ namespace DTSC {
conn.SendNow("\000\000\356", 3);//End this track Object
}
///\brief Determines the "packed" size of a read-only meta object
unsigned int readOnlyMeta::getSendLen() {
unsigned int dataLen = 16 + (vod ? 14 : 0) + (live ? 15 : 0) + (merged ? 17 : 0) + (bufferWindow ? 24 : 0) + 21;
for (std::map<unsigned int, readOnlyTrack>::iterator it = tracks.begin(); it != tracks.end(); it++) {
dataLen += it->second.getSendLen();
}
return dataLen + 8; //add 8 bytes header length
}
///\brief Writes a read-only meta object to a pointer
void readOnlyMeta::writeTo(char * p) {
int dataLen = getSendLen() - 8;//strip 8 bytes header
writePointer(p, DTSC::Magic_Header, 4);
writePointer(p, convertInt(dataLen), 4);
writePointer(p, "\340\000\006tracks\340", 10);
for (std::map<unsigned int, readOnlyTrack>::iterator it = tracks.begin(); it != tracks.end(); it++) {
it->second.writeTo(p);
}
writePointer(p, "\000\000\356", 3);
if (vod) {
writePointer(p, "\000\003vod\001", 6);
writePointer(p, convertLongLong(1), 8);
}
if (live) {
writePointer(p, "\000\004live\001", 7);
writePointer(p, convertLongLong(1), 8);
}
if (merged) {
writePointer(p, "\000\006merged\001", 9);
writePointer(p, convertLongLong(1), 8);
}
if (bufferWindow) {
writePointer(p, "\000\015buffer_window\001", 16);
writePointer(p, convertLongLong(bufferWindow), 8);
}
writePointer(p, "\000\012moreheader\001", 13);
writePointer(p, convertLongLong(moreheader), 8);
writePointer(p, "\000\000\356", 3);//End global object
}
///\brief Writes a read-only meta object to a socket
void readOnlyMeta::send(Socket::Connection & conn) {
int dataLen = getSendLen() - 8; //strip 8 bytes header
conn.SendNow(DTSC::Magic_Header, 4);
conn.SendNow(convertInt(dataLen), 4);
conn.SendNow("\340\000\006tracks\340", 10);
for (std::map<unsigned int, readOnlyTrack>::iterator it = tracks.begin(); it != tracks.end(); it++) {
it->second.send(conn);
}
conn.SendNow("\000\000\356", 3);
if (vod) {
conn.SendNow("\000\003vod\001", 6);
conn.SendNow(convertLongLong(1), 8);
}
if (live) {
conn.SendNow("\000\004live\001", 7);
conn.SendNow(convertLongLong(1), 8);
}
if (merged) {
conn.SendNow("\000\006merged\001", 9);
conn.SendNow(convertLongLong(1), 8);
}
if (bufferWindow) {
conn.SendNow("\000\015buffer_window\001", 16);
conn.SendNow(convertLongLong(bufferWindow), 8);
}
conn.SendNow("\000\012moreheader\001", 13);
conn.SendNow(convertLongLong(moreheader), 8);
conn.SendNow("\000\000\356", 3);//End global object
}
///\brief Determines the "packed" size of a meta object
unsigned int Meta::getSendLen() {
unsigned int dataLen = 16 + (vod ? 14 : 0) + (live ? 15 : 0) + (merged ? 17 : 0) + (bufferWindow ? 24 : 0) + 21;
@ -2007,51 +1613,6 @@ namespace DTSC {
conn.SendNow("\000\000\356", 3);//End global object
}
///\brief Converts a read-only track to a JSON::Value
JSON::Value readOnlyTrack::toJSON() {
JSON::Value result;
if (fragments) {
result["fragments"] = std::string((char *)fragments, fragLen * 11);
}
if (keys) {
result["keys"] = std::string((char *)keys, keyLen * 16);
}
if (keySizes.size()){
std::string tmp;
tmp.reserve(keySizes.size() * 4);
for (unsigned int i = 0; i < keySizes.size(); i++){
tmp += ((char)(keySizes[i] >> 24));
tmp += ((char)(keySizes[i] >> 16));
tmp += ((char)(keySizes[i] >> 8));
tmp += ((char)keySizes[i]);
}
result["keysizes"] = tmp;
}
if (parts) {
result["parts"] = std::string((char *)parts, partLen * 9);
}
result["trackid"] = trackID;
result["firstms"] = (long long)firstms;
result["lastms"] = (long long)lastms;
result["bps"] = bps;
if (missedFrags) {
result["missed_frags"] = missedFrags;
}
result["codec"] = codec;
result["type"] = type;
result["init"] = init;
if (type == "audio") {
result["rate"] = rate;
result["size"] = size;
result["channels"] = channels;
} else if (type == "video") {
result["width"] = width;
result["height"] = height;
result["fpks"] = fpks;
}
return result;
}
///\brief Converts a track to a JSON::Value
JSON::Value Track::toJSON() {
JSON::Value result;
@ -2126,29 +1687,6 @@ namespace DTSC {
return result;
}
///\brief Converts a read-only meta object to a human readable string
///\param str The stringstream to append to
///\param indent the amount of indentation needed
///\param verbosity How verbose the output needs to be
void readOnlyMeta::toPrettyString(std::ostream & str, int indent, int verbosity) {
for (std::map<unsigned int, readOnlyTrack>::iterator it = tracks.begin(); it != tracks.end(); it++) {
it->second.toPrettyString(str, indent, verbosity);
}
if (vod) {
str << std::string(indent, ' ') << "Video on Demand" << std::endl;
}
if (live) {
str << std::string(indent, ' ') << "Live" << std::endl;
}
if (merged) {
str << std::string(indent, ' ') << "Merged file" << std::endl;
}
if (bufferWindow) {
str << std::string(indent, ' ') << "Buffer Window: " << bufferWindow << std::endl;
}
str << std::string(indent, ' ') << "More Header: " << moreheader << std::endl;
}
///\brief Converts a meta object to a human readable string
///\param str The stringstream to append to
///\param indent the amount of indentation needed
@ -2172,57 +1710,12 @@ namespace DTSC {
str << std::string(indent, ' ') << "More Header: " << moreheader << std::endl;
}
///\brief Converts a read-only meta object to a JSON::Value
JSON::Value readOnlyMeta::toJSON() {
JSON::Value result;
for (std::map<unsigned int, readOnlyTrack>::iterator it = tracks.begin(); it != tracks.end(); it++) {
result["tracks"][it->second.getWritableIdentifier()] = it->second.toJSON();
}
if (vod) {
result["vod"] = 1ll;
}
if (live) {
result["live"] = 1ll;
}
if (merged) {
result["merged"] = 1ll;
}
result["moreheader"] = moreheader;
if (bufferWindow) {
result["buffer_window"] = bufferWindow;
}
return result;
}
///\brief Resets a meta object, removes all unimportant meta values
void Meta::reset() {
for (std::map<unsigned int, Track>::iterator it = tracks.begin(); it != tracks.end(); it++) {
it->second.reset();
}
}
///\brief Returns whether a read-only meta object is fixed or not
bool readOnlyMeta::isFixed() {
for (std::map<unsigned int, readOnlyTrack>::iterator it = tracks.begin(); it != tracks.end(); it++) {
if (!it->second.keyLen || !(it->second.keys[it->second.keyLen - 1].getBpos())) {
return false;
}
}
return true;
}
///\brief Returns whether a meta object is fixed or not
bool Meta::isFixed() {
for (std::map<unsigned int, Track>::iterator it = tracks.begin(); it != tracks.end(); it++) {
if (it->second.type == "meta" || it->second.type == "") {
continue;
}
if (!it->second.keys.size() || !(it->second.keys.rbegin()->getBpos())) {
return false;
}
}
return true;
}
}