diff --git a/lib/dtsc.cpp b/lib/dtsc.cpp index 68d0144d..e0bbcd4d 100644 --- a/lib/dtsc.cpp +++ b/lib/dtsc.cpp @@ -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; -} diff --git a/lib/dtsc.h b/lib/dtsc.h index 92501c49..1395386f 100644 --- a/lib/dtsc.h +++ b/lib/dtsc.h @@ -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 fragments; + std::deque keys; + std::deque keySizes; + std::deque 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 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 fragments; - std::deque keys; - std::deque keySizes; - std::deque 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 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 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 trackMapping; long long int currtime; long long int lastreadpos; diff --git a/lib/dtscmeta.cpp b/lib/dtscmeta.cpp index cfbc35fc..9a69ddd8 100644 --- a/lib/dtscmeta.cpp +++ b/lib/dtscmeta.cpp @@ -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(rhs.fragments, rhs.fragments + rhs.fragLen); - } - if (rhs.keys && rhs.keyLen) { - keys = std::deque(rhs.keys, rhs.keys + rhs.keyLen); - } - if (rhs.parts && rhs.partLen) { - parts = std::deque(rhs.parts, rhs.parts + rhs.partLen); - } - for(std::vector::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::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; isecond.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::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::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::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::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::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::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::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::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::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; - } }