From 6e95dbe10bd9238fe20efd6b92a0cf873bbff1c4 Mon Sep 17 00:00:00 2001 From: Erik Zandvliet Date: Wed, 22 May 2013 15:48:26 +0200 Subject: [PATCH] Multiple updates for DTSCv2 Filtering. --- lib/dtsc.cpp | 104 +++++++++++++++++++++++---------------------------- lib/dtsc.h | 30 +++++++++++++-- 2 files changed, 73 insertions(+), 61 deletions(-) diff --git a/lib/dtsc.cpp b/lib/dtsc.cpp index 18cc9369..534852ce 100644 --- a/lib/dtsc.cpp +++ b/lib/dtsc.cpp @@ -719,6 +719,9 @@ bool DTSC::File::reachedEOF(){ /// If the packet could not be read for any reason, the reason is printed to stderr. /// Reading the packet means the file position is increased to the next packet. void DTSC::File::seekNext(){ + fseek(F,currentPositions.begin()->seekPos, SEEK_SET); + seek_time(currentPositions.begin()->seekTime + 1, currentPositions.begin()->trackID); + currentPositions.erase(currentPositions.begin()); lastreadpos = ftell(F); if (fread(buffer, 4, 1, F) != 1){ if (feof(F)){ @@ -773,21 +776,6 @@ void DTSC::File::seekNext(){ }else{ jsonbuffer = JSON::fromDTMI(strbuffer); } - if (jsonbuffer.isMember("keyframe")){ - if (selectedTracks.size()){ - if (metadata["tracks"][selectedTracks[0]]["keybpos"][currframe].asInt() != lastreadpos){ - 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 - } - } - } } /// Returns the byte positon of the start of the last packet that was read. @@ -805,55 +793,54 @@ JSON::Value & DTSC::File::getJSON(){ return jsonbuffer; } -/// Attempts to seek to the given frame number within the file. -/// Returns true if successful, false otherwise. -bool DTSC::File::seek_frame(int frameno){ - int bytePos = -1; - int replaceBytePos = -1; - for (int i = 0; i < metadata["tracks"][selectedTracks[0]]["keynum"].size(); i++){ - if (metadata["tracks"][selectedTracks[0]]["keynum"][i].asInt() == frameno){ - bytePos = metadata["tracks"][selectedTracks[0]]["keybpos"][i].asInt(); +bool DTSC::File::seek_time(int ms, int trackNo){ + seekPos tmpPos; + tmpPos.trackID = trackNo; + for (int i = 0; i < metadata["tracks"][trackMapping[trackNo]]["keynum"].size(); i++){ + if (metadata["tracks"][trackMapping[trackNo]]["keytime"][i].asInt() > ms){ break; } - if (metadata["tracks"][selectedTracks[0]]["keynum"][i].asInt() < frameno){ - replaceBytePos = metadata["tracks"][selectedTracks[0]]["keybpos"][i].asInt(); + tmpPos.seekTime = metadata["tracks"][trackMapping[trackNo]]["keytime"][i].asInt(); + tmpPos.seekPos = metadata["tracks"][trackMapping[trackNo]]["keybpos"][i].asInt(); + } + bool foundPacket = false; + while ( !foundPacket){ + //Seek to first packet after ms. + seek_bpos(tmpPos.seekPos); + //read the header + char header[20]; + fread((void*)header, 20, 1, F); + //check if packetID matches, if not, skip size + 8 bytes. + int packSize = ntohl(((int*)header)[1]); + int packID = ntohl(((int*)header)[2]); + if (packID != trackNo){ + tmpPos.seekPos += 8 + packSize; + continue; + } + //get timestamp of packet, if too large, break, if not, skip size bytes. + long long unsigned int myTime = ((long long unsigned int)ntohl(((int*)header)[3]) << 32); + myTime += ntohl(((int*)header)[4]); + if (myTime >= ms){ + tmpPos.seekTime = myTime; + foundPacket = true; + }else{ + tmpPos.seekPos += 8 + packSize; + continue; } } - if (bytePos == -1){ - bytePos = replaceBytePos; - } - if (bytePos > -1){ - if (fseek(F, bytePos, SEEK_SET) == 0){ -#if DEBUG >= 5 - std::cerr << "Seek direct from " << currframe << " @ " << metadata["tracks"][selectedTracks[0]]["keybpos"][currframe].asInt() << " to " << frameno << " @ " << bytePos << std::endl; -#endif - currframe = frameno; - return true; - } - } - return false; + currentPositions.insert(tmpPos); + fprintf(stderr, "TrackID %d, Time seek %d -- retrieved bytepos %d, timestamp %d\n", trackNo, ms, tmpPos.seekPos, tmpPos.seekTime); } /// Attempts to seek to the given time in ms within the file. /// Returns true if successful, false otherwise. bool DTSC::File::seek_time(int ms){ - currtime = 0; - currframe = 1; - int bytePos = -1; - for (int i = 0; i < metadata["tracks"][selectedTracks[0]]["keynum"].size(); i++){ - if (metadata["tracks"][selectedTracks[0]]["keytime"][i].asInt() > ms){ - break; - } - if (metadata["tracks"][selectedTracks[0]]["keytime"][i].asInt() > currtime){ - currtime = metadata["tracks"][selectedTracks[0]]["keytime"][i].asInt(); - currframe = i + 1; - } - bytePos = metadata["tracks"][selectedTracks[0]]["keybpos"][i].asInt(); + currentPositions.clear(); + seekPos tmpPos; + for (std::set::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){ + seek_time(ms,(*it)); } - if (fseek(F, bytePos, SEEK_SET) == 0){ - return true; - } - return false; + return true; } bool DTSC::File::seek_bpos(int bpos){ @@ -872,10 +859,6 @@ void DTSC::File::writePacket(JSON::Value & newPacket){ writePacket(newPacket.toNetPacked()); } -void DTSC::File::selectTracks(std::vector & trackIDs){ - selectedTracks = trackIDs; -} - bool DTSC::File::atKeyframe(){ if (getJSON().isMember("keyframe")){ return true; @@ -892,6 +875,11 @@ bool DTSC::File::atKeyframe(){ return inHeader; } +void DTSC::File::selectTracks(std::set & tracks){ + currentPositions.clear(); + selectedTracks = tracks; +} + /// Close the file if open DTSC::File::~File(){ if (F){ diff --git a/lib/dtsc.h b/lib/dtsc.h index 4f772025..e83ef8fc 100644 --- a/lib/dtsc.h +++ b/lib/dtsc.h @@ -64,6 +64,29 @@ namespace DTSC { extern char Magic_Packet[]; ///< The magic bytes for a DTSC packet extern char Magic_Packet2[]; ///< The magic bytes for a DTSC packet version 2 + /// A simple structure used for ordering byte seek positions. + struct seekPos { + bool operator < (const seekPos& rhs) const { + if (seekTime < rhs.seekTime){ + return true; + }else{ + if (seekTime == rhs.seekTime){ + if (seekPos < rhs.seekPos){ + return true; + }else{ + if (trackID < rhs.trackID){ + return true; + } + } + } + } + return false; + } + long long unsigned int seekTime; + long long unsigned int seekPos; + unsigned int trackID; + }; + /// A simple wrapper class that will open a file and allow easy reading/writing of DTSC data from/to it. class File{ public: @@ -83,13 +106,13 @@ namespace DTSC { void seekNext(); std::string & getPacket(); JSON::Value & getJSON(); - bool seek_frame(int frameno); bool seek_time(int seconds); + bool seek_time(int seconds, int trackNo); bool seek_bpos(int bpos); void writePacket(std::string & newPacket); void writePacket(JSON::Value & newPacket); - void selectTracks(std::vector & trackIDs); bool atKeyframe(); + void selectTracks(std::set & tracks); private: void readHeader(int pos); std::string strbuffer; @@ -104,7 +127,8 @@ namespace DTSC { unsigned long headerSize; char buffer[4]; bool created; - std::vector selectedTracks; + std::set currentPositions; + std::set selectedTracks; }; //FileWriter