From 8d83a203bebf1756b92eeefc499cab1145cfb06c Mon Sep 17 00:00:00 2001 From: Thulinma Date: Mon, 14 Nov 2016 11:01:00 +0100 Subject: [PATCH] Added new generalized input keepRunning() function, FLV input now shuts down if the file is updated file it is active, added 15 second DTSH regeneration window --- src/input/input.cpp | 26 ++++++++++++++++++++------ src/input/input.h | 2 ++ src/input/input_flv.cpp | 24 ++++++++++++++++++++++++ src/input/input_flv.h | 2 ++ 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/input/input.cpp b/src/input/input.cpp index 91df1c0c..8a2ff609 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -81,7 +81,8 @@ namespace Mist { INSANE_MSG("No header exists to compare - ignoring header check"); return; } - if (bufHeader.st_mtime < bufStream.st_mtime) { + //the same second is not enough - add a 15 second window where we consider it too old + if (bufHeader.st_mtime < bufStream.st_mtime + 15) { INFO_MSG("Overwriting outdated DTSH header file: %s ", headerFile.c_str()); remove(headerFile.c_str()); } @@ -166,13 +167,17 @@ namespace Mist { char userPageName[NAME_BUFFER_SIZE]; snprintf(userPageName, NAME_BUFFER_SIZE, SHM_USERS, streamName.c_str()); userPage.init(userPageName, PLAY_EX_SIZE, true); - - DEBUG_MSG(DLVL_DEVEL,"Input for stream %s started", streamName.c_str()); - - long long int activityCounter = Util::bootSecs(); - while (((Util::bootSecs() - activityCounter) < INPUT_TIMEOUT || (myMeta.live && (Util::bootSecs() - activityCounter) < myMeta.biggestFragment()/500)) && config->is_active) { //15 second timeout + + DEBUG_MSG(DLVL_DEVEL, "Input for stream %s started", streamName.c_str()); + activityCounter = Util::bootSecs(); + //main serve loop + while (keepRunning()) { + //load pages for connected clients on request + //through the callbackWrapper function userPage.parseEach(callbackWrapper); + //unload pages that haven't been used for a while removeUnused(); + //If users are connected and tracks exist, reset the activity counter if (userPage.connectedUsers) { if (myMeta.tracks.size()){ activityCounter = Util::bootSecs(); @@ -181,6 +186,7 @@ namespace Mist { }else{ DEBUG_MSG(DLVL_INSANE, "Timer running"); } + //if not shutting down, wait 1 second before looping if (config->is_active){ Util::wait(1000); } @@ -190,6 +196,14 @@ namespace Mist { //end player functionality } + bool Input::keepRunning(){ + //We keep running in serve mode if the config is still active AND either + // - INPUT_TIMEOUT seconds haven't passed yet, + // - this is a live stream and at least two of the biggest fragment haven't passed yet, + bool ret = (config->is_active && ((Util::bootSecs() - activityCounter) < INPUT_TIMEOUT || (myMeta.live && (Util::bootSecs() - activityCounter) < myMeta.biggestFragment()/500))); + return ret; + } + /// Main loop for stream-style inputs. /// This loop will start the buffer without resume support, and then repeatedly call ..... followed by .... void Input::stream(){ diff --git a/src/input/input.h b/src/input/input.h index 996f4261..88d8ddd2 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -34,6 +34,7 @@ namespace Mist { virtual void getNext(bool smart = true) {}; virtual void seek(int seekTime){}; virtual void finish(); + virtual bool keepRunning(); virtual bool openStreamSource() { return false; }; virtual void closeStreamSource() {}; virtual void parseStreamHeader() {}; @@ -60,6 +61,7 @@ namespace Mist { unsigned int benchMark; bool isBuffer; + uint64_t activityCounter; JSON::Value capa; diff --git a/src/input/input_flv.cpp b/src/input/input_flv.cpp index 1065f6ef..9d8f6557 100644 --- a/src/input/input_flv.cpp +++ b/src/input/input_flv.cpp @@ -5,6 +5,9 @@ #include #include #include +#include //for stat +#include //for stat +#include //for stat #include #include #include @@ -46,9 +49,30 @@ namespace Mist { if (!inFile) { return false; } + struct stat statData; + lastModTime = 0; + if (stat(config->getString("input").c_str(), &statData) != -1){ + lastModTime = statData.st_mtime; + } return true; } + /// Overrides the default keepRunning function to shut down + /// if the file disappears or changes, by polling the file's mtime. + /// If neither applies, calls the original function. + bool inputFLV::keepRunning(){ + struct stat statData; + if (stat(config->getString("input").c_str(), &statData) == -1){ + INFO_MSG("Shutting down because input file disappeared"); + return false; + } + if (lastModTime != statData.st_mtime){ + INFO_MSG("Shutting down because input file changed"); + return false; + } + return Input::keepRunning(); + } + bool inputFLV::readHeader() { if (!inFile){return false;} //See whether a separate header file exists. diff --git a/src/input/input_flv.h b/src/input/input_flv.h index 66b85861..d2c438f1 100644 --- a/src/input/input_flv.h +++ b/src/input/input_flv.h @@ -13,7 +13,9 @@ namespace Mist { void getNext(bool smart = true); void seek(int seekTime); void trackSelect(std::string trackSpec); + bool keepRunning(); FLV::Tag tmpTag; + uint64_t lastModTime; FILE * inFile; }; }