diff --git a/src/output/output.cpp b/src/output/output.cpp index 0cf9a10f..fce5158e 100644 --- a/src/output/output.cpp +++ b/src/output/output.cpp @@ -462,14 +462,21 @@ namespace Mist{ } /*LTS-END*/ - 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, wipe the existing selections, if any. + + //First, back up and wipe the existing selections, if any. + std::set oldSel = selectedTracks; selectedTracks.clear(); + bool autoSeek = buffer.size(); + uint64_t seekTarget = currentTime(); + /*LTS-START*/ bool noSelAudio = false, noSelVideo = false, noSelSub = false; //Then, select the tracks we've been asked to select. @@ -492,6 +499,11 @@ namespace Mist{ 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 @@ -571,6 +583,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;} /*LTS-START*/ if (noSelAudio && trit->second.type == "audio"){continue;} if (noSelVideo && trit->second.type == "video"){continue;} @@ -584,6 +597,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;} /*LTS-START*/ if (noSelAudio && trit->second.type == "audio"){continue;} if (noSelVideo && trit->second.type == "video"){continue;} @@ -618,6 +632,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. @@ -1280,6 +1300,7 @@ namespace Mist{ static int nonVideoCount = 0; static unsigned int emptyCount = 0; if (!buffer.size()){ + /// \TODO Do we really need this? Seems error-prone. if (isRecording() && myMeta.live){ selectDefaultTracks(); initialSeek(); @@ -1293,7 +1314,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 6d07c7eb..b59efd7f 100644 --- a/src/output/output.h +++ b/src/output/output.h @@ -56,7 +56,7 @@ namespace Mist { void setBlocking(bool blocking); void updateMeta(); void selectTrack(const std::string &trackType, const std::string &trackVal); /*LTS*/ - void selectDefaultTracks(); + bool selectDefaultTracks(); bool connectToFile(std::string file); static bool listenMode(){return true;} uint32_t currTrackCount() const; diff --git a/src/output/output_dtsc.cpp b/src/output/output_dtsc.cpp index bc39c16d..c3a6f0bb 100644 --- a/src/output/output_dtsc.cpp +++ b/src/output/output_dtsc.cpp @@ -121,12 +121,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; - seek(currentTime()); return; } } 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_progressive_flv.cpp b/src/output/output_progressive_flv.cpp index 5cd9efaf..1aea3a64 100644 --- a/src/output/output_progressive_flv.cpp +++ b/src/output/output_progressive_flv.cpp @@ -57,10 +57,8 @@ 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"); for (std::set::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){ if (myMeta.tracks[*it].type == "video" && tag.DTSCVideoInit(myMeta.tracks[*it])){ myConn.SendNow(tag.data, tag.len); @@ -69,7 +67,6 @@ namespace Mist { myConn.SendNow(tag.data, tag.len); } } - initialSeek(); return; } } diff --git a/src/output/output_rtmp.cpp b/src/output/output_rtmp.cpp index e23e772f..7de0b5d7 100644 --- a/src/output/output_rtmp.cpp +++ b/src/output/output_rtmp.cpp @@ -222,12 +222,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; } }