Added minKeepAway support to DTSC::Track object, senders and parsers
This commit is contained in:
parent
bb2e6de56a
commit
b0c7897568
4 changed files with 51 additions and 20 deletions
|
@ -786,6 +786,53 @@ namespace Mist{
|
||||||
seek(seekPos);
|
seek(seekPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This function attempts to forward playback in live streams to a more live point.
|
||||||
|
/// It seeks to the last sync'ed keyframe of the main track, no closer than needsLookAhead+minKeepAway ms from the end.
|
||||||
|
/// Aborts if not live, there is no main track or it has no keyframes.
|
||||||
|
bool Output::liveSeek(){
|
||||||
|
unsigned long long seekPos = 0;
|
||||||
|
if (!myMeta.live){return false;}
|
||||||
|
long unsigned int mainTrack = getMainSelectedTrack();
|
||||||
|
//cancel if there are no keys in the main track
|
||||||
|
if (!myMeta.tracks.count(mainTrack)){return false;}
|
||||||
|
DTSC::Track & mainTrk = myMeta.tracks[mainTrack];
|
||||||
|
if (!mainTrk.keys.size()){return false;}
|
||||||
|
uint32_t minKeepAway = mainTrk.minKeepAway;
|
||||||
|
|
||||||
|
//Only skip forward if we can win at least 500ms
|
||||||
|
if (thisPacket.getTime() + 500 > mainTrk.keys.rbegin()->getTime()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::deque<DTSC::Key>::reverse_iterator it = myMeta.tracks[mainTrack].keys.rbegin(); it != myMeta.tracks[mainTrack].keys.rend(); ++it){
|
||||||
|
seekPos = it->getTime();
|
||||||
|
if(seekPos <= thisPacket.getTime()){return false;}
|
||||||
|
bool good = true;
|
||||||
|
//check if all tracks have data for this point in time
|
||||||
|
for (std::set<unsigned long>::iterator ti = selectedTracks.begin(); ti != selectedTracks.end(); ++ti){
|
||||||
|
if (!myMeta.tracks.count(*ti)){
|
||||||
|
HIGH_MSG("Skipping track %lu, not in tracks", *ti);
|
||||||
|
continue;
|
||||||
|
}//ignore missing tracks
|
||||||
|
DTSC::Track & thisTrack = myMeta.tracks[*ti];
|
||||||
|
if (thisTrack.lastms < seekPos+needsLookAhead+thisTrack.minKeepAway){good = false; break;}
|
||||||
|
if (mainTrack == *ti){continue;}//skip self
|
||||||
|
if (thisTrack.lastms == thisTrack.firstms){
|
||||||
|
HIGH_MSG("Skipping track %lu, last equals first", *ti);
|
||||||
|
continue;
|
||||||
|
}//ignore point-tracks
|
||||||
|
HIGH_MSG("Track %lu is good", *ti);
|
||||||
|
}
|
||||||
|
//if yes, seek here
|
||||||
|
if (good){
|
||||||
|
INFO_MSG("Skipping forward %llums (%u ms LA, %lu ms mKA)", seekPos - thisPacket.getTime(), needsLookAhead, mainTrk.minKeepAway);
|
||||||
|
seek(seekPos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Output::requestHandler(){
|
void Output::requestHandler(){
|
||||||
static bool firstData = true;//only the first time, we call onRequest if there's data buffered already.
|
static bool firstData = true;//only the first time, we call onRequest if there's data buffered already.
|
||||||
if ((firstData && myConn.Received().size()) || myConn.spool()){
|
if ((firstData && myConn.Received().size()) || myConn.spool()){
|
||||||
|
|
|
@ -69,6 +69,7 @@ namespace Mist {
|
||||||
virtual void onRequest();
|
virtual void onRequest();
|
||||||
static void listener(Util::Config & conf, int (*callback)(Socket::Connection & S));
|
static void listener(Util::Config & conf, int (*callback)(Socket::Connection & S));
|
||||||
virtual void initialSeek();
|
virtual void initialSeek();
|
||||||
|
virtual bool liveSeek();
|
||||||
virtual bool onFinish() {
|
virtual bool onFinish() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -925,16 +925,8 @@ namespace Mist {
|
||||||
if (myMeta.live) {
|
if (myMeta.live) {
|
||||||
//if header needed
|
//if header needed
|
||||||
if (!partListLength || partListSent >= partListLength) {
|
if (!partListLength || partListSent >= partListLength) {
|
||||||
DTSC::Track & mainTrk = myMeta.tracks[vidTrack];
|
if (fragSeqNum > 10){
|
||||||
// The extra 2000ms here is for the metadata sync delay.
|
if (liveSeek()){return;}
|
||||||
// It can be removed once we get rid of that.
|
|
||||||
// (sync delay = ~1s, minimum lookAhead is 420ms -> ~600ms extra needed, we use 2000ms to be safe)
|
|
||||||
if (myMeta.sourceURI.find("http://") == std::string::npos || myMeta.sourceURI.find(".m3u") == std::string::npos){
|
|
||||||
if (fragSeqNum > 10 && thisPacket.getTime() + needsLookAhead + 2000 < mainTrk.keys.rbegin()->getTime() && mainTrk.lastms - mainTrk.keys.rbegin()->getTime() > needsLookAhead){
|
|
||||||
INFO_MSG("Skipping forward %llums (%u ms LA)", mainTrk.keys.rbegin()->getTime() - thisPacket.getTime(), needsLookAhead);
|
|
||||||
seek(mainTrk.keys.rbegin()->getTime());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//building set first
|
//building set first
|
||||||
buildFragment();//map with metadata for keyframe
|
buildFragment();//map with metadata for keyframe
|
||||||
|
|
|
@ -108,16 +108,7 @@ namespace Mist{
|
||||||
if (myMeta.live && lastTimeSync + 666 < timestamp){
|
if (myMeta.live && lastTimeSync + 666 < timestamp){
|
||||||
lastTimeSync = timestamp;
|
lastTimeSync = timestamp;
|
||||||
updateMeta();
|
updateMeta();
|
||||||
DTSC::Track &mainTrk = myMeta.tracks[getMainSelectedTrack()];
|
if (liveSeek()){return;}
|
||||||
// The extra 2000ms here is for the metadata sync delay.
|
|
||||||
// It can be removed once we get rid of that.
|
|
||||||
if (timestamp + 2000 + needsLookAhead < mainTrk.keys.rbegin()->getTime() &&
|
|
||||||
mainTrk.lastms - mainTrk.keys.rbegin()->getTime() > needsLookAhead){
|
|
||||||
INFO_MSG("Skipping forward %llums (%llu ms LA)",
|
|
||||||
mainTrk.keys.rbegin()->getTime() - thisPacket.getTime(), needsLookAhead);
|
|
||||||
seek(mainTrk.keys.rbegin()->getTime());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *socket = 0;
|
void *socket = 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue