Fixed live support for DTSC metadata, improved track reset and ordering handling.
This commit is contained in:
parent
88dfb7d535
commit
fc12369e5e
3 changed files with 50 additions and 43 deletions
53
lib/dtsc.cpp
53
lib/dtsc.cpp
|
@ -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,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.
|
/// 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()){
|
||||||
metadata.tracks[trid].fragments.pop_front();
|
metadata.tracks[trid].fragments.pop_front();
|
||||||
// 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
lib/dtsc.h
10
lib/dtsc.h
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue