From 22295d3b5d59e70ee36de3ddfa8ce0bbe39d40e4 Mon Sep 17 00:00:00 2001 From: Erik Zandvliet Date: Fri, 17 May 2013 15:15:52 +0200 Subject: [PATCH] Progress on HTTP Smooth output for DTSCv2 --- lib/dtsc.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++---------- lib/dtsc.h | 5 ++-- lib/json.cpp | 31 ++++++++++++++--------- 3 files changed, 78 insertions(+), 27 deletions(-) diff --git a/lib/dtsc.cpp b/lib/dtsc.cpp index 15e07e20..18cc9369 100644 --- a/lib/dtsc.cpp +++ b/lib/dtsc.cpp @@ -62,6 +62,12 @@ bool DTSC::Stream::parsePacket(std::string & buffer){ metadata = JSON::fromDTMI2(buffer.substr(8)); } metadata.removeMember("moreheader"); + trackMapping.clear(); + if (metadata.isMember("tracks")){ + for (JSON::ObjIter it = metadata["tracks"].ObjBegin(); it != metadata["tracks"].ObjEnd(); it++){ + trackMapping.insert(std::pair(it->second["trackid"].asInt(),it->first)); + } + } buffer.erase(0, len + 8); if (buffer.length() <= 8){ return false; @@ -79,6 +85,9 @@ bool DTSC::Stream::parsePacket(std::string & buffer){ } if (version == 2){ buffers.front() = JSON::fromDTMI2(buffer.substr(8)); + if (!buffers.front().isMember("datatype")){ + buffers.front()["datatype"] = metadata["tracks"][trackMapping[buffers.front()["trackid"].asInt()]]["type"]; + } } datapointertype = INVALID; if (buffers.front().isMember("data")){ @@ -149,6 +158,12 @@ bool DTSC::Stream::parsePacket(Socket::Buffer & buffer){ metadata = JSON::fromDTMI((unsigned char*)wholepacket.c_str() + 8, len, i); metadata.removeMember("moreheader"); metadata.netPrepare(); + trackMapping.clear(); + if (metadata.isMember("tracks")){ + for (JSON::ObjIter it = metadata["tracks"].ObjBegin(); it != metadata["tracks"].ObjEnd(); it++){ + trackMapping.insert(std::pair(it->second["trackid"].asInt(),it->first)); + } + } if ( !buffer.available(8)){ return false; } @@ -174,6 +189,9 @@ bool DTSC::Stream::parsePacket(Socket::Buffer & buffer){ } if (version == 2){ buffers.front() = JSON::fromDTMI2(wholepacket.substr(8)); + if (!buffers.front().isMember("datatype")){ + buffers.front()["datatype"] = metadata["tracks"][trackMapping[buffers.front()["trackid"].asInt()]]["type"]; + } } datapointertype = INVALID; if (buffers.front().isMember("data")){ @@ -535,6 +553,7 @@ DTSC::File & DTSC::File::operator =(const File & rhs){ currtime = rhs.currtime; lastreadpos = rhs.lastreadpos; headerSize = rhs.headerSize; + trackMapping = rhs.trackMapping; memcpy(buffer, rhs.buffer, 4); } @@ -569,11 +588,14 @@ DTSC::File::File(std::string filename, bool create){ headerSize = ntohl(ubuffer[0]); } readHeader(0); + trackMapping.clear(); + if (metadata.isMember("tracks")){ + for (JSON::ObjIter it = metadata["tracks"].ObjBegin(); it != metadata["tracks"].ObjEnd(); it++){ + trackMapping.insert(std::pair(it->second["trackid"].asInt(),it->first)); + } + } fseek(F, 8 + headerSize, SEEK_SET); currframe = 0; - //currframe = 1; - //frames[1] = 8 + headerSize; - //msframes[1] = 0; } /// Returns the header metadata for this file as JSON::Value. @@ -723,7 +745,7 @@ void DTSC::File::seekNext(){ version = 2; } if (version == 0){ - fprintf(stderr, "Invalid packet header @ %#x - %.4s != %.4s\n", getBytePos(), buffer, DTSC::Magic_Packet2); + fprintf(stderr, "Invalid packet header @ %#x - %.4s != %.4s\n", lastreadpos, buffer, DTSC::Magic_Packet2); strbuffer = ""; jsonbuffer.null(); return; @@ -735,7 +757,7 @@ void DTSC::File::seekNext(){ return; } uint32_t * ubuffer = (uint32_t *)buffer; - long packSize = ntohl(ubuffer[0]) + (version == 2 ? 12 : 0); + long packSize = ntohl(ubuffer[0]); strbuffer.resize(packSize); if (fread((void*)strbuffer.c_str(), packSize, 1, F) != 1){ fprintf(stderr, "Could not read packet\n"); @@ -745,20 +767,25 @@ void DTSC::File::seekNext(){ } if (version == 2){ jsonbuffer = JSON::fromDTMI2(strbuffer); + if (!jsonbuffer.isMember("datatype")){ + jsonbuffer["datatype"] = metadata["tracks"][trackMapping[jsonbuffer["trackid"].asInt()]]["type"]; + } }else{ jsonbuffer = JSON::fromDTMI(strbuffer); } if (jsonbuffer.isMember("keyframe")){ - if (metadata["tracks"][selectedTracks[0]]["keybpos"][currframe].asInt() != lastreadpos){ - currframe++; - currtime = jsonbuffer["time"].asInt(); -#if DEBUG >= 6 + if (selectedTracks.size()){ if (metadata["tracks"][selectedTracks[0]]["keybpos"][currframe].asInt() != lastreadpos){ - std::cerr << "Found a new frame " << currframe << " @ " << lastreadpos << "b/" << currtime << "ms" << std::endl; - } else{ - std::cerr << "Passing frame " << currframe << " @ " << lastreadpos << "b/" << currtime << "ms" << std::endl; - } + currframe++; + currtime = jsonbuffer["time"].asInt(); +#if DEBUG >= 6 + if (metadata["tracks"][selectedTracks[0]]["keybpos"][currframe].asInt() != lastreadpos){ + std::cerr << "Found a new frame " << currframe << " @ " << lastreadpos << "b/" << currtime << "ms" << std::endl; + } else{ + std::cerr << "Passing frame " << currframe << " @ " << lastreadpos << "b/" << currtime << "ms" << std::endl; + } #endif + } } } } @@ -849,6 +876,22 @@ void DTSC::File::selectTracks(std::vector & trackIDs){ selectedTracks = trackIDs; } +bool DTSC::File::atKeyframe(){ + if (getJSON().isMember("keyframe")){ + return true; + } + bool inHeader = false; + for (JSON::ObjIter oIt = metadata["tracks"].ObjBegin(); oIt != metadata["tracks"].ObjEnd(); oIt++){ + for (JSON::ArrIter aIt = oIt->second["keynum"].ArrBegin(); aIt != oIt->second["keynum"].ArrEnd(); aIt++){ + if ((*aIt).asInt() == getBytePos()){ + inHeader = true; + break; + } + } + } + return inHeader; +} + /// Close the file if open DTSC::File::~File(){ if (F){ diff --git a/lib/dtsc.h b/lib/dtsc.h index ce18679e..4f772025 100644 --- a/lib/dtsc.h +++ b/lib/dtsc.h @@ -89,14 +89,14 @@ namespace DTSC { void writePacket(std::string & newPacket); void writePacket(JSON::Value & newPacket); void selectTracks(std::vector & trackIDs); + bool atKeyframe(); private: void readHeader(int pos); std::string strbuffer; JSON::Value jsonbuffer; JSON::Value metadata; JSON::Value firstmetadata; - //std::map frames; - //std::map msframes; + std::map trackMapping; long long int currtime; long long int lastreadpos; int currframe; @@ -157,5 +157,6 @@ namespace DTSC { datatype datapointertype; unsigned int buffercount; unsigned int buffertime; + std::map trackMapping; }; } diff --git a/lib/json.cpp b/lib/json.cpp index 1322c739..d39e2921 100644 --- a/lib/json.cpp +++ b/lib/json.cpp @@ -493,12 +493,15 @@ void JSON::Value::netPrepare(){ if (objVal["datatype"].asString() == "meta"){ packID = 3; } + //endmark and the likes... if (packID == -1){ packID = 0; } } removeMember("time"); - removeMember("datatype"); + if (packID != 0){ + removeMember("datatype"); + } removeMember("trackid"); packed = toPacked(); objVal["time"] = (long long int)time; @@ -512,20 +515,24 @@ void JSON::Value::netPrepare(){ memcpy((void*)strVal.c_str(), "DTSC", 4); } //insert the packet length at bytes 4-7 - unsigned int size = htonl(packed.size()); + unsigned int size = packed.size(); + if (packID != -1){ + size += 12; + } + size = htonl(size); memcpy((void*)(strVal.c_str() + 4), (void*) &size, 4); //copy the rest of the string - if (packID != -1){ - packID = htonl(packID); - memcpy((void*)(strVal.c_str() + 8), (void*) &packID, 4); - int tmpHalf = htonl((int)(time >> 32)); - memcpy((void*)(strVal.c_str() + 12), (void*) &tmpHalf, 4); - tmpHalf = htonl((int)(time & 0xFFFFFFFF)); - memcpy((void*)(strVal.c_str() + 16), (void*) &tmpHalf, 4); - memcpy((void*)(strVal.c_str() + 20), packed.c_str(), packed.size()); - }else{ + if (packID == -1){ memcpy((void*)(strVal.c_str() + 8), packed.c_str(), packed.size()); + return; } + packID = htonl(packID); + memcpy((void*)(strVal.c_str() + 8), (void*) &packID, 4); + int tmpHalf = htonl((int)(time >> 32)); + memcpy((void*)(strVal.c_str() + 12), (void*) &tmpHalf, 4); + tmpHalf = htonl((int)(time & 0xFFFFFFFF)); + memcpy((void*)(strVal.c_str() + 16), (void*) &tmpHalf, 4); + memcpy((void*)(strVal.c_str() + 20), packed.c_str(), packed.size()); } /// Packs any object-type JSON::Value to a std::string for transfer over the network, including proper DTMI header. @@ -869,8 +876,8 @@ JSON::Value JSON::fromDTMI(std::string data){ } //fromDTMI JSON::Value JSON::fromDTMI2(std::string data){ - JSON::Value tmp = fromDTMI(data.substr(12)); long long int tmpTrackID = ntohl(((int*)(data.c_str()))[0]); + JSON::Value tmp = fromDTMI(data.substr(12)); long long int tmpTime = ntohl(((int*)(data.c_str() + 4))[0]); tmpTime << 32; tmpTime += ntohl(((int*)(data.c_str() + 8))[0]);