From 972315959248b4b4501cd142a790634367e5cb8b Mon Sep 17 00:00:00 2001 From: Thulinma Date: Wed, 4 Jul 2018 11:43:29 +0200 Subject: [PATCH] Improved selectDefaultTracks function to give feedback on selection changes. --- src/output/output.cpp | 29 ++++++++++++++++++++++++++--- src/output/output.h | 2 +- src/output/output_json.cpp | 6 ++++++ src/output/output_rtmp.cpp | 7 ++----- 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/output/output.cpp b/src/output/output.cpp index 20d94182..649679cf 100644 --- a/src/output/output.cpp +++ b/src/output/output.cpp @@ -255,16 +255,31 @@ namespace Mist{ } } - void Output::selectDefaultTracks(){ + /// Automatically selects the tracks that are possible and/or wanted. + /// Returns true if the track selection changed in any way. + bool Output::selectDefaultTracks(){ if (!isInitialized){ initialize(); - if (!isInitialized){return;} + if (!isInitialized){return false;} } + + //First, back up and wipe the existing selections, if any. + std::set oldSel = selectedTracks; + selectedTracks.clear(); + + bool autoSeek = buffer.size(); + uint64_t seekTarget = currentTime(); + //check which tracks don't actually exist std::set toRemove; for (std::set::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){ if (!myMeta.tracks.count(*it)){ toRemove.insert(*it); + continue; + } + //autoSeeking and target not in bounds? Drop it too. + if (autoSeek && myMeta.tracks[*it].lastms < seekTarget - 6000){ + toRemove.insert(*it); } } //remove those from selectedtracks @@ -344,6 +359,7 @@ namespace Mist{ if (myMeta.live){ for (std::map::reverse_iterator trit = myMeta.tracks.rbegin(); trit != myMeta.tracks.rend(); trit++){ if ((!byType && trit->second.codec == strRef.substr(shift)) || (byType && trit->second.type == strRef.substr(shift)) || strRef.substr(shift) == "*"){ + if (autoSeek && trit->second.lastms < seekTarget - 6000){continue;} selectedTracks.insert(trit->first); found = true; if (!multiSel){break;} @@ -352,6 +368,7 @@ namespace Mist{ }else{ for (std::map::iterator trit = myMeta.tracks.begin(); trit != myMeta.tracks.end(); trit++){ if ((!byType && trit->second.codec == strRef.substr(shift)) || (byType && trit->second.type == strRef.substr(shift)) || strRef.substr(shift) == "*"){ + if (autoSeek && trit->second.lastms < seekTarget - 6000){continue;} selectedTracks.insert(trit->first); found = true; if (!multiSel){break;} @@ -381,6 +398,12 @@ namespace Mist{ if (!selectedTracks.size() && myMeta.tracks.size() && capa["codecs"][bestSoFar].size()){ WARN_MSG("No tracks selected (%u total) for stream %s!", myMeta.tracks.size(), streamName.c_str()); } + bool madeChange = (oldSel != selectedTracks); + if (autoSeek && madeChange){ + INFO_MSG("Automatically seeking to position %llu to resume playback", seekTarget); + seek(seekTarget); + } + return madeChange; } /// Clears the buffer, sets parseData to false, and generally makes not very much happen at all. @@ -825,7 +848,7 @@ namespace Mist{ if (buffer.size() != selectedTracks.size()){ std::set dropTracks; if (buffer.size() < selectedTracks.size()){ - //prepare to drop any selectedTrack without buffe entry + //prepare to drop any selectedTrack without buffer entry for (std::set::iterator it = selectedTracks.begin(); it != selectedTracks.end(); ++it){ bool found = false; for (std::set::iterator bi = buffer.begin(); bi != buffer.end(); ++bi){ diff --git a/src/output/output.h b/src/output/output.h index d58cdfae..4db104be 100644 --- a/src/output/output.h +++ b/src/output/output.h @@ -51,7 +51,7 @@ namespace Mist { uint64_t endTime(); void setBlocking(bool blocking); void updateMeta(); - void selectDefaultTracks(); + bool selectDefaultTracks(); bool connectToFile(std::string file); static bool listenMode(){return true;} uint32_t currTrackCount() const; diff --git a/src/output/output_json.cpp b/src/output/output_json.cpp index ca7b682c..610619b1 100644 --- a/src/output/output_json.cpp +++ b/src/output/output_json.cpp @@ -28,6 +28,12 @@ namespace Mist { } void OutJSON::sendNext(){ + if (keepReselecting){ + //If we can select more tracks, do it and continue. + if (selectDefaultTracks()){ + return;//After a seek, the current packet is invalid. Do nothing and return here. + } + } JSON::Value jPack = thisPacket.toJSON(); if (dupcheck){ if (jPack.compareExcept(lastVal, nodup)){ diff --git a/src/output/output_rtmp.cpp b/src/output/output_rtmp.cpp index b0115571..27405122 100644 --- a/src/output/output_rtmp.cpp +++ b/src/output/output_rtmp.cpp @@ -160,12 +160,9 @@ namespace Mist { lastMeta = Util::epoch(); updateMeta(); if (myMeta.tracks.size() > 1){ - size_t prevTrackCount = selectedTracks.size(); - selectDefaultTracks(); - if (selectedTracks.size() > prevTrackCount){ - INFO_MSG("Picked up new track - selecting it and resetting state."); + if (selectDefaultTracks()){ + INFO_MSG("Track selection changed - resending headers and continuing"); sentHeader = false; - initialSeek(); return; } }