Fix playlist support not resuming on the correct page number and/or with the correct timestamp
This commit is contained in:
parent
c9cd529927
commit
5f8518fe23
3 changed files with 59 additions and 32 deletions
|
@ -623,6 +623,7 @@ namespace Mist {
|
|||
return;
|
||||
}
|
||||
|
||||
nProxy.pagesByTrack.clear();
|
||||
|
||||
timeOffset = 0;
|
||||
uint64_t minFirstMs = 0;
|
||||
|
@ -631,6 +632,49 @@ namespace Mist {
|
|||
if (config->getBool("realtime")){
|
||||
seek(0);
|
||||
|
||||
minFirstMs = 0xFFFFFFFFFFFFFFFFull;
|
||||
uint64_t maxFirstMs = 0;
|
||||
uint64_t minLastMs = 0xFFFFFFFFFFFFFFFFull;
|
||||
uint64_t maxLastMs = 0;
|
||||
|
||||
//track lowest firstms value
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); ++it){
|
||||
if (it->second.firstms < minFirstMs){minFirstMs = it->second.firstms;}
|
||||
if (it->second.firstms > maxFirstMs){maxFirstMs = it->second.firstms;}
|
||||
if (it->second.lastms < minLastMs){minLastMs = it->second.lastms;}
|
||||
if (it->second.lastms > maxLastMs){maxLastMs = it->second.lastms;}
|
||||
}
|
||||
if (maxFirstMs - minFirstMs > 500){
|
||||
WARN_MSG("Begin timings of tracks for this file are %" PRIu64 " ms apart. This may mess up playback to some degree. (Range: %" PRIu64 "ms - %" PRIu64 "ms)", maxFirstMs-minFirstMs, minFirstMs, maxFirstMs);
|
||||
}
|
||||
if (maxLastMs - minLastMs > 500){
|
||||
WARN_MSG("Stop timings of tracks for this file are %" PRIu64 " ms apart. This may mess up playback to some degree. (Range: %" PRIu64 "ms - %" PRIu64 "ms)", maxLastMs-minLastMs, minLastMs, maxLastMs);
|
||||
}
|
||||
|
||||
bool needsWait = true;
|
||||
//change firstms of all tracks to -1 to indicate we're resuming
|
||||
std::map<unsigned int, uint64_t> preFirstMs;
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); ++it){
|
||||
preFirstMs[it->first] = it->second.firstms;
|
||||
it->second.firstms = -1;
|
||||
}
|
||||
//negotiate all tracks with buffer
|
||||
while (needsWait && config->is_active && nProxy.userClient.isAlive()){
|
||||
needsWait = false;
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); ++it){
|
||||
if (!it->first){continue;}
|
||||
if (nProxy.trackState.count(it->first) && nProxy.trackState[it->first] == FILL_ACC){continue;}
|
||||
nProxy.continueNegotiate(it->first, myMeta);
|
||||
if (nProxy.trackState.count(it->first) && nProxy.trackState[it->first] == FILL_ACC){continue;}
|
||||
needsWait = true;
|
||||
}
|
||||
if (needsWait){Util::sleep(200);}
|
||||
}
|
||||
//Restore firstms of tracks - should not be needed, but why risk messing things up..?
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); ++it){
|
||||
it->second.firstms = preFirstMs[it->first];
|
||||
}
|
||||
|
||||
|
||||
char nameBuf[NAME_BUFFER_SIZE];
|
||||
snprintf(nameBuf, NAME_BUFFER_SIZE, SHM_STREAM_INDEX, streamName.c_str());
|
||||
|
@ -653,33 +697,16 @@ namespace Mist {
|
|||
liveSem = 0;
|
||||
}
|
||||
DTSC::Meta tmpM(tmpMeta);
|
||||
minFirstMs = 0xFFFFFFFFFFFFFFFFull;
|
||||
uint64_t maxFirstMs = 0;
|
||||
uint64_t minLastMs = 0xFFFFFFFFFFFFFFFFull;
|
||||
uint64_t maxLastMs = 0;
|
||||
|
||||
//track lowest firstms value
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); ++it){
|
||||
if (it->second.firstms < minFirstMs){minFirstMs = it->second.firstms;}
|
||||
if (it->second.firstms > maxFirstMs){maxFirstMs = it->second.firstms;}
|
||||
if (it->second.lastms < minLastMs){minLastMs = it->second.lastms;}
|
||||
if (it->second.lastms > maxLastMs){maxLastMs = it->second.lastms;}
|
||||
}
|
||||
if (maxFirstMs - minFirstMs > 500){
|
||||
WARN_MSG("Begin timings of tracks for this file are %" PRIu64 " ms apart. This may mess up playback to some degree. (Range: %" PRIu64 "ms - %" PRIu64 "ms)", maxFirstMs-minFirstMs, minFirstMs, maxFirstMs);
|
||||
}
|
||||
if (maxLastMs - minLastMs > 500){
|
||||
WARN_MSG("Stop timings of tracks for this file are %" PRIu64 " ms apart. This may mess up playback to some degree. (Range: %" PRIu64 "ms - %" PRIu64 "ms)", maxLastMs-minLastMs, minLastMs, maxLastMs);
|
||||
}
|
||||
//find highest current time
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator secondIt = tmpM.tracks.begin(); secondIt != tmpM.tracks.end(); ++secondIt){
|
||||
VERYHIGH_MSG("Track %u starts at %" PRIu64, secondIt->first, secondIt->second.lastms);
|
||||
timeOffset = std::max(timeOffset, (int64_t)secondIt->second.lastms);
|
||||
}
|
||||
|
||||
if (timeOffset){
|
||||
if (minFirstMs == 0xFFFFFFFFFFFFFFFFull){minFirstMs = 0;}
|
||||
MEDIUM_MSG("Offset is %" PRId64 ", adding 1s and subtracting the start time of %" PRIu64, timeOffset, minFirstMs);
|
||||
timeOffset += 1000;//Add an artificial frame at 25 FPS to make sure we append, not overwrite
|
||||
MEDIUM_MSG("Offset is %" PRId64 "ms, adding 40ms and subtracting the start time of %" PRIu64, timeOffset, minFirstMs);
|
||||
timeOffset += 40;//Add an artificial frame at 25 FPS to make sure we append, not overwrite
|
||||
timeOffset -= minFirstMs;//we don't need to add the lowest firstms value to the offset, as it's already there
|
||||
}
|
||||
}
|
||||
|
@ -690,7 +717,6 @@ namespace Mist {
|
|||
selectedTracks.insert(it->first);
|
||||
it->second.minKeepAway = SIMULATED_LIVE_BUFFER;
|
||||
}
|
||||
nProxy.pagesByTrack.clear();
|
||||
|
||||
simStartTime = config->getInteger("simulated-starttime");
|
||||
if (!simStartTime){simStartTime = Util::bootMS();}
|
||||
|
|
|
@ -656,6 +656,7 @@ namespace Mist {
|
|||
negotiatingTracks.erase(value);
|
||||
}
|
||||
if (activeTracks.count(value)) {
|
||||
updateTrackMeta(value);
|
||||
updateMeta();
|
||||
activeTracks.erase(value);
|
||||
if (!config->getBool("resume")){
|
||||
|
@ -809,7 +810,7 @@ namespace Mist {
|
|||
int collidesWith = -1;
|
||||
std::string newTrackIdentifier = trackMeta.tracks.find(value)->second.getIdentifier();
|
||||
std::string newTrackInit = trackMeta.tracks.find(value)->second.init;
|
||||
INFO_MSG("Attempting colision detection for track %s", newTrackIdentifier.c_str());
|
||||
MEDIUM_MSG("Attempting collision detection for track %s", newTrackIdentifier.c_str());
|
||||
|
||||
//First check for matches on INIT data
|
||||
for (std::map<unsigned int, DTSC::Track>::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++) {
|
||||
|
@ -845,7 +846,7 @@ namespace Mist {
|
|||
if (finalMap == -1) {
|
||||
//No collision has been detected, assign a new final number
|
||||
finalMap = (myMeta.tracks.size() ? myMeta.tracks.rbegin()->first : 0) + 1;
|
||||
MEDIUM_MSG("No colision detected for temporary track %lu from user %u, assigning final track number %lu", value, id, finalMap);
|
||||
MEDIUM_MSG("No collision detected for temporary track %lu from user %u, assigning final track number %lu", value, id, finalMap);
|
||||
/*LTS-START*/
|
||||
if (Triggers::shouldTrigger("STREAM_TRACK_ADD")) {
|
||||
std::string payload = config->getString("streamname") + "\n" + JSON::Value(finalMap).asString() + "\n";
|
||||
|
@ -884,7 +885,7 @@ namespace Mist {
|
|||
pushLocation[finalMap] = data;
|
||||
//Initialize the metadata for this track if it was not in place yet.
|
||||
if (!myMeta.tracks.count(finalMap)) {
|
||||
DEBUG_MSG(DLVL_MEDIUM, "Inserting metadata for track number %d", finalMap);
|
||||
DEBUG_MSG(DLVL_MEDIUM, "Inserting metadata for track number %" PRIu64, finalMap);
|
||||
myMeta.tracks[finalMap] = trackMeta.tracks.begin()->second;
|
||||
myMeta.tracks[finalMap].firstms = 0;
|
||||
myMeta.tracks[finalMap].lastms = 0;
|
||||
|
@ -936,7 +937,7 @@ namespace Mist {
|
|||
//Add an entry into bufferLocations[tNum] for the pages we haven't handled yet.
|
||||
if (!locations.count(keyNum)) {
|
||||
locations[keyNum].curOffset = 0;
|
||||
VERYHIGH_MSG("Page %d detected, with %d keys", keyNum, Bit::btohl(tmpOffset+4));
|
||||
VERYHIGH_MSG("Page %lu detected, with %" PRIu32 " keys", keyNum, Bit::btohl(tmpOffset+4));
|
||||
}
|
||||
locations[keyNum].pageNum = keyNum;
|
||||
locations[keyNum].keyNum = Bit::btohl(tmpOffset+4);
|
||||
|
@ -948,7 +949,7 @@ namespace Mist {
|
|||
}
|
||||
|
||||
void inputBuffer::updateMetaFromPage(unsigned long tNum, unsigned long pageNum) {
|
||||
VERYHIGH_MSG("Updating meta for track %d page %d", tNum, pageNum);
|
||||
VERYHIGH_MSG("Updating meta for track %lu page %lu", tNum, pageNum);
|
||||
DTSCPageData & pageData = bufferLocations[tNum][pageNum];
|
||||
|
||||
//If the current page is over its 8mb "splitting" boundary
|
||||
|
|
12
src/io.cpp
12
src/io.cpp
|
@ -487,7 +487,7 @@ namespace Mist {
|
|||
continueNegotiate(tid, myMeta);
|
||||
//If the track is declined, stop here
|
||||
if (trackState[tid] == FILL_DEC) {
|
||||
INFO_MSG("Track %lu declined", tid);
|
||||
WARN_MSG("Track %lu declined", tid);
|
||||
preBuffer[tid].clear();
|
||||
return;
|
||||
}
|
||||
|
@ -496,7 +496,6 @@ namespace Mist {
|
|||
preBuffer[tid].push_back(packet);
|
||||
}else{
|
||||
if (preBuffer[tid].size()){
|
||||
INFO_MSG("Track %lu accepted as track %lu", tid, trackMap[tid] );
|
||||
while (preBuffer[tid].size()){
|
||||
bufferSinglePacket(preBuffer[tid].front(), myMeta);
|
||||
preBuffer[tid].pop_front();
|
||||
|
@ -543,13 +542,14 @@ namespace Mist {
|
|||
//If there is no page, create it
|
||||
if (!pagesByTrack.count(tid) || pagesByTrack[tid].size() == 0) {
|
||||
nextPageNum = 1;
|
||||
pagesByTrack[tid][1].dataSize = DEFAULT_DATA_PAGE_SIZE;//Initialize op 25mb
|
||||
pagesByTrack[tid][1].pageNum = 1;
|
||||
pagesByTrack[tid][1].firstTime = packet.getTime();
|
||||
pagesByTrack[tid][nextPageNum].dataSize = DEFAULT_DATA_PAGE_SIZE;//Initialize op 25mb
|
||||
pagesByTrack[tid][nextPageNum].pageNum = nextPageNum;
|
||||
pagesByTrack[tid][nextPageNum].curOffset = 0;
|
||||
pagesByTrack[tid][nextPageNum].firstTime = packet.getTime();
|
||||
}
|
||||
//Take the last allocated page
|
||||
std::map<unsigned long, DTSCPageData>::reverse_iterator tmpIt = pagesByTrack[tid].rbegin();
|
||||
int currentPageNum = tmpIt->second.pageNum;
|
||||
unsigned long currentPageNum = tmpIt->first;
|
||||
if (!pagesByTrack[tid][currentPageNum].curOffset) {
|
||||
pagesByTrack[tid][currentPageNum].firstTime = packet.getTime();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue