From fc12369e5e811b05c987c8208d0213a5da59665b Mon Sep 17 00:00:00 2001 From: Thulinma Date: Mon, 16 Dec 2013 13:07:57 +0100 Subject: [PATCH] Fixed live support for DTSC metadata, improved track reset and ordering handling. --- lib/dtsc.cpp | 67 ++++++++++++++++++++++-------------------------- lib/dtsc.h | 8 +++--- lib/dtscmeta.cpp | 18 +++++++++++-- 3 files changed, 50 insertions(+), 43 deletions(-) diff --git a/lib/dtsc.cpp b/lib/dtsc.cpp index 9e1a6dc1..55eae8c8 100644 --- a/lib/dtsc.cpp +++ b/lib/dtsc.cpp @@ -218,19 +218,9 @@ void DTSC::Stream::addPacket(JSON::Value & newPack){ livePos newPos; newPos.trackID = newPack["trackid"].asInt(); newPos.seekTime = newPack["time"].asInt(); - if (buffercount > 1 && buffers.size() > 0){ - livePos lastPos = buffers.rbegin()->first; - if (newPos < lastPos){ - if ((lastPos.seekTime > 1000) && newPos.seekTime < lastPos.seekTime - 1000){ - resetStream(); - }else{ - newPos.seekTime = lastPos.seekTime+1; - } - } - }else{ + if (buffercount > 1 && metadata.tracks[newPos.trackID].keys.size() > 1 && newPos.seekTime < metadata.tracks[newPos.trackID].keys.rbegin()->getTime()){ resetStream(); } - std::string newTrack = metadata.tracks[newPos.trackID].getIdentifier(); while (buffers.count(newPos) > 0){ newPos.seekTime++; } @@ -261,19 +251,18 @@ void DTSC::Stream::addPacket(JSON::Value & newPack){ keyframes[newPos.trackID].insert(newPos); } metadata.live = true; + //throw away buffers if buffer time is met + int trid = buffers.begin()->first.trackID; + int firstTime = buffers.begin()->first.seekTime; + while (metadata.tracks[trid].keys.size() > 2 && metadata.tracks[trid].keys.rbegin()->getTime() - firstTime > buffertime){ + cutOneBuffer(); + trid = buffers.begin()->first.trackID; + firstTime = buffers.begin()->first.seekTime; + } + metadata.bufferWindow = buffertime; } - //increase buffer size if too little time available - unsigned int timeBuffered = buffers.rbegin()->second["time"].asInt() - buffers.begin()->second["time"].asInt(); - if (buffercount > 1){ - if (timeBuffered < buffertime){ - buffercount = buffers.size(); - if (buffercount < 2){buffercount = 2;} - } - metadata.bufferWindow = timeBuffered; - } - - while (buffers.size() > buffercount){ + while (buffercount == 1 && buffers.size() > 1){ cutOneBuffer(); } } @@ -282,24 +271,30 @@ void DTSC::Stream::addPacket(JSON::Value & newPack){ /// Will print a warning to std::cerr if a track has less than 2 keyframes left because of this. void DTSC::Stream::cutOneBuffer(){ int trid = buffers.begin()->first.trackID; - if (buffercount > 1 && keyframes[trid].count(buffers.begin()->first)){ - //if there are < 3 keyframes, throwing one away would mean less than 2 left. - if (keyframes[trid].size() < 3){ - std::cerr << "Warning - track " << trid << " doesn't have enough keyframes to be reliably served." << std::endl; + int delTime = buffers.begin()->first.seekTime; + if (buffercount > 1){ + while (keyframes[trid].size() > 0 && keyframes[trid].begin()->seekTime <= delTime){ + keyframes[trid].erase(keyframes[trid].begin()); } - keyframes[trid].erase(buffers.begin()->first); - for (int i = 0; i < metadata.tracks[trid].keys[0].getParts(); i++){ - metadata.tracks[trid].parts.pop_front(); + while (metadata.tracks[trid].keys.size() && metadata.tracks[trid].keys[0].getTime() <= delTime){ + for (int i = 0; i < metadata.tracks[trid].keys[0].getParts(); i++){ + metadata.tracks[trid].parts.pop_front(); + } + metadata.tracks[trid].keys.pop_front(); } - metadata.tracks[trid].keys.pop_front(); - metadata.tracks[trid].firstms = metadata.tracks[trid].keys[0].getTime(); - // delete fragments of which the beginning can no longer be reached - while (metadata.tracks[trid].fragments.size() && metadata.tracks[trid].fragments[0].getNumber() < metadata.tracks[trid].keys[0].getNumber()){ - metadata.tracks[trid].fragments.pop_front(); - // increase the missed fragments counter - metadata.tracks[trid].missedFrags++; + if (metadata.tracks[trid].keys.size()){ + metadata.tracks[trid].firstms = metadata.tracks[trid].keys[0].getTime(); + //delete fragments of which the beginning can no longer be reached + while (metadata.tracks[trid].fragments.size() && metadata.tracks[trid].fragments[0].getNumber() < metadata.tracks[trid].keys[0].getNumber()){ + metadata.tracks[trid].fragments.pop_front(); + //increase the missed fragments counter + metadata.tracks[trid].missedFrags++; + } + }else{ + metadata.tracks[trid].fragments.clear(); } } + deletionCallback(buffers.begin()->first); buffers.erase(buffers.begin()); } diff --git a/lib/dtsc.h b/lib/dtsc.h index ceb8eebd..f604232c 100644 --- a/lib/dtsc.h +++ b/lib/dtsc.h @@ -77,13 +77,11 @@ namespace DTSC { if (seekTime < rhs.seekTime){ return true; }else{ - if (seekTime == rhs.seekTime){ - if (trackID < rhs.trackID){ - return true; - } + if (seekTime > rhs.seekTime){ + return false; } } - return false; + return (trackID < rhs.trackID); } volatile long long unsigned int seekTime; volatile unsigned int trackID; diff --git a/lib/dtscmeta.cpp b/lib/dtscmeta.cpp index 45216fed..941dcdbe 100644 --- a/lib/dtscmeta.cpp +++ b/lib/dtscmeta.cpp @@ -155,7 +155,7 @@ namespace DTSC { firstms = trackRef["firstms"].asInt(); lastms = trackRef["lastms"].asInt(); bps = trackRef["bps"].asInt(); - missedFrags = trackRef["missed_fags"].asInt(); + missedFrags = trackRef["missed_frags"].asInt(); codec = trackRef["codec"].asString(); type = trackRef["type"].asString(); init = trackRef["init"].asString(); @@ -222,7 +222,7 @@ namespace DTSC { firstms = trackRef["firstms"].asInt(); lastms = trackRef["lastms"].asInt(); bps = trackRef["bps"].asInt(); - missedFrags = trackRef["missed_fags"].asInt(); + missedFrags = trackRef["missed_frags"].asInt(); codec = trackRef["codec"].asString(); type = trackRef["type"].asString(); init = trackRef["init"].asString(); @@ -243,6 +243,10 @@ namespace DTSC { } void Track::update(JSON::Value & pack){ + if (pack["time"].asInt() < lastms){ + std::cerr << "Received packets for track " << trackID << " in wrong order (" << pack["time"].asInt() << " < " << lastms << ") - ignoring!" << std::endl; + return; + } Part newPart; newPart.setSize(pack["data"].asString().size()); newPart.setOffset(pack["offset"].asInt()); @@ -442,6 +446,7 @@ namespace DTSC { result += 15 + idHeader.size();//idheader result += 20 + commentHeader.size();//commentheader } + if (missedFrags){result += 23;} return result; } @@ -459,6 +464,7 @@ namespace DTSC { result += 15 + idHeader.size();//idheader result += 20 + commentHeader.size();//commentheader } + if (missedFrags){result += 23;} return result; } @@ -477,6 +483,10 @@ namespace DTSC { 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); @@ -539,6 +549,10 @@ namespace DTSC { } 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);