Added skipDynamic optional argument to most binary representations of metadata/tracks, which skips sending dynamic parts of the metadata if true.

This commit is contained in:
Thulinma 2016-02-15 11:48:45 +01:00
parent 10af060ab4
commit 668560ff05
11 changed files with 344 additions and 111 deletions

View file

@ -9,6 +9,7 @@
char DTSC::Magic_Header[] = "DTSC";
char DTSC::Magic_Packet[] = "DTPD";
char DTSC::Magic_Packet2[] = "DTP2";
char DTSC::Magic_Command[] = "DTCM";
DTSC::File::File() {
F = 0;
@ -32,8 +33,7 @@ DTSC::File & DTSC::File::operator =(const File & rhs) {
if (rhs.myPack) {
myPack = rhs.myPack;
}
metaStorage = rhs.metaStorage;
metadata = metaStorage;
metadata = rhs.metadata;
currtime = rhs.currtime;
lastreadpos = rhs.lastreadpos;
headerSize = rhs.headerSize;
@ -67,7 +67,7 @@ DTSC::File::File(std::string filename, bool create) {
}
created = create;
if (!F) {
DEBUG_MSG(DLVL_ERROR, "Could not open file %s", filename.c_str());
HIGH_MSG("Could not open file %s", filename.c_str());
return;
}
fseek(F, 0, SEEK_END);
@ -83,7 +83,7 @@ DTSC::File::File(std::string filename, bool create) {
return;
}
if (memcmp(buffer, DTSC::Magic_Header, 4) != 0) {
if (memcmp(buffer, DTSC::Magic_Packet2, 4) != 0 && memcmp(buffer, DTSC::Magic_Packet, 4) != 0) {
if (memcmp(buffer, DTSC::Magic_Packet2, 4) != 0 && memcmp(buffer, DTSC::Magic_Packet, 4) != 0 && memcmp(buffer, DTSC::Magic_Command, 4) != 0) {
DEBUG_MSG(DLVL_ERROR, "%s is not a valid DTSC file", filename.c_str());
fclose(F);
F = 0;
@ -113,8 +113,7 @@ DTSC::File::File(std::string filename, bool create) {
fseek(F, 0, SEEK_SET);
File Fhead(filename + ".dtsh");
if (Fhead) {
metaStorage = Fhead.metaStorage;
metadata = metaStorage;
metadata = Fhead.metadata;
}
}
currframe = 0;
@ -346,8 +345,9 @@ void DTSC::File::seekNext() {
}
void DTSC::File::parseNext(){
char header_buffer[4] = {0, 0, 0, 0};
lastreadpos = ftell(F);
if (fread(buffer, 4, 1, F) != 1) {
if (fread(header_buffer, 4, 1, F) != 1) {
if (feof(F)) {
DEBUG_MSG(DLVL_DEVEL, "End of file reached @ %d", (int)lastreadpos);
} else {
@ -356,55 +356,26 @@ void DTSC::File::parseNext(){
myPack.null();
return;
}
if (memcmp(buffer, DTSC::Magic_Header, 4) == 0) {
if (lastreadpos != 0) {
readHeader(lastreadpos);
std::string tmp = metaStorage.toNetPacked();
myPack.reInit(tmp.data(), tmp.size());
DEBUG_MSG(DLVL_DEVEL, "Read another header");
} else {
if (fread(buffer, 4, 1, F) != 1) {
DEBUG_MSG(DLVL_ERROR, "Could not read header size @ %d", (int)lastreadpos);
myPack.null();
return;
}
long packSize = ntohl(((unsigned long *)buffer)[0]);
std::string strBuffer = "DTSC";
strBuffer.append((char *)buffer, 4);
strBuffer.resize(packSize + 8);
if (fread((void *)(strBuffer.c_str() + 8), packSize, 1, F) != 1) {
DEBUG_MSG(DLVL_ERROR, "Could not read header @ %d", (int)lastreadpos);
myPack.null();
return;
}
myPack.reInit(strBuffer.data(), strBuffer.size());
}
return;
}
long long unsigned int version = 0;
if (memcmp(buffer, DTSC::Magic_Packet, 4) == 0) {
if (memcmp(header_buffer, DTSC::Magic_Packet, 4) == 0 || memcmp(header_buffer, DTSC::Magic_Command, 4) == 0 || memcmp(header_buffer, DTSC::Magic_Header, 4) == 0) {
version = 1;
}
if (memcmp(buffer, DTSC::Magic_Packet2, 4) == 0) {
if (memcmp(header_buffer, DTSC::Magic_Packet2, 4) == 0) {
version = 2;
}
if (version == 0) {
DEBUG_MSG(DLVL_ERROR, "Invalid packet header @ %#x - %.4s != %.4s @ %d", (unsigned int)lastreadpos, (char *)buffer, DTSC::Magic_Packet2, (int)lastreadpos);
DEBUG_MSG(DLVL_ERROR, "Invalid packet header @ %#x: %.4s", (unsigned int)lastreadpos, (char *)buffer);
myPack.null();
return;
}
if (fread(buffer, 4, 1, F) != 1) {
DEBUG_MSG(DLVL_ERROR, "Could not read packet size @ %d", (int)lastreadpos);
DEBUG_MSG(DLVL_ERROR, "Could not read packet size @ %#x", (unsigned int)lastreadpos);
myPack.null();
return;
}
long packSize = ntohl(((unsigned long *)buffer)[0]);
char * packBuffer = (char *)malloc(packSize + 8);
if (version == 1) {
memcpy(packBuffer, "DTPD", 4);
} else {
memcpy(packBuffer, "DTP2", 4);
}
memcpy(packBuffer, header_buffer, 4);
memcpy(packBuffer + 4, buffer, 4);
if (fread((void *)(packBuffer + 8), packSize, 1, F) != 1) {
DEBUG_MSG(DLVL_ERROR, "Could not read packet @ %d", (int)lastreadpos);

View file

@ -34,6 +34,7 @@ namespace DTSC {
extern char Magic_Header[]; ///< The magic bytes for a DTSC header
extern char Magic_Packet[]; ///< The magic bytes for a DTSC packet
extern char Magic_Packet2[]; ///< The magic bytes for a DTSC packet version 2
extern char Magic_Command[]; ///< The magic bytes for a DTCM packet
///\brief A simple structure used for ordering byte seek positions.
struct seekPos {
@ -61,7 +62,8 @@ namespace DTSC {
DTSC_INVALID,
DTSC_HEAD,
DTSC_V1,
DTSC_V2
DTSC_V2,
DTCM
};
/// This class allows scanning through raw binary format DTSC data.
@ -295,10 +297,10 @@ namespace DTSC {
void update(long long packTime, long long packOffset, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 5000);
*/
void update(long long packTime, long long packOffset, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 5000, const char * iVec = 0);
int getSendLen();
void send(Socket::Connection & conn);
int getSendLen(bool skipDynamic = false);
void send(Socket::Connection & conn, bool skipDynamic = false);
void writeTo(char *& p);
JSON::Value toJSON(bool skipBinary = false);
JSON::Value toJSON(bool skipDynamic = false);
std::deque<Fragment> fragments;
std::deque<Key> keys;
std::deque<unsigned long> keySizes;
@ -352,8 +354,8 @@ namespace DTSC {
void update(long long packTime, long long packOffset, long long packTrack, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize = 0, unsigned long segment_size = 5000);
LTS*/
void update(long long packTime, long long packOffset, long long packTrack, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize = 0, unsigned long segment_size = 5000, const char * iVec = 0);
unsigned int getSendLen();
void send(Socket::Connection & conn);
unsigned int getSendLen(bool skipDynamic = false);
void send(Socket::Connection & conn, bool skipDynamic = false);
void writeTo(char * p);
JSON::Value toJSON();
void reset();
@ -398,7 +400,6 @@ namespace DTSC {
long int endPos;
void readHeader(int pos);
DTSC::Packet myPack;
JSON::Value metaStorage;
Meta metadata;
std::map<unsigned int, std::string> trackMapping;
long long int currtime;

View file

@ -159,8 +159,12 @@ namespace DTSC {
if (!memcmp(data, Magic_Header, 4)) {
version = DTSC_HEAD;
} else {
DEBUG_MSG(DLVL_FAIL, "ReInit received a packet with invalid header");
return;
if (!memcmp(data, Magic_Command, 4)) {
version = DTCM;
} else {
DEBUG_MSG(DLVL_FAIL, "ReInit received a packet with invalid header");
return;
}
}
}
}
@ -1510,15 +1514,17 @@ namespace DTSC {
}
///\brief Determines the "packed" size of a track
int Track::getSendLen() {
int result = 146 + init.size() + codec.size() + type.size() + getWritableIdentifier().size();
result += fragments.size() * PACKED_FRAGMENT_SIZE;
result += keys.size() * PACKED_KEY_SIZE;
if (keySizes.size()){
result += 11 + (keySizes.size() * 4) + 4;
int Track::getSendLen(bool skipDynamic) {
int result = 107 + init.size() + codec.size() + type.size() + getWritableIdentifier().size();
if (!skipDynamic){
result += fragments.size() * PACKED_FRAGMENT_SIZE + 16;
result += keys.size() * PACKED_KEY_SIZE + 11;
if (keySizes.size()){
result += (keySizes.size() * 4) + 15;
}
result += parts.size() * 9 + 12;
result += (ivecs.size() * 8) + 12; /*LTS*/
}
result += parts.size() * 9;
result += (ivecs.size() * 8) + 12; /*LTS*/
if (type == "audio") {
result += 49;
} else if (type == "video") {
@ -1624,46 +1630,48 @@ namespace DTSC {
}
///\brief Writes a track to a socket
void Track::send(Socket::Connection & conn) {
void Track::send(Socket::Connection & conn, bool skipDynamic) {
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(fragments.size() * PACKED_FRAGMENT_SIZE), 4);
for (std::deque<Fragment>::iterator it = fragments.begin(); it != fragments.end(); it++) {
conn.SendNow(it->getData(), PACKED_FRAGMENT_SIZE);
if (!skipDynamic){
conn.SendNow("\000\011fragments\002", 12);
conn.SendNow(convertInt(fragments.size() * PACKED_FRAGMENT_SIZE), 4);
for (std::deque<Fragment>::iterator it = fragments.begin(); it != fragments.end(); it++) {
conn.SendNow(it->getData(), PACKED_FRAGMENT_SIZE);
}
conn.SendNow("\000\004keys\002", 7);
conn.SendNow(convertInt(keys.size() * PACKED_KEY_SIZE), 4);
for (std::deque<Key>::iterator it = keys.begin(); it != keys.end(); it++) {
conn.SendNow(it->getData(), PACKED_KEY_SIZE);
}
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(parts.size() * 9), 4);
for (std::deque<Part>::iterator it = parts.begin(); it != parts.end(); it++) {
conn.SendNow(it->getData(), 9);
}
/*LTS-START*/
conn.SendNow("\000\005ivecs\002", 8);
conn.SendNow(convertInt(ivecs.size() * 8), 4);
for (std::deque<Ivec>::iterator it = ivecs.begin(); it != ivecs.end(); it++) {
conn.SendNow(it->getData(), 8);
}
/*LTS-END*/
}
conn.SendNow("\000\004keys\002", 7);
conn.SendNow(convertInt(keys.size() * PACKED_KEY_SIZE), 4);
for (std::deque<Key>::iterator it = keys.begin(); it != keys.end(); it++) {
conn.SendNow(it->getData(), PACKED_KEY_SIZE);
}
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(parts.size() * 9), 4);
for (std::deque<Part>::iterator it = parts.begin(); it != parts.end(); it++) {
conn.SendNow(it->getData(), 9);
}
/*LTS-START*/
conn.SendNow("\000\005ivecs\002", 8);
conn.SendNow(convertInt(ivecs.size() * 8), 4);
for (std::deque<Ivec>::iterator it = ivecs.begin(); it != ivecs.end(); it++) {
conn.SendNow(it->getData(), 8);
}
/*LTS-END*/
conn.SendNow("\000\007trackid\001", 10);
conn.SendNow(convertLongLong(trackID), 8);
if (missedFrags) {
if (!skipDynamic && missedFrags) {
conn.SendNow("\000\014missed_frags\001", 15);
conn.SendNow(convertLongLong(missedFrags), 8);
}
@ -1701,10 +1709,10 @@ namespace DTSC {
}
///\brief Determines the "packed" size of a meta object
unsigned int Meta::getSendLen() {
unsigned int Meta::getSendLen(bool skipDynamic) {
unsigned int dataLen = 16 + (vod ? 14 : 0) + (live ? 15 : 0) + (merged ? 17 : 0) + (bufferWindow ? 24 : 0) + 21;
for (std::map<unsigned int, Track>::iterator it = tracks.begin(); it != tracks.end(); it++) {
dataLen += it->second.getSendLen();
dataLen += it->second.getSendLen(skipDynamic);
}
return dataLen + 8; //add 8 bytes header
}
@ -1741,13 +1749,13 @@ namespace DTSC {
}
///\brief Writes a meta object to a socket
void Meta::send(Socket::Connection & conn) {
int dataLen = getSendLen() - 8; //strip 8 bytes header
void Meta::send(Socket::Connection & conn, bool skipDynamic) {
int dataLen = getSendLen(skipDynamic) - 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, Track>::iterator it = tracks.begin(); it != tracks.end(); it++) {
it->second.send(conn);
it->second.send(conn, skipDynamic);
}
conn.SendNow("\000\000\356", 3);//End tracks object
if (vod) {
@ -1772,10 +1780,10 @@ namespace DTSC {
}
///\brief Converts a track to a JSON::Value
JSON::Value Track::toJSON(bool skipBinary) {
JSON::Value Track::toJSON(bool skipDynamic) {
JSON::Value result;
std::string tmp;
if (!skipBinary) {
if (!skipDynamic) {
tmp.reserve(fragments.size() * PACKED_FRAGMENT_SIZE);
for (std::deque<Fragment>::iterator it = fragments.begin(); it != fragments.end(); it++) {
tmp.append(it->getData(), PACKED_FRAGMENT_SIZE);
@ -1810,8 +1818,8 @@ namespace DTSC {
}
result["ivecs"] = tmp;
/*LTS-END*/
result["init"] = init;
}
result["init"] = init;
result["trackid"] = trackID;
result["firstms"] = (long long)firstms;
result["lastms"] = (long long)lastms;