From b0d4422d27ae3748a8989701a44ad20955d76620 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 22 Dec 2022 13:41:10 +0100 Subject: [PATCH] Added machine readable exit reasons, INPUT_END trigger, OUTPUT_END trigger, and updated RECORDING_END trigger to include all of these. --- lib/config.cpp | 12 +- lib/config.h | 12 +- lib/defines.h | 24 ++++ src/controller/controller.cpp | 1 + src/controller/controller_capabilities.cpp | 19 ++- src/input/input.cpp | 128 ++++++++++++++++----- src/input/input.h | 2 + src/input/input_aac.cpp | 44 +++---- src/input/input_av.cpp | 12 +- src/input/input_buffer.cpp | 2 +- src/input/input_dtsc.cpp | 28 +++-- src/input/input_dtsccrypt.cpp | 20 ++-- src/input/input_ebml.cpp | 21 +++- src/input/input_flac.cpp | 32 +++--- src/input/input_flv.cpp | 19 ++- src/input/input_folder.cpp | 16 +-- src/input/input_h264.cpp | 2 +- src/input/input_hls.cpp | 17 +-- src/input/input_ismv.cpp | 30 +++-- src/input/input_mp3.cpp | 23 ++-- src/input/input_mp4.cpp | 32 +++--- src/input/input_ogg.cpp | 9 +- src/input/input_playlist.cpp | 12 +- src/input/input_rtsp.cpp | 20 ++-- src/input/input_sdp.cpp | 14 ++- src/input/input_srt.cpp | 13 ++- src/input/input_ts.cpp | 27 +++-- src/input/input_tsrist.cpp | 8 +- src/input/input_tssrt.cpp | 4 +- src/io.cpp | 2 +- src/output/mist_out.cpp | 2 +- src/output/output.cpp | 80 ++++++++----- src/output/output.h | 3 + src/output/output_dtsc.cpp | 2 +- src/output/output_h264.cpp | 2 +- src/output/output_https.cpp | 10 +- src/output/output_mp4.cpp | 2 +- src/output/output_rtmp.cpp | 2 +- src/output/output_rtsp.cpp | 2 +- src/output/output_ts.cpp | 2 +- src/output/output_tsrist.cpp | 7 +- src/output/output_tssrt.cpp | 13 ++- src/output/output_webrtc.cpp | 2 +- src/process/process_exec.cpp | 1 + src/process/process_ffmpeg.cpp | 1 + src/process/process_livepeer.cpp | 7 +- src/session.cpp | 6 +- 47 files changed, 493 insertions(+), 256 deletions(-) diff --git a/lib/config.cpp b/lib/config.cpp index a0067920..ee3e7190 100644 --- a/lib/config.cpp +++ b/lib/config.cpp @@ -42,19 +42,21 @@ bool Util::Config::is_restarting = false; static Socket::Server *serv_sock_pointer = 0; uint32_t Util::printDebugLevel = DEBUG; __thread char Util::streamName[256] = {0}; -__thread char Util::exitReason[256] ={0}; - +__thread char Util::exitReason[256] = {0}; +__thread char* Util::mRExitReason = (char*)ER_UNKNOWN; +Util::binType Util::Config::binaryType = UNSET; void Util::setStreamName(const std::string & sn){ strncpy(Util::streamName, sn.c_str(), 256); } -void Util::logExitReason(const char *format, ...){ +void Util::logExitReason(const char* shortString, const char *format, ...){ if (exitReason[0]){return;} va_list args; va_start(args, format); vsnprintf(exitReason, 255, format, args); va_end(args); + mRExitReason = (char*)shortString; } std::string Util::listenInterface; @@ -597,9 +599,9 @@ void Util::Config::signal_handler(int signum, siginfo_t *sigInfo, void *ignore){ case SI_TIMER: case SI_ASYNCIO: case SI_MESGQ: - logExitReason("signal %s (%d) from process %d", strsignal(signum), signum, sigInfo->si_pid); + logExitReason(ER_CLEAN_SIGNAL, "signal %s (%d) from process %d", strsignal(signum), signum, sigInfo->si_pid); break; - default: logExitReason("signal %s (%d)", strsignal(signum), signum); + default: logExitReason(ER_CLEAN_SIGNAL, "signal %s (%d)", strsignal(signum), signum); } is_active = false; default: diff --git a/lib/config.h b/lib/config.h index 7c04a253..bf1eed98 100644 --- a/lib/config.h +++ b/lib/config.h @@ -17,7 +17,16 @@ namespace Util{ extern __thread char streamName[256]; ///< Used by debug messages to identify the stream name void setStreamName(const std::string & sn); extern __thread char exitReason[256]; - void logExitReason(const char *format, ...); + extern __thread char* mRExitReason; + void logExitReason(const char* shortString, const char *format, ...); + + enum binType { + UNSET, + INPUT, + OUTPUT, + PROCESS, + CONTROLLER + }; /// Deals with parsing configuration from commandline options. class Config{ @@ -30,6 +39,7 @@ namespace Util{ // variables static bool is_active; ///< Set to true by activate(), set to false by the signal handler. static bool is_restarting; ///< Set to true when restarting, set to false on boot. + static binType binaryType; // functions Config(); Config(std::string cmd); diff --git a/lib/defines.h b/lib/defines.h index be68782f..df239192 100644 --- a/lib/defines.h +++ b/lib/defines.h @@ -303,3 +303,27 @@ static inline void show_stackframe(){} #define SESS_HTTP_AS_UNSPECIFIED 4 #define SESS_TKN_DEFAULT_MODE 15 +#define ER_UNKNOWN "UNKNOWN" +#define ER_CLEAN_LIVE_BUFFER_REQ "CLEAN_LIVE_BUFFER_REQ" +#define ER_CLEAN_CONTROLLER_REQ "CLEAN_CONTROLLER_REQ" +#define ER_CLEAN_INTENDED_STOP "CLEAN_INTENDED_STOP" +#define ER_CLEAN_REMOTE_CLOSE "CLEAN_REMOTE_CLOSE" +#define ER_CLEAN_INACTIVE "CLEAN_INACTIVE" +#define ER_CLEAN_SIGNAL "CLEAN_SIGNAL" +#define ER_CLEAN_EOF "CLEAN_EOF" +#define ER_READ_START_FAILURE "READ_START_FAILURE" +#define ER_PROCESS_SPECIFIC "PROCESS_SPECIFIC" +#define ER_FORMAT_SPECIFIC "FORMAT_SPECIFIC" +#define ER_INTERNAL_ERROR "INTERNAL_ERROR" +#define ER_WRITE_FAILURE "WRITE_FAILURE" +#define ER_EXEC_FAILURE "EXEC_FAILURE" +#define ER_MEMORY "OUT_OF_MEMORY" +#define ER_SHM_LOST "SHM_LOST" +#define ER_UNSUPPORTED "UNSUPPORTED" +#define ER_SEGFAULT "SEGFAULT" +#define ER_TRIGGER "TRIGGER" +#define ER_SIGTRAP "SIGTRAP" +#define ER_SIGABRT "SIGABRT" +#define ER_SIGILL "SIGILL" +#define ER_SIGFPE "SIGFPE" +#define ER_SIGBUS "SIGBUS" diff --git a/src/controller/controller.cpp b/src/controller/controller.cpp index ca697abe..db9e4e91 100644 --- a/src/controller/controller.cpp +++ b/src/controller/controller.cpp @@ -629,6 +629,7 @@ int main(int argc, char **argv){ } Controller::conf = Util::Config(argv[0]); + Util::Config::binaryType = Util::CONTROLLER; Controller::conf.activate(); if (getenv("ATHEIST")){return main_loop(argc, argv);} uint64_t reTimer = 0; diff --git a/src/controller/controller_capabilities.cpp b/src/controller/controller_capabilities.cpp index b3729f2d..426edea2 100644 --- a/src/controller/controller_capabilities.cpp +++ b/src/controller/controller_capabilities.cpp @@ -115,6 +115,12 @@ namespace Controller{ trgs["STREAM_END"]["response"] = "ignored"; trgs["STREAM_END"]["response_action"] = "None."; + trgs["INPUT_ABORT"]["when"] = "Every time an Input process exits with an error"; + trgs["INPUT_ABORT"]["stream_specific"] = true; + trgs["INPUT_ABORT"]["payload"] = "stream name (string)\nsource URI (string)\nbinary name (string)\npid (integer)\nmachine-readable reason for exit (string, enum)\nhuman-readable reason for exit (string)"; + trgs["INPUT_ABORT"]["response"] = "ignored"; + trgs["INPUT_ABORT"]["response_action"] = "None."; + trgs["RTMP_PUSH_REWRITE"]["when"] = "On incoming RTMP pushes, allows rewriting the RTMP URL to/from custom formatting"; trgs["RTMP_PUSH_REWRITE"]["stream_specific"] = false; @@ -150,10 +156,21 @@ namespace Controller{ "(integer)\nseconds spent recording (integer)\nunix time recording started (integer)\nunix " "time recording stopped (integer)\ntotal milliseconds of media data recorded " "(integer)\nmillisecond timestamp of first media packet (integer)\nmillisecond timestamp " - "of last media packet (integer)\n"; + "of last media packet (integer)\nmachine-readable reason for exit (string, enum)\nhuman-readable reason for exit (string)"; trgs["RECORDING_END"]["response"] = "ignored"; trgs["RECORDING_END"]["response_action"] = "None."; + trgs["OUTPUT_END"]["when"] = "When an output finishes"; + trgs["OUTPUT_END"]["stream_specific"] = true; + trgs["OUTPUT_END"]["payload"] = + "stream name (string)\npush target (string)\nconnector / filetype (string)\nbytes recorded " + "(integer)\nseconds spent recording (integer)\nunix time output started (integer)\nunix " + "time output stopped (integer)\ntotal milliseconds of media data recorded " + "(integer)\nmillisecond timestamp of first media packet (integer)\nmillisecond timestamp " + "of last media packet (integer)\nmachine-readable reason for exit (string, enum)\nhuman-readable reason for exit (string)"; + trgs["OUTPUT_END"]["response"] = "ignored"; + trgs["OUTPUT_END"]["response_action"] = "None."; + trgs["CONN_OPEN"]["when"] = "After a new connection is accepted"; trgs["CONN_OPEN"]["stream_specific"] = true; trgs["CONN_OPEN"]["payload"] = "stream name (string)\nconnection address (string)\nconnector " diff --git a/src/input/input.cpp b/src/input/input.cpp index 24ae2597..83852ccf 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -93,6 +93,7 @@ namespace Mist{ Input::Input(Util::Config *cfg) : InOutBase(){ config = cfg; standAlone = true; + Util::Config::binaryType = Util::INPUT; JSON::Value option; option["long"] = "json"; @@ -399,8 +400,8 @@ namespace Mist{ } if (!checkArguments()){ - FAIL_MSG("Setup failed - exiting"); - return 0; + Util::logExitReason(ER_UNKNOWN, "Setup failed - exiting"); + return exitAndLogReason(); } IPC::semaphore playerLock; @@ -476,8 +477,12 @@ namespace Mist{ streamStatus.master = false; if (streamStatus){streamStatus.mapped[0] = STRMSTAT_INIT;} } - int ret = 0; - if (preRun()){ret = run();} + int ret = 1; + if (preRun()){ + ret = run(); + }else{ + return exitAndLogReason(); + } if (playerLock){ playerLock.unlink(); char pageName[NAME_BUFFER_SIZE]; @@ -514,7 +519,9 @@ namespace Mist{ // Abandon all semaphores, ye who enter here. playerLock.abandon(); pullLock.abandon(); - if (!preRun()){return 0;} + if (!preRun()){ + return exitAndLogReason(); + } return run(); } Util::Procs::fork_complete(); @@ -538,8 +545,9 @@ namespace Mist{ } HIGH_MSG("Done waiting for child for stream %s", streamName.c_str()); // if the exit was clean, don't restart it - if (WIFEXITED(status) && (WEXITSTATUS(status) == 0)){ - INFO_MSG("Input for stream %s shut down cleanly", streamName.c_str()); + int exitCode = WEXITSTATUS(status); + if (WIFEXITED(status) && (exitCode == 0 || exitCode == 1)){ + HIGH_MSG("Input for stream %s shut down cleanly", streamName.c_str()); break; } if (playerLock){ @@ -548,12 +556,49 @@ namespace Mist{ streamStatus.init(pageName, 2, false, false); if (streamStatus){streamStatus.mapped[0] = STRMSTAT_INVALID;} } -#if DEBUG >= DLVL_DEVEL + // Fire the INPUT_ABORT trigger if the child process ends with an abnormal exit code + // Prevents automatic restarts of the input for unrecoverable errors + if (WIFEXITED(status)){ + char exitReason[256]; + memcpy(exitReason, Util::exitReason, 256); + if (exitCode == 2){ + WARN_MSG("Child process %u exited with exit code %i (major error occurred), cleaning up...", pid, exitCode); + Util::logExitReason(ER_UNKNOWN, "Child process %u exited with exit code %i (major error occurred)", pid, exitCode); + }else if (exitCode == 132){ + WARN_MSG("Child process %u exited with exit code %i (SIGILL), cleaning up...", pid, exitCode); + Util::logExitReason(ER_SIGILL, "Child process %u exited with exit code %i (SIGILL)", pid, exitCode); + }else if (exitCode == 133){ + WARN_MSG("Child process %u exited with exit code %i (SIGTRAP)", pid, exitCode); + Util::logExitReason(ER_SIGTRAP, "Child process %u exited with exit code %i (SIGTRAP)", pid, exitCode); + }else if (exitCode == 134){ + WARN_MSG("Child process %u exited with exit code %i (SIGABRT)", pid, exitCode); + Util::logExitReason(ER_SIGABRT, "Child process %u exited with exit code %i (SIGABRT)", pid, exitCode); + }else if (exitCode == 136){ + WARN_MSG("Child process %u exited with exit code %i (SIGFPE)", pid, exitCode); + Util::logExitReason(ER_SIGFPE, "Child process %u exited with exit code %i (SIGFPE)", pid, exitCode); + }else if (exitCode == 137){ + WARN_MSG("Child process %u exited with exit code %i (used too much memory), cleaning up...", pid, exitCode); + Util::logExitReason(ER_MEMORY, "Child process %u exited with exit code %i (used too much memory)", pid, exitCode); + }else if (exitCode == 138){ + WARN_MSG("Child process %u exited with exit code %i (SIGBUS)", pid, exitCode); + Util::logExitReason(ER_SIGBUS, "Child process %u exited with exit code %i (SIGBUS)", pid, exitCode); + }else if (exitCode == 139){ + WARN_MSG("Child process %u exited with exit code %i (SEGFAULT)", pid, exitCode); + Util::logExitReason(ER_SEGFAULT, "Child process %u exited with exit code %i (SEGFAULT)", pid, exitCode); + }else{ + WARN_MSG("Child process %u exited with an unhandled exit code %i, cleaning up...", pid, exitCode); + Util::logExitReason(ER_UNKNOWN, "Child process %u exited with an unhandled exit code %i", pid, exitCode); + } + doInputAbortTrigger(pid, Util::mRExitReason, Util::exitReason); + memcpy(Util::exitReason, exitReason, 256); + } + + #if DEBUG >= DLVL_DEVEL WARN_MSG( "Input for stream %s uncleanly shut down! Aborting restart; this is a development build.", streamName.c_str()); break; -#else + #else if (config->is_active){ WARN_MSG("Input for stream %s uncleanly shut down! Cleaning and restarting...", streamName.c_str()); }else{ @@ -609,8 +654,8 @@ namespace Mist{ if (needHeader()){ uint64_t timer = Util::getMicros(); if (!readHeader() || (!M && needsLock())){ - FAIL_MSG("Reading header for '%s' failed.", config->getString("input").c_str()); - return 0; + Util::logExitReason(ER_READ_START_FAILURE, "Reading header for '%s' failed", config->getString("input").c_str()); + return exitAndLogReason(); } timer = Util::getMicros(timer); INFO_MSG("Created header in %.3f ms (%zu tracks)", (double)timer/1000.0, M?M.trackCount():(size_t)0); @@ -639,7 +684,7 @@ namespace Mist{ INFO_MSG("Starting serve"); serve(); } - return 0; + return exitAndLogReason(); } void Input::convert(){ @@ -694,6 +739,40 @@ namespace Mist{ outMeta.toFile(fileName + ".dtsh"); } + // Fires the `INPUT_ABORT` trigger. Allows overrides to allow parent processes + // to fire the trigger for child processes which have already exited (EG segfaults) + void Input::doInputAbortTrigger(pid_t pid, char *mRExitReason, char *exitReason){ + // Calculate variables required for the trigger + if (Util::Config::binaryType == Util::INPUT && Triggers::shouldTrigger("INPUT_ABORT", streamName)){ + std::ostringstream pidString; + pidString << pid; + std::string payload = streamName + "\n" + config->getString("input") + "\n" \ + + "MistIn" + capa["name"].asString() + "\n" + pidString.str() + "\n" \ + + mRExitReason + "\n" + exitReason; + Triggers::doTrigger("INPUT_ABORT", payload, streamName); + } + } + + // Logs the current exit reason and returns a 0 or 1 depending on whether + // this was a clean exit or not + bool Input::exitAndLogReason(){ + int returnCode = 1; + // If no reason is set at all, return the default status + if (!Util::exitReason[0]){ + INFO_MSG("Input closing without a set exit reason"); + }else if(strncmp(Util::mRExitReason, "CLEAN", 5) == 0){ + INFO_MSG("Input closing cleanly with reason: %s", Util::exitReason); + returnCode = 0; + }else{ + WARN_MSG("Input closing unclean, reason: %s", Util::exitReason); + } + // If this is an unclean exit, fire the INPUT_ABORT trigger + if (returnCode){ + doInputAbortTrigger(getpid(), Util::mRExitReason, Util::exitReason); + } + return returnCode; + } + /// Checks in the server configuration if this stream is set to always on or not. /// Returns true if it is, or if the stream could not be found in the configuration. /// If the compiled default debug level is < INFO, instead returns false if the stream is not found. @@ -748,7 +827,7 @@ namespace Mist{ if (Triggers::shouldTrigger("STREAM_READY", config->getString("streamname"))){ std::string payload = config->getString("streamname") + "\n" + capa["name"].asStringRef(); if (!Triggers::doTrigger("STREAM_READY", payload, config->getString("streamname"))){ - Util::logExitReason("STREAM_READY trigger returned false"); + Util::logExitReason(ER_TRIGGER, "STREAM_READY trigger returned false"); config->is_active = false; } } @@ -789,7 +868,6 @@ namespace Mist{ config->is_active = false; } finish(); - INFO_MSG("Input closing clean, reason: %s", Util::exitReason); userSelect.clear(); if (!isThread()){ if (streamStatus){streamStatus.mapped[0] = STRMSTAT_OFF;} @@ -837,7 +915,7 @@ namespace Mist{ } /*LTS-END*/ if (!ret && ((Util::bootSecs() - activityCounter) >= INPUT_TIMEOUT)){ - Util::logExitReason("no activity for %u seconds", Util::bootSecs() - activityCounter); + Util::logExitReason(ER_CLEAN_INACTIVE, "no activity for %u seconds", Util::bootSecs() - activityCounter); } return ret; } @@ -882,14 +960,13 @@ namespace Mist{ if (config->getBool("realtime")){ realtimeMainLoop(); finish(); - INFO_MSG("Real-time input closing clean; reason: %s", Util::exitReason); return; } meta.reInit(streamName, false); if (!openStreamSource()){ - FAIL_MSG("Unable to connect to source"); + Util::logExitReason(ER_READ_START_FAILURE, "Unable to connect to source"); return; } parseStreamHeader(); @@ -897,9 +974,9 @@ namespace Mist{ if (publishesTracks()){ std::set validTracks = M.getMySourceTracks(getpid()); if (!validTracks.size()){ + Util::logExitReason(ER_CLEAN_EOF, "No tracks found, cancelling pull"); userSelect.clear(); finish(); - INFO_MSG("No tracks found, cancelling"); return; } } @@ -908,7 +985,6 @@ namespace Mist{ closeStreamSource(); userSelect.clear(); finish(); - INFO_MSG("Input closing clean; reason: %s", Util::exitReason); return; } @@ -929,17 +1005,17 @@ namespace Mist{ } while (thisPacket && config->is_active && userSelect[thisIdx]){ if (userSelect[thisIdx].getStatus() & COMM_STATUS_REQDISCONNECT){ - Util::logExitReason("buffer requested shutdown"); + Util::logExitReason(ER_CLEAN_LIVE_BUFFER_REQ, "buffer requested shutdown"); break; } if (isSingular() && !bufferActive()){ - Util::logExitReason("Buffer shut down"); + Util::logExitReason(ER_SHM_LOST, "Buffer shut down"); return; } bufferLivePacket(thisPacket); getNext(); if (!thisPacket){ - Util::logExitReason("no more data"); + Util::logExitReason(ER_CLEAN_EOF, "no more data"); break; } if (thisPacket && !userSelect.count(thisIdx)){ @@ -952,7 +1028,7 @@ namespace Mist{ if (statComm){ if (!statComm){ config->is_active = false; - Util::logExitReason("received shutdown request from controller"); + Util::logExitReason(ER_CLEAN_CONTROLLER_REQ, "received shutdown request from controller"); return; } uint64_t now = Util::bootSecs(); @@ -1080,7 +1156,7 @@ namespace Mist{ while (config->is_active){ getNext(); if (!thisPacket){ - Util::logExitReason("no more data"); + Util::logExitReason(ER_CLEAN_EOF, "no more data"); break; } idx = realTimeTrackMap.count(thisIdx) ? realTimeTrackMap[thisIdx] : INVALID_TRACK_ID; @@ -1088,7 +1164,7 @@ namespace Mist{ userSelect[idx].reload(streamName, idx, COMM_STATUS_ACTIVE | COMM_STATUS_SOURCE | COMM_STATUS_DONOTTRACK); } if (userSelect[idx].getStatus() & COMM_STATUS_REQDISCONNECT){ - Util::logExitReason("buffer requested shutdown"); + Util::logExitReason(ER_CLEAN_LIVE_BUFFER_REQ, "buffer requested shutdown"); break; } while (config->is_active && userSelect[idx] && @@ -1114,7 +1190,7 @@ namespace Mist{ if (statComm){ if (statComm.getStatus() & COMM_STATUS_REQDISCONNECT){ config->is_active = false; - Util::logExitReason("received shutdown request from controller"); + Util::logExitReason(ER_CLEAN_CONTROLLER_REQ, "received shutdown request from controller"); return; } uint64_t now = Util::bootSecs(); diff --git a/src/input/input.h b/src/input/input.h index 63ada152..57b9a0f0 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -95,6 +95,8 @@ namespace Mist{ virtual void connStats(Comms::Connections & statComm); virtual void parseHeader(); bool bufferFrame(size_t track, uint32_t keyNum); + void doInputAbortTrigger(pid_t pid, char *mRExitReason, char *exitReason); + bool exitAndLogReason(); uint64_t activityCounter; diff --git a/src/input/input_aac.cpp b/src/input/input_aac.cpp index ba697dae..1d15f846 100644 --- a/src/input/input_aac.cpp +++ b/src/input/input_aac.cpp @@ -80,12 +80,12 @@ namespace Mist{ bool inputAAC::checkArguments(){ if (!config->getString("streamname").size()){ if (config->getString("output") == "-"){ - std::cerr << "Output to stdout not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Output to stdout not yet supported"); return false; } }else{ if (config->getString("output") != "-"){ - std::cerr << "File output in player mode not supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "File output in player mode not supported"); return false; } } @@ -94,7 +94,10 @@ namespace Mist{ bool inputAAC::preRun(){ inFile.open(config->getString("input")); - if (!inFile || inFile.isEOF()){return false;} + if (!inFile || inFile.isEOF()){ + Util::logExitReason(ER_READ_START_FAILURE, "Reading header for '%s' failed: Could not open input stream", config->getString("input").c_str()); + return false; + } struct stat statData; lastModTime = 0; @@ -131,7 +134,7 @@ namespace Mist{ size_t bytesRead = 0; if (!inFile || inFile.isEOF()){ - INFO_MSG("Could not open input stream"); + Util::logExitReason(ER_READ_START_FAILURE, "Reading header for '%s' failed: Could not open input stream", config->getString("input").c_str()); return false; } @@ -140,15 +143,12 @@ namespace Mist{ // Read fixed + variable header inFile.readSome(aacData, bytesRead, 6); if (bytesRead < 6){ - WARN_MSG("Not enough bytes left in buffer. Quitting..."); - // Dump for debug purposes - INFO_MSG("Header contains bytes: %x %x %x %x %x %x", aacData[0] - , aacData[1], aacData[2], aacData[3], aacData[4], aacData[5]); + Util::logExitReason(ER_READ_START_FAILURE, "Reading header for '%s' failed: Not enough bytes left in buffer", config->getString("input").c_str()); return false; } // Confirm syncword (= FFF) if (aacData[0] != 0xFF || (aacData[1] & 0xF0) != 0xF0){ - WARN_MSG("Invalid sync word at start of header"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Reading header for '%s' failed: Invalid sync word at start of header", config->getString("input").c_str()); return false; } // Calculate the starting position of the next frame @@ -172,7 +172,7 @@ namespace Mist{ // Create ADTS object of complete frame info aac::adts adtsPack(aacFrame, frameSize); if (!adtsPack){ - WARN_MSG("Could not parse ADTS package!"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Reading header for '%s' failed: Could not parse ADTS package", config->getString("input").c_str()); return false; } @@ -231,7 +231,7 @@ namespace Mist{ size_t disregardAmount = 0; if (!inFile || inFile.isEOF()){ - INFO_MSG("Reached EOF"); + Util::logExitReason(ER_CLEAN_EOF, "Reached EOF"); return; } @@ -251,9 +251,10 @@ namespace Mist{ aacData[3] == 0x54 && aacData[4] == 0x41 && aacData[5] == 0x47){ inFile.readAll(aacData, bytesRead); INFO_MSG("Throwing out %zu bytes of metadata...", bytesRead); + Util::logExitReason(ER_CLEAN_EOF, "Reached EOF"); return; } - WARN_MSG("Invalid sync word at start of header"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Invalid sync word at start of header"); return; } // Calculate the starting position of the next frame @@ -278,21 +279,7 @@ namespace Mist{ // Create ADTS object of frame aac::adts adtsPack(aacFrame, frameSize); if (!adtsPack){ - WARN_MSG("Could not parse ADTS package!"); - WARN_MSG("Current frame info:"); - WARN_MSG("Current frame pos: %zu", filePos); - WARN_MSG("Next frame pos: %zu", nextFramePos); - WARN_MSG("Frame size expected: %" PRIu64, frameSize); - WARN_MSG("Bytes read: %zu", bytesRead); - WARN_MSG("ADTS getAACProfile: %li", adtsPack.getAACProfile()); - WARN_MSG("ADTS getFrequencyIndex: %li", adtsPack.getFrequencyIndex()); - WARN_MSG("ADTS getFrequency: %li", adtsPack.getFrequency()); - WARN_MSG("ADTS getChannelConfig: %li", adtsPack.getChannelConfig()); - WARN_MSG("ADTS getChannelCount: %li", adtsPack.getChannelCount()); - WARN_MSG("ADTS getHeaderSize: %li", adtsPack.getHeaderSize()); - WARN_MSG("ADTS getPayloadSize: %li", adtsPack.getPayloadSize()); - WARN_MSG("ADTS getCompleteSize: %li", adtsPack.getCompleteSize()); - WARN_MSG("ADTS getSampleCount: %li", adtsPack.getSampleCount()); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Could not parse ADTS package"); return; } @@ -313,8 +300,7 @@ namespace Mist{ if (trks.size()){ audioTrack = *(trks.begin()); }else{ - Util::logExitReason("no audio track in header"); - FAIL_MSG("No audio track in header - aborting"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "No audio track in header"); return; } } diff --git a/src/input/input_av.cpp b/src/input/input_av.cpp index 3863acb6..7850c405 100644 --- a/src/input/input_av.cpp +++ b/src/input/input_av.cpp @@ -43,17 +43,17 @@ namespace Mist{ bool inputAV::checkArguments(){ if (config->getString("input") == "-"){ - std::cerr << "Input from stdin not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Input from stdin not yet supported"); return false; } if (!config->getString("streamname").size()){ if (config->getString("output") == "-"){ - std::cerr << "Output to stdout not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Output to stdout not yet supported"); return false; } }else{ if (config->getString("output") != "-"){ - std::cerr << "File output in player mode not supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "File output in player mode not supported"); return false; } } @@ -79,7 +79,7 @@ namespace Mist{ if (ret != 0){ char errstr[300]; av_strerror(ret, errstr, 300); - FAIL_MSG("Could not open file: %s", errstr); + Util::logExitReason(ER_READ_START_FAILURE, "Could not open file: %s", errstr); return false; // Couldn't open file } @@ -88,7 +88,7 @@ namespace Mist{ if (ret < 0){ char errstr[300]; av_strerror(ret, errstr, 300); - FAIL_MSG("Could not find stream info: %s", errstr); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Could not find stream info: %s", errstr); return false; } return true; @@ -195,7 +195,7 @@ namespace Mist{ thisPacket.null(); preRun(); // failure :-( - FAIL_MSG("getNext failed"); + Util::logExitReason(ER_UNKNOWN, "getNext failed"); } void inputAV::seek(uint64_t seekTime, size_t idx){ diff --git a/src/input/input_buffer.cpp b/src/input/input_buffer.cpp index d1ccfbcf..c974e4e5 100644 --- a/src/input/input_buffer.cpp +++ b/src/input/input_buffer.cpp @@ -489,7 +489,7 @@ namespace Mist{ } if (hasPush){everHadPush = true;} if (!hasPush && everHadPush && !resumeMode && config->is_active){ - Util::logExitReason("source disconnected for non-resumable stream"); + Util::logExitReason(ER_CLEAN_EOF, "source disconnected for non-resumable stream"); if (streamStatus){streamStatus.mapped[0] = STRMSTAT_SHUTDOWN;} config->is_active = false; userSelect.clear(); diff --git a/src/input/input_dtsc.cpp b/src/input/input_dtsc.cpp index 35d1387b..f71d0cd9 100644 --- a/src/input/input_dtsc.cpp +++ b/src/input/input_dtsc.cpp @@ -210,12 +210,12 @@ namespace Mist{ if (!needsLock()){return true;} if (!config->getString("streamname").size()){ if (config->getString("output") == "-"){ - std::cerr << "Output to stdout not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Output to stdout not yet supported"); return false; } }else{ if (config->getString("output") != "-"){ - std::cerr << "File output in player mode not supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "File output in player mode not supported"); return false; } } @@ -223,7 +223,7 @@ namespace Mist{ // open File F = fopen(config->getString("input").c_str(), "r+b"); if (!F){ - HIGH_MSG("Could not open file %s", config->getString("input").c_str()); + Util::logExitReason(ER_READ_START_FAILURE, "Could not open file %s", config->getString("input").c_str()); return false; } fseek(F, 0, SEEK_SET); @@ -236,17 +236,20 @@ namespace Mist{ } bool inputDTSC::readHeader(){ - if (!F){return false;} + if (!F){ + Util::logExitReason(ER_READ_START_FAILURE, "Reading header for '%s' failed: Could not open input stream", config->getString("input").c_str()); + return false; + } size_t moreHeader = 0; do{ char hdr[8]; fseek(F, moreHeader, SEEK_SET); if (fread(hdr, 8, 1, F) != 1){ - FAIL_MSG("Could not read header @ bpos %zu", moreHeader); + Util::logExitReason(ER_READ_START_FAILURE, "Reading header for '%s' failed: Could not read header @ bpos %zu", config->getString("input").c_str(), moreHeader); return false; } if (memcmp(hdr, DTSC::Magic_Header, 4)){ - FAIL_MSG("File does not have a DTSC header @ bpos %zu", moreHeader); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Reading header for '%s' failed: File does not have a DTSC header @ bpos %zu", config->getString("input").c_str(), moreHeader); return false; } size_t pktLen = Bit::btohl(hdr + 4); @@ -283,6 +286,7 @@ namespace Mist{ fseek(F, thisPos.bytePos, SEEK_SET); if (feof(F)){ thisPacket.null(); + Util::logExitReason(ER_CLEAN_EOF, "End of file reached"); return; } clearerr(F); @@ -290,9 +294,9 @@ namespace Mist{ lastreadpos = ftell(F); if (fread(buffer, 4, 1, F) != 1){ if (feof(F)){ - INFO_MSG("End of file reached while seeking @ %" PRIu64, lastreadpos); + Util::logExitReason(ER_CLEAN_EOF, "End of file reached while seeking @ %" PRIu64, lastreadpos); }else{ - ERROR_MSG("Could not seek to next @ %" PRIu64, lastreadpos); + Util::logExitReason(ER_UNKNOWN, "Could not seek to next @ %" PRIu64, lastreadpos); } thisPacket.null(); return; @@ -306,13 +310,13 @@ namespace Mist{ if (memcmp(buffer, DTSC::Magic_Packet, 4) == 0){version = 1;} if (memcmp(buffer, DTSC::Magic_Packet2, 4) == 0){version = 2;} if (version == 0){ - ERROR_MSG("Invalid packet header @ %#" PRIx64 " - %.4s != %.4s @ %" PRIu64, lastreadpos, + Util::logExitReason(ER_FORMAT_SPECIFIC, "Invalid packet header @ %#" PRIx64 " - %.4s != %.4s @ %" PRIu64, lastreadpos, buffer, DTSC::Magic_Packet2, lastreadpos); thisPacket.null(); return; } if (fread(buffer + 4, 4, 1, F) != 1){ - ERROR_MSG("Could not read packet size @ %" PRIu64, lastreadpos); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Could not read packet size @ %" PRIu64, lastreadpos); thisPacket.null(); return; } @@ -321,7 +325,7 @@ namespace Mist{ pBuf.resize(8 + packSize); memcpy((char *)pBuf.data(), buffer, 8); if (fread((void *)(pBuf.data() + 8), packSize, 1, F) != 1){ - ERROR_MSG("Could not read packet @ %" PRIu64, lastreadpos); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Could not read packet @ %" PRIu64, lastreadpos); thisPacket.null(); return; } @@ -353,7 +357,7 @@ namespace Mist{ } if (cmd == "error"){ thisPacket.getString("msg", cmd); - Util::logExitReason("%s", cmd.c_str()); + Util::logExitReason(ER_FORMAT_SPECIFIC, "%s", cmd.c_str()); thisPacket.null(); return; } diff --git a/src/input/input_dtsccrypt.cpp b/src/input/input_dtsccrypt.cpp index 3a75648d..dec6a4d6 100644 --- a/src/input/input_dtsccrypt.cpp +++ b/src/input/input_dtsccrypt.cpp @@ -56,7 +56,7 @@ namespace Mist{ key = Encodings::Base64::decode(config->getString("key")); if (key == ""){ if (config->getString("keyseed") == "" || config->getString("keyid") == ""){ - std::cerr << "No key given, and no keyseed/keyid geven" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "No key given, and no keyseed/keyid given"); return false; } std::string tmpSeed = Encodings::Base64::decode(config->getString("keyseed")); @@ -66,29 +66,35 @@ namespace Mist{ } if (config->getString("input") == "-"){ - std::cerr << "Input from stdin not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Input from stdin not yet supported"); return false; } if (!config->getString("streamname").size()){ if (config->getString("output") == "-"){ - std::cerr << "Output to stdout not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Output to stdout not yet supported"); return false; } }else{ if (config->getString("output") != "-"){ - std::cerr << "File output in player mode not supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "File output in player mode not supported"); return false; } } // open File inFile = DTSC::File(config->getString("input")); - if (!inFile){return false;} + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Opening input '%s' failed", config->getString("input").c_str()); + return false; + } return true; } bool inputDTSC::readHeader(){ - if (!inFile){return false;} + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Reading header for '%s' failed: Could not open input stream", config->getString("input").c_str()); + return false; + } DTSC::File tmp(config->getString("input") + ".dtsh"); if (tmp){ myMeta = tmp.getMeta(); @@ -96,7 +102,7 @@ namespace Mist{ return true; } if (inFile.getMeta().moreheader < 0 || inFile.getMeta().tracks.size() == 0){ - DEBUG_MSG(DLVL_FAIL, "Missing external header file"); + Util::logExitReason(ER_READ_START_FAILURE, "Missing external header file"); return false; } myMeta = DTSC::Meta(inFile.getMeta()); diff --git a/src/input/input_ebml.cpp b/src/input/input_ebml.cpp index 64abb994..2530a447 100644 --- a/src/input/input_ebml.cpp +++ b/src/input/input_ebml.cpp @@ -105,12 +105,12 @@ namespace Mist{ bool InputEBML::checkArguments(){ if (!config->getString("streamname").size()){ if (config->getString("output") == "-"){ - std::cerr << "Output to stdout not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Output to stdout not yet supported"); return false; } }else{ if (config->getString("output") != "-"){ - std::cerr << "File output in player mode not supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "File output in player mode not supported"); return false; } } @@ -150,7 +150,10 @@ namespace Mist{ int fin = -1, fout = -1; Util::Procs::StartPiped(args, &fin, &fout, 0); - if (fout == -1){return false;} + if (fout == -1){ + Util::logExitReason(ER_PROCESS_SPECIFIC, "Unable to start mkv-exec process `%s`", args); + return false; + } dup2(fout, 0); inFile.open(0); return true; @@ -161,7 +164,10 @@ namespace Mist{ }else{ // open File inFile.open(config->getString("input")); - if (!inFile){return false;} + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Opening input '%s' failed", config->getString("input").c_str()); + return false; + } standAlone = inFile.isSeekable(); } return true; @@ -261,7 +267,10 @@ namespace Mist{ } bool InputEBML::readHeader(){ - if (!inFile){return false;} + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Reading header for '%s' failed: Could not open input stream", config->getString("input").c_str()); + return false; + } if (!meta || (needsLock() && isSingular())){ meta.reInit(isSingular() ? streamName : ""); } @@ -728,7 +737,7 @@ namespace Mist{ } } if (seekPos > readPos + readBuffer.size()){ - Util::logExitReason("Input file seek abort"); + Util::logExitReason(ER_READ_START_FAILURE, "Input file seek abort"); config->is_active = false; readBufferOffset = 0; return; diff --git a/src/input/input_flac.cpp b/src/input/input_flac.cpp index 38ca3a89..fc7e1d21 100644 --- a/src/input/input_flac.cpp +++ b/src/input/input_flac.cpp @@ -40,17 +40,17 @@ namespace Mist{ bool inputFLAC::checkArguments(){ if (config->getString("input") == "-"){ - std::cerr << "Input from stdin not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Input from stdin not yet supported"); return false; } if (!config->getString("streamname").size()){ if (config->getString("output") == "-"){ - std::cerr << "Output to stdout not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Output to stdout not yet supported"); return false; } }else{ if (config->getString("output") != "-"){ - std::cerr << "File output in player mode not supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "File output in player mode not supported"); return false; } } @@ -59,7 +59,10 @@ namespace Mist{ bool inputFLAC::preRun(){ inFile = fopen(config->getString("input").c_str(), "r"); - if (!inFile){return false;} + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Opening input '%s' failed", config->getString("input").c_str()); + return false; + } return true; } @@ -81,7 +84,7 @@ namespace Mist{ bool inputFLAC::readMagicPacket(){ char magic[4]; if (fread(magic, 4, 1, inFile) != 1){ - FAIL_MSG("Could not read magic word - aborting!"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Could not read magic word - aborting!"); return false; } @@ -90,12 +93,15 @@ namespace Mist{ return true; } - FAIL_MSG("Not a FLAC file - aborting!"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Not a FLAC file - aborting!"); return false; } bool inputFLAC::readHeader(){ - if (!inFile){return false;} + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Opening input '%s' failed", config->getString("input").c_str()); + return false; + } if (readExistingHeader()){ WARN_MSG("header exists, read old one"); @@ -118,7 +124,7 @@ namespace Mist{ char metahead[4]; while (!feof(inFile) && !lastMeta){ if (fread(metahead, 4, 1, inFile) != 1){ - FAIL_MSG("Could not read metadata block header - aborting!"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Could not read metadata block header - aborting!"); return false; } @@ -132,7 +138,7 @@ namespace Mist{ char metaTmp[bytes]; if (fread(metaTmp, bytes, 1, inFile) != 1){ - FAIL_MSG("Could not read streaminfo metadata - aborting!"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Could not read streaminfo metadata - aborting!"); return false; } @@ -147,8 +153,8 @@ namespace Mist{ blockSize = (metaTmp[0] << 8 | metaTmp[1]); if ((metaTmp[2] << 8 | metaTmp[3]) != blockSize){ - FAIL_MSG("variable block size not supported!"); - return 1; + Util::logExitReason(ER_FORMAT_SPECIFIC, "variable block size not supported!"); + return false; } sampleRate = ((metaTmp[10] << 12) | (metaTmp[11] << 4) | ((metaTmp[12] & 0xf0) >> 4)); @@ -174,11 +180,11 @@ namespace Mist{ } if (!sampleRate){ - FAIL_MSG("Could not get sample rate from file header"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Could not get sample rate from file header"); return false; } if (!channels){ - FAIL_MSG("no channel information found!"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "no channel information found!"); return false; } diff --git a/src/input/input_flv.cpp b/src/input/input_flv.cpp index 2409fc49..828f47c7 100644 --- a/src/input/input_flv.cpp +++ b/src/input/input_flv.cpp @@ -32,17 +32,17 @@ namespace Mist{ bool inputFLV::checkArguments(){ if (config->getString("input") == "-"){ - std::cerr << "Input from stdin not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Input from stdin not yet supported"); return false; } if (!config->getString("streamname").size()){ if (config->getString("output") == "-"){ - std::cerr << "Output to stdout not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Output to stdout not yet supported"); return false; } }else{ if (config->getString("output") != "-"){ - std::cerr << "File output in player mode not supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "File output in player mode not supported"); return false; } } @@ -52,7 +52,10 @@ namespace Mist{ bool inputFLV::preRun(){ // open File inFile = fopen(config->getString("input").c_str(), "r"); - if (!inFile){return false;} + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Opening input '%s' failed", config->getString("input").c_str()); + return false; + } struct stat statData; lastModTime = 0; if (stat(config->getString("input").c_str(), &statData) != -1){ @@ -78,7 +81,10 @@ namespace Mist{ } bool inputFLV::readHeader(){ - if (!inFile){return false;} + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Reading header for '%s' failed: Could not open input stream", config->getString("input").c_str()); + return false; + } meta.reInit(isSingular() ? streamName : ""); // Create header file from FLV data Util::fseek(inFile, 13, SEEK_SET); @@ -128,13 +134,14 @@ namespace Mist{ } } if (feof(inFile)){ + Util::logExitReason(ER_CLEAN_EOF, "Reached EOF"); thisPacket.null(); return; } if (FLV::Parse_Error){ FLV::Parse_Error = false; tmpTag = FLV::Tag(); - FAIL_MSG("FLV error @ %" PRIu64 ": %s", lastBytePos, FLV::Error_Str.c_str()); + Util::logExitReason(ER_FORMAT_SPECIFIC, "FLV error @ %" PRIu64 ": %s", lastBytePos, FLV::Error_Str.c_str()); thisPacket.null(); return; } diff --git a/src/input/input_folder.cpp b/src/input/input_folder.cpp index 5d9f13a6..007b1e25 100644 --- a/src/input/input_folder.cpp +++ b/src/input/input_folder.cpp @@ -27,27 +27,27 @@ namespace Mist{ streamName = config->getString("streamname"); if (streamName.find_first_of("+ ") == std::string::npos){ - FAIL_MSG("Folder input requires a + or space in the stream name."); - return 1; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Folder input requires a + or space in the stream name."); + return exitAndLogReason(); } std::string folder = config->getString("input"); if (folder[folder.size() - 1] != '/'){ - FAIL_MSG("Input path must end in a forward slash."); - return 1; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Input path must end in a forward slash."); + return exitAndLogReason(); } std::string folder_noslash = folder.substr(0, folder.size() - 1); struct stat fileCheck; if (stat(folder_noslash.c_str(), &fileCheck) != 0 || !S_ISDIR(fileCheck.st_mode)){ - FAIL_MSG("Folder input requires a folder as input."); - return 1; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Folder input requires a folder as input."); + return exitAndLogReason(); } std::string path = folder + streamName.substr(streamName.find_first_of("+ ") + 1); if (stat(path.c_str(), &fileCheck) != 0 || S_ISDIR(fileCheck.st_mode)){ - FAIL_MSG("File not found: %s", path.c_str()); - return 1; + Util::logExitReason(ER_FORMAT_SPECIFIC, "File not found: %s", path.c_str()); + return exitAndLogReason(); } Util::startInput(streamName, path, false); diff --git a/src/input/input_h264.cpp b/src/input/input_h264.cpp index f374c84f..5de7610f 100644 --- a/src/input/input_h264.cpp +++ b/src/input/input_h264.cpp @@ -66,7 +66,7 @@ namespace Mist{ bool InputH264::checkArguments(){ std::string input = config->getString("input"); if (input != "-" && input.substr(0, 10) != "h264-exec:"){ - FAIL_MSG("Unsupported input type: %s", input.c_str()); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Unsupported input type: %s", input.c_str()); return false; } return true; diff --git a/src/input/input_hls.cpp b/src/input/input_hls.cpp index 80eb1e24..e527134e 100644 --- a/src/input/input_hls.cpp +++ b/src/input/input_hls.cpp @@ -740,7 +740,10 @@ namespace Mist{ return false; } - if (!initPlaylist(config->getString("input"), false)){return false;} + if (!initPlaylist(config->getString("input"), false)){ + Util::logExitReason(ER_UNKNOWN, "Failed to load HLS playlist, aborting"); + return false; + } // If the playlist is of event type, init the amount of segments in the playlist if (isLiveDVR){ @@ -756,7 +759,7 @@ namespace Mist{ void inputHLS::parseStreamHeader(){ if (!initPlaylist(config->getString("input"))){ - FAIL_MSG("Failed to load HLS playlist, aborting"); + Util::logExitReason(ER_UNKNOWN, "Failed to load HLS playlist, aborting"); return; } meta.reInit(isSingular() ? streamName : "", false); @@ -1195,7 +1198,7 @@ namespace Mist{ tsStream.getPacket(tid, thisPacket); } if (!thisPacket){ - FAIL_MSG("Could not getNext TS packet!"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Could not getNext TS packet!"); return; } @@ -1256,7 +1259,7 @@ namespace Mist{ // Nothing works! // HLS input will now quit trying to prevent severe mental depression. - INFO_MSG("No packets can be read - exhausted all playlists"); + Util::logExitReason(ER_CLEAN_EOF, "No packets can be read - exhausted all playlists"); thisPacket.null(); return; } @@ -1481,14 +1484,14 @@ namespace Mist{ INFO_MSG("Downloading main playlist file from '%s'", uri.c_str()); HTTP::URIReader plsDL; if (!plsDL.open(playlistRootPath) || !plsDL){ - FAIL_MSG("Could not open main playlist, aborting"); + Util::logExitReason(ER_READ_START_FAILURE, "Could not open main playlist, aborting"); return false; } char * dataPtr; size_t dataLen; plsDL.readAll(dataPtr, dataLen); if (!dataLen){ - FAIL_MSG("Could not download main playlist, aborting."); + Util::logExitReason(ER_READ_START_FAILURE, "Could not download main playlist, aborting."); return false; } urlSource.str(std::string(dataPtr, dataLen)); @@ -1503,7 +1506,7 @@ namespace Mist{ } fileSource.open(playlistLocation.c_str()); if (!fileSource.good()){ - FAIL_MSG("Could not open playlist (%s): %s", strerror(errno), playlistLocation.c_str()); + Util::logExitReason(ER_READ_START_FAILURE, "Could not open playlist (%s): %s", strerror(errno), playlistLocation.c_str()); } } diff --git a/src/input/input_ismv.cpp b/src/input/input_ismv.cpp index a642f70b..db9228f3 100644 --- a/src/input/input_ismv.cpp +++ b/src/input/input_ismv.cpp @@ -24,17 +24,17 @@ namespace Mist{ bool inputISMV::checkArguments(){ if (config->getString("input") == "-"){ - std::cerr << "Input from stdin not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Input from stdin not yet supported"); return false; } if (!config->getString("streamname").size()){ if (config->getString("output") == "-"){ - std::cerr << "Output to stdout not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Output to stdout not yet supported"); return false; } }else{ if (config->getString("output") != "-"){ - std::cerr << "File output in player mode not supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "File output in player mode not supported"); return false; } } @@ -43,11 +43,18 @@ namespace Mist{ bool inputISMV::preRun(){ inFile = fopen(config->getString("input").c_str(), "r"); - return inFile; // True if not null + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Opening input '%s' failed", config->getString("input").c_str()); + return false; + } + return true; } bool inputISMV::readHeader(){ - if (!inFile){return false;} + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Reading header for '%s' failed: Could not open input stream", config->getString("input").c_str()); + return false; + } meta.reInit(streamName); // parse ismv header fseek(inFile, 0, SEEK_SET); @@ -189,7 +196,10 @@ namespace Mist{ MP4::MOOF moof; moof.read(inFile); - if (feof(inFile)){return false;} + if (feof(inFile)){ + Util::logExitReason(ER_CLEAN_EOF, "Reached EOF"); + return false; + } MP4::TRAF trafBox = moof.getChild(); for (size_t j = 0; j < trafBox.getContentCount(); j++){ @@ -205,7 +215,11 @@ namespace Mist{ } MP4::skipBox(inFile); - return !feof(inFile); + if (feof(inFile)){ + Util::logExitReason(ER_CLEAN_EOF, "Reached EOF"); + return false; + } + return true; } void inputISMV::bufferFragmentData(size_t trackId, uint32_t keyNum){ @@ -230,7 +244,7 @@ namespace Mist{ if (trafBox.getContent(j).isType("trun")){trunBox = (MP4::TRUN &)trafBox.getContent(j);} if (trafBox.getContent(j).isType("tfhd")){ if (M.getID(trackId) != ((MP4::TFHD &)trafBox.getContent(j)).getTrackID()){ - FAIL_MSG("Trackids do not match"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Trackids do not match"); return; } } diff --git a/src/input/input_mp3.cpp b/src/input/input_mp3.cpp index 473866fc..c1391651 100644 --- a/src/input/input_mp3.cpp +++ b/src/input/input_mp3.cpp @@ -25,17 +25,17 @@ namespace Mist{ bool inputMP3::checkArguments(){ if (config->getString("input") == "-"){ - std::cerr << "Input from stdin not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Input from stdin not yet supported"); return false; } if (!config->getString("streamname").size()){ if (config->getString("output") == "-"){ - std::cerr << "Output to stdout not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Output to stdout not yet supported"); return false; } }else{ if (config->getString("output") != "-"){ - std::cerr << "File output in player mode not supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "File output in player mode not supported"); return false; } } @@ -45,12 +45,18 @@ namespace Mist{ bool inputMP3::preRun(){ // open File inFile = fopen(config->getString("input").c_str(), "r"); - if (!inFile){return false;} + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Opening input '%s' failed", config->getString("input").c_str()); + return false; + } return true; } bool inputMP3::readHeader(){ - if (!inFile){return false;} + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Reading header for '%s' failed: Could not open input stream", config->getString("input").c_str()); + return false; + } meta.reInit(isSingular() ? streamName : ""); size_t tNum = meta.addTrack(); meta.setID(tNum, tNum); @@ -93,7 +99,10 @@ namespace Mist{ static char packHeader[3000]; size_t filePos = ftell(inFile); size_t read = fread(packHeader, 1, 3000, inFile); - if (!read){return;} + if (!read){ + Util::logExitReason(ER_CLEAN_EOF, "Reached EOF"); + return; + } if (packHeader[0] != 0xFF || (packHeader[1] & 0xE0) != 0xE0){ // Find the first occurence of sync byte char *i = (char *)memchr(packHeader, (char)0xFF, read); @@ -107,7 +116,7 @@ namespace Mist{ } } if (!offset){ - FAIL_MSG("Sync byte not found from offset %zu", filePos); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Sync byte not found from offset %zu", filePos); return; } filePos += offset; diff --git a/src/input/input_mp4.cpp b/src/input/input_mp4.cpp index 73f8dec6..342c1612 100644 --- a/src/input/input_mp4.cpp +++ b/src/input/input_mp4.cpp @@ -127,17 +127,17 @@ namespace Mist{ bool inputMP4::checkArguments(){ if (config->getString("input") == "-"){ - std::cerr << "Input from stdin not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Input from stdin not yet supported"); return false; } if (!config->getString("streamname").size()){ if (config->getString("output") == "-"){ - std::cerr << "Output to stdout not yet supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Output to stdout not yet supported"); return false; } }else{ if (config->getString("output") != "-"){ - std::cerr << "File output in player mode not supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "File output in player mode not supported"); return false; } streamName = config->getString("streamname"); @@ -148,9 +148,12 @@ namespace Mist{ bool inputMP4::preRun(){ // open File inFile.open(config->getString("input")); - if (!inFile){return false;} + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Could not open URL or contains no data"); + return false; + } if (!inFile.isSeekable()){ - FAIL_MSG("MP4 input only supports seekable data sources, for now, and this source is not seekable: %s", config->getString("input").c_str()); + Util::logExitReason(ER_READ_START_FAILURE, "MP4 input only supports seekable data sources, for now, and this source is not seekable: %s", config->getString("input").c_str()); return false; } return true; @@ -168,7 +171,7 @@ namespace Mist{ bool inputMP4::readHeader(){ if (!inFile){ - Util::logExitReason("Could not open input file"); + Util::logExitReason(ER_READ_START_FAILURE, "Reading header for '%s' failed: Could not open input stream", config->getString("input").c_str()); return false; } bool hasMoov = false; @@ -183,7 +186,7 @@ namespace Mist{ while (readBuffer.size() < 16 && inFile && keepRunning()){inFile.readSome(16, *this);} //Failed? Abort. if (readBuffer.size() < 16){ - FAIL_MSG("Could not read box header from input!"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Could not read box header from input!"); break; } //Box type is always on bytes 5-8 from the start of a box @@ -192,7 +195,7 @@ namespace Mist{ if (boxType == "moov"){ while (readBuffer.size() < boxSize && inFile && keepRunning()){inFile.readSome(boxSize-readBuffer.size(), *this);} if (readBuffer.size() < boxSize){ - FAIL_MSG("Could not read entire MOOV box into memory"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Could not read entire MOOV box into memory"); break; } MP4::Box moovBox(readBuffer, false); @@ -221,8 +224,11 @@ namespace Mist{ } if (!hasMoov){ - if (!inFile){Util::logExitReason("URIReader for source file was disconnected!");} - Util::logExitReason("No MOOV box found in source file; aborting!"); + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Reading header for '%s' failed: URIReader for source file was disconnected!", config->getString("input").c_str()); + }else{ + Util::logExitReason(ER_FORMAT_SPECIFIC, "Reading header for '%s' failed: No MOOV box found in source file; aborting!", config->getString("input").c_str()); + } return false; } @@ -515,7 +521,7 @@ namespace Mist{ INFO_MSG("Buffer contains %" PRIu64 "-%" PRIu64 ", but we need %" PRIu64 "; seeking!", readPos, readPos + readBuffer.size(), curPart.bpos); readBuffer.truncate(0); if (!inFile.seek(curPart.bpos)){ - FAIL_MSG("seek unsuccessful @bpos %" PRIu64 ": %s", curPart.bpos, strerror(errno)); + Util::logExitReason(ER_FORMAT_SPECIFIC, "seek unsuccessful @bpos %" PRIu64 ": %s", curPart.bpos, strerror(errno)); thisPacket.null(); return; } @@ -536,7 +542,7 @@ namespace Mist{ FAIL_MSG("Read unsuccessful at %" PRIu64 ", seeking to retry...", readPos+readBuffer.size()); readBuffer.truncate(0); if (!inFile.seek(curPart.bpos)){ - FAIL_MSG("seek unsuccessful @bpos %" PRIu64 ": %s", curPart.bpos, strerror(errno)); + Util::logExitReason(ER_FORMAT_SPECIFIC, "seek unsuccessful @bpos %" PRIu64 ": %s", curPart.bpos, strerror(errno)); thisPacket.null(); return; } @@ -545,7 +551,7 @@ namespace Mist{ inFile.readSome((curPart.bpos+curPart.size) - (readPos+readBuffer.size()), *this); } if (readPos+readBuffer.size() < curPart.bpos+curPart.size){ - FAIL_MSG("Read retry unsuccessful at %" PRIu64 ", aborting", readPos+readBuffer.size()); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Read retry unsuccessful at %" PRIu64 ", aborting", readPos+readBuffer.size()); thisPacket.null(); return; } diff --git a/src/input/input_ogg.cpp b/src/input/input_ogg.cpp index 7689a189..a5e4a2ab 100644 --- a/src/input/input_ogg.cpp +++ b/src/input/input_ogg.cpp @@ -54,7 +54,10 @@ namespace Mist{ bool inputOGG::preRun(){ // open File inFile = fopen(config->getString("input").c_str(), "r"); - if (!inFile){return false;} + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Opening input '%s' failed", config->getString("input").c_str()); + return false; + } return true; } @@ -142,7 +145,7 @@ namespace Mist{ size_t len = myPage.getSegmentLen(i); theora::header tmpHead((char *)myPage.getSegment(i), len); if (!tmpHead.isHeader()){// not copying the header anymore, should this check isHeader? - FAIL_MSG("Theora Header read failed!"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Reading header for '%s' failed: Theora header read failed", config->getString("input").c_str()); return false; } switch (tmpHead.getHeaderType()){ @@ -174,7 +177,7 @@ namespace Mist{ size_t len = myPage.getSegmentLen(i); vorbis::header tmpHead((char *)myPage.getSegment(i), len); if (!tmpHead.isHeader()){ - FAIL_MSG("Header read failed!"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Reading header for '%s' failed: Header read failed", config->getString("input").c_str()); return false; } switch (tmpHead.getHeaderType()){ diff --git a/src/input/input_playlist.cpp b/src/input/input_playlist.cpp index 7e132040..dc355f17 100644 --- a/src/input/input_playlist.cpp +++ b/src/input/input_playlist.cpp @@ -22,17 +22,17 @@ namespace Mist{ bool inputPlaylist::checkArguments(){ if (config->getString("input") == "-"){ - std::cerr << "Input from stdin not supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Input from stdin not yet supported"); return false; } if (!config->getString("streamname").size()){ if (config->getString("output") == "-"){ - std::cerr << "Output to stdout not supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "Output to stdout not yet supported"); return false; } }else{ if (config->getString("output") != "-"){ - std::cerr << "File output not supported" << std::endl; + Util::logExitReason(ER_FORMAT_SPECIFIC, "File output in player mode not supported"); return false; } } @@ -45,7 +45,7 @@ namespace Mist{ killSwitch.reload(streamName, (size_t)INVALID_TRACK_ID, (uint8_t)(COMM_STATUS_ACTIVE | COMM_STATUS_DONOTTRACK)); while (config->is_active){ if (killSwitch && killSwitch.getStatus() & COMM_STATUS_REQDISCONNECT){ - Util::logExitReason("buffer requested shutdown"); + Util::logExitReason(ER_CLEAN_LIVE_BUFFER_REQ, "buffer requested shutdown"); config->is_active = false; break; } @@ -55,7 +55,7 @@ namespace Mist{ wallTime = wTime->tm_hour * 60 + wTime->tm_min; reloadPlaylist(); if (!playlist.size()){ - Util::logExitReason("No entries in playlist"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "No entries in playlist"); return; } ++playlistIndex; @@ -112,7 +112,7 @@ namespace Mist{ seenValidEntry = true; while (Util::Procs::isRunning(spawn_pid) && config->is_active){ if (killSwitch && killSwitch.getStatus() & COMM_STATUS_REQDISCONNECT){ - Util::logExitReason("buffer requested shutdown"); + Util::logExitReason(ER_CLEAN_LIVE_BUFFER_REQ, "buffer requested shutdown"); config->is_active = false; break; } diff --git a/src/input/input_rtsp.cpp b/src/input/input_rtsp.cpp index 59b25e1f..dbb2cf52 100644 --- a/src/input/input_rtsp.cpp +++ b/src/input/input_rtsp.cpp @@ -122,12 +122,12 @@ namespace Mist{ bool InputRTSP::checkArguments(){ const std::string &inpt = config->getString("input"); if (inpt.substr(0, 7) != "rtsp://"){ - FAIL_MSG("Unsupported RTSP URL: '%s'", inpt.c_str()); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Unsupported RTSP URL: '%s'", inpt.c_str()); return false; } const std::string &transport = config->getString("transport"); if (transport != "TCP" && transport != "UDP" && transport != "tcp" && transport != "udp"){ - FAIL_MSG("Not a supported transport mode: %s", transport.c_str()); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Not a supported transport mode: %s", transport.c_str()); return false; } if (transport == "UDP" || transport == "udp"){TCPmode = false;} @@ -142,7 +142,11 @@ namespace Mist{ bool InputRTSP::openStreamSource(){ tcpCon.open(url.host, url.getPort(), false); mainConn = &tcpCon; - return tcpCon; + if (!tcpCon){ + Util::logExitReason(ER_READ_START_FAILURE, "Opening TCP socket `%s:%s` failed", url.host.c_str(), url.getPort()); + return false; + } + return true; } void InputRTSP::parseStreamHeader(){ @@ -152,7 +156,7 @@ namespace Mist{ extraHeaders["Accept"] = "application/sdp"; sendCommand("DESCRIBE", url.getUrl(), "", &extraHeaders); if (!tcpCon || !seenSDP){ - FAIL_MSG("Could not get stream description!"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Could not get stream description!"); return; } if (sdpState.tracks.size()){ @@ -178,7 +182,7 @@ namespace Mist{ atLeastOne = true; continue; } - FAIL_MSG("Could not setup track %s!", M.getTrackIdentifier(it->first).c_str()); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Could not setup track %s!", M.getTrackIdentifier(it->first).c_str()); tcpCon.close(); return; } @@ -214,7 +218,7 @@ namespace Mist{ if (statComm){ if (statComm.getStatus() & COMM_STATUS_REQDISCONNECT){ config->is_active = false; - Util::logExitReason("received shutdown request from controller"); + Util::logExitReason(ER_CLEAN_CONTROLLER_REQ, "received shutdown request from controller"); return; } uint64_t now = Util::bootSecs(); @@ -229,7 +233,7 @@ namespace Mist{ } } if (!tcpCon){ - Util::logExitReason("TCP connection closed"); + Util::logExitReason(ER_CLEAN_REMOTE_CLOSE, "TCP connection closed"); } } @@ -402,7 +406,7 @@ namespace Mist{ userSelect[idx].reload(streamName, idx, COMM_STATUS_ACTIVE | COMM_STATUS_SOURCE | COMM_STATUS_DONOTTRACK); } if (userSelect[idx].getStatus() & COMM_STATUS_REQDISCONNECT){ - Util::logExitReason("buffer requested shutdown"); + Util::logExitReason(ER_CLEAN_LIVE_BUFFER_REQ, "buffer requested shutdown"); tcpCon.close(); } } diff --git a/src/input/input_sdp.cpp b/src/input/input_sdp.cpp index 4132905b..036b64c0 100644 --- a/src/input/input_sdp.cpp +++ b/src/input/input_sdp.cpp @@ -77,7 +77,7 @@ namespace Mist{ bool InputSDP::checkArguments(){ const std::string &inpt = config->getString("input"); if (inpt.substr(inpt.length() - 4) != ".sdp"){ - FAIL_MSG("Expected a SDP file but received: '%s'", inpt.c_str()); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Expected a SDP file but received: '%s'", inpt.c_str()); return false; } return true; @@ -88,13 +88,17 @@ namespace Mist{ const std::string &inpt = config->getString("input"); reader.open(inpt); // Will return false if it cant open file or it is EOF - return reader; + if (!reader){ + Util::logExitReason(ER_READ_START_FAILURE, "Opening input '%s' failed", config->getString("input").c_str()); + return false; + } + return true; } /// Gets and parses the SDP file void InputSDP::parseStreamHeader(){ if (!reader){ - FAIL_MSG("Connection lost with input. Could not get stream description!"); + Util::logExitReason(ER_READ_START_FAILURE, "Connection lost with input. Could not get stream description!"); return; } @@ -206,7 +210,7 @@ namespace Mist{ if (statComm){ if (statComm.getStatus() == COMM_STATUS_REQDISCONNECT){ config->is_active = false; - Util::logExitReason("received shutdown request from controller"); + Util::logExitReason(ER_CLEAN_CONTROLLER_REQ, "received shutdown request from controller"); return; } uint64_t now = Util::bootSecs(); @@ -312,7 +316,7 @@ namespace Mist{ userSelect[idx].reload(streamName, idx, COMM_STATUS_ACTIVE | COMM_STATUS_SOURCE | COMM_STATUS_DONOTTRACK); } if (userSelect[idx].getStatus() == COMM_STATUS_REQDISCONNECT){ - Util::logExitReason("buffer requested shutdown"); + Util::logExitReason(ER_CLEAN_LIVE_BUFFER_REQ, "buffer requested shutdown"); } } diff --git a/src/input/input_srt.cpp b/src/input/input_srt.cpp index d990dba5..926e3b5f 100644 --- a/src/input/input_srt.cpp +++ b/src/input/input_srt.cpp @@ -17,7 +17,7 @@ namespace Mist{ fileSource.close(); fileSource.open(config->getString("input").c_str()); if (!fileSource.is_open()){ - FAIL_MSG("Could not open file %s: %s", config->getString("input").c_str(), strerror(errno)); + Util::logExitReason(ER_READ_START_FAILURE, "Could not open file %s: %s", config->getString("input").c_str(), strerror(errno)); return false; } return true; @@ -25,7 +25,7 @@ namespace Mist{ bool InputSrt::checkArguments(){ if (config->getString("input") == "-"){ - FAIL_MSG("Reading from standard input not yet supported"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Input from stdin not yet supported"); return false; }else{ preRun(); @@ -33,12 +33,12 @@ namespace Mist{ if (!config->getString("streamname").size()){ if (config->getString("output") == "-"){ - FAIL_MSG("Writing to standard output not yet supported"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Output to stdout not yet supported"); return false; } }else{ if (config->getString("output") != "-"){ - FAIL_MSG("File output in player mode not supported"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "File output in player mode not supported"); return false; } } @@ -46,7 +46,10 @@ namespace Mist{ } bool InputSrt::readHeader(){ - if (!fileSource.good()){return false;} + if (!fileSource.good()){ + Util::logExitReason(ER_READ_START_FAILURE, "Reading header for '%s' failed: Could not open input stream", config->getString("input").c_str()); + return false; + } size_t idx = meta.addTrack(); meta.setID(idx, 1); meta.setType(idx, "meta"); diff --git a/src/input/input_ts.cpp b/src/input/input_ts.cpp index 36a0cae5..a94d2e9e 100644 --- a/src/input/input_ts.cpp +++ b/src/input/input_ts.cpp @@ -353,7 +353,11 @@ namespace Mist{ FILE * inFile = fopen(inCfg.c_str() + 9, "r"); reader.open(fileno(inFile)); standAlone = false; - return inFile; + if (!inFile){ + Util::logExitReason(ER_READ_START_FAILURE, "Opening input '%s' failed", inCfg.c_str()); + return false; + } + return true; } //Anything else, read through URIReader HTTP::URL url = HTTP::localURIResolver().link(inCfg); @@ -361,7 +365,11 @@ namespace Mist{ if (url.protocol == "https-ts"){url.protocol = "https";} reader.open(url); standAlone = reader.isSeekable(); - return reader; + if (!reader){ + Util::logExitReason(ER_READ_START_FAILURE, "Opening input '%s' failed", inCfg.c_str()); + return false; + } + return true; } void inputTS::dataCallback(const char *ptr, size_t size){ @@ -387,7 +395,10 @@ namespace Mist{ /// for a specific track to metadata. After the entire stream has been read, /// it writes the remaining metadata. bool inputTS::readHeader(){ - if (!reader){return false;} + if (!reader){ + Util::logExitReason(ER_READ_START_FAILURE, "Reading header for '%s' failed: Could not open input stream", config->getString("input").c_str()); + return false; + } meta.reInit(isSingular() ? streamName : ""); TS::Packet packet; // to analyse and extract data DTSC::Packet headerPack; @@ -471,7 +482,7 @@ namespace Mist{ } if (!thisPacket){ - INFO_MSG("Could not getNext TS packet!"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Could not getNext TS packet!"); return; } tsStream.initializeMetadata(meta); @@ -583,7 +594,7 @@ namespace Mist{ } if (!reader){ config->is_active = false; - Util::logExitReason("end of streamed input"); + Util::logExitReason(ER_CLEAN_EOF, "end of streamed input"); return; } }else{ @@ -635,7 +646,7 @@ namespace Mist{ if (statComm){ if (statComm.getStatus() & COMM_STATUS_REQDISCONNECT){ config->is_active = false; - Util::logExitReason("received shutdown request from controller"); + Util::logExitReason(ER_CLEAN_CONTROLLER_REQ, "received shutdown request from controller"); return; } uint64_t now = Util::bootSecs(); @@ -654,7 +665,7 @@ namespace Mist{ if (hasStarted && !threadTimer.size()){ if (!isAlwaysOn()){ config->is_active = false; - Util::logExitReason("no active threads and we had input in the past"); + Util::logExitReason(ER_CLEAN_INACTIVE, "no active threads and we had input in the past"); return; }else{ liveStream.clear(); @@ -686,7 +697,7 @@ namespace Mist{ if (Util::bootSecs() - noDataSince > 20){ if (!isAlwaysOn()){ config->is_active = false; - Util::logExitReason("no packets received for 20 seconds"); + Util::logExitReason(ER_CLEAN_INACTIVE, "no packets received for 20 seconds"); return; }else{ noDataSince = Util::bootSecs(); diff --git a/src/input/input_tsrist.cpp b/src/input/input_tsrist.cpp index f694bedf..ef079338 100644 --- a/src/input/input_tsrist.cpp +++ b/src/input/input_tsrist.cpp @@ -167,7 +167,7 @@ namespace Mist{ standAlone = false; HTTP::URL u(source); if (u.protocol != "rist"){ - FAIL_MSG("Input protocol must begin with rist://"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "Input protocol must begin with rist://"); return false; } std::map arguments; @@ -184,7 +184,7 @@ namespace Mist{ while (!hasRaw && config->is_active){ Util::sleep(50); if (!bufferActive()){ - Util::logExitReason("Buffer shut down"); + Util::logExitReason(ER_SHM_LOST, "Buffer shut down"); return; } } @@ -198,7 +198,7 @@ namespace Mist{ }else{ Util::sleep(50); if (!bufferActive()){ - Util::logExitReason("Buffer shut down"); + Util::logExitReason(ER_SHM_LOST, "Buffer shut down"); return; } } @@ -224,7 +224,7 @@ namespace Mist{ void inputTSRIST::onFail(const std::string & msg){ FAIL_MSG("%s", msg.c_str()); - Util::logExitReason(msg.c_str()); + Util::logExitReason(ER_FORMAT_SPECIFIC, msg.c_str()); } bool inputTSRIST::openStreamSource(){ diff --git a/src/input/input_tssrt.cpp b/src/input/input_tssrt.cpp index 025feacb..bd142ab9 100644 --- a/src/input/input_tssrt.cpp +++ b/src/input/input_tssrt.cpp @@ -229,9 +229,9 @@ namespace Mist{ if (!thisPacket){ if (srtConn){ INFO_MSG("Could not getNext TS packet!"); - Util::logExitReason("internal TS parser error"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "internal TS parser error"); }else{ - Util::logExitReason("SRT connection close"); + Util::logExitReason(ER_CLEAN_REMOTE_CLOSE, "SRT connection close"); } return; } diff --git a/src/io.cpp b/src/io.cpp index b2af874a..0e2cf07a 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -471,7 +471,7 @@ namespace Mist{ if (!livePage[packTrack].exists()){ WARN_MSG("Data page '%s' was deleted - forcing source shutdown to prevent unstable state", livePage[packTrack].name.c_str()); - Util::logExitReason("data page was deleted, forcing shutdown to prevent unstable state"); + Util::logExitReason(ER_SHM_LOST, "data page was deleted, forcing shutdown to prevent unstable state"); bufferFinalize(packTrack, livePage[packTrack]); kill(getpid(), SIGINT); return; diff --git a/src/output/mist_out.cpp b/src/output/mist_out.cpp index b2eefee5..454106a0 100644 --- a/src/output/mist_out.cpp +++ b/src/output/mist_out.cpp @@ -20,7 +20,7 @@ int spawnForked(Socket::Connection &S){ void handleUSR1(int signum, siginfo_t *sigInfo, void *ignore){ HIGH_MSG("USR1 received - triggering rolling restart"); Util::Config::is_restarting = true; - Util::logExitReason("signal USR1"); + Util::logExitReason(ER_CLEAN_SIGNAL, "signal USR1"); Util::Config::is_active = false; } diff --git a/src/output/output.cpp b/src/output/output.cpp index 78800d38..bec82727 100644 --- a/src/output/output.cpp +++ b/src/output/output.cpp @@ -113,6 +113,7 @@ namespace Mist{ firstData = true; newUA = true; lastPushUpdate = 0; + Util::Config::binaryType = Util::OUTPUT; lastRecv = Util::bootSecs(); if (myConn){ @@ -185,7 +186,7 @@ namespace Mist{ }else{ MEDIUM_MSG("onFail '%s': %s", streamName.c_str(), msg.c_str()); } - Util::logExitReason(msg.c_str()); + Util::logExitReason(ER_UNKNOWN, msg.c_str()); isInitialized = false; wantRequest = false; parseData = false; @@ -1519,12 +1520,14 @@ namespace Mist{ if (!streamName.size()){ WARN_MSG("Recording unconnected %s output to file! Cancelled.", capa["name"].asString().c_str()); onFail("Unconnected recording output", true); + recEndTrigger(); return 2; } initialize(); if (!M.getValidTracks().size() || !userSelect.size() || !keepGoing()){ INFO_MSG("Stream not available - aborting"); onFail("Stream not available for recording", true); + recEndTrigger(); return 3; } initialSeek(); @@ -1562,6 +1565,7 @@ namespace Mist{ }else{ if (!connectToFile(newTarget, targetParams.count("append"))){ onFail("Could not connect to the target for recording", true); + recEndTrigger(); return 3; } INFO_MSG("Recording %s to %s with %s format", streamName.c_str(), @@ -1752,7 +1756,7 @@ namespace Mist{ INFO_MSG("Switching to next push target filename: %s", newTarget.c_str()); if (!connectToFile(newTarget)){ FAIL_MSG("Failed to open file, aborting: %s", newTarget.c_str()); - Util::logExitReason("failed to open file, aborting: %s", newTarget.c_str()); + Util::logExitReason(ER_WRITE_FAILURE, "failed to open file, aborting: %s", newTarget.c_str()); onFinish(); break; } @@ -1763,7 +1767,7 @@ namespace Mist{ }else{ if (!onFinish()){ INFO_MSG("Shutting down because planned stopping point reached"); - Util::logExitReason("planned stopping point reached"); + Util::logExitReason(ER_CLEAN_INTENDED_STOP, "planned stopping point reached"); break; } } @@ -1779,20 +1783,20 @@ namespace Mist{ } /*LTS-END*/ if (!onFinish()){ - Util::logExitReason("end of stream"); + Util::logExitReason(ER_CLEAN_EOF, "end of stream"); break; } } } if (!meta){ - Util::logExitReason("lost internal connection to stream data"); + Util::logExitReason(ER_SHM_LOST, "lost internal connection to stream data"); break; } } stats(); } - if (!config->is_active){Util::logExitReason("set inactive");} - if (!myConn){Util::logExitReason("connection closed");} + if (!config->is_active){Util::logExitReason(ER_UNKNOWN, "set inactive");} + if (!myConn){Util::logExitReason(ER_CLEAN_REMOTE_CLOSE, "connection closed");} if (strncmp(Util::exitReason, "connection closed", 17) == 0){ MEDIUM_MSG("Client handler shutting down, exit reason: %s", Util::exitReason); }else{ @@ -1831,7 +1835,6 @@ namespace Mist{ }else{ FAIL_MSG("Lost connection to the playlist file `%s` during segmenting", playlistLocationString.c_str()); Util::logExitReason("Lost connection to the playlist file `%s` during segmenting", playlistLocationString.c_str()); - return 1; } } @@ -1841,25 +1844,10 @@ namespace Mist{ streamName + "\n" + getConnectedHost() + "\n" + capa["name"].asStringRef() + "\n" + reqUrl; Triggers::doTrigger("CONN_CLOSE", payload, streamName); } - if (isRecordingToFile && config->hasOption("target") && Triggers::shouldTrigger("RECORDING_END", streamName)){ - uint64_t rightNow = Util::epoch(); - std::stringstream payl; - payl << streamName << '\n'; - payl << config->getString("target") << '\n'; - payl << capa["name"].asStringRef() << '\n'; - payl << myConn.dataUp() << '\n'; - payl << (Util::bootSecs() - myConn.connTime()) << '\n'; - payl << (rightNow - (Util::bootSecs() - myConn.connTime())) << '\n'; - payl << rightNow << '\n'; - if (firstPacketTime != 0xFFFFFFFFFFFFFFFFull){ - payl << (lastPacketTime - firstPacketTime) << '\n'; - }else{ - payl << 0 << '\n'; - } - payl << firstPacketTime << '\n'; - payl << lastPacketTime << '\n'; - Triggers::doTrigger("RECORDING_END", payl.str(), streamName); + if (isRecordingToFile){ + recEndTrigger(); } + outputEndTrigger(); /*LTS-END*/ disconnect(); @@ -1971,7 +1959,7 @@ namespace Mist{ } if (!dropTracks.size()){ FAIL_MSG("Could not equalize tracks! This is very very very bad and I am now going to shut down to prevent worse."); - Util::logExitReason("Could not equalize tracks"); + Util::logExitReason(ER_INTERNAL_ERROR, "Could not equalize tracks"); parseData = false; config->is_active = false; return false; @@ -2099,11 +2087,11 @@ namespace Mist{ //every ~1 second, check if the stream is not offline if (emptyCount % 100 == 0 && Util::getStreamStatus(streamName) == STRMSTAT_OFF){ if (M.getLive()){ - Util::logExitReason("Live stream source shut down"); + Util::logExitReason(ER_CLEAN_EOF, "Live stream source shut down"); thisPacket.null(); return true; }else if (!Util::startInput(streamName)){ - Util::logExitReason("VoD stream source shut down and could not be restarted"); + Util::logExitReason(ER_UNKNOWN, "VoD stream source shut down and could not be restarted"); thisPacket.null(); return true; } @@ -2329,6 +2317,40 @@ namespace Mist{ return true; } + std::string Output::getExitTriggerPayload(){ + uint64_t rightNow = Util::epoch(); + std::stringstream payl; + payl << streamName << '\n'; + payl << config->getString("target") << '\n'; + payl << capa["name"].asStringRef() << '\n'; + payl << myConn.dataUp() << '\n'; + payl << (Util::bootSecs() - myConn.connTime()) << '\n'; + payl << (rightNow - (Util::bootSecs() - myConn.connTime())) << '\n'; + payl << rightNow << '\n'; + if (firstPacketTime != 0xFFFFFFFFFFFFFFFFull){ + payl << (lastPacketTime - firstPacketTime) << '\n'; + }else{ + payl << 0 << '\n'; + } + payl << firstPacketTime << '\n'; + payl << lastPacketTime << '\n'; + payl << Util::mRExitReason << '\n'; + payl << Util::exitReason << '\n'; + return payl.str(); + } + + void Output::recEndTrigger(){ + if (Util::Config::binaryType == Util::OUTPUT && config->hasOption("target") && Triggers::shouldTrigger("RECORDING_END", streamName)){ + Triggers::doTrigger("RECORDING_END", getExitTriggerPayload(), streamName); + } + } + + void Output::outputEndTrigger(){ + if (Util::Config::binaryType == Util::OUTPUT && config->hasOption("target") && Triggers::shouldTrigger("OUTPUT_END", streamName)){ + Triggers::doTrigger("OUTPUT_END", getExitTriggerPayload(), streamName); + } + } + /// Checks if the set streamName allows pushes from this connector/IP/password combination. /// Runs all appropriate triggers and checks. /// Returns true if the push should continue, false otherwise. diff --git a/src/output/output.h b/src/output/output.h index 5ce23375..15f617ee 100644 --- a/src/output/output.h +++ b/src/output/output.h @@ -151,6 +151,9 @@ namespace Mist{ virtual bool isRecording(); virtual bool isFileTarget(); virtual bool isPushing(){return pushing;}; + std::string getExitTriggerPayload(); + void recEndTrigger(); + void outputEndTrigger(); bool allowPush(const std::string &passwd); void waitForStreamPushReady(); diff --git a/src/output/output_dtsc.cpp b/src/output/output_dtsc.cpp index 2f4c5380..6f1be4ee 100644 --- a/src/output/output_dtsc.cpp +++ b/src/output/output_dtsc.cpp @@ -328,7 +328,7 @@ namespace Mist{ if (!newStream.size()){ FAIL_MSG("Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL", getConnectedHost().c_str(), reqUrl.c_str()); - Util::logExitReason( + Util::logExitReason(ER_TRIGGER, "Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL", getConnectedHost().c_str(), reqUrl.c_str()); onFail("Push not allowed - rejected by trigger"); diff --git a/src/output/output_h264.cpp b/src/output/output_h264.cpp index 174fd56b..35c8acb3 100644 --- a/src/output/output_h264.cpp +++ b/src/output/output_h264.cpp @@ -169,7 +169,7 @@ namespace Mist{ }else if (command["type"] == "set_speed") { handleWebsocketSetSpeed(command); }else if (command["type"] == "stop") { - Util::logExitReason("User requested stop"); + Util::logExitReason(ER_CLEAN_REMOTE_CLOSE, "User requested stop"); myConn.close(); }else if (command["type"] == "play") { parseData = true; diff --git a/src/output/output_https.cpp b/src/output/output_https.cpp index 59fa0bfd..6d10d0f0 100644 --- a/src/output/output_https.cpp +++ b/src/output/output_https.cpp @@ -92,7 +92,7 @@ namespace Mist{ char error_buf[200]; mbedtls_strerror(ret, error_buf, 200); MEDIUM_MSG("Could not handshake, SSL error: %s (%d)", error_buf, ret); - Util::logExitReason("Could not handshake, SSL error: %s (%d)", error_buf, ret); + Util::logExitReason(ER_READ_START_FAILURE, "Could not handshake, SSL error: %s (%d)", error_buf, ret); C.close(); return; }else{ @@ -111,7 +111,7 @@ namespace Mist{ int fd[2]; if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fd) != 0){ FAIL_MSG("Could not open anonymous socket for SSL<->HTTP connection!"); - Util::logExitReason("Could not open anonymous socket for SSL<->HTTP connection!"); + Util::logExitReason(ER_READ_START_FAILURE, "Could not open anonymous socket for SSL<->HTTP connection!"); return 1; } std::deque args; @@ -137,7 +137,7 @@ namespace Mist{ close(fd[1]); if (http_proc < 2){ FAIL_MSG("Could not spawn MistOutHTTP process for SSL connection!"); - Util::logExitReason("Could not spawn MistOutHTTP process for SSL connection!"); + Util::logExitReason(ER_EXEC_FAILURE, "Could not spawn MistOutHTTP process for SSL connection!"); return 1; } Socket::Connection http(fd[0]); @@ -153,7 +153,7 @@ namespace Mist{ if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE){ if (ret <= 0){ HIGH_MSG("SSL disconnect!"); - Util::logExitReason("SSL client disconnected"); + Util::logExitReason(ER_CLEAN_REMOTE_CLOSE, "SSL client disconnected"); break; } // we received ret bytes of data to pass on. Do so. @@ -172,7 +172,7 @@ namespace Mist{ ret = mbedtls_ssl_write(&ssl, (const unsigned char *)http_buf.get().data() + done, toSend - done); if (ret == MBEDTLS_ERR_NET_CONN_RESET || ret == MBEDTLS_ERR_SSL_CLIENT_RECONNECT){ HIGH_MSG("SSL disconnect!"); - Util::logExitReason("SSL client disconnected"); + Util::logExitReason(ER_CLEAN_REMOTE_CLOSE, "SSL client disconnected"); http.close(); break; } diff --git a/src/output/output_mp4.cpp b/src/output/output_mp4.cpp index 1c8d533d..72c1e7a4 100644 --- a/src/output/output_mp4.cpp +++ b/src/output/output_mp4.cpp @@ -1529,7 +1529,7 @@ namespace Mist{ }else if (command["type"] == "set_speed") { handleWebsocketSetSpeed(command); }else if (command["type"] == "stop") { - Util::logExitReason("User requested stop"); + Util::logExitReason(ER_CLEAN_REMOTE_CLOSE, "User requested stop"); myConn.close(); }else if (command["type"] == "play") { parseData = true; diff --git a/src/output/output_rtmp.cpp b/src/output/output_rtmp.cpp index 2583392c..39277cb0 100644 --- a/src/output/output_rtmp.cpp +++ b/src/output/output_rtmp.cpp @@ -1190,7 +1190,7 @@ namespace Mist{ if (!newStream.size()){ FAIL_MSG("Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL", getConnectedHost().c_str(), reqUrl.c_str()); - Util::logExitReason( + Util::logExitReason(ER_TRIGGER, "Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL", getConnectedHost().c_str(), reqUrl.c_str()); onFinish(); diff --git a/src/output/output_rtsp.cpp b/src/output/output_rtsp.cpp index ef546824..ffb7014d 100644 --- a/src/output/output_rtsp.cpp +++ b/src/output/output_rtsp.cpp @@ -388,7 +388,7 @@ namespace Mist{ if (!newStream.size()){ FAIL_MSG("Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL", getConnectedHost().c_str(), qUrl.getUrl().c_str()); - Util::logExitReason( + Util::logExitReason(ER_TRIGGER, "Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL", getConnectedHost().c_str(), qUrl.getUrl().c_str()); onFinish(); diff --git a/src/output/output_ts.cpp b/src/output/output_ts.cpp index 6ab2d84f..bf74ab3a 100644 --- a/src/output/output_ts.cpp +++ b/src/output/output_ts.cpp @@ -235,7 +235,7 @@ namespace Mist{ }else{ myConn.SendNow(tsData, len); if (!myConn){ - Util::logExitReason("connection closed by peer"); + Util::logExitReason(ER_CLEAN_REMOTE_CLOSE, "connection closed by peer"); config->is_active = false; } } diff --git a/src/output/output_tsrist.cpp b/src/output/output_tsrist.cpp index 578ddae0..fa00a379 100644 --- a/src/output/output_tsrist.cpp +++ b/src/output/output_tsrist.cpp @@ -167,7 +167,7 @@ namespace Mist{ if (!newStream.size()){ FAIL_MSG("Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL", getConnectedHost().c_str(), reqUrl.getUrl().c_str()); - Util::logExitReason( + Util::logExitReason(ER_TRIGGER, "Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL", getConnectedHost().c_str(), reqUrl.getUrl().c_str()); onFinish(); @@ -390,14 +390,14 @@ void handleUSR1(int signum, siginfo_t *sigInfo, void *ignore){ if (!sockCount){ INFO_MSG("USR1 received - triggering rolling restart (no connections active)"); Util::Config::is_restarting = true; - Util::logExitReason("signal USR1, no connections"); + Util::logExitReason(ER_CLEAN_SIGNAL, "signal USR1, no connections"); ///\TODO Update for RIST //server_socket.close(); Util::Config::is_active = false; }else{ INFO_MSG("USR1 received - triggering rolling restart when connection count reaches zero"); Util::Config::is_restarting = true; - Util::logExitReason("signal USR1, after disconnect wait"); + Util::logExitReason(ER_CLEAN_SIGNAL, "signal USR1, after disconnect wait"); } } @@ -405,6 +405,7 @@ int main(int argc, char *argv[]){ DTSC::trackValidMask = TRACK_VALID_EXT_HUMAN; Util::redirectLogsIfNeeded(); Util::Config conf(argv[0]); + Util::Config::binaryType = Util::OUTPUT; mistOut::init(&conf); if (conf.parseArgs(argc, argv)){ if (conf.getBool("json")){ diff --git a/src/output/output_tssrt.cpp b/src/output/output_tssrt.cpp index d172d2a5..fb76ba5f 100644 --- a/src/output/output_tssrt.cpp +++ b/src/output/output_tssrt.cpp @@ -104,7 +104,7 @@ namespace Mist{ if (!newStream.size()){ FAIL_MSG("Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL", getConnectedHost().c_str(), reqUrl.getUrl().c_str()); - Util::logExitReason( + Util::logExitReason(ER_TRIGGER, "Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL", getConnectedHost().c_str(), reqUrl.getUrl().c_str()); onFinish(); @@ -291,7 +291,7 @@ namespace Mist{ srtConn.connect(target.host, target.getPort(), "output", targetParams); if (!srtConn){Util::sleep(500);} }else{ - Util::logExitReason("SRT connection closed"); + Util::logExitReason(ER_CLEAN_REMOTE_CLOSE, "SRT connection closed"); myConn.close(); parseData = false; return; @@ -301,7 +301,7 @@ namespace Mist{ srtConn.SendNow(packetBuffer, packetBuffer.size()); if (!srtConn){ if (!config->getString("target").size()){ - Util::logExitReason("SRT connection closed"); + Util::logExitReason(ER_CLEAN_REMOTE_CLOSE, "SRT connection closed"); myConn.close(); parseData = false; } @@ -366,7 +366,7 @@ namespace Mist{ } bool OutTSSRT::dropPushTrack(uint32_t trackId, const std::string & dropReason){ - Util::logExitReason("track dropped by buffer"); + Util::logExitReason(ER_SHM_LOST, "track dropped by buffer"); myConn.close(); srtConn.close(); return Output::dropPushTrack(trackId, dropReason); @@ -401,13 +401,13 @@ void handleUSR1(int signum, siginfo_t *sigInfo, void *ignore){ if (!sockCount){ INFO_MSG("USR1 received - triggering rolling restart (no connections active)"); Util::Config::is_restarting = true; - Util::logExitReason("signal USR1, no connections"); + Util::logExitReason(ER_CLEAN_SIGNAL, "signal USR1, no connections"); server_socket.close(); Util::Config::is_active = false; }else{ INFO_MSG("USR1 received - triggering rolling restart when connection count reaches zero"); Util::Config::is_restarting = true; - Util::logExitReason("signal USR1, after disconnect wait"); + Util::logExitReason(ER_CLEAN_SIGNAL, "signal USR1, after disconnect wait"); } } @@ -437,6 +437,7 @@ int main(int argc, char *argv[]){ DTSC::trackValidMask = TRACK_VALID_EXT_HUMAN; Util::redirectLogsIfNeeded(); Util::Config conf(argv[0]); + Util::Config::binaryType = Util::OUTPUT; mistOut::init(&conf); if (conf.parseArgs(argc, argv)){ if (conf.getBool("json")){ diff --git a/src/output/output_webrtc.cpp b/src/output/output_webrtc.cpp index 1485e80a..143a63d6 100644 --- a/src/output/output_webrtc.cpp +++ b/src/output/output_webrtc.cpp @@ -309,7 +309,7 @@ namespace Mist{ if (!parseData){udp.sendPaced(10000);} //After 10s of no packets, abort if (Util::bootMS() > lastRecv + 10000){ - Util::logExitReason("received no data for 10+ seconds"); + Util::logExitReason(ER_CLEAN_INACTIVE, "received no data for 10+ seconds"); config->is_active = false; } return; diff --git a/src/process/process_exec.cpp b/src/process/process_exec.cpp index af78e03f..ffece533 100644 --- a/src/process/process_exec.cpp +++ b/src/process/process_exec.cpp @@ -273,6 +273,7 @@ void sourceThread(void *){ int main(int argc, char *argv[]){ DTSC::trackValidMask = TRACK_VALID_INT_PROCESS; Util::Config config(argv[0]); + Util::Config::binaryType = Util::PROCESS; JSON::Value capa; { diff --git a/src/process/process_ffmpeg.cpp b/src/process/process_ffmpeg.cpp index 67141cea..7284016b 100644 --- a/src/process/process_ffmpeg.cpp +++ b/src/process/process_ffmpeg.cpp @@ -71,6 +71,7 @@ void sourceThread(void *){ int main(int argc, char *argv[]){ DTSC::trackValidMask = TRACK_VALID_INT_PROCESS; Util::Config config(argv[0]); + Util::Config::binaryType = Util::PROCESS; JSON::Value capa; { diff --git a/src/process/process_livepeer.cpp b/src/process/process_livepeer.cpp index 21f3a177..7fc55afa 100644 --- a/src/process/process_livepeer.cpp +++ b/src/process/process_livepeer.cpp @@ -248,7 +248,7 @@ namespace Mist{ if (!thisPacket){ Util::sleep(25); if (userSelect.size() && userSelect.begin()->second.getStatus() == COMM_STATUS_REQDISCONNECT){ - Util::logExitReason("buffer requested shutdown"); + Util::logExitReason(ER_CLEAN_LIVE_BUFFER_REQ, "buffer requested shutdown"); return; } } @@ -486,7 +486,7 @@ void uploadThread(void * num){ attempts++; Util::sleep(100);//Rate-limit retries if (attempts > 4){ - Util::logExitReason("too many upload failures"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "too many upload failures"); conf.is_active = false; return; } @@ -497,7 +497,7 @@ void uploadThread(void * num){ Mist::pickRandomBroadcaster(); if (!Mist::currBroadAddr.size()){ FAIL_MSG("Cannot switch to new broadcaster: none available"); - Util::logExitReason("no Livepeer broadcasters available"); + Util::logExitReason(ER_FORMAT_SPECIFIC, "no Livepeer broadcasters available"); conf.is_active = false; return; } @@ -523,6 +523,7 @@ void uploadThread(void * num){ int main(int argc, char *argv[]){ DTSC::trackValidMask = TRACK_VALID_INT_PROCESS; Util::Config config(argv[0]); + Util::Config::binaryType = Util::PROCESS; JSON::Value capa; { diff --git a/src/session.cpp b/src/session.cpp index f2026cc8..016e12e5 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -258,7 +258,7 @@ int main(int argc, char **argv){ "\n" + thisReqUrl + "\n" + thisSessionId; if (!Triggers::doTrigger("USER_NEW", payload, thisStreamName)){ // Mark all connections of this session as finished, since this viewer is not allowed to view this stream - Util::logExitReason("Session rejected by USER_NEW"); + Util::logExitReason(ER_TRIGGER, "Session rejected by USER_NEW"); connections.setExit(); connections.finishAll(); } @@ -355,7 +355,7 @@ int main(int argc, char **argv){ "\n" + thisReqUrl + "\n" + thisSessionId; if (!Triggers::doTrigger("USER_NEW", payload, thisStreamName)){ INFO_MSG("USER_NEW rejected stream %s", thisStreamName.c_str()); - Util::logExitReason("Session rejected by USER_NEW"); + Util::logExitReason(ER_TRIGGER, "Session rejected by USER_NEW"); connections.setExit(); connections.finishAll(); break; @@ -373,7 +373,7 @@ int main(int argc, char **argv){ shouldSleep = connections.getExit(); }//connections scope end if (Util::bootSecs() - lastSeen > STATS_DELAY){ - Util::logExitReason("Session inactive for %d seconds", STATS_DELAY); + Util::logExitReason(ER_CLEAN_INACTIVE, "Session inactive for %d seconds", STATS_DELAY); } // Trigger USER_END