Fixed live support for DTSC metadata, improved track reset and ordering handling.

This commit is contained in:
Thulinma 2013-12-16 13:07:57 +01:00
parent 88dfb7d535
commit fc12369e5e
3 changed files with 50 additions and 43 deletions

View file

@ -218,19 +218,9 @@ void DTSC::Stream::addPacket(JSON::Value & newPack){
livePos newPos; livePos newPos;
newPos.trackID = newPack["trackid"].asInt(); newPos.trackID = newPack["trackid"].asInt();
newPos.seekTime = newPack["time"].asInt(); newPos.seekTime = newPack["time"].asInt();
if (buffercount > 1 && buffers.size() > 0){ if (buffercount > 1 && metadata.tracks[newPos.trackID].keys.size() > 1 && newPos.seekTime < metadata.tracks[newPos.trackID].keys.rbegin()->getTime()){
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{
resetStream(); resetStream();
} }
std::string newTrack = metadata.tracks[newPos.trackID].getIdentifier();
while (buffers.count(newPos) > 0){ while (buffers.count(newPos) > 0){
newPos.seekTime++; newPos.seekTime++;
} }
@ -261,19 +251,18 @@ void DTSC::Stream::addPacket(JSON::Value & newPack){
keyframes[newPos.trackID].insert(newPos); keyframes[newPos.trackID].insert(newPos);
} }
metadata.live = true; 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 while (buffercount == 1 && buffers.size() > 1){
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){
cutOneBuffer(); cutOneBuffer();
} }
} }
@ -282,16 +271,18 @@ 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. /// Will print a warning to std::cerr if a track has less than 2 keyframes left because of this.
void DTSC::Stream::cutOneBuffer(){ void DTSC::Stream::cutOneBuffer(){
int trid = buffers.begin()->first.trackID; int trid = buffers.begin()->first.trackID;
if (buffercount > 1 && keyframes[trid].count(buffers.begin()->first)){ int delTime = buffers.begin()->first.seekTime;
//if there are < 3 keyframes, throwing one away would mean less than 2 left. if (buffercount > 1){
if (keyframes[trid].size() < 3){ while (keyframes[trid].size() > 0 && keyframes[trid].begin()->seekTime <= delTime){
std::cerr << "Warning - track " << trid << " doesn't have enough keyframes to be reliably served." << std::endl; keyframes[trid].erase(keyframes[trid].begin());
} }
keyframes[trid].erase(buffers.begin()->first); 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++){ for (int i = 0; i < metadata.tracks[trid].keys[0].getParts(); i++){
metadata.tracks[trid].parts.pop_front(); metadata.tracks[trid].parts.pop_front();
} }
metadata.tracks[trid].keys.pop_front(); metadata.tracks[trid].keys.pop_front();
}
if (metadata.tracks[trid].keys.size()){
metadata.tracks[trid].firstms = metadata.tracks[trid].keys[0].getTime(); metadata.tracks[trid].firstms = metadata.tracks[trid].keys[0].getTime();
//delete fragments of which the beginning can no longer be reached //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()){ while (metadata.tracks[trid].fragments.size() && metadata.tracks[trid].fragments[0].getNumber() < metadata.tracks[trid].keys[0].getNumber()){
@ -299,7 +290,11 @@ void DTSC::Stream::cutOneBuffer(){
//increase the missed fragments counter //increase the missed fragments counter
metadata.tracks[trid].missedFrags++; metadata.tracks[trid].missedFrags++;
} }
}else{
metadata.tracks[trid].fragments.clear();
} }
}
deletionCallback(buffers.begin()->first);
buffers.erase(buffers.begin()); buffers.erase(buffers.begin());
} }

View file

@ -77,14 +77,12 @@ namespace DTSC {
if (seekTime < rhs.seekTime){ if (seekTime < rhs.seekTime){
return true; return true;
}else{ }else{
if (seekTime == rhs.seekTime){ if (seekTime > rhs.seekTime){
if (trackID < rhs.trackID){
return true;
}
}
}
return false; return false;
} }
}
return (trackID < rhs.trackID);
}
volatile long long unsigned int seekTime; volatile long long unsigned int seekTime;
volatile unsigned int trackID; volatile unsigned int trackID;
}; };

View file

@ -155,7 +155,7 @@ namespace DTSC {
firstms = trackRef["firstms"].asInt(); firstms = trackRef["firstms"].asInt();
lastms = trackRef["lastms"].asInt(); lastms = trackRef["lastms"].asInt();
bps = trackRef["bps"].asInt(); bps = trackRef["bps"].asInt();
missedFrags = trackRef["missed_fags"].asInt(); missedFrags = trackRef["missed_frags"].asInt();
codec = trackRef["codec"].asString(); codec = trackRef["codec"].asString();
type = trackRef["type"].asString(); type = trackRef["type"].asString();
init = trackRef["init"].asString(); init = trackRef["init"].asString();
@ -222,7 +222,7 @@ namespace DTSC {
firstms = trackRef["firstms"].asInt(); firstms = trackRef["firstms"].asInt();
lastms = trackRef["lastms"].asInt(); lastms = trackRef["lastms"].asInt();
bps = trackRef["bps"].asInt(); bps = trackRef["bps"].asInt();
missedFrags = trackRef["missed_fags"].asInt(); missedFrags = trackRef["missed_frags"].asInt();
codec = trackRef["codec"].asString(); codec = trackRef["codec"].asString();
type = trackRef["type"].asString(); type = trackRef["type"].asString();
init = trackRef["init"].asString(); init = trackRef["init"].asString();
@ -243,6 +243,10 @@ namespace DTSC {
} }
void Track::update(JSON::Value & pack){ 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; Part newPart;
newPart.setSize(pack["data"].asString().size()); newPart.setSize(pack["data"].asString().size());
newPart.setOffset(pack["offset"].asInt()); newPart.setOffset(pack["offset"].asInt());
@ -442,6 +446,7 @@ namespace DTSC {
result += 15 + idHeader.size();//idheader result += 15 + idHeader.size();//idheader
result += 20 + commentHeader.size();//commentheader result += 20 + commentHeader.size();//commentheader
} }
if (missedFrags){result += 23;}
return result; return result;
} }
@ -459,6 +464,7 @@ namespace DTSC {
result += 15 + idHeader.size();//idheader result += 15 + idHeader.size();//idheader
result += 20 + commentHeader.size();//commentheader result += 20 + commentHeader.size();//commentheader
} }
if (missedFrags){result += 23;}
return result; return result;
} }
@ -477,6 +483,10 @@ namespace DTSC {
conn.SendNow((char*)parts, partLen*9); conn.SendNow((char*)parts, partLen*9);
conn.SendNow("\000\007trackid\001", 10); conn.SendNow("\000\007trackid\001", 10);
conn.SendNow(convertLongLong(trackID), 8); 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("\000\007firstms\001", 10);
conn.SendNow(convertLongLong(firstms), 8); conn.SendNow(convertLongLong(firstms), 8);
conn.SendNow("\000\006lastms\001", 9); conn.SendNow("\000\006lastms\001", 9);
@ -539,6 +549,10 @@ namespace DTSC {
} }
conn.SendNow("\000\007trackid\001", 10); conn.SendNow("\000\007trackid\001", 10);
conn.SendNow(convertLongLong(trackID), 8); 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("\000\007firstms\001", 10);
conn.SendNow(convertLongLong(firstms), 8); conn.SendNow(convertLongLong(firstms), 8);
conn.SendNow("\000\006lastms\001", 9); conn.SendNow("\000\006lastms\001", 9);