diff --git a/lib/defines.h b/lib/defines.h index bc393c91..7853e0bc 100644 --- a/lib/defines.h +++ b/lib/defines.h @@ -107,6 +107,14 @@ static inline void show_stackframe(){} #define FLIP_MIN_DURATION 20000 #define SHM_STREAM_INDEX "MstSTRM%s" //%s stream name +#define SHM_STREAM_STATE "MstSTATE%s" //%s stream name +#define STRMSTAT_OFF 0 +#define STRMSTAT_INIT 1 +#define STRMSTAT_BOOT 2 +#define STRMSTAT_WAIT 3 +#define STRMSTAT_READY 4 +#define STRMSTAT_SHUTDOWN 5 +#define STRMSTAT_INVALID 255 #define SHM_TRACK_META "MstTRAK%s@%lu" //%s stream name, %lu track ID #define SHM_TRACK_INDEX "MstTRID%s@%lu" //%s stream name, %lu track ID #define SHM_TRACK_INDEX_SIZE 8192 diff --git a/lib/stream.cpp b/lib/stream.cpp index c67f22da..f7211552 100644 --- a/lib/stream.cpp +++ b/lib/stream.cpp @@ -299,3 +299,11 @@ bool Util::startInput(std::string streamname, std::string filename, bool forkFir return streamAlive(streamname); } +uint8_t Util::getStreamStatus(std::string & streamname){ + char pageName[NAME_BUFFER_SIZE]; + snprintf(pageName, NAME_BUFFER_SIZE, SHM_STREAM_STATE, streamname.c_str()); + IPC::sharedPage streamStatus(pageName, 1, false, false); + if (!streamStatus){return STRMSTAT_OFF;} + return streamStatus.mapped[0]; +} + diff --git a/lib/stream.h b/lib/stream.h index 837bf7ef..d42ebabe 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -12,5 +12,6 @@ namespace Util { bool streamAlive(std::string & streamname); bool startInput(std::string streamname, std::string filename = "", bool forkFirst = true, bool isProvider = false); JSON::Value getStreamConfig(std::string streamname); + uint8_t getStreamStatus(std::string & streamname); } diff --git a/src/input/input.cpp b/src/input/input.cpp index 08e7cfd9..b991cae3 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -114,6 +114,10 @@ namespace Mist { DEBUG_MSG(DLVL_DEVEL, "A player for stream %s is already running", streamName.c_str()); return 1; } + char pageName[NAME_BUFFER_SIZE]; + snprintf(pageName, NAME_BUFFER_SIZE, SHM_STREAM_STATE, streamName.c_str()); + streamStatus.init(pageName, 1, true, false); + if (streamStatus){streamStatus.mapped[0] = STRMSTAT_INIT;} } config->activate(); uint64_t reTimer = 0; @@ -142,6 +146,7 @@ namespace Mist { MEDIUM_MSG("Input for stream %s shut down cleanly", streamName.c_str()); break; } + if (streamStatus){streamStatus.mapped[0] = STRMSTAT_INVALID;} #if DEBUG >= DLVL_DEVEL WARN_MSG("Aborting autoclean; this is a development build."); INFO_MSG("Input for stream %s uncleanly shut down! Aborting restart; this is a development build.", streamName.c_str()); @@ -162,6 +167,7 @@ namespace Mist { } int Input::run() { + if (streamStatus){streamStatus.mapped[0] = STRMSTAT_BOOT;} checkHeaderTimes(config->getString("input")); if (!readHeader()){ std::cerr << "Reading header for " << config->getString("input") << " failed." << std::endl; @@ -256,6 +262,7 @@ namespace Mist { char userPageName[NAME_BUFFER_SIZE]; snprintf(userPageName, NAME_BUFFER_SIZE, SHM_USERS, streamName.c_str()); userPage.init(userPageName, PLAY_EX_SIZE, true); + if (streamStatus){streamStatus.mapped[0] = STRMSTAT_READY;} DEBUG_MSG(DLVL_DEVEL, "Input for stream %s started", streamName.c_str()); activityCounter = Util::bootSecs(); @@ -279,6 +286,7 @@ namespace Mist { Util::wait(1000); } } + if (streamStatus){streamStatus.mapped[0] = STRMSTAT_SHUTDOWN;} config->is_active = false; finish(); DEBUG_MSG(DLVL_DEVEL, "Input for stream %s closing clean", streamName.c_str()); diff --git a/src/input/input.h b/src/input/input.h index 9d11e430..de117e83 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -69,6 +69,7 @@ namespace Mist { //Create server for user pages IPC::sharedServer userPage; + IPC::sharedPage streamStatus; std::map > pageCounter; diff --git a/src/input/input_buffer.cpp b/src/input/input_buffer.cpp index 561ec99b..103424c0 100644 --- a/src/input/input_buffer.cpp +++ b/src/input/input_buffer.cpp @@ -394,6 +394,7 @@ namespace Mist { } } updateMeta(); + if (streamStatus){streamStatus.mapped[0] = hasPush ? STRMSTAT_READY : STRMSTAT_WAIT;} static bool everHadPush = false; if (hasPush) { hasPush = false;