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:
parent
10af060ab4
commit
668560ff05
11 changed files with 344 additions and 111 deletions
53
lib/dtsc.cpp
53
lib/dtsc.cpp
|
@ -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);
|
||||
|
|
15
lib/dtsc.h
15
lib/dtsc.h
|
@ -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;
|
||||
|
|
112
lib/dtscmeta.cpp
112
lib/dtscmeta.cpp
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue