Added ability for outputs to elect to only receive completed (i.e.: whole) keyframes, by Oswald de Bruin.

This commit is contained in:
Thulinma 2015-09-03 20:18:12 +02:00
parent c254085579
commit 17f3a37454
2 changed files with 45 additions and 0 deletions

View file

@ -39,10 +39,12 @@ namespace Mist {
sought = false; sought = false;
isInitialized = false; isInitialized = false;
isBlocking = false; isBlocking = false;
completeKeysOnly = false;
lastStats = 0; lastStats = 0;
maxSkipAhead = 7500; maxSkipAhead = 7500;
minSkipAhead = 5000; minSkipAhead = 5000;
realTime = 1000; realTime = 1000;
completeKeyReadyTimeOut = false;
if (myConn){ if (myConn){
setBlocking(true); setBlocking(true);
}else{ }else{
@ -584,6 +586,47 @@ namespace Mist {
Util::sleep(nxt.time - (((Util::getMS() - firstTime)*1000)+minSkipAhead)/realTime); Util::sleep(nxt.time - (((Util::getMS() - firstTime)*1000)+minSkipAhead)/realTime);
} }
} }
//delay the stream until its current keyframe is complete
if (completeKeysOnly){
bool completeKeyReady = false;
int timeoutTries = 40;//attempts to updateMeta before timeOut and moving on; default is approximately 10 seconds
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
if (it->second.keys.size() >1){
int thisTimeoutTries = ((it->second.lastms - it->second.firstms) / (it->second.keys.size()-1)) / 125;
if (thisTimeoutTries > timeoutTries) timeoutTries = thisTimeoutTries;
}
}
while(!completeKeyReady && timeoutTries>0){
completeKeyReady = true;
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){
if (!it->second.keys.size() || it->second.keys.rbegin()->getTime() + it->second.keys.rbegin()->getLength() <= nxt.time ){
completeKeyReady = false;
break;
}
}
if (!completeKeyReady){
if (completeKeyReadyTimeOut){
INSANE_MSG("Complete Key not ready and time-out is being skipped");
timeoutTries = 0;
}else{
INSANE_MSG("Timeout: %d",timeoutTries);
timeoutTries--;//we count down
stats();
Util::wait(250);
updateMeta();
}
}
}
if (timeoutTries<=0){
if (!completeKeyReadyTimeOut){
INFO_MSG("Wait for keyframe Timeout triggered! Ended to avoid endless loops");
}
completeKeyReadyTimeOut = true;
}else{
//untimeout handling
completeKeyReadyTimeOut = false;
}
}
if (curPage[nxt.tid]){ if (curPage[nxt.tid]){
if (nxt.offset < curPage[nxt.tid].len){ if (nxt.offset < curPage[nxt.tid].len){
unsigned long long nextTime = getDTSCTime(curPage[nxt.tid].mapped, nxt.offset); unsigned long long nextTime = getDTSCTime(curPage[nxt.tid].mapped, nxt.offset);

View file

@ -73,6 +73,7 @@ namespace Mist {
std::map<unsigned long, unsigned long> nxtKeyNum;///< Contains the number of the next key, for page seeking purposes. std::map<unsigned long, unsigned long> nxtKeyNum;///< Contains the number of the next key, for page seeking purposes.
std::set<sortedPageInfo> buffer;///< A sorted list of next-to-be-loaded packets. std::set<sortedPageInfo> buffer;///< A sorted list of next-to-be-loaded packets.
bool sought;///<If a seek has been done, this is set to true. Used for seeking on prepareNext(). bool sought;///<If a seek has been done, this is set to true. Used for seeking on prepareNext().
bool completeKeyReadyTimeOut;//a bool to see if there has been a keyframe TimeOut for complete keys in Live
protected://these are to be messed with by child classes protected://these are to be messed with by child classes
IPC::sharedClient statsPage;///< Shared memory used for statistics reporting. IPC::sharedClient statsPage;///< Shared memory used for statistics reporting.
bool isBlocking;///< If true, indicates that myConn is blocking. bool isBlocking;///< If true, indicates that myConn is blocking.
@ -83,6 +84,7 @@ namespace Mist {
unsigned int maxSkipAhead;///< Maximum ms that we will go ahead of the intended timestamps. unsigned int maxSkipAhead;///< Maximum ms that we will go ahead of the intended timestamps.
unsigned int minSkipAhead;///< Minimum ms that we will go ahead of the intended timestamps. unsigned int minSkipAhead;///< Minimum ms that we will go ahead of the intended timestamps.
unsigned int realTime;///< Playback speed in ms of data per second. eg: 0 is infinite, 1000 real-time, 5000 is 0.2X speed, 500 = 2X speed. unsigned int realTime;///< Playback speed in ms of data per second. eg: 0 is infinite, 1000 real-time, 5000 is 0.2X speed, 500 = 2X speed.
bool completeKeysOnly;///< Bool if we send whole keys only, so the metadata is complete and the output knows in advance what will be sent.
//Read/write status variables //Read/write status variables
Socket::Connection & myConn;///< Connection to the client. Socket::Connection & myConn;///< Connection to the client.