From 5f8518fe2397a3ae47c6459395d1f0cca6c565cd Mon Sep 17 00:00:00 2001 From: Thulinma Date: Fri, 19 Feb 2021 22:40:01 +0100 Subject: [PATCH] Fix playlist support not resuming on the correct page number and/or with the correct timestamp --- src/input/input.cpp | 68 ++++++++++++++++++++++++++------------ src/input/input_buffer.cpp | 11 +++--- src/io.cpp | 12 +++---- 3 files changed, 59 insertions(+), 32 deletions(-) diff --git a/src/input/input.cpp b/src/input/input.cpp index d8f762b8..f5f3c8e6 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -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::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 preFirstMs; + for (std::map::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::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::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::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::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();} diff --git a/src/input/input_buffer.cpp b/src/input/input_buffer.cpp index eea8e9c2..68296ff9 100644 --- a/src/input/input_buffer.cpp +++ b/src/input/input_buffer.cpp @@ -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::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 diff --git a/src/io.cpp b/src/io.cpp index a3448415..5a9dd10a 100644 --- a/src/io.cpp +++ b/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::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(); }