From bb6c7073302016a690c375aa567548dca1f7a275 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Tue, 21 May 2024 01:06:02 +0000 Subject: [PATCH 01/24] refactor: MistOutSRT --> MistOutSubRip --- src/output/meson.build | 2 +- src/output/{output_srt.cpp => output_subrip.cpp} | 14 +++++++------- src/output/{output_srt.h => output_subrip.h} | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) rename src/output/{output_srt.cpp => output_subrip.cpp} (93%) rename src/output/{output_srt.h => output_subrip.h} (69%) diff --git a/src/output/meson.build b/src/output/meson.build index 4d7777281..62e85a0b8 100644 --- a/src/output/meson.build +++ b/src/output/meson.build @@ -10,7 +10,7 @@ outputs = [ {'name' : 'MP3', 'format' : 'mp3', 'extra': ['http']}, {'name' : 'H264', 'format' : 'h264', 'extra': ['http']}, {'name' : 'HDS', 'format' : 'hds', 'extra': ['http']}, - {'name' : 'SubRip', 'format' : 'srt', 'extra': ['http']}, + {'name' : 'SubRip', 'format' : 'subrip', 'extra': ['http']}, {'name' : 'JSON', 'format' : 'json', 'extra': ['http']}, {'name' : 'TS', 'format' : 'ts', 'extra': ['ts']}, {'name' : 'HTTPTS', 'format' : 'httpts', 'extra': ['http', 'ts']}, diff --git a/src/output/output_srt.cpp b/src/output/output_subrip.cpp similarity index 93% rename from src/output/output_srt.cpp rename to src/output/output_subrip.cpp index aaa658978..f6322655f 100644 --- a/src/output/output_srt.cpp +++ b/src/output/output_subrip.cpp @@ -1,14 +1,14 @@ -#include "output_srt.h" +#include "output_subrip.h" #include #include #include #include namespace Mist{ - OutSRT::OutSRT(Socket::Connection &conn) : HTTPOutput(conn){realTime = 0;} - OutSRT::~OutSRT(){} + OutSubRip::OutSubRip(Socket::Connection &conn) : HTTPOutput(conn){realTime = 0;} + OutSubRip::~OutSubRip(){} - void OutSRT::init(Util::Config *cfg){ + void OutSubRip::init(Util::Config *cfg){ HTTPOutput::init(cfg); capa["name"] = "SubRip"; capa["friendly"] = "SubRip (SRT/WebVTT) over HTTP"; @@ -29,7 +29,7 @@ namespace Mist{ capa["methods"][1u]["url_rel"] = "/$.webvtt"; } - void OutSRT::sendNext(){ + void OutSubRip::sendNext(){ // Reached the end we wanted? Stop here. if (filter_to > 0 && thisTime > filter_to && filter_to > filter_from){ config->is_active = false; @@ -63,7 +63,7 @@ namespace Mist{ myConn.SendNow("\n\n"); } - void OutSRT::sendHeader(){ + void OutSubRip::sendHeader(){ H.setCORSHeaders(); H.SetHeader("Content-Type", (webVTT ? "text/vtt; charset=utf-8" : "text/plain; charset=utf-8")); H.protocol = "HTTP/1.0"; @@ -72,7 +72,7 @@ namespace Mist{ sentHeader = true; } - void OutSRT::onHTTP(){ + void OutSubRip::onHTTP(){ std::string method = H.method; webVTT = (H.url.find(".vtt") != std::string::npos) || (H.url.find(".webvtt") != std::string::npos); if (H.GetVar("track").size()){ diff --git a/src/output/output_srt.h b/src/output/output_subrip.h similarity index 69% rename from src/output/output_srt.h rename to src/output/output_subrip.h index 4901dc30e..ec458a24b 100644 --- a/src/output/output_srt.h +++ b/src/output/output_subrip.h @@ -1,10 +1,10 @@ #include "output_http.h" namespace Mist{ - class OutSRT : public HTTPOutput{ + class OutSubRip : public HTTPOutput{ public: - OutSRT(Socket::Connection &conn); - ~OutSRT(); + OutSubRip(Socket::Connection &conn); + ~OutSubRip(); static void init(Util::Config *cfg); void onHTTP(); void sendNext(); @@ -19,4 +19,4 @@ namespace Mist{ }; }// namespace Mist -typedef Mist::OutSRT mistOut; +typedef Mist::OutSubRip mistOut; From fead24663e6212aa3ec5eee4b873f3dd9b16d6d8 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Thu, 9 May 2024 00:58:32 +0000 Subject: [PATCH 02/24] onebinary: MistServer! --- src/meson.build | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/meson.build b/src/meson.build index 43c40a041..f75ab68ed 100644 --- a/src/meson.build +++ b/src/meson.build @@ -14,3 +14,31 @@ executables += { 'deps' : [libmist_dep] } +executables += { + 'name': 'MistServer', + 'sources': [ + files( + 'output/mist_out.cpp', + 'output/output.cpp', + 'output/output_rtmp.cpp' + ), + io_cpp, + header_tgts + ], + 'defines': [ + string_opt.format('OUTPUTTYPE', 'output_rtmp.h') + ], + 'deps' : [libmist_dep] +} + # executables += { + # 'name': 'MistOut'+output.get('name'), + # 'sources' : [ + # sources, + # header_tgts + # ], + # 'deps' : deps, + # 'defines' : [ + # string_opt.format('OUTPUTTYPE', 'output_'+output.get('format')+'.h'), + # '-DTS_BASECLASS='+tsBaseClass + # ] + # } \ No newline at end of file From 28c16529cddb6bbb2ef733844ee94dac4ab18303 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Thu, 9 May 2024 02:46:02 +0000 Subject: [PATCH 03/24] onebinary: combine MistOutHLS and MistOutHTTP --- src/meson.build | 23 ++++++++++++++++++++- src/output/mist_out.cpp | 43 +++++++++++++++++++++++++++++++--------- src/output/output_hls.h | 2 -- src/output/output_rtmp.h | 2 -- 4 files changed, 56 insertions(+), 14 deletions(-) diff --git a/src/meson.build b/src/meson.build index f75ab68ed..823a8f6b0 100644 --- a/src/meson.build +++ b/src/meson.build @@ -20,16 +20,37 @@ executables += { files( 'output/mist_out.cpp', 'output/output.cpp', + 'output/output_hls.cpp', + 'output/output_http.cpp', + 'output/output_ts.cpp', + 'output/output_ts_base.cpp', 'output/output_rtmp.cpp' ), io_cpp, header_tgts ], 'defines': [ - string_opt.format('OUTPUTTYPE', 'output_rtmp.h') + '-DTS_BASECLASS=HTTPOutput', ], 'deps' : [libmist_dep] } + +# executables += { +# 'name': 'MistServer', +# 'sources': [ +# files( +# 'output/mist_out.cpp', +# 'output/output.cpp', +# 'output/output_rtmp.cpp' +# ), +# io_cpp, +# header_tgts +# ], +# 'defines': [ +# string_opt.format('OUTPUTTYPE', 'output_rtmp.h') +# ], +# 'deps' : [libmist_dep] +# } # executables += { # 'name': 'MistOut'+output.get('name'), # 'sources' : [ diff --git a/src/output/mist_out.cpp b/src/output/mist_out.cpp index 454106a08..475700f1a 100644 --- a/src/output/mist_out.cpp +++ b/src/output/mist_out.cpp @@ -1,10 +1,12 @@ -#include OUTPUTTYPE +#include "output_rtmp.h" +#include "output_hls.h" #include #include #include #include #include +template int spawnForked(Socket::Connection &S){ { struct sigaction new_action; @@ -13,7 +15,7 @@ int spawnForked(Socket::Connection &S){ new_action.sa_flags = 0; sigaction(SIGUSR1, &new_action, NULL); } - mistOut tmp(S); + T tmp(S); return tmp.run(); } @@ -24,15 +26,16 @@ void handleUSR1(int signum, siginfo_t *sigInfo, void *ignore){ Util::Config::is_active = false; } -int main(int argc, char *argv[]){ +template +int Main(int argc, char *argv[]){ DTSC::trackValidMask = TRACK_VALID_EXT_HUMAN; Util::redirectLogsIfNeeded(); Util::Config conf(argv[0]); - mistOut::init(&conf); + T::init(&conf); if (conf.parseArgs(argc, argv)){ if (conf.getBool("json")){ - mistOut::capa["version"] = PACKAGE_VERSION; - std::cout << mistOut::capa.toString() << std::endl; + T::capa["version"] = PACKAGE_VERSION; + std::cout << T::capa.toString() << std::endl; return -1; } { @@ -50,7 +53,7 @@ int main(int argc, char *argv[]){ } } conf.activate(); - if (mistOut::listenMode()){ + if (T::listenMode()){ { struct sigaction new_action; new_action.sa_sigaction = handleUSR1; @@ -58,7 +61,7 @@ int main(int argc, char *argv[]){ new_action.sa_flags = 0; sigaction(SIGUSR1, &new_action, NULL); } - mistOut::listener(conf, spawnForked); + T::listener(conf, spawnForked); if (conf.is_restarting && Socket::checkTrueSocket(0)){ INFO_MSG("Reloading input while re-using server socket"); execvp(argv[0], argv); @@ -66,7 +69,7 @@ int main(int argc, char *argv[]){ } }else{ Socket::Connection S(fileno(stdout), fileno(stdin)); - mistOut tmp(S); + T tmp(S); return tmp.run(); } } @@ -74,3 +77,25 @@ int main(int argc, char *argv[]){ return 0; } +int main(int argc, char *argv[]){ + if (argc < 2) { + INFO_MSG("usage: %s [MistSomething]", argv[0]); + return 1; + } + // Create a new argv array without argv[1] + int new_argc = argc - 1; + char** new_argv = new char*[new_argc]; + for (int i = 0, j = 0; i < argc; ++i) { + if (i != 1) { + new_argv[j++] = argv[i]; + } + } + if (strcmp(argv[1], "MistOutHLS") == 0) { + return Main(new_argc, new_argv); + } + else if (strcmp(argv[1], "MistOutRTMP") == 0) { + return Main(new_argc, new_argv); + } + INFO_MSG("binary not found: %s", argv[1]); + return 0; +} diff --git a/src/output/output_hls.h b/src/output/output_hls.h index 129873f92..b4c8b04c0 100644 --- a/src/output/output_hls.h +++ b/src/output/output_hls.h @@ -25,5 +25,3 @@ namespace Mist{ uint64_t until; }; }// namespace Mist - -typedef Mist::OutHLS mistOut; diff --git a/src/output/output_rtmp.h b/src/output/output_rtmp.h index e2b571f00..95296c08a 100644 --- a/src/output/output_rtmp.h +++ b/src/output/output_rtmp.h @@ -54,5 +54,3 @@ namespace Mist{ void calcNextFrameInfo(); }; }// namespace Mist - -typedef Mist::OutRTMP mistOut; From 67c97c76fb56c73f70cffc8b53b6d310f91b4b81 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Thu, 9 May 2024 03:09:45 +0000 Subject: [PATCH 04/24] onebinary: move up to mistserver.cpp --- src/meson.build | 2 +- src/mistserver.cpp | 31 +++++++++++++++++++++++++++++++ src/output/mist_out.cpp | 27 +-------------------------- 3 files changed, 33 insertions(+), 27 deletions(-) create mode 100644 src/mistserver.cpp diff --git a/src/meson.build b/src/meson.build index 823a8f6b0..9ac8a4763 100644 --- a/src/meson.build +++ b/src/meson.build @@ -18,7 +18,7 @@ executables += { 'name': 'MistServer', 'sources': [ files( - 'output/mist_out.cpp', + 'mistserver.cpp', 'output/output.cpp', 'output/output_hls.cpp', 'output/output_http.cpp', diff --git a/src/mistserver.cpp b/src/mistserver.cpp new file mode 100644 index 000000000..5d1d80615 --- /dev/null +++ b/src/mistserver.cpp @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include +#include "output/mist_out.cpp" +#include "output/output_rtmp.h" +#include "output/output_hls.h" + +int main(int argc, char *argv[]){ + if (argc < 2) { + INFO_MSG("usage: %s [MistSomething]", argv[0]); + return 1; + } + // Create a new argv array without argv[1] + int new_argc = argc - 1; + char** new_argv = new char*[new_argc]; + for (int i = 0, j = 0; i < argc; ++i) { + if (i != 1) { + new_argv[j++] = argv[i]; + } + } + if (strcmp(argv[1], "MistOutHLS") == 0) { + return OutputMain(new_argc, new_argv); + } + else if (strcmp(argv[1], "MistOutRTMP") == 0) { + return OutputMain(new_argc, new_argv); + } + INFO_MSG("binary not found: %s", argv[1]); + return 0; +} diff --git a/src/output/mist_out.cpp b/src/output/mist_out.cpp index 475700f1a..6b5d842f8 100644 --- a/src/output/mist_out.cpp +++ b/src/output/mist_out.cpp @@ -1,5 +1,3 @@ -#include "output_rtmp.h" -#include "output_hls.h" #include #include #include @@ -27,7 +25,7 @@ void handleUSR1(int signum, siginfo_t *sigInfo, void *ignore){ } template -int Main(int argc, char *argv[]){ +int OutputMain(int argc, char *argv[]){ DTSC::trackValidMask = TRACK_VALID_EXT_HUMAN; Util::redirectLogsIfNeeded(); Util::Config conf(argv[0]); @@ -76,26 +74,3 @@ int Main(int argc, char *argv[]){ INFO_MSG("Exit reason: %s", Util::exitReason); return 0; } - -int main(int argc, char *argv[]){ - if (argc < 2) { - INFO_MSG("usage: %s [MistSomething]", argv[0]); - return 1; - } - // Create a new argv array without argv[1] - int new_argc = argc - 1; - char** new_argv = new char*[new_argc]; - for (int i = 0, j = 0; i < argc; ++i) { - if (i != 1) { - new_argv[j++] = argv[i]; - } - } - if (strcmp(argv[1], "MistOutHLS") == 0) { - return Main(new_argc, new_argv); - } - else if (strcmp(argv[1], "MistOutRTMP") == 0) { - return Main(new_argc, new_argv); - } - INFO_MSG("binary not found: %s", argv[1]); - return 0; -} From 3097f2b6acd7d45f8ea5df397ab7daf82532866c Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Thu, 9 May 2024 03:19:44 +0000 Subject: [PATCH 05/24] onebinary: add MistInBuffer --- src/input/input_buffer.h | 2 -- src/input/mist_in.cpp | 6 +++--- src/meson.build | 2 ++ src/mistserver.cpp | 5 +++++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/input/input_buffer.h b/src/input/input_buffer.h index 9e53b26ba..d85b6380a 100644 --- a/src/input/input_buffer.h +++ b/src/input/input_buffer.h @@ -58,5 +58,3 @@ namespace Mist{ std::map sourcePids; }; }// namespace Mist - -typedef Mist::InputBuffer mistIn; diff --git a/src/input/mist_in.cpp b/src/input/mist_in.cpp index 8ca95daeb..a9e31501c 100644 --- a/src/input/mist_in.cpp +++ b/src/input/mist_in.cpp @@ -1,9 +1,9 @@ -#include INPUTTYPE #include -int main(int argc, char *argv[]){ +template +int InputMain(int argc, char *argv[]){ Util::redirectLogsIfNeeded(); Util::Config conf(argv[0]); - mistIn conv(&conf); + T conv(&conf); return conv.boot(argc, argv); } diff --git a/src/meson.build b/src/meson.build index 9ac8a4763..67b1491ec 100644 --- a/src/meson.build +++ b/src/meson.build @@ -19,6 +19,8 @@ executables += { 'sources': [ files( 'mistserver.cpp', + 'input/input.cpp', + 'input/input_buffer.cpp', 'output/output.cpp', 'output/output_hls.cpp', 'output/output_http.cpp', diff --git a/src/mistserver.cpp b/src/mistserver.cpp index 5d1d80615..a3f95dd4c 100644 --- a/src/mistserver.cpp +++ b/src/mistserver.cpp @@ -6,6 +6,8 @@ #include "output/mist_out.cpp" #include "output/output_rtmp.h" #include "output/output_hls.h" +#include "input/mist_in.cpp" +#include "input/input_buffer.h" int main(int argc, char *argv[]){ if (argc < 2) { @@ -26,6 +28,9 @@ int main(int argc, char *argv[]){ else if (strcmp(argv[1], "MistOutRTMP") == 0) { return OutputMain(new_argc, new_argv); } + else if (strcmp(argv[1], "MistInBuffer") == 0) { + return InputMain(new_argc, new_argv); + } INFO_MSG("binary not found: %s", argv[1]); return 0; } From cbcc864b61efacf1b1860f2250e02a0e0f7bc18c Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Thu, 9 May 2024 03:30:08 +0000 Subject: [PATCH 06/24] onebinary: add MistOutHTTP --- src/meson.build | 4 +++- src/mistserver.cpp | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/meson.build b/src/meson.build index 67b1491ec..e22bda98b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -24,12 +24,14 @@ executables += { 'output/output.cpp', 'output/output_hls.cpp', 'output/output_http.cpp', + 'output/output_http_internal.cpp', 'output/output_ts.cpp', 'output/output_ts_base.cpp', 'output/output_rtmp.cpp' ), io_cpp, - header_tgts + header_tgts, + embed_tgts ], 'defines': [ '-DTS_BASECLASS=HTTPOutput', diff --git a/src/mistserver.cpp b/src/mistserver.cpp index a3f95dd4c..195ed425a 100644 --- a/src/mistserver.cpp +++ b/src/mistserver.cpp @@ -6,6 +6,7 @@ #include "output/mist_out.cpp" #include "output/output_rtmp.h" #include "output/output_hls.h" +#include "output/output_http_internal.h" #include "input/mist_in.cpp" #include "input/input_buffer.h" @@ -25,6 +26,9 @@ int main(int argc, char *argv[]){ if (strcmp(argv[1], "MistOutHLS") == 0) { return OutputMain(new_argc, new_argv); } + else if (strcmp(argv[1], "MistOutHTTP") == 0) { + return OutputMain(new_argc, new_argv); + } else if (strcmp(argv[1], "MistOutRTMP") == 0) { return OutputMain(new_argc, new_argv); } From 17086a7a74c5cc0a29944dbf737c6d45d1db1bb6 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Thu, 9 May 2024 03:33:00 +0000 Subject: [PATCH 07/24] onebinary: add MistSession --- src/mistserver.cpp | 4 ++++ src/session.cpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mistserver.cpp b/src/mistserver.cpp index 195ed425a..b2c5aa749 100644 --- a/src/mistserver.cpp +++ b/src/mistserver.cpp @@ -9,6 +9,7 @@ #include "output/output_http_internal.h" #include "input/mist_in.cpp" #include "input/input_buffer.h" +#include "session.cpp" int main(int argc, char *argv[]){ if (argc < 2) { @@ -35,6 +36,9 @@ int main(int argc, char *argv[]){ else if (strcmp(argv[1], "MistInBuffer") == 0) { return InputMain(new_argc, new_argv); } + else if (strcmp(argv[1], "MistSession") == 0) { + return SessionMain(new_argc, new_argv); + } INFO_MSG("binary not found: %s", argv[1]); return 0; } diff --git a/src/session.cpp b/src/session.cpp index 6eebc16d6..bb5e64077 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -112,7 +112,7 @@ void userOnDisconnect(Comms::Connections & connections, size_t idx){ connPktretrans.erase(idx); } -int main(int argc, char **argv){ +int SessionMain(int argc, char **argv){ Comms::Sessions sessions; uint64_t lastSeen = Util::bootSecs(); Util::redirectLogsIfNeeded(); From fcbc98dcf92b3b721af8d2c756be2df40111dd15 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Tue, 1 Feb 2022 22:05:40 -0800 Subject: [PATCH 08/24] controller: add MIST_NO_PRETTY_LOGGING --- src/controller/controller.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/controller/controller.cpp b/src/controller/controller.cpp index e05b99d52..c79840efa 100644 --- a/src/controller/controller.cpp +++ b/src/controller/controller.cpp @@ -378,7 +378,11 @@ int main_loop(int argc, char **argv){ msghandler.detach(); // Attempt to open and redirect log messages to named pipe int outFD = -1; - if ((outFD = open(logPipe.c_str(), O_WRONLY)) == -1){ + if (getenv("MIST_NO_PRETTY_LOGGING")) { + WARN_MSG( + "MIST_NO_PRETTY_LOGGING is active, printing lots of pipes"); + } + else if ((outFD = open(logPipe.c_str(), O_WRONLY)) == -1){ ERROR_MSG( "Could not open log message pipe %s for writing! %s; falling back to standard error", logPipe.c_str(), strerror(errno)); From a9d7e6f123b0750abe3358e267dbfcdacbf0b280 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Fri, 10 May 2024 02:24:17 +0000 Subject: [PATCH 09/24] onebinary: it almost works! --- src/controller/controller.cpp | 2 +- src/controller/controller_capabilities.cpp | 14 ++++++++++++++ src/controller/controller_connectors.cpp | 19 ++++++++++--------- src/input/input.cpp | 1 + src/input/input.h | 4 ++-- src/meson.build | 18 ++++++++++++++++-- src/mistserver.cpp | 13 ++++++++++--- src/output/mist_out.cpp | 4 ++-- 8 files changed, 56 insertions(+), 19 deletions(-) diff --git a/src/controller/controller.cpp b/src/controller/controller.cpp index c79840efa..1ece3b021 100644 --- a/src/controller/controller.cpp +++ b/src/controller/controller.cpp @@ -618,7 +618,7 @@ int main_loop(int argc, char **argv){ ///\brief The controller angel process. /// Starts a forked main_loop in a loop. Yes, you read that right. -int main(int argc, char **argv){ +int ControllerMain(int argc, char **argv){ Util::Procs::setHandler(); // set child handler { struct sigaction new_action; diff --git a/src/controller/controller_capabilities.cpp b/src/controller/controller_capabilities.cpp index 426edea2d..db883ec6c 100644 --- a/src/controller/controller_capabilities.cpp +++ b/src/controller/controller_capabilities.cpp @@ -1,4 +1,8 @@ #include "controller_capabilities.h" +#include "../output/output_rtmp.h" +#include "../output/output_hls.h" +#include "../output/output_http_internal.h" +#include "../input/input_buffer.h" #include #include #include @@ -249,6 +253,7 @@ namespace Controller{ /// Aquire list of available protocols, storing in global 'capabilities' JSON::Value. void checkAvailProtocols(){ + #ifdef GO_AWAY std::deque execs; Util::getMyExec(execs); std::string arg_one; @@ -313,6 +318,15 @@ namespace Controller{ } } } + #else + // Mist::OutHTTP + // Mist::OutRTMP + // Mist::inputBuffer + capabilities["inputs"]["Buffer"] = JSON::fromString(Mist::inputBuffer::capa.toString()); + capabilities["connectors"]["HLS"] = JSON::fromString(Mist::OutHLS::capa.toString()); + capabilities["connectors"]["HTTP"] = JSON::fromString(Mist::OutHTTP::capa.toString()); + capabilities["connectors"]["RTMP"] = JSON::fromString(Mist::OutRTMP::capa.toString()); + #endif } ///\brief A class storing information about the cpu the server is running on. diff --git a/src/controller/controller_connectors.cpp b/src/controller/controller_connectors.cpp index 52d9e9533..d53dad391 100644 --- a/src/controller/controller_connectors.cpp +++ b/src/controller/controller_connectors.cpp @@ -126,14 +126,14 @@ namespace Controller{ } static inline void buildPipedArguments(JSON::Value &p, char *argarr[], const JSON::Value &capabilities){ - int argnum = 0; + int argnum = 1; static std::string tmparg; - tmparg = Util::getMyPath() + std::string("MistOut") + p["connector"].asStringRef(); - struct stat buf; - if (::stat(tmparg.c_str(), &buf) != 0){ - tmparg = Util::getMyPath() + std::string("MistConn") + p["connector"].asStringRef(); - } - if (::stat(tmparg.c_str(), &buf) != 0){return;} + tmparg = std::string("MistOut") + p["connector"].asStringRef(); + // struct stat buf; + // if (::stat(tmparg.c_str(), &buf) != 0){ + // tmparg = Util::getMyPath() + std::string("MistConn") + p["connector"].asStringRef(); + // } + // if (::stat(tmparg.c_str(), &buf) != 0){return;} argarr[argnum++] = (char *)tmparg.c_str(); const JSON::Value &pipedCapa = capabilities["connectors"][p["connector"].asStringRef()]; if (pipedCapa.isMember("required")){builPipedPart(p, argarr, argnum, pipedCapa["required"]);} @@ -160,7 +160,7 @@ namespace Controller{ // used for building args int err = fileno(stderr); - char *argarr[15]; // approx max # of args (with a wide margin) + char *argarr[16] = {"/home/iameli/code/mistserver/build/MistServer"}; // approx max # of args (with a wide margin) int i; std::string tmp; @@ -255,11 +255,12 @@ namespace Controller{ Log("CONF", "Starting connector: " + *runningConns.begin()); action = true; // clear out old args - for (i = 0; i < 15; i++){argarr[i] = 0;} + for (i = 1; i < 16; i++){argarr[i] = 0;} // get args for this connector JSON::Value p = JSON::fromString(*runningConns.begin()); buildPipedArguments(p, (char **)&argarr, capabilities); // start piped w/ generated args + INFO_MSG("piped command[0]: %s [1]: %s", argarr[0], argarr[1]) currentConnectors[*runningConns.begin()] = Util::Procs::StartPiped(argarr, 0, 0, &err); Triggers::doTrigger("OUTPUT_START", *runningConns.begin()); // LTS } diff --git a/src/input/input.cpp b/src/input/input.cpp index 9b86937f6..0af61b19b 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -18,6 +18,7 @@ namespace Mist{ Util::Config *Input::config = NULL; + JSON::Value Input::capa = JSON::Value(); void Input::userLeadIn(){ connectedUsers = 0; diff --git a/src/input/input.h b/src/input/input.h index 4fe2c4ed7..bcd159b61 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -54,6 +54,8 @@ namespace Mist{ virtual bool needsLock(){return !config->getBool("realtime");} virtual bool publishesTracks(){return true;} + static JSON::Value capa; + protected: bool internalOnly; bool isBuffer; @@ -104,8 +106,6 @@ namespace Mist{ uint64_t activityCounter; - JSON::Value capa; - std::map > keyTimes; std::map keyLoadPriority; diff --git a/src/meson.build b/src/meson.build index e22bda98b..6fb8e692d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -27,14 +27,28 @@ executables += { 'output/output_http_internal.cpp', 'output/output_ts.cpp', 'output/output_ts_base.cpp', - 'output/output_rtmp.cpp' + 'output/output_rtmp.cpp', + 'controller/controller_external_writers.cpp', + 'controller/controller_updater.cpp', + 'controller/controller_streams.cpp', + 'controller/controller_storage.cpp', + 'controller/controller_connectors.cpp', + 'controller/controller_statistics.cpp', + 'controller/controller_limits.cpp', + 'controller/controller_capabilities.cpp', + 'controller/controller_uplink.cpp', + 'controller/controller_api.cpp', + 'controller/controller_push.cpp', + 'controller/controller_variables.cpp', ), io_cpp, header_tgts, - embed_tgts + embed_tgts, + server_html ], 'defines': [ '-DTS_BASECLASS=HTTPOutput', + '-DONE_BINARY=true', ], 'deps' : [libmist_dep] } diff --git a/src/mistserver.cpp b/src/mistserver.cpp index b2c5aa749..6919729ed 100644 --- a/src/mistserver.cpp +++ b/src/mistserver.cpp @@ -10,11 +10,12 @@ #include "input/mist_in.cpp" #include "input/input_buffer.h" #include "session.cpp" +#include "controller/controller.cpp" int main(int argc, char *argv[]){ + INFO_MSG("starting") if (argc < 2) { - INFO_MSG("usage: %s [MistSomething]", argv[0]); - return 1; + return 201; } // Create a new argv array without argv[1] int new_argc = argc - 1; @@ -24,6 +25,9 @@ int main(int argc, char *argv[]){ new_argv[j++] = argv[i]; } } + if (strcmp(argv[1], "MistController") == 0) { + return ControllerMain(new_argc, new_argv); + } if (strcmp(argv[1], "MistOutHLS") == 0) { return OutputMain(new_argc, new_argv); } @@ -39,6 +43,9 @@ int main(int argc, char *argv[]){ else if (strcmp(argv[1], "MistSession") == 0) { return SessionMain(new_argc, new_argv); } + else { + return ControllerMain(argc, argv); + } INFO_MSG("binary not found: %s", argv[1]); - return 0; + return 202; } diff --git a/src/output/mist_out.cpp b/src/output/mist_out.cpp index 6b5d842f8..9120a9575 100644 --- a/src/output/mist_out.cpp +++ b/src/output/mist_out.cpp @@ -17,7 +17,7 @@ int spawnForked(Socket::Connection &S){ return tmp.run(); } -void handleUSR1(int signum, siginfo_t *sigInfo, void *ignore){ +void handleUSR1Output(int signum, siginfo_t *sigInfo, void *ignore){ HIGH_MSG("USR1 received - triggering rolling restart"); Util::Config::is_restarting = true; Util::logExitReason(ER_CLEAN_SIGNAL, "signal USR1"); @@ -54,7 +54,7 @@ int OutputMain(int argc, char *argv[]){ if (T::listenMode()){ { struct sigaction new_action; - new_action.sa_sigaction = handleUSR1; + new_action.sa_sigaction = handleUSR1Output; sigemptyset(&new_action.sa_mask); new_action.sa_flags = 0; sigaction(SIGUSR1, &new_action, NULL); From f07bea0dd99ef80be3b43285fc86b762cc4e57ee Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Tue, 14 May 2024 20:18:47 +0000 Subject: [PATCH 10/24] onebinary: no arguments == MistController --- src/mistserver.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mistserver.cpp b/src/mistserver.cpp index 6919729ed..32ca0b335 100644 --- a/src/mistserver.cpp +++ b/src/mistserver.cpp @@ -13,9 +13,8 @@ #include "controller/controller.cpp" int main(int argc, char *argv[]){ - INFO_MSG("starting") if (argc < 2) { - return 201; + return ControllerMain(argc, argv); } // Create a new argv array without argv[1] int new_argc = argc - 1; From f9b46b8ff6ce1a9725027fbdaaf42f74b69e596b Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Tue, 14 May 2024 22:01:34 +0000 Subject: [PATCH 11/24] onebinary: integrate with MistIn and MistSession --- lib/comms.cpp | 3 ++- lib/stream.cpp | 7 ++++--- src/controller/controller_capabilities.cpp | 12 +++++------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/comms.cpp b/lib/comms.cpp index b0eb028d2..92ac4352e 100644 --- a/lib/comms.cpp +++ b/lib/comms.cpp @@ -360,7 +360,8 @@ namespace Comms{ Socket::hostBytesToStr(ip.data(), ip.size(), host); pid_t thisPid; std::deque args; - args.push_back(Util::getMyPath() + "MistSession"); + args.push_back(Util::getMyPath() + "MistServer"); + args.push_back("MistSession"); args.push_back(sessionId); // First bit defines whether to include stream name diff --git a/lib/stream.cpp b/lib/stream.cpp index 48332c6cb..bfbd1ecfa 100644 --- a/lib/stream.cpp +++ b/lib/stream.cpp @@ -640,10 +640,11 @@ bool Util::startInput(std::string streamname, std::string filename, bool forkFir setenv("MISTPROVIDER", "1", 1); } - std::string player_bin = Util::getMyPath() + "MistIn" + input["name"].asStringRef(); - char *argv[30] ={(char *)player_bin.c_str(), (char *)"-s", (char *)streamname.c_str(), + std::string player_bin = "MistIn" + input["name"].asStringRef(); + std::string mistserver_bin = Util::getMyPath() + "MistServer"; + char *argv[30] ={(char *)(mistserver_bin).c_str(), (char *)player_bin.c_str(), (char *)"-s", (char *)streamname.c_str(), (char *)filename.c_str()}; - int argNum = 3; + int argNum = 4; std::string debugLvl; if (Util::printDebugLevel != DEBUG && !str_args.count("--debug")){ debugLvl = JSON::Value(Util::printDebugLevel).asString(); diff --git a/src/controller/controller_capabilities.cpp b/src/controller/controller_capabilities.cpp index db883ec6c..29e335690 100644 --- a/src/controller/controller_capabilities.cpp +++ b/src/controller/controller_capabilities.cpp @@ -319,13 +319,11 @@ namespace Controller{ } } #else - // Mist::OutHTTP - // Mist::OutRTMP - // Mist::inputBuffer - capabilities["inputs"]["Buffer"] = JSON::fromString(Mist::inputBuffer::capa.toString()); - capabilities["connectors"]["HLS"] = JSON::fromString(Mist::OutHLS::capa.toString()); - capabilities["connectors"]["HTTP"] = JSON::fromString(Mist::OutHTTP::capa.toString()); - capabilities["connectors"]["RTMP"] = JSON::fromString(Mist::OutRTMP::capa.toString()); + // produced with e.g. `./MistOutHLS -j | jq '. | tostring'` + capabilities["inputs"]["Buffer"] = JSON::fromString("{\"desc\":\"This input type is both used for push- and pull-based streams. It provides a buffer for live media data. The push://[host][@password] style source allows all enabled protocols that support push input to accept a push into MistServer, where you can accept incoming streams from everyone, based on a set password, and/or use hostname/IP whitelisting.\",\"name\":\"Buffer\",\"non-provider\":true,\"optional\":{\"DVR\":{\"default\":50000,\"help\":\"The target available buffer time for this live stream, in milliseconds. This is the time available to seek around in, and will automatically be extended to fit whole keyframes as well as the minimum duration needed for stable playback.\",\"name\":\"Buffer time (ms)\",\"option\":\"--buffer\",\"type\":\"uint\"},\"cut\":{\"default\":0,\"help\":\"Any timestamps before this will be cut from the live buffer.\",\"name\":\"Cut time (ms)\",\"option\":\"--cut\",\"type\":\"uint\"},\"debug\":{\"help\":\"The debug level at which messages need to be printed.\",\"name\":\"debug\",\"option\":\"--debug\",\"type\":\"debug\"},\"fallback_stream\":{\"default\":\"\",\"help\":\"Alternative stream to load for playback when there is no active broadcast\",\"name\":\"Fallback stream\",\"type\":\"str\"},\"inputtimeout\":{\"default\":30,\"help\":\"How long the input should remain loaded without activity\",\"name\":\"Input inactivity timeout\",\"option\":\"--inputtimeout\",\"type\":\"uint\",\"unit\":\"s\"},\"maxkeepaway\":{\"default\":45000,\"help\":\"Maximum distance in milliseconds to fall behind the live point for stable playback.\",\"name\":\"Maximum live keep-away distance\",\"option\":\"--resume\",\"type\":\"uint\"},\"pagetimeout\":{\"default\":15,\"help\":\"For bufferless or live inputs like HLS, set the timeout in seconds for old, inactive pages to be deleted. A longer value results in more memory usage, but ensures that recently buffered data stays in memory for longer\",\"name\":\"Memory page timeout\",\"option\":\"--pagetimeout\",\"type\":\"uint\"},\"resume\":{\"default\":0,\"help\":\"If enabled, the buffer will linger after source disconnect to allow resuming the stream later. If disabled, the buffer will instantly close on source disconnect.\",\"name\":\"Resume support\",\"option\":\"--resume\",\"select\":[[\"0\",\"Disabled\"],[\"1\",\"Enabled\"]],\"type\":\"select\"},\"segmentsize\":{\"default\":1900,\"help\":\"Target time duration in milliseconds for segments.\",\"name\":\"Segment size (ms)\",\"option\":\"--segment-size\",\"type\":\"uint\"}},\"priority\":9,\"source_match\":\"push://*\",\"version\":\"3.3\"}"); + capabilities["connectors"]["HLS"] = JSON::fromString("{\"codecs\":[[[\"+HEVC\"],[\"+H264\"],[\"+MPEG2\"],[\"+AAC\"],[\"+MP3\"],[\"+AC3\"],[\"+MP2\"],[\"+subtitle\"]]],\"deps\":\"HTTP\",\"desc\":\"Segmented streaming in Apple (TS-based) format over HTTP ( = HTTP Live Streaming)\",\"exceptions\":{\"codec:HEVC\":[[\"blacklist\"]],\"codec:MP3\":[[\"blacklist\",[\"Mozilla/\"]],[\"whitelist\",[\"iPad\",\"iPhone\",\"iPod\",\"MacIntel\",\"Edge\"]]]},\"forward\":{\"ip\":{\"help\":\"Data to pretend arrived on the socket before parsing the socket.\",\"name\":\"Previous request\",\"option\":\"--prequest\",\"type\":\"str\"},\"streamname\":{\"help\":\"What streamname to serve.\",\"name\":\"Stream\",\"option\":\"--stream\",\"type\":\"str\"}},\"friendly\":\"Apple segmented over HTTP (HLS)\",\"methods\":[{\"handler\":\"http\",\"hrn\":\"HLS (TS)\",\"priority\":9,\"type\":\"html5/application/vnd.apple.mpegurl\"}],\"name\":\"HLS\",\"optional\":{\"chunkpath\":{\"default\":\"\",\"help\":\"Chunks will be served from this path.\",\"name\":\"Prepend path for chunks\",\"option\":\"--chunkpath\",\"short\":\"e\",\"type\":\"str\"},\"debug\":{\"help\":\"The debug level at which messages need to be printed.\",\"name\":\"debug\",\"option\":\"--debug\",\"type\":\"debug\"},\"default_track_sorting\":{\"default\":\"\",\"help\":\"What tracks are selected first when no specific track selector is used for playback.\",\"name\":\"Default track sorting\",\"option\":\"--default_track_sorting\",\"select\":[[\"\",\"Default (last added for live, first added for VoD)\"],[\"bps_lth\",\"Bit rate, low to high\"],[\"bps_htl\",\"Bit rate, high to low\"],[\"id_lth\",\"Track ID, low to high\"],[\"id_htl\",\"Track ID, high to low\"],[\"res_lth\",\"Resolution, low to high\"],[\"res_htl\",\"Resolution, high to low\"]],\"short\":\"S\",\"type\":\"select\"},\"listlimit\":{\"default\":0,\"help\":\"Maximum number of parts in live playlists. (0 = infinite)\",\"name\":\"Live playlist limit\",\"option\":\"--list-limit\",\"type\":\"uint\"},\"nonchunked\":{\"help\":\"Disables chunked transfer encoding, forcing per-segment buffering. Reduces performance significantly, but increases compatibility somewhat.\",\"name\":\"Send whole segments\",\"option\":\"--nonchunked\"},\"username\":{\"default\":\"root\",\"help\":\"Username to drop privileges to - default if unprovided means do not drop privileges\",\"name\":\"Username\",\"option\":\"--username\",\"short\":\"u\",\"type\":\"str\"}},\"url_prefix\":\"/hls/$/\",\"url_rel\":\"/hls/$/index.m3u8\",\"version\":\"3.3\"}"); + capabilities["connectors"]["HTTP"] = JSON::fromString("{\"codecs\":[null],\"desc\":\"HTTP connection handler, provides all enabled HTTP-based outputs\",\"forward\":{\"ip\":{\"help\":\"Data to pretend arrived on the socket before parsing the socket.\",\"name\":\"Previous request\",\"option\":\"--prequest\",\"type\":\"str\"},\"streamname\":{\"help\":\"What streamname to serve.\",\"name\":\"Stream\",\"option\":\"--stream\",\"type\":\"str\"}},\"friendly\":\"HTTP\",\"name\":\"HTTP\",\"optional\":{\"certbot\":{\"default\":\"\",\"help\":\"Automatically set by the MistUtilCertbot authentication hook for certbot. Not intended to be set manually.\",\"name\":\"Certbot validation token\",\"option\":\"--certbot\",\"short\":\"C\",\"type\":\"str\"},\"debug\":{\"help\":\"The debug level at which messages need to be printed.\",\"name\":\"debug\",\"option\":\"--debug\",\"type\":\"debug\"},\"default_track_sorting\":{\"default\":\"\",\"help\":\"What tracks are selected first when no specific track selector is used for playback.\",\"name\":\"Default track sorting\",\"option\":\"--default_track_sorting\",\"select\":[[\"\",\"Default (last added for live, first added for VoD)\"],[\"bps_lth\",\"Bit rate, low to high\"],[\"bps_htl\",\"Bit rate, high to low\"],[\"id_lth\",\"Track ID, low to high\"],[\"id_htl\",\"Track ID, high to low\"],[\"res_lth\",\"Resolution, low to high\"],[\"res_htl\",\"Resolution, high to low\"]],\"short\":\"S\",\"type\":\"select\"},\"interface\":{\"default\":\"0.0.0.0\",\"help\":\"Address of the interface to listen on\",\"name\":\"Interface\",\"option\":\"--interface\",\"short\":\"i\",\"type\":\"str\"},\"nostreamtext\":{\"default\":\"\",\"help\":\"Text or HTML to display when streams are unavailable.\",\"name\":\"Stream unavailable text\",\"option\":\"--nostreamtext\",\"type\":\"str\"},\"port\":{\"default\":8080,\"help\":\"TCP port to listen on\",\"name\":\"TCP port\",\"option\":\"--port\",\"short\":\"p\",\"type\":\"uint\"},\"pubaddr\":{\"default\":\"\",\"help\":\"Full public address this output is available as, if being proxied\",\"name\":\"Public address\",\"option\":\"--public-address\",\"type\":\"inputlist\"},\"username\":{\"default\":\"root\",\"help\":\"Username to drop privileges to - default if unprovided means do not drop privileges\",\"name\":\"Username\",\"option\":\"--username\",\"short\":\"u\",\"type\":\"str\"},\"wrappers\":{\"allowed\":[\"html5\",\"hlsjs\",\"videojs\",\"dashjs\",\"webrtc\",\"mews\",\"rawws\",\"flv\",\"flash_strobe\"],\"default\":\"\",\"help\":\"Which players are attempted and in what order.\",\"name\":\"Active players\",\"option\":\"--wrappers\",\"short\":\"w\",\"type\":\"ord_multi_sel\"}},\"protocol\":\"http://\",\"provides\":\"HTTP\",\"url_match\":[\"/crossdomain.xml\",\"/clientaccesspolicy.xml\",\"/$.html\",\"/favicon.ico\",\"/$.smil\",\"/info_$.js\",\"/json_$.js\",\"/player.js\",\"/videojs.js\",\"/dashjs.js\",\"/webrtc.js\",\"/flv.js\",\"/hlsjs.js\",\"/libde265.js\",\"/skins/default.css\",\"/skins/dev.css\",\"/skins/videojs.css\",\"/embed_$.js\",\"/flashplayer.swf\",\"/oldflashplayer.swf\"],\"url_prefix\":\"/.well-known/\",\"url_rel\":\"/$.html\",\"version\":\"3.3\"}"); + capabilities["connectors"]["RTMP"] = JSON::fromString("{\"codecs\":[[[\"H264\",\"H263\",\"VP6\",\"VP6Alpha\",\"ScreenVideo2\",\"ScreenVideo1\",\"JPEG\"],[\"AAC\",\"MP3\",\"Speex\",\"Nellymoser\",\"PCM\",\"ADPCM\",\"ALAW\",\"ULAW\"]]],\"deps\":\"\",\"desc\":\"Real time streaming over Adobe RTMP\",\"friendly\":\"RTMP\",\"incoming_push_url\":\"rtmp://$host:$port/$password/$stream\",\"methods\":[{\"handler\":\"rtmp\",\"hrn\":\"RTMP\",\"player_url\":\"/flashplayer.swf\",\"priority\":7,\"type\":\"flash/10\"}],\"name\":\"RTMP\",\"optional\":{\"acceptable\":{\"default\":0,\"help\":\"Whether to allow only incoming pushes (2), only outgoing pulls (1), or both (0, default)\",\"name\":\"Acceptable connection types\",\"option\":\"--acceptable\",\"select\":[[0,\"Allow both incoming and outgoing connections\"],[1,\"Allow only outgoing connections\"],[2,\"Allow only incoming connections\"]],\"short\":\"T\",\"type\":\"select\"},\"debug\":{\"help\":\"The debug level at which messages need to be printed.\",\"name\":\"debug\",\"option\":\"--debug\",\"type\":\"debug\"},\"default_track_sorting\":{\"default\":\"\",\"help\":\"What tracks are selected first when no specific track selector is used for playback.\",\"name\":\"Default track sorting\",\"option\":\"--default_track_sorting\",\"select\":[[\"\",\"Default (last added for live, first added for VoD)\"],[\"bps_lth\",\"Bit rate, low to high\"],[\"bps_htl\",\"Bit rate, high to low\"],[\"id_lth\",\"Track ID, low to high\"],[\"id_htl\",\"Track ID, high to low\"],[\"res_lth\",\"Resolution, low to high\"],[\"res_htl\",\"Resolution, high to low\"]],\"short\":\"S\",\"type\":\"select\"},\"interface\":{\"default\":\"0.0.0.0\",\"help\":\"Address of the interface to listen on\",\"name\":\"Interface\",\"option\":\"--interface\",\"short\":\"i\",\"type\":\"str\"},\"maxkbps\":{\"default\":0,\"help\":\"Maximum bitrate to allow in the ingest direction, in kilobits per second.\",\"name\":\"Max. kbps\",\"option\":\"--maxkbps\",\"short\":\"K\",\"type\":\"uint\"},\"port\":{\"default\":1935,\"help\":\"TCP port to listen on\",\"name\":\"TCP port\",\"option\":\"--port\",\"short\":\"p\",\"type\":\"uint\"},\"username\":{\"default\":\"root\",\"help\":\"Username to drop privileges to - default if unprovided means do not drop privileges\",\"name\":\"Username\",\"option\":\"--username\",\"short\":\"u\",\"type\":\"str\"}},\"push_parameters\":{\"append\":{\"format\":\"set_or_unset\",\"help\":\"If set to any value, will (if possible) append to an existing file, rather than overwriting it\",\"name\":\"Append to file\",\"sort\":\"bf\",\"type\":\"bool\"},\"audio\":{\"help\":\"Override which audio tracks of the stream should be selected\",\"name\":\"Audio track(s)\",\"sort\":\"aa\",\"type\":\"string\",\"validate\":[\"track_selector\"]},\"duration\":{\"disable\":[\"recstop\",\"stop\"],\"help\":\"How much media time to push, in seconds. Internally overrides \\\"recstop\\\"\",\"name\":\"Duration of push\",\"sort\":\"bi\",\"type\":\"int\",\"unit\":\"s\"},\"m3u8\":{\"help\":\"If set, will write a m3u8 playlist file for the segments to the given path (relative from the first segment path). When this parameter is used, at least one of the variables $segmentCounter or $currentMediaTime must be part of the segment path (to keep segments from overwriting each other). The \\\"Split interval\\\" parameter will default to 60 seconds when using this option.\",\"name\":\"Playlist path (relative to segments)\",\"sort\":\"apa\",\"type\":\"string\"},\"maxEntries\":{\"help\":\"When writing a playlist, delete oldest segment entries once this entry count has been reached (and, if possible, also delete said segments themselves). When set to 0 or left empty, does not delete.\",\"name\":\"Playlist max entries\",\"sort\":\"apc\",\"type\":\"int\"},\"maxwaittrackms\":{\"default\":\"5s, or 120s when using a non-default GOP count\",\"help\":\"When waiting for GOPs on the main track, give up when this much data is available in the main track buffer\",\"name\":\"Max buffer duration for GOP count wait\",\"sort\":\"be\",\"type\":\"int\",\"unit\":\"ms\"},\"noendlist\":{\"format\":\"set_or_unset\",\"help\":\"If set, does not write #X-EXT-ENDLIST when finalizing the playlist on exit\",\"name\":\"Don't end playlist\",\"sort\":\"bfa\",\"type\":\"bool\"},\"pushdelay\":{\"disable\":[\"realtime\",\"start\"],\"help\":\"Ensures the stream is always delayed by at least this many seconds. Internally overrides the \\\"realtime\\\" and \\\"start\\\" parameters\",\"name\":\"Push delay\",\"sort\":\"bg\",\"type\":\"int\",\"unit\":\"s\"},\"rate\":{\"default\":\"1\",\"help\":\"Multiplier for the playback speed rate, or 0 to not limit\",\"name\":\"Playback rate\",\"sort\":\"ba\",\"type\":\"int\"},\"realtime\":{\"format\":\"set_or_unset\",\"help\":\"If set to any value, removes the rate override to unlimited normally applied to push outputs\",\"name\":\"Don't speed up output\",\"sort\":\"bb\",\"type\":\"bool\"},\"recstart\":{\"file_only\":true,\"help\":\"What internal media timestamp to start from\",\"name\":\"Media timestamp to start from\",\"sort\":\"bp\",\"type\":\"int\",\"unit\":\"s\"},\"recstartunix\":{\"disable\":[\"recstart\"],\"file_only\":true,\"help\":\"What unix timestamp to start from\",\"name\":\"Unix timestamp to start from\",\"sort\":\"br\",\"type\":\"unixtime\",\"unit\":\"s\"},\"recstop\":{\"file_only\":true,\"help\":\"What internal media timestamp to stop at\",\"name\":\"Media timestamp to stop at\",\"sort\":\"bo\",\"type\":\"int\",\"unit\":\"s\"},\"recstopunix\":{\"disable\":[\"recstop\"],\"file_only\":true,\"help\":\"What unix timestamp to stop at\",\"name\":\"Unix timestamp to stop at\",\"sort\":\"bq\",\"type\":\"unixtime\",\"unit\":\"s\"},\"split\":{\"help\":\"Performs a gapless restart of the recording every this many seconds. Always aligns to the next keyframe after this duration, to ensure each recording is fully playable. When set to zero (the default) will not split at all.\",\"name\":\"Split interval\",\"sort\":\"bh\",\"type\":\"int\",\"unit\":\"s\"},\"start\":{\"help\":\"What internal media timestamp to start from\",\"name\":\"Media timestamp to start from\",\"prot_only\":true,\"sort\":\"bl\",\"type\":\"int\",\"unit\":\"s\"},\"startunix\":{\"disable\":[\"start\"],\"help\":\"What unix timestamp to start from\",\"name\":\"Unix timestamp to start from\",\"prot_only\":true,\"sort\":\"bn\",\"type\":\"unixtime\",\"unit\":\"s\"},\"stop\":{\"help\":\"What internal media timestamp to stop at\",\"name\":\"Media timestamp to stop at\",\"prot_only\":true,\"sort\":\"bk\",\"type\":\"int\",\"unit\":\"s\"},\"stopunix\":{\"disable\":[\"stop\"],\"help\":\"What unix timestamp to stop at\",\"name\":\"Unix timestamp to stop at\",\"prot_only\":true,\"sort\":\"bm\",\"type\":\"unixtime\",\"unit\":\"s\"},\"subtitle\":{\"help\":\"Override which subtitle tracks of the stream should be selected\",\"name\":\"Subtitle track(s)\",\"sort\":\"ac\",\"type\":\"string\",\"validate\":[\"track_selector\"]},\"targetAge\":{\"help\":\"When writing a playlist, delete segment entries that are more than this many seconds old from the playlist (and, if possible, also delete said segments themselves). When set to 0 or left empty, does not delete.\",\"name\":\"Playlist target age\",\"sort\":\"apb\",\"type\":\"int\",\"unit\":\"s\"},\"unmask\":{\"format\":\"set_or_unset\",\"help\":\"If set to any value, removes any applied track masking before selecting tracks, acting as if no mask was applied at all\",\"name\":\"Unmask tracks\",\"sort\":\"bc\",\"type\":\"bool\"},\"video\":{\"help\":\"Override which video tracks of the stream should be selected\",\"name\":\"Video track(s)\",\"sort\":\"ab\",\"type\":\"string\",\"validate\":[\"track_selector\"]},\"waittrackcount\":{\"default\":2,\"help\":\"Before starting, wait until this number of GOPs is available in the main selected track\",\"name\":\"Wait for GOP count\",\"sort\":\"bd\",\"type\":\"int\"}},\"push_urls\":[\"rtmp://*\",\"rtmps://*\"],\"url_rel\":\"/play/$\",\"version\":\"3.3\"}"); #endif } From a82333c1cc0f7c36ef110cd2abecf4a8f09e839a Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Wed, 15 May 2024 18:58:52 +0000 Subject: [PATCH 12/24] onebinary: working header generation --- meson.build | 72 ++++++++++++++++++- scripts/make_header.sh | 13 ++++ scripts/onebinary_gen.py | 64 +++++++++++++++++ src/controller/controller.cpp | 5 ++ src/controller/controller_capabilities.cpp | 14 ++-- .../controller_capabilities_static.h | 7 ++ src/input/input_buffer.h | 4 ++ src/input/mist_in.cpp | 9 +++ src/meson.build | 68 ------------------ src/output/mist_out.cpp | 9 +++ src/output/output_hls.h | 4 ++ src/output/output_rtmp.h | 4 ++ 12 files changed, 195 insertions(+), 78 deletions(-) create mode 100755 scripts/make_header.sh create mode 100644 scripts/onebinary_gen.py create mode 100644 src/controller/controller_capabilities_static.h diff --git a/meson.build b/meson.build index e82969953..f7f26bbcb 100644 --- a/meson.build +++ b/meson.build @@ -203,18 +203,88 @@ subdir('test') exec_tgts = [] +make_header = find_program('scripts/make_header.sh') + +onebinary_stuff = [] +onebinary_stuff += 'MistOutRTMP' +onebinary_stuff += 'MistOutHLS' +onebinary_stuff += 'MistOutHTTP' +onebinary_stuff += 'MistInBuffer' + +onebinary_tgts = [] + ## This makes sure all (installable) executables are build in top level directory ## Done because MistController expects its binaries to all be in the same directory foreach exec : executables - exec_tgts += executable( + my_exec = executable( exec.get('name'), exec.get('sources'), dependencies: exec.get('deps'), cpp_args: exec.get('defines'), install: true, ) + exec_tgts += my_exec + gen_src_name = exec.get('name') + '.json' + gen_src = custom_target(gen_src_name, + input: [my_exec], + output: [exec.get('name') + '.json'], + command: [make_header, '@INPUT@', '@OUTPUT0@'] + ) + if onebinary_stuff.contains(exec.get('name')) + onebinary_tgts += gen_src + endif endforeach +prog_python = find_program('python3') + +onebinary_header = custom_target('onebinary', + input: [onebinary_tgts], + output: ['controller_static_capabilities.cpp'], + command: [prog_python, '../scripts/onebinary_gen.py', '--cap-header', '@OUTPUT0@', '--entrypoint', 'foo.cpp', '@INPUT@'], + depends: [onebinary_tgts] +) + +onebinary = executable( + 'MistServer', + [ + files( + 'src/mistserver.cpp', + 'src/input/input.cpp', + 'src/input/input_buffer.cpp', + 'src/output/output.cpp', + 'src/output/output_hls.cpp', + 'src/output/output_http.cpp', + 'src/output/output_http_internal.cpp', + 'src/output/output_ts.cpp', + 'src/output/output_ts_base.cpp', + 'src/output/output_rtmp.cpp', + 'src/controller/controller_external_writers.cpp', + 'src/controller/controller_updater.cpp', + 'src/controller/controller_streams.cpp', + 'src/controller/controller_storage.cpp', + 'src/controller/controller_connectors.cpp', + 'src/controller/controller_statistics.cpp', + 'src/controller/controller_limits.cpp', + 'src/controller/controller_capabilities.cpp', + 'src/controller/controller_uplink.cpp', + 'src/controller/controller_api.cpp', + 'src/controller/controller_push.cpp', + 'src/controller/controller_variables.cpp', + ), + io_cpp, + header_tgts, + embed_tgts, + server_html, + onebinary_header, + ], + cpp_args: [ + '-DTS_BASECLASS=HTTPOutput', + '-DONE_BINARY=1', + ], + dependencies : [libmist_dep], + install: true, +) + # Docs doxygen = find_program('doxygen', required: false) if doxygen.found() diff --git a/scripts/make_header.sh b/scripts/make_header.sh new file mode 100755 index 000000000..d61fd7f19 --- /dev/null +++ b/scripts/make_header.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -euo pipefail + +set +e +json="$(./$1 -j)" +status=$? +set -e +echo "$json" > $2 +if [[ "$status" == "255" ]]; then + exit 0 +fi +exit $status diff --git a/scripts/onebinary_gen.py b/scripts/onebinary_gen.py new file mode 100644 index 000000000..94f7b11cf --- /dev/null +++ b/scripts/onebinary_gen.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python + +# Generates files necessary with hardcoded capabilities for Python + +import os +from pathlib import Path +import json +import argparse + +parser = argparse.ArgumentParser( + prog='onebinary_gen.py', + description='Generates header files necessary to create the MistServer combined binary' +) + +parser.add_argument('--cap-header', help="location of the generated capabilities header", required=True) +parser.add_argument('--entrypoint', help="location of the generated entrypoint file", required=True) +parser.add_argument('files', metavar='N', type=str, nargs='+', help='input binary json files generated elsewhere') + +args = parser.parse_args() + +MIST_IN = "MistIn" +MIST_OUT = "MistOut" +CAP_LINE = ' capabilities["{category}"]["{connector}"] = JSON::fromString({json_str});' + +capabilities = [] + +for name in args.files: + path = Path(name) + stem = path.stem + text = path.read_text().strip("\n") + json_str = json.dumps(text) + category = '' + connector = '' + if stem.startswith(MIST_IN): + category = "inputs" + connector = stem[len(MIST_IN):] + elif stem.startswith(MIST_OUT): + category = "connectors" + connector = stem[len(MIST_OUT):] + else: + raise Exception("unknown binary naming convention: " + stem) + capabilities.append({ + 'json_str': json_str, + 'category': category, + 'connector': connector, + }) + +cap_lines = [ + '#include "src/controller/controller_capabilities_static.h"', + 'namespace Controller{', + ' void addStaticCapabilities(JSON::Value &capabilities) {', +] + +for cap in capabilities: + line = CAP_LINE.format(**cap) + cap_lines.append(line) + +cap_lines.extend([ + ' }', + '}', +]) + +out_fullpath = os.path.join(os.getcwd(), args.cap_header) +Path(out_fullpath).write_text('\n'.join(cap_lines)) diff --git a/src/controller/controller.cpp b/src/controller/controller.cpp index 1ece3b021..ec41a3bdc 100644 --- a/src/controller/controller.cpp +++ b/src/controller/controller.cpp @@ -677,3 +677,8 @@ int ControllerMain(int argc, char **argv){ return 0; } +#ifndef ONE_BINARY +int main(int argc, char **argv){ + return ControllerMain(argc, argv); +} +#endif diff --git a/src/controller/controller_capabilities.cpp b/src/controller/controller_capabilities.cpp index 29e335690..34a695128 100644 --- a/src/controller/controller_capabilities.cpp +++ b/src/controller/controller_capabilities.cpp @@ -1,8 +1,7 @@ #include "controller_capabilities.h" -#include "../output/output_rtmp.h" -#include "../output/output_hls.h" -#include "../output/output_http_internal.h" -#include "../input/input_buffer.h" +#ifdef ONE_BINARY +#include "controller_capabilities_static.h" +#endif #include #include #include @@ -253,7 +252,7 @@ namespace Controller{ /// Aquire list of available protocols, storing in global 'capabilities' JSON::Value. void checkAvailProtocols(){ - #ifdef GO_AWAY + #ifndef ONE_BINARY std::deque execs; Util::getMyExec(execs); std::string arg_one; @@ -320,10 +319,7 @@ namespace Controller{ } #else // produced with e.g. `./MistOutHLS -j | jq '. | tostring'` - capabilities["inputs"]["Buffer"] = JSON::fromString("{\"desc\":\"This input type is both used for push- and pull-based streams. It provides a buffer for live media data. The push://[host][@password] style source allows all enabled protocols that support push input to accept a push into MistServer, where you can accept incoming streams from everyone, based on a set password, and/or use hostname/IP whitelisting.\",\"name\":\"Buffer\",\"non-provider\":true,\"optional\":{\"DVR\":{\"default\":50000,\"help\":\"The target available buffer time for this live stream, in milliseconds. This is the time available to seek around in, and will automatically be extended to fit whole keyframes as well as the minimum duration needed for stable playback.\",\"name\":\"Buffer time (ms)\",\"option\":\"--buffer\",\"type\":\"uint\"},\"cut\":{\"default\":0,\"help\":\"Any timestamps before this will be cut from the live buffer.\",\"name\":\"Cut time (ms)\",\"option\":\"--cut\",\"type\":\"uint\"},\"debug\":{\"help\":\"The debug level at which messages need to be printed.\",\"name\":\"debug\",\"option\":\"--debug\",\"type\":\"debug\"},\"fallback_stream\":{\"default\":\"\",\"help\":\"Alternative stream to load for playback when there is no active broadcast\",\"name\":\"Fallback stream\",\"type\":\"str\"},\"inputtimeout\":{\"default\":30,\"help\":\"How long the input should remain loaded without activity\",\"name\":\"Input inactivity timeout\",\"option\":\"--inputtimeout\",\"type\":\"uint\",\"unit\":\"s\"},\"maxkeepaway\":{\"default\":45000,\"help\":\"Maximum distance in milliseconds to fall behind the live point for stable playback.\",\"name\":\"Maximum live keep-away distance\",\"option\":\"--resume\",\"type\":\"uint\"},\"pagetimeout\":{\"default\":15,\"help\":\"For bufferless or live inputs like HLS, set the timeout in seconds for old, inactive pages to be deleted. A longer value results in more memory usage, but ensures that recently buffered data stays in memory for longer\",\"name\":\"Memory page timeout\",\"option\":\"--pagetimeout\",\"type\":\"uint\"},\"resume\":{\"default\":0,\"help\":\"If enabled, the buffer will linger after source disconnect to allow resuming the stream later. If disabled, the buffer will instantly close on source disconnect.\",\"name\":\"Resume support\",\"option\":\"--resume\",\"select\":[[\"0\",\"Disabled\"],[\"1\",\"Enabled\"]],\"type\":\"select\"},\"segmentsize\":{\"default\":1900,\"help\":\"Target time duration in milliseconds for segments.\",\"name\":\"Segment size (ms)\",\"option\":\"--segment-size\",\"type\":\"uint\"}},\"priority\":9,\"source_match\":\"push://*\",\"version\":\"3.3\"}"); - capabilities["connectors"]["HLS"] = JSON::fromString("{\"codecs\":[[[\"+HEVC\"],[\"+H264\"],[\"+MPEG2\"],[\"+AAC\"],[\"+MP3\"],[\"+AC3\"],[\"+MP2\"],[\"+subtitle\"]]],\"deps\":\"HTTP\",\"desc\":\"Segmented streaming in Apple (TS-based) format over HTTP ( = HTTP Live Streaming)\",\"exceptions\":{\"codec:HEVC\":[[\"blacklist\"]],\"codec:MP3\":[[\"blacklist\",[\"Mozilla/\"]],[\"whitelist\",[\"iPad\",\"iPhone\",\"iPod\",\"MacIntel\",\"Edge\"]]]},\"forward\":{\"ip\":{\"help\":\"Data to pretend arrived on the socket before parsing the socket.\",\"name\":\"Previous request\",\"option\":\"--prequest\",\"type\":\"str\"},\"streamname\":{\"help\":\"What streamname to serve.\",\"name\":\"Stream\",\"option\":\"--stream\",\"type\":\"str\"}},\"friendly\":\"Apple segmented over HTTP (HLS)\",\"methods\":[{\"handler\":\"http\",\"hrn\":\"HLS (TS)\",\"priority\":9,\"type\":\"html5/application/vnd.apple.mpegurl\"}],\"name\":\"HLS\",\"optional\":{\"chunkpath\":{\"default\":\"\",\"help\":\"Chunks will be served from this path.\",\"name\":\"Prepend path for chunks\",\"option\":\"--chunkpath\",\"short\":\"e\",\"type\":\"str\"},\"debug\":{\"help\":\"The debug level at which messages need to be printed.\",\"name\":\"debug\",\"option\":\"--debug\",\"type\":\"debug\"},\"default_track_sorting\":{\"default\":\"\",\"help\":\"What tracks are selected first when no specific track selector is used for playback.\",\"name\":\"Default track sorting\",\"option\":\"--default_track_sorting\",\"select\":[[\"\",\"Default (last added for live, first added for VoD)\"],[\"bps_lth\",\"Bit rate, low to high\"],[\"bps_htl\",\"Bit rate, high to low\"],[\"id_lth\",\"Track ID, low to high\"],[\"id_htl\",\"Track ID, high to low\"],[\"res_lth\",\"Resolution, low to high\"],[\"res_htl\",\"Resolution, high to low\"]],\"short\":\"S\",\"type\":\"select\"},\"listlimit\":{\"default\":0,\"help\":\"Maximum number of parts in live playlists. (0 = infinite)\",\"name\":\"Live playlist limit\",\"option\":\"--list-limit\",\"type\":\"uint\"},\"nonchunked\":{\"help\":\"Disables chunked transfer encoding, forcing per-segment buffering. Reduces performance significantly, but increases compatibility somewhat.\",\"name\":\"Send whole segments\",\"option\":\"--nonchunked\"},\"username\":{\"default\":\"root\",\"help\":\"Username to drop privileges to - default if unprovided means do not drop privileges\",\"name\":\"Username\",\"option\":\"--username\",\"short\":\"u\",\"type\":\"str\"}},\"url_prefix\":\"/hls/$/\",\"url_rel\":\"/hls/$/index.m3u8\",\"version\":\"3.3\"}"); - capabilities["connectors"]["HTTP"] = JSON::fromString("{\"codecs\":[null],\"desc\":\"HTTP connection handler, provides all enabled HTTP-based outputs\",\"forward\":{\"ip\":{\"help\":\"Data to pretend arrived on the socket before parsing the socket.\",\"name\":\"Previous request\",\"option\":\"--prequest\",\"type\":\"str\"},\"streamname\":{\"help\":\"What streamname to serve.\",\"name\":\"Stream\",\"option\":\"--stream\",\"type\":\"str\"}},\"friendly\":\"HTTP\",\"name\":\"HTTP\",\"optional\":{\"certbot\":{\"default\":\"\",\"help\":\"Automatically set by the MistUtilCertbot authentication hook for certbot. Not intended to be set manually.\",\"name\":\"Certbot validation token\",\"option\":\"--certbot\",\"short\":\"C\",\"type\":\"str\"},\"debug\":{\"help\":\"The debug level at which messages need to be printed.\",\"name\":\"debug\",\"option\":\"--debug\",\"type\":\"debug\"},\"default_track_sorting\":{\"default\":\"\",\"help\":\"What tracks are selected first when no specific track selector is used for playback.\",\"name\":\"Default track sorting\",\"option\":\"--default_track_sorting\",\"select\":[[\"\",\"Default (last added for live, first added for VoD)\"],[\"bps_lth\",\"Bit rate, low to high\"],[\"bps_htl\",\"Bit rate, high to low\"],[\"id_lth\",\"Track ID, low to high\"],[\"id_htl\",\"Track ID, high to low\"],[\"res_lth\",\"Resolution, low to high\"],[\"res_htl\",\"Resolution, high to low\"]],\"short\":\"S\",\"type\":\"select\"},\"interface\":{\"default\":\"0.0.0.0\",\"help\":\"Address of the interface to listen on\",\"name\":\"Interface\",\"option\":\"--interface\",\"short\":\"i\",\"type\":\"str\"},\"nostreamtext\":{\"default\":\"\",\"help\":\"Text or HTML to display when streams are unavailable.\",\"name\":\"Stream unavailable text\",\"option\":\"--nostreamtext\",\"type\":\"str\"},\"port\":{\"default\":8080,\"help\":\"TCP port to listen on\",\"name\":\"TCP port\",\"option\":\"--port\",\"short\":\"p\",\"type\":\"uint\"},\"pubaddr\":{\"default\":\"\",\"help\":\"Full public address this output is available as, if being proxied\",\"name\":\"Public address\",\"option\":\"--public-address\",\"type\":\"inputlist\"},\"username\":{\"default\":\"root\",\"help\":\"Username to drop privileges to - default if unprovided means do not drop privileges\",\"name\":\"Username\",\"option\":\"--username\",\"short\":\"u\",\"type\":\"str\"},\"wrappers\":{\"allowed\":[\"html5\",\"hlsjs\",\"videojs\",\"dashjs\",\"webrtc\",\"mews\",\"rawws\",\"flv\",\"flash_strobe\"],\"default\":\"\",\"help\":\"Which players are attempted and in what order.\",\"name\":\"Active players\",\"option\":\"--wrappers\",\"short\":\"w\",\"type\":\"ord_multi_sel\"}},\"protocol\":\"http://\",\"provides\":\"HTTP\",\"url_match\":[\"/crossdomain.xml\",\"/clientaccesspolicy.xml\",\"/$.html\",\"/favicon.ico\",\"/$.smil\",\"/info_$.js\",\"/json_$.js\",\"/player.js\",\"/videojs.js\",\"/dashjs.js\",\"/webrtc.js\",\"/flv.js\",\"/hlsjs.js\",\"/libde265.js\",\"/skins/default.css\",\"/skins/dev.css\",\"/skins/videojs.css\",\"/embed_$.js\",\"/flashplayer.swf\",\"/oldflashplayer.swf\"],\"url_prefix\":\"/.well-known/\",\"url_rel\":\"/$.html\",\"version\":\"3.3\"}"); - capabilities["connectors"]["RTMP"] = JSON::fromString("{\"codecs\":[[[\"H264\",\"H263\",\"VP6\",\"VP6Alpha\",\"ScreenVideo2\",\"ScreenVideo1\",\"JPEG\"],[\"AAC\",\"MP3\",\"Speex\",\"Nellymoser\",\"PCM\",\"ADPCM\",\"ALAW\",\"ULAW\"]]],\"deps\":\"\",\"desc\":\"Real time streaming over Adobe RTMP\",\"friendly\":\"RTMP\",\"incoming_push_url\":\"rtmp://$host:$port/$password/$stream\",\"methods\":[{\"handler\":\"rtmp\",\"hrn\":\"RTMP\",\"player_url\":\"/flashplayer.swf\",\"priority\":7,\"type\":\"flash/10\"}],\"name\":\"RTMP\",\"optional\":{\"acceptable\":{\"default\":0,\"help\":\"Whether to allow only incoming pushes (2), only outgoing pulls (1), or both (0, default)\",\"name\":\"Acceptable connection types\",\"option\":\"--acceptable\",\"select\":[[0,\"Allow both incoming and outgoing connections\"],[1,\"Allow only outgoing connections\"],[2,\"Allow only incoming connections\"]],\"short\":\"T\",\"type\":\"select\"},\"debug\":{\"help\":\"The debug level at which messages need to be printed.\",\"name\":\"debug\",\"option\":\"--debug\",\"type\":\"debug\"},\"default_track_sorting\":{\"default\":\"\",\"help\":\"What tracks are selected first when no specific track selector is used for playback.\",\"name\":\"Default track sorting\",\"option\":\"--default_track_sorting\",\"select\":[[\"\",\"Default (last added for live, first added for VoD)\"],[\"bps_lth\",\"Bit rate, low to high\"],[\"bps_htl\",\"Bit rate, high to low\"],[\"id_lth\",\"Track ID, low to high\"],[\"id_htl\",\"Track ID, high to low\"],[\"res_lth\",\"Resolution, low to high\"],[\"res_htl\",\"Resolution, high to low\"]],\"short\":\"S\",\"type\":\"select\"},\"interface\":{\"default\":\"0.0.0.0\",\"help\":\"Address of the interface to listen on\",\"name\":\"Interface\",\"option\":\"--interface\",\"short\":\"i\",\"type\":\"str\"},\"maxkbps\":{\"default\":0,\"help\":\"Maximum bitrate to allow in the ingest direction, in kilobits per second.\",\"name\":\"Max. kbps\",\"option\":\"--maxkbps\",\"short\":\"K\",\"type\":\"uint\"},\"port\":{\"default\":1935,\"help\":\"TCP port to listen on\",\"name\":\"TCP port\",\"option\":\"--port\",\"short\":\"p\",\"type\":\"uint\"},\"username\":{\"default\":\"root\",\"help\":\"Username to drop privileges to - default if unprovided means do not drop privileges\",\"name\":\"Username\",\"option\":\"--username\",\"short\":\"u\",\"type\":\"str\"}},\"push_parameters\":{\"append\":{\"format\":\"set_or_unset\",\"help\":\"If set to any value, will (if possible) append to an existing file, rather than overwriting it\",\"name\":\"Append to file\",\"sort\":\"bf\",\"type\":\"bool\"},\"audio\":{\"help\":\"Override which audio tracks of the stream should be selected\",\"name\":\"Audio track(s)\",\"sort\":\"aa\",\"type\":\"string\",\"validate\":[\"track_selector\"]},\"duration\":{\"disable\":[\"recstop\",\"stop\"],\"help\":\"How much media time to push, in seconds. Internally overrides \\\"recstop\\\"\",\"name\":\"Duration of push\",\"sort\":\"bi\",\"type\":\"int\",\"unit\":\"s\"},\"m3u8\":{\"help\":\"If set, will write a m3u8 playlist file for the segments to the given path (relative from the first segment path). When this parameter is used, at least one of the variables $segmentCounter or $currentMediaTime must be part of the segment path (to keep segments from overwriting each other). The \\\"Split interval\\\" parameter will default to 60 seconds when using this option.\",\"name\":\"Playlist path (relative to segments)\",\"sort\":\"apa\",\"type\":\"string\"},\"maxEntries\":{\"help\":\"When writing a playlist, delete oldest segment entries once this entry count has been reached (and, if possible, also delete said segments themselves). When set to 0 or left empty, does not delete.\",\"name\":\"Playlist max entries\",\"sort\":\"apc\",\"type\":\"int\"},\"maxwaittrackms\":{\"default\":\"5s, or 120s when using a non-default GOP count\",\"help\":\"When waiting for GOPs on the main track, give up when this much data is available in the main track buffer\",\"name\":\"Max buffer duration for GOP count wait\",\"sort\":\"be\",\"type\":\"int\",\"unit\":\"ms\"},\"noendlist\":{\"format\":\"set_or_unset\",\"help\":\"If set, does not write #X-EXT-ENDLIST when finalizing the playlist on exit\",\"name\":\"Don't end playlist\",\"sort\":\"bfa\",\"type\":\"bool\"},\"pushdelay\":{\"disable\":[\"realtime\",\"start\"],\"help\":\"Ensures the stream is always delayed by at least this many seconds. Internally overrides the \\\"realtime\\\" and \\\"start\\\" parameters\",\"name\":\"Push delay\",\"sort\":\"bg\",\"type\":\"int\",\"unit\":\"s\"},\"rate\":{\"default\":\"1\",\"help\":\"Multiplier for the playback speed rate, or 0 to not limit\",\"name\":\"Playback rate\",\"sort\":\"ba\",\"type\":\"int\"},\"realtime\":{\"format\":\"set_or_unset\",\"help\":\"If set to any value, removes the rate override to unlimited normally applied to push outputs\",\"name\":\"Don't speed up output\",\"sort\":\"bb\",\"type\":\"bool\"},\"recstart\":{\"file_only\":true,\"help\":\"What internal media timestamp to start from\",\"name\":\"Media timestamp to start from\",\"sort\":\"bp\",\"type\":\"int\",\"unit\":\"s\"},\"recstartunix\":{\"disable\":[\"recstart\"],\"file_only\":true,\"help\":\"What unix timestamp to start from\",\"name\":\"Unix timestamp to start from\",\"sort\":\"br\",\"type\":\"unixtime\",\"unit\":\"s\"},\"recstop\":{\"file_only\":true,\"help\":\"What internal media timestamp to stop at\",\"name\":\"Media timestamp to stop at\",\"sort\":\"bo\",\"type\":\"int\",\"unit\":\"s\"},\"recstopunix\":{\"disable\":[\"recstop\"],\"file_only\":true,\"help\":\"What unix timestamp to stop at\",\"name\":\"Unix timestamp to stop at\",\"sort\":\"bq\",\"type\":\"unixtime\",\"unit\":\"s\"},\"split\":{\"help\":\"Performs a gapless restart of the recording every this many seconds. Always aligns to the next keyframe after this duration, to ensure each recording is fully playable. When set to zero (the default) will not split at all.\",\"name\":\"Split interval\",\"sort\":\"bh\",\"type\":\"int\",\"unit\":\"s\"},\"start\":{\"help\":\"What internal media timestamp to start from\",\"name\":\"Media timestamp to start from\",\"prot_only\":true,\"sort\":\"bl\",\"type\":\"int\",\"unit\":\"s\"},\"startunix\":{\"disable\":[\"start\"],\"help\":\"What unix timestamp to start from\",\"name\":\"Unix timestamp to start from\",\"prot_only\":true,\"sort\":\"bn\",\"type\":\"unixtime\",\"unit\":\"s\"},\"stop\":{\"help\":\"What internal media timestamp to stop at\",\"name\":\"Media timestamp to stop at\",\"prot_only\":true,\"sort\":\"bk\",\"type\":\"int\",\"unit\":\"s\"},\"stopunix\":{\"disable\":[\"stop\"],\"help\":\"What unix timestamp to stop at\",\"name\":\"Unix timestamp to stop at\",\"prot_only\":true,\"sort\":\"bm\",\"type\":\"unixtime\",\"unit\":\"s\"},\"subtitle\":{\"help\":\"Override which subtitle tracks of the stream should be selected\",\"name\":\"Subtitle track(s)\",\"sort\":\"ac\",\"type\":\"string\",\"validate\":[\"track_selector\"]},\"targetAge\":{\"help\":\"When writing a playlist, delete segment entries that are more than this many seconds old from the playlist (and, if possible, also delete said segments themselves). When set to 0 or left empty, does not delete.\",\"name\":\"Playlist target age\",\"sort\":\"apb\",\"type\":\"int\",\"unit\":\"s\"},\"unmask\":{\"format\":\"set_or_unset\",\"help\":\"If set to any value, removes any applied track masking before selecting tracks, acting as if no mask was applied at all\",\"name\":\"Unmask tracks\",\"sort\":\"bc\",\"type\":\"bool\"},\"video\":{\"help\":\"Override which video tracks of the stream should be selected\",\"name\":\"Video track(s)\",\"sort\":\"ab\",\"type\":\"string\",\"validate\":[\"track_selector\"]},\"waittrackcount\":{\"default\":2,\"help\":\"Before starting, wait until this number of GOPs is available in the main selected track\",\"name\":\"Wait for GOP count\",\"sort\":\"bd\",\"type\":\"int\"}},\"push_urls\":[\"rtmp://*\",\"rtmps://*\"],\"url_rel\":\"/play/$\",\"version\":\"3.3\"}"); + Controller::addStaticCapabilities(capabilities); #endif } diff --git a/src/controller/controller_capabilities_static.h b/src/controller/controller_capabilities_static.h new file mode 100644 index 000000000..70f898a94 --- /dev/null +++ b/src/controller/controller_capabilities_static.h @@ -0,0 +1,7 @@ +#include + +namespace Controller{ + + /// Add capabilities + void addStaticCapabilities(JSON::Value &capabilities); +} diff --git a/src/input/input_buffer.h b/src/input/input_buffer.h index d85b6380a..7a60da3ec 100644 --- a/src/input/input_buffer.h +++ b/src/input/input_buffer.h @@ -58,3 +58,7 @@ namespace Mist{ std::map sourcePids; }; }// namespace Mist + +#ifndef ONE_BINARY +typedef Mist::inputBuffer mistIn; +#endif diff --git a/src/input/mist_in.cpp b/src/input/mist_in.cpp index a9e31501c..3332c455c 100644 --- a/src/input/mist_in.cpp +++ b/src/input/mist_in.cpp @@ -1,3 +1,6 @@ +#ifndef ONE_BINARY +#include INPUTTYPE +#endif #include template @@ -7,3 +10,9 @@ int InputMain(int argc, char *argv[]){ T conv(&conf); return conv.boot(argc, argv); } + +#ifndef ONE_BINARY +int main(int argc, char *argv[]){ + return InputMain(argc, argv); +} +#endif diff --git a/src/meson.build b/src/meson.build index 6fb8e692d..33db51a31 100644 --- a/src/meson.build +++ b/src/meson.build @@ -13,71 +13,3 @@ executables += { 'defines': [], 'deps' : [libmist_dep] } - -executables += { - 'name': 'MistServer', - 'sources': [ - files( - 'mistserver.cpp', - 'input/input.cpp', - 'input/input_buffer.cpp', - 'output/output.cpp', - 'output/output_hls.cpp', - 'output/output_http.cpp', - 'output/output_http_internal.cpp', - 'output/output_ts.cpp', - 'output/output_ts_base.cpp', - 'output/output_rtmp.cpp', - 'controller/controller_external_writers.cpp', - 'controller/controller_updater.cpp', - 'controller/controller_streams.cpp', - 'controller/controller_storage.cpp', - 'controller/controller_connectors.cpp', - 'controller/controller_statistics.cpp', - 'controller/controller_limits.cpp', - 'controller/controller_capabilities.cpp', - 'controller/controller_uplink.cpp', - 'controller/controller_api.cpp', - 'controller/controller_push.cpp', - 'controller/controller_variables.cpp', - ), - io_cpp, - header_tgts, - embed_tgts, - server_html - ], - 'defines': [ - '-DTS_BASECLASS=HTTPOutput', - '-DONE_BINARY=true', - ], - 'deps' : [libmist_dep] -} - -# executables += { -# 'name': 'MistServer', -# 'sources': [ -# files( -# 'output/mist_out.cpp', -# 'output/output.cpp', -# 'output/output_rtmp.cpp' -# ), -# io_cpp, -# header_tgts -# ], -# 'defines': [ -# string_opt.format('OUTPUTTYPE', 'output_rtmp.h') -# ], -# 'deps' : [libmist_dep] -# } - # executables += { - # 'name': 'MistOut'+output.get('name'), - # 'sources' : [ - # sources, - # header_tgts - # ], - # 'deps' : deps, - # 'defines' : [ - # string_opt.format('OUTPUTTYPE', 'output_'+output.get('format')+'.h'), - # '-DTS_BASECLASS='+tsBaseClass - # ] - # } \ No newline at end of file diff --git a/src/output/mist_out.cpp b/src/output/mist_out.cpp index 9120a9575..61d84fd5b 100644 --- a/src/output/mist_out.cpp +++ b/src/output/mist_out.cpp @@ -1,3 +1,6 @@ +#ifndef ONE_BINARY +#include OUTPUTTYPE +#endif #include #include #include @@ -74,3 +77,9 @@ int OutputMain(int argc, char *argv[]){ INFO_MSG("Exit reason: %s", Util::exitReason); return 0; } + +#ifndef ONE_BINARY +int main(int argc, char *argv[]){ + return OutputMain(argc, argv); +} +#endif diff --git a/src/output/output_hls.h b/src/output/output_hls.h index b4c8b04c0..ff3fb6727 100644 --- a/src/output/output_hls.h +++ b/src/output/output_hls.h @@ -25,3 +25,7 @@ namespace Mist{ uint64_t until; }; }// namespace Mist + +#ifndef ONE_BINARY +typedef Mist::OutHLS mistOut; +#endif diff --git a/src/output/output_rtmp.h b/src/output/output_rtmp.h index 95296c08a..ba65112f5 100644 --- a/src/output/output_rtmp.h +++ b/src/output/output_rtmp.h @@ -54,3 +54,7 @@ namespace Mist{ void calcNextFrameInfo(); }; }// namespace Mist + +#ifndef ONE_BINARY +typedef Mist::OutRTMP mistOut; +#endif From f92f261d1ba09dd9f98829d72df0d41bf71b2659 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Wed, 15 May 2024 20:04:48 +0000 Subject: [PATCH 13/24] onebinary: working entrypoint generation --- meson.build | 10 ++++--- scripts/onebinary_gen.py | 60 ++++++++++++++++++++++++++++++++++++++++ src/input/input_buffer.h | 2 +- src/mistserver.cpp | 50 --------------------------------- 4 files changed, 67 insertions(+), 55 deletions(-) delete mode 100644 src/mistserver.cpp diff --git a/meson.build b/meson.build index f7f26bbcb..133e75a4a 100644 --- a/meson.build +++ b/meson.build @@ -209,9 +209,10 @@ onebinary_stuff = [] onebinary_stuff += 'MistOutRTMP' onebinary_stuff += 'MistOutHLS' onebinary_stuff += 'MistOutHTTP' -onebinary_stuff += 'MistInBuffer' +# onebinary_stuff += 'MistInBuffer' onebinary_tgts = [] +onebinary_sources = [] ## This makes sure all (installable) executables are build in top level directory ## Done because MistController expects its binaries to all be in the same directory @@ -236,11 +237,12 @@ foreach exec : executables endforeach prog_python = find_program('python3') +script = files('scripts/onebinary_gen.py') onebinary_header = custom_target('onebinary', input: [onebinary_tgts], - output: ['controller_static_capabilities.cpp'], - command: [prog_python, '../scripts/onebinary_gen.py', '--cap-header', '@OUTPUT0@', '--entrypoint', 'foo.cpp', '@INPUT@'], + output: ['controller_static_capabilities.cpp', 'mistserver.cpp'], + command: [prog_python, script, '--cap-header', '@OUTPUT0@', '--entrypoint', '@OUTPUT1@', '@INPUT@'], depends: [onebinary_tgts] ) @@ -248,7 +250,6 @@ onebinary = executable( 'MistServer', [ files( - 'src/mistserver.cpp', 'src/input/input.cpp', 'src/input/input_buffer.cpp', 'src/output/output.cpp', @@ -271,6 +272,7 @@ onebinary = executable( 'src/controller/controller_push.cpp', 'src/controller/controller_variables.cpp', ), + onebinary_sources, io_cpp, header_tgts, embed_tgts, diff --git a/scripts/onebinary_gen.py b/scripts/onebinary_gen.py index 94f7b11cf..cb51e2c82 100644 --- a/scripts/onebinary_gen.py +++ b/scripts/onebinary_gen.py @@ -31,18 +31,23 @@ json_str = json.dumps(text) category = '' connector = '' + class_name = '' if stem.startswith(MIST_IN): category = "inputs" connector = stem[len(MIST_IN):] + class_name = "Mist::In" + connector elif stem.startswith(MIST_OUT): category = "connectors" connector = stem[len(MIST_OUT):] + class_name = "Mist::Out" + connector else: raise Exception("unknown binary naming convention: " + stem) capabilities.append({ 'json_str': json_str, 'category': category, 'connector': connector, + 'class_name': class_name, + 'binary_name' : stem, }) cap_lines = [ @@ -62,3 +67,58 @@ out_fullpath = os.path.join(os.getcwd(), args.cap_header) Path(out_fullpath).write_text('\n'.join(cap_lines)) + +entrypoint_lines = [] + +entrypoint_lines.extend([ + '#include ', + '#include ', + '#include ', + '#include ', + '#include ', + '#include "src/output/mist_out.cpp"', + '#include "src/output/output_rtmp.h"', + '#include "src/output/output_hls.h"', + '#include "src/output/output_http_internal.h"', + '#include "src/input/mist_in.cpp"', + '#include "src/input/input_buffer.h"', + '#include "src/session.cpp"', + '#include "src/controller/controller.cpp"', + 'int main(int argc, char *argv[]){', + ' if (argc < 2) {', + ' return ControllerMain(argc, argv);', + ' }', + ' // Create a new argv array without argv[1]', + ' int new_argc = argc - 1;', + ' char** new_argv = new char*[new_argc];', + ' for (int i = 0, j = 0; i < argc; ++i) {', + ' if (i != 1) {', + ' new_argv[j++] = argv[i];', + ' }', + ' }', + ' if (strcmp(argv[1], "MistController") == 0) {', + ' return ControllerMain(new_argc, new_argv);', + ' }', +]) + +for cap in capabilities: + entrypoint_lines.extend([ + ' else if (strcmp(argv[1], "' + cap['binary_name'] + '") == 0) {', + ' return OutputMain<' + cap['class_name'] + '>(new_argc, new_argv);', + ' }', + ]) + +entrypoint_lines.extend([ + ' else if (strcmp(argv[1], "MistSession") == 0) {', + ' return SessionMain(new_argc, new_argv);', + ' }', + ' else {', + ' return ControllerMain(argc, argv);', + ' }', + ' INFO_MSG("binary not found: %s", argv[1]);', + ' return 202;', + '}', +]) + +entrypoint_fullpath = os.path.join(os.getcwd(), args.entrypoint) +Path(entrypoint_fullpath).write_text('\n'.join(entrypoint_lines)) diff --git a/src/input/input_buffer.h b/src/input/input_buffer.h index 7a60da3ec..5d9be3e9d 100644 --- a/src/input/input_buffer.h +++ b/src/input/input_buffer.h @@ -60,5 +60,5 @@ namespace Mist{ }// namespace Mist #ifndef ONE_BINARY -typedef Mist::inputBuffer mistIn; +typedef Mist::InputBuffer mistIn; #endif diff --git a/src/mistserver.cpp b/src/mistserver.cpp deleted file mode 100644 index 32ca0b335..000000000 --- a/src/mistserver.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include -#include -#include -#include -#include "output/mist_out.cpp" -#include "output/output_rtmp.h" -#include "output/output_hls.h" -#include "output/output_http_internal.h" -#include "input/mist_in.cpp" -#include "input/input_buffer.h" -#include "session.cpp" -#include "controller/controller.cpp" - -int main(int argc, char *argv[]){ - if (argc < 2) { - return ControllerMain(argc, argv); - } - // Create a new argv array without argv[1] - int new_argc = argc - 1; - char** new_argv = new char*[new_argc]; - for (int i = 0, j = 0; i < argc; ++i) { - if (i != 1) { - new_argv[j++] = argv[i]; - } - } - if (strcmp(argv[1], "MistController") == 0) { - return ControllerMain(new_argc, new_argv); - } - if (strcmp(argv[1], "MistOutHLS") == 0) { - return OutputMain(new_argc, new_argv); - } - else if (strcmp(argv[1], "MistOutHTTP") == 0) { - return OutputMain(new_argc, new_argv); - } - else if (strcmp(argv[1], "MistOutRTMP") == 0) { - return OutputMain(new_argc, new_argv); - } - else if (strcmp(argv[1], "MistInBuffer") == 0) { - return InputMain(new_argc, new_argv); - } - else if (strcmp(argv[1], "MistSession") == 0) { - return SessionMain(new_argc, new_argv); - } - else { - return ControllerMain(argc, argv); - } - INFO_MSG("binary not found: %s", argv[1]); - return 202; -} From 23f6dd33ace210e4a7cb91936471cb6b32f21022 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Wed, 15 May 2024 22:04:34 +0000 Subject: [PATCH 14/24] onebinary: entrypoint dynamically gets headers too --- meson.build | 6 +++--- scripts/onebinary_gen.py | 27 ++++++++++++++++++++++----- src/input/meson.build | 7 ++++++- src/output/meson.build | 7 ++++++- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/meson.build b/meson.build index 133e75a4a..715337554 100644 --- a/meson.build +++ b/meson.build @@ -212,7 +212,7 @@ onebinary_stuff += 'MistOutHTTP' # onebinary_stuff += 'MistInBuffer' onebinary_tgts = [] -onebinary_sources = [] +onebinary_headers = [] ## This makes sure all (installable) executables are build in top level directory ## Done because MistController expects its binaries to all be in the same directory @@ -233,6 +233,7 @@ foreach exec : executables ) if onebinary_stuff.contains(exec.get('name')) onebinary_tgts += gen_src + onebinary_headers += exec.get('headers') endif endforeach @@ -240,7 +241,7 @@ prog_python = find_program('python3') script = files('scripts/onebinary_gen.py') onebinary_header = custom_target('onebinary', - input: [onebinary_tgts], + input: [onebinary_tgts, onebinary_headers], output: ['controller_static_capabilities.cpp', 'mistserver.cpp'], command: [prog_python, script, '--cap-header', '@OUTPUT0@', '--entrypoint', '@OUTPUT1@', '@INPUT@'], depends: [onebinary_tgts] @@ -272,7 +273,6 @@ onebinary = executable( 'src/controller/controller_push.cpp', 'src/controller/controller_variables.cpp', ), - onebinary_sources, io_cpp, header_tgts, embed_tgts, diff --git a/scripts/onebinary_gen.py b/scripts/onebinary_gen.py index cb51e2c82..a4eb83588 100644 --- a/scripts/onebinary_gen.py +++ b/scripts/onebinary_gen.py @@ -18,13 +18,28 @@ args = parser.parse_args() +json_files = [] +header_files = [] +for file in args.files: + if file.endswith('.json'): + json_files.append(file) + elif file.endswith('h'): + header_files.append(file) + else: + raise Exception("unknown file type: " + file) + +# print('json') +# print(json_files) +# print('h') +# print(header_files) + MIST_IN = "MistIn" MIST_OUT = "MistOut" CAP_LINE = ' capabilities["{category}"]["{connector}"] = JSON::fromString({json_str});' capabilities = [] -for name in args.files: +for name in json_files: path = Path(name) stem = path.stem text = path.read_text().strip("\n") @@ -76,12 +91,14 @@ '#include ', '#include ', '#include ', +]) + +for header_file in header_files: + entrypoint_lines.append('#include "' + header_file + '"') + +entrypoint_lines.extend([ '#include "src/output/mist_out.cpp"', - '#include "src/output/output_rtmp.h"', - '#include "src/output/output_hls.h"', - '#include "src/output/output_http_internal.h"', '#include "src/input/mist_in.cpp"', - '#include "src/input/input_buffer.h"', '#include "src/session.cpp"', '#include "src/controller/controller.cpp"', 'int main(int argc, char *argv[]){', diff --git a/src/input/meson.build b/src/input/meson.build index b4e72f27b..ae17eae77 100644 --- a/src/input/meson.build +++ b/src/input/meson.build @@ -61,6 +61,8 @@ foreach input : inputs deps += av_libs endif + inputtype_header = 'input_'+input.get('format')+'.h' + executables += { 'name' : 'MistIn'+input.get('name'), 'sources' : [ @@ -74,7 +76,10 @@ foreach input : inputs ], 'deps' : deps, 'defines': [ - string_opt.format('INPUTTYPE', 'input_'+input.get('format')+'.h') + string_opt.format('INPUTTYPE', inputtype_header) + ], + 'headers': [ + inputtype_header ] } endforeach diff --git a/src/output/meson.build b/src/output/meson.build index 62e85a0b8..866460579 100644 --- a/src/output/meson.build +++ b/src/output/meson.build @@ -102,6 +102,8 @@ foreach output : outputs sources += base endif + outputtype_header = 'output_'+output.get('format')+'.h' + executables += { 'name': 'MistOut'+output.get('name'), 'sources' : [ @@ -110,8 +112,11 @@ foreach output : outputs ], 'deps' : deps, 'defines' : [ - string_opt.format('OUTPUTTYPE', 'output_'+output.get('format')+'.h'), + string_opt.format('OUTPUTTYPE', outputtype_header), '-DTS_BASECLASS='+tsBaseClass + ], + 'headers' : [ + files(outputtype_header) ] } endforeach From 5ed95b5822fcee51fcfbcb796e89ce81d62cc4a7 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Wed, 15 May 2024 23:24:39 +0000 Subject: [PATCH 15/24] onebinary: sources and stuff populated dynamically --- meson.build | 16 ++++++---------- scripts/onebinary_gen.py | 24 ++++++++++++++++-------- src/controller/controller.h | 1 + src/input/meson.build | 8 +++++++- src/input/mist_in.cpp | 1 + src/output/meson.build | 18 +++++++++++++++--- src/session.h | 2 ++ 7 files changed, 48 insertions(+), 22 deletions(-) create mode 100644 src/controller/controller.h create mode 100644 src/session.h diff --git a/meson.build b/meson.build index 715337554..0b3983f30 100644 --- a/meson.build +++ b/meson.build @@ -209,10 +209,11 @@ onebinary_stuff = [] onebinary_stuff += 'MistOutRTMP' onebinary_stuff += 'MistOutHLS' onebinary_stuff += 'MistOutHTTP' -# onebinary_stuff += 'MistInBuffer' +onebinary_stuff += 'MistInBuffer' onebinary_tgts = [] onebinary_headers = [] +onebinary_sources = [] ## This makes sure all (installable) executables are build in top level directory ## Done because MistController expects its binaries to all be in the same directory @@ -234,6 +235,7 @@ foreach exec : executables if onebinary_stuff.contains(exec.get('name')) onebinary_tgts += gen_src onebinary_headers += exec.get('headers') + onebinary_sources += exec.get('sources_debased') endif endforeach @@ -251,15 +253,6 @@ onebinary = executable( 'MistServer', [ files( - 'src/input/input.cpp', - 'src/input/input_buffer.cpp', - 'src/output/output.cpp', - 'src/output/output_hls.cpp', - 'src/output/output_http.cpp', - 'src/output/output_http_internal.cpp', - 'src/output/output_ts.cpp', - 'src/output/output_ts_base.cpp', - 'src/output/output_rtmp.cpp', 'src/controller/controller_external_writers.cpp', 'src/controller/controller_updater.cpp', 'src/controller/controller_streams.cpp', @@ -272,7 +265,10 @@ onebinary = executable( 'src/controller/controller_api.cpp', 'src/controller/controller_push.cpp', 'src/controller/controller_variables.cpp', + 'src/session.cpp', + 'src/controller/controller.cpp', ), + onebinary_sources, io_cpp, header_tgts, embed_tgts, diff --git a/scripts/onebinary_gen.py b/scripts/onebinary_gen.py index a4eb83588..2094ddd50 100644 --- a/scripts/onebinary_gen.py +++ b/scripts/onebinary_gen.py @@ -50,11 +50,13 @@ if stem.startswith(MIST_IN): category = "inputs" connector = stem[len(MIST_IN):] - class_name = "Mist::In" + connector + class_name = "Mist::Input" + connector + func_name = "InputMain" elif stem.startswith(MIST_OUT): category = "connectors" connector = stem[len(MIST_OUT):] class_name = "Mist::Out" + connector + func_name = "OutputMain" else: raise Exception("unknown binary naming convention: " + stem) capabilities.append({ @@ -63,6 +65,7 @@ 'connector': connector, 'class_name': class_name, 'binary_name' : stem, + 'func_name': func_name, }) cap_lines = [ @@ -85,22 +88,27 @@ entrypoint_lines = [] +for header_file in header_files: + entrypoint_lines.append('#include "' + header_file + '"') + entrypoint_lines.extend([ '#include ', '#include ', '#include ', '#include ', '#include ', + '#include "src/session.h"', + '#include "src/controller/controller.h"', + '#include "src/output/mist_out.cpp"', + '#include "src/input/mist_in.cpp"', ]) -for header_file in header_files: - entrypoint_lines.append('#include "' + header_file + '"') entrypoint_lines.extend([ - '#include "src/output/mist_out.cpp"', - '#include "src/input/mist_in.cpp"', - '#include "src/session.cpp"', - '#include "src/controller/controller.cpp"', + # '#include "src/output/mist_out.cpp"', + # '#include "src/input/mist_in.cpp"', + # '#include "src/session.cpp"', + # '#include "src/controller/controller.cpp"', 'int main(int argc, char *argv[]){', ' if (argc < 2) {', ' return ControllerMain(argc, argv);', @@ -121,7 +129,7 @@ for cap in capabilities: entrypoint_lines.extend([ ' else if (strcmp(argv[1], "' + cap['binary_name'] + '") == 0) {', - ' return OutputMain<' + cap['class_name'] + '>(new_argc, new_argv);', + ' return ' + cap['func_name'] +'<' + cap['class_name'] + '>(new_argc, new_argv);', ' }', ]) diff --git a/src/controller/controller.h b/src/controller/controller.h new file mode 100644 index 000000000..dccc5518e --- /dev/null +++ b/src/controller/controller.h @@ -0,0 +1 @@ +int ControllerMain(int argc, char **argv); diff --git a/src/input/meson.build b/src/input/meson.build index ae17eae77..23b66f47b 100644 --- a/src/input/meson.build +++ b/src/input/meson.build @@ -74,12 +74,18 @@ foreach input : inputs io_cpp, header_tgts ], + 'sources_debased' : [ + files( + 'input.cpp', + 'input_'+input.get('format')+'.cpp' + ) + ], 'deps' : deps, 'defines': [ string_opt.format('INPUTTYPE', inputtype_header) ], 'headers': [ - inputtype_header + files(inputtype_header) ] } endforeach diff --git a/src/input/mist_in.cpp b/src/input/mist_in.cpp index 3332c455c..c79e0e453 100644 --- a/src/input/mist_in.cpp +++ b/src/input/mist_in.cpp @@ -2,6 +2,7 @@ #include INPUTTYPE #endif #include +#include template int InputMain(int argc, char *argv[]){ diff --git a/src/output/meson.build b/src/output/meson.build index 866460579..dd1eea7f1 100644 --- a/src/output/meson.build +++ b/src/output/meson.build @@ -68,9 +68,6 @@ foreach output : outputs if output.has_key('extra') extra = output.get('extra') - if not extra.contains('debased') - sources += base - endif if extra.contains('http') sources += files('output_http.cpp') if extra.contains('ts') @@ -98,6 +95,18 @@ foreach output : outputs if extra.contains('embed') sources += embed_tgts endif + endif + + sources_debased = [] + foreach source : sources + sources_debased += source + endforeach + + if output.has_key('extra') + extra = output.get('extra') + if not extra.contains('debased') + sources += base + endif else sources += base endif @@ -110,6 +119,9 @@ foreach output : outputs sources, header_tgts ], + 'sources_debased' : [ + sources_debased + ], 'deps' : deps, 'defines' : [ string_opt.format('OUTPUTTYPE', outputtype_header), diff --git a/src/session.h b/src/session.h new file mode 100644 index 000000000..1587ff44f --- /dev/null +++ b/src/session.h @@ -0,0 +1,2 @@ + +int SessionMain(int argc, char **argv); \ No newline at end of file From 7f4f9cc91ea853c2f8772d20695012ad6c7d3ef5 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Wed, 15 May 2024 23:38:50 +0000 Subject: [PATCH 16/24] onebinary: add #pragma once to input.h --- src/input/input.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/input/input.h b/src/input/input.h index bcd159b61..305853625 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -1,3 +1,4 @@ +#pragma once #include #include #include From e90d6aea3321d60f4e9952d24768d0d0a5b7757a Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Thu, 16 May 2024 00:15:17 +0000 Subject: [PATCH 17/24] onebinary: modify inputs to be friends --- lib/checksum.h | 1 + lib/sdp.h | 1 + lib/ts_stream.h | 1 + meson.build | 20 ++++++++++++++++++++ src/input/input_aac.h | 2 ++ src/input/input_av.h | 2 ++ src/input/input_balancer.h | 2 ++ src/input/input_buffer.h | 2 ++ src/input/input_dtsc.h | 3 +++ src/input/input_dtsccrypt.h | 2 ++ src/input/input_ebml.h | 2 ++ src/input/input_flac.h | 2 ++ src/input/input_flv.h | 2 ++ src/input/input_folder.h | 2 ++ src/input/input_h264.h | 2 ++ src/input/input_hls.h | 2 ++ src/input/input_ismv.h | 2 ++ src/input/input_mp3.h | 2 ++ src/input/input_mp4.h | 2 ++ src/input/input_ogg.h | 2 ++ src/input/input_playlist.h | 2 ++ src/input/input_rtsp.h | 3 +++ src/input/input_sdp.h | 3 +++ src/input/input_subrip.h | 2 ++ src/input/input_ts.h | 2 ++ src/input/input_tsrist.h | 2 ++ src/input/input_tssrt.h | 2 ++ src/session.cpp | 6 ++++++ 28 files changed, 78 insertions(+) diff --git a/lib/checksum.h b/lib/checksum.h index 87b6515c0..14c7f7994 100644 --- a/lib/checksum.h +++ b/lib/checksum.h @@ -1,3 +1,4 @@ +#pragma once #include #include "defines.h" diff --git a/lib/sdp.h b/lib/sdp.h index 05b550bb3..711ccf133 100644 --- a/lib/sdp.h +++ b/lib/sdp.h @@ -1,3 +1,4 @@ +#pragma once #include "dtsc.h" #include "h265.h" #include "http_parser.h" diff --git a/lib/ts_stream.h b/lib/ts_stream.h index 01f5c3c60..7ac8f3fe3 100644 --- a/lib/ts_stream.h +++ b/lib/ts_stream.h @@ -1,3 +1,4 @@ +#pragma once #include "adts.h" #include "h265.h" #include "ts_packet.h" diff --git a/meson.build b/meson.build index 0b3983f30..fefc41553 100644 --- a/meson.build +++ b/meson.build @@ -209,7 +209,27 @@ onebinary_stuff = [] onebinary_stuff += 'MistOutRTMP' onebinary_stuff += 'MistOutHLS' onebinary_stuff += 'MistOutHTTP' +onebinary_stuff += 'MistInAAC' +onebinary_stuff += 'MistInBalancer' onebinary_stuff += 'MistInBuffer' +onebinary_stuff += 'MistInDTSC' +onebinary_stuff += 'MistInEBML' +onebinary_stuff += 'MistInFLAC' +onebinary_stuff += 'MistInFLV' +onebinary_stuff += 'MistInFolder' +onebinary_stuff += 'MistInH264' +onebinary_stuff += 'MistInHLS' +# onebinary_stuff += 'MistInISMV' +onebinary_stuff += 'MistInMP3' +onebinary_stuff += 'MistInMP4' +onebinary_stuff += 'MistInOGG' +onebinary_stuff += 'MistInPlaylist' +# onebinary_stuff += 'MistInRTSP' +onebinary_stuff += 'MistInSDP' +# onebinary_stuff += 'MistInSubRip' +onebinary_stuff += 'MistInTS' +# onebinary_stuff += 'MistInTSRIST' +# onebinary_stuff += 'MistInTSSRT' onebinary_tgts = [] onebinary_headers = [] diff --git a/src/input/input_aac.h b/src/input/input_aac.h index ce8bd812f..cee75453b 100644 --- a/src/input/input_aac.h +++ b/src/input/input_aac.h @@ -24,4 +24,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputAAC mistIn; +#endif diff --git a/src/input/input_av.h b/src/input/input_av.h index 3449c7431..23b518957 100644 --- a/src/input/input_av.h +++ b/src/input/input_av.h @@ -31,4 +31,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputAV mistIn; +#endif diff --git a/src/input/input_balancer.h b/src/input/input_balancer.h index f54ee420d..d9fe4e78d 100644 --- a/src/input/input_balancer.h +++ b/src/input/input_balancer.h @@ -13,4 +13,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputBalancer mistIn; +#endif diff --git a/src/input/input_buffer.h b/src/input/input_buffer.h index 5d9be3e9d..544e49f7e 100644 --- a/src/input/input_buffer.h +++ b/src/input/input_buffer.h @@ -59,6 +59,8 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY #ifndef ONE_BINARY typedef Mist::InputBuffer mistIn; #endif +#endif diff --git a/src/input/input_dtsc.h b/src/input/input_dtsc.h index dd68f968a..c142d5fe1 100644 --- a/src/input/input_dtsc.h +++ b/src/input/input_dtsc.h @@ -1,3 +1,4 @@ +#pragma once #include "input.h" #include @@ -61,4 +62,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputDTSC mistIn; +#endif diff --git a/src/input/input_dtsccrypt.h b/src/input/input_dtsccrypt.h index 944348a0a..2c016ce7f 100644 --- a/src/input/input_dtsccrypt.h +++ b/src/input/input_dtsccrypt.h @@ -21,4 +21,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputDTSC mistIn; +#endif diff --git a/src/input/input_ebml.h b/src/input/input_ebml.h index 1fbc6dbc5..aac9ef5e3 100644 --- a/src/input/input_ebml.h +++ b/src/input/input_ebml.h @@ -167,4 +167,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputEBML mistIn; +#endif diff --git a/src/input/input_flac.h b/src/input/input_flac.h index 9dc4661c8..6647b7875 100644 --- a/src/input/input_flac.h +++ b/src/input/input_flac.h @@ -45,4 +45,6 @@ namespace Mist{ }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputFLAC mistIn; +#endif diff --git a/src/input/input_flv.h b/src/input/input_flv.h index 3a455feb5..5f2e81450 100644 --- a/src/input/input_flv.h +++ b/src/input/input_flv.h @@ -22,4 +22,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputFLV mistIn; +#endif diff --git a/src/input/input_folder.h b/src/input/input_folder.h index 5597c4a34..837702cee 100644 --- a/src/input/input_folder.h +++ b/src/input/input_folder.h @@ -15,4 +15,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputFolder mistIn; +#endif diff --git a/src/input/input_h264.h b/src/input/input_h264.h index 7ef3cfd27..e19ec9dca 100644 --- a/src/input/input_h264.h +++ b/src/input/input_h264.h @@ -28,4 +28,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputH264 mistIn; +#endif diff --git a/src/input/input_hls.h b/src/input/input_hls.h index 277118b68..c66e1521f 100644 --- a/src/input/input_hls.h +++ b/src/input/input_hls.h @@ -187,4 +187,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputHLS mistIn; +#endif diff --git a/src/input/input_ismv.h b/src/input/input_ismv.h index 0afbd6f78..7dd1fcfab 100644 --- a/src/input/input_ismv.h +++ b/src/input/input_ismv.h @@ -47,4 +47,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputISMV mistIn; +#endif diff --git a/src/input/input_mp3.h b/src/input/input_mp3.h index 08b6f54ee..911358c79 100644 --- a/src/input/input_mp3.h +++ b/src/input/input_mp3.h @@ -30,4 +30,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputMP3 mistIn; +#endif diff --git a/src/input/input_mp4.h b/src/input/input_mp4.h index 88a8c39b1..5ceadf195 100644 --- a/src/input/input_mp4.h +++ b/src/input/input_mp4.h @@ -101,4 +101,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputMP4 mistIn; +#endif diff --git a/src/input/input_ogg.h b/src/input/input_ogg.h index 815bf4248..aa6816a07 100644 --- a/src/input/input_ogg.h +++ b/src/input/input_ogg.h @@ -58,4 +58,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputOGG mistIn; +#endif diff --git a/src/input/input_playlist.h b/src/input/input_playlist.h index 8890956f7..61cc6619b 100644 --- a/src/input/input_playlist.h +++ b/src/input/input_playlist.h @@ -28,4 +28,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputPlaylist mistIn; +#endif diff --git a/src/input/input_rtsp.h b/src/input/input_rtsp.h index 430c221c9..8a9ca04ff 100644 --- a/src/input/input_rtsp.h +++ b/src/input/input_rtsp.h @@ -1,3 +1,4 @@ +#pragma once #include "input.h" #include #include @@ -52,4 +53,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputRTSP mistIn; +#endif diff --git a/src/input/input_sdp.h b/src/input/input_sdp.h index d3b3531c5..dcbb059e8 100644 --- a/src/input/input_sdp.h +++ b/src/input/input_sdp.h @@ -1,3 +1,4 @@ +#pragma once #include "input.h" #include #include @@ -66,4 +67,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputSDP mistIn; +#endif diff --git a/src/input/input_subrip.h b/src/input/input_subrip.h index 9f12b08b2..5bbf74334 100644 --- a/src/input/input_subrip.h +++ b/src/input/input_subrip.h @@ -25,4 +25,6 @@ namespace Mist{ }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputSubRip mistIn; +#endif diff --git a/src/input/input_ts.h b/src/input/input_ts.h index 1bc45214b..676aa5b08 100644 --- a/src/input/input_ts.h +++ b/src/input/input_ts.h @@ -56,4 +56,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputTS mistIn; +#endif diff --git a/src/input/input_tsrist.h b/src/input/input_tsrist.h index 26bec4736..a6ed1e8fc 100644 --- a/src/input/input_tsrist.h +++ b/src/input/input_tsrist.h @@ -42,4 +42,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputTSRIST mistIn; +#endif diff --git a/src/input/input_tssrt.h b/src/input/input_tssrt.h index 786eb165a..7feae2997 100644 --- a/src/input/input_tssrt.h +++ b/src/input/input_tssrt.h @@ -49,4 +49,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::InputTSSRT mistIn; +#endif diff --git a/src/session.cpp b/src/session.cpp index bb5e64077..cdd3f03e2 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -429,3 +429,9 @@ int SessionMain(int argc, char **argv){ INFO_MSG("Shutting down session %s: %s", thisSessionId.c_str(), Util::exitReason); return 0; } + +#ifndef ONE_BINARY +int main(int argc, char **argv){ + return SessionMain(argc, argv); +} +#endif From 287f893a055482d368f4131f17b55e359c742d73 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Thu, 16 May 2024 00:25:11 +0000 Subject: [PATCH 18/24] onebinary: fix global state collisions in RTSP and SDP --- meson.build | 2 +- src/input/input_rtsp.cpp | 12 ++++++------ src/input/input_sdp.cpp | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/meson.build b/meson.build index fefc41553..9c6cf4bef 100644 --- a/meson.build +++ b/meson.build @@ -224,7 +224,7 @@ onebinary_stuff += 'MistInMP3' onebinary_stuff += 'MistInMP4' onebinary_stuff += 'MistInOGG' onebinary_stuff += 'MistInPlaylist' -# onebinary_stuff += 'MistInRTSP' +onebinary_stuff += 'MistInRTSP' onebinary_stuff += 'MistInSDP' # onebinary_stuff += 'MistInSubRip' onebinary_stuff += 'MistInTS' diff --git a/src/input/input_rtsp.cpp b/src/input/input_rtsp.cpp index dbb2cf528..24890de4e 100644 --- a/src/input/input_rtsp.cpp +++ b/src/input/input_rtsp.cpp @@ -3,10 +3,10 @@ Mist::InputRTSP *classPointer = 0; Socket::Connection *mainConn = 0; -void incomingPacket(const DTSC::Packet &pkt){ +void incomingPacketRTSP(const DTSC::Packet &pkt){ classPointer->incoming(pkt); } -void insertRTP(const uint64_t track, const RTP::Packet &p){ +void insertRTPRTSP(const uint64_t track, const RTP::Packet &p){ classPointer->incomingRTP(track, p); } @@ -15,7 +15,7 @@ void insertRTP(const uint64_t track, const RTP::Packet &p){ ///\param data The RTP Packet that needs to be sent ///\param len The size of data ///\param channel Not used here, but is kept for compatibility with sendTCP -void sendUDP(void *socket, const char *data, size_t len, uint8_t channel){ +void sendUDPRTSP(void *socket, const char *data, size_t len, uint8_t channel){ ((Socket::UDPConnection *)socket)->SendNow(data, len); if (mainConn){mainConn->addUp(len);} } @@ -31,7 +31,7 @@ namespace Mist{ packetOffset = 0; TCPmode = true; sdpState.myMeta = &meta; - sdpState.incomingPacketCallback = incomingPacket; + sdpState.incomingPacketCallback = incomingPacketRTSP; classPointer = this; standAlone = false; seenSDP = false; @@ -363,7 +363,7 @@ namespace Mist{ for (std::map::iterator it = sdpState.tracks.begin(); it != sdpState.tracks.end(); ++it){ Socket::UDPConnection &s = it->second.data; - it->second.sorter.setCallback(it->first, insertRTP); + it->second.sorter.setCallback(it->first, insertRTPRTSP); while (s.Receive()){ r = true; // if (s.getDestPort() != it->second.sPortA){ @@ -377,7 +377,7 @@ namespace Mist{ } if (Util::bootSecs() != it->second.rtcpSent){ it->second.rtcpSent = Util::bootSecs(); - it->second.pack.sendRTCP_RR(it->second, sendUDP); + it->second.pack.sendRTCP_RR(it->second, sendUDPRTSP); } } return r; diff --git a/src/input/input_sdp.cpp b/src/input/input_sdp.cpp index 309854dea..57c1fe7cd 100644 --- a/src/input/input_sdp.cpp +++ b/src/input/input_sdp.cpp @@ -1,14 +1,14 @@ #include "input_sdp.h" // Will point to current InputSDP obj after constructor is called -Mist::InputSDP *classPointer = 0; +Mist::InputSDP *classPointerSDP = 0; size_t bytesUp = 0; // CB used to receive DTSC packets back from RTP sorter -void incomingPacket(const DTSC::Packet &pkt){ - classPointer->incoming(pkt); +void incomingPacketSDP(const DTSC::Packet &pkt){ + classPointerSDP->incoming(pkt); } void insertRTP(const uint64_t track, const RTP::Packet &p){ - classPointer->incomingRTP(track, p); + classPointerSDP->incomingRTP(track, p); } /// Function used to send RTCP packets over UDP @@ -16,7 +16,7 @@ void insertRTP(const uint64_t track, const RTP::Packet &p){ ///\param data The RTP Packet that needs to be sent ///\param len The size of data ///\param channel Not used here, but is kept for compatibility with sendTCP -void sendUDP(void *socket, const char *data, size_t len, uint8_t channel){ +void sendUDPSDP(void *socket, const char *data, size_t len, uint8_t channel){ ((Socket::UDPConnection *)socket)->SendNow(data, len); bytesUp += len; } @@ -30,8 +30,8 @@ namespace Mist{ setPacketOffset = false; packetOffset = 0; sdpState.myMeta = &meta; - sdpState.incomingPacketCallback = incomingPacket; - classPointer = this; + sdpState.incomingPacketCallback = incomingPacketSDP; + classPointerSDP = this; standAlone = false; hasBork = false; bytesRead = 0; @@ -280,7 +280,7 @@ namespace Mist{ // Send RTCP packet back to host if (Util::bootSecs() > it->second.rtcpSent + rtcpInterval){ it->second.rtcpSent = Util::bootSecs(); - it->second.pack.sendRTCP_RR(it->second, sendUDP); + it->second.pack.sendRTCP_RR(it->second, sendUDPSDP); } } if (!receivedPacket){ From ddd65fefa7897ff3c12e9dd044357275ed19616c Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Thu, 16 May 2024 00:29:43 +0000 Subject: [PATCH 19/24] onebinary: fix global name collisions in InputISMV --- meson.build | 2 +- src/input/input_ismv.cpp | 4 ++-- src/input/input_ismv.h | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/meson.build b/meson.build index 9c6cf4bef..511ea27ab 100644 --- a/meson.build +++ b/meson.build @@ -219,7 +219,7 @@ onebinary_stuff += 'MistInFLV' onebinary_stuff += 'MistInFolder' onebinary_stuff += 'MistInH264' onebinary_stuff += 'MistInHLS' -# onebinary_stuff += 'MistInISMV' +onebinary_stuff += 'MistInISMV' onebinary_stuff += 'MistInMP3' onebinary_stuff += 'MistInMP4' onebinary_stuff += 'MistInOGG' diff --git a/src/input/input_ismv.cpp b/src/input/input_ismv.cpp index 3645e8838..840bd8fa7 100644 --- a/src/input/input_ismv.cpp +++ b/src/input/input_ismv.cpp @@ -102,7 +102,7 @@ namespace Mist{ if (!buffered.size()){return;} - seekPos thisPos = *buffered.begin(); + seekPosISMV thisPos = *buffered.begin(); buffered.erase(buffered.begin()); fseek(inFile, thisPos.position, SEEK_SET); @@ -252,7 +252,7 @@ namespace Mist{ currentPosition = ftell(inFile) + 8; for (unsigned int i = 0; i < trunBox.getSampleInformationCount(); i++){ - seekPos myPos; + seekPosISMV myPos; myPos.position = currentPosition; myPos.trackId = trackId; myPos.time = currentTime; diff --git a/src/input/input_ismv.h b/src/input/input_ismv.h index 7dd1fcfab..08b9882bb 100644 --- a/src/input/input_ismv.h +++ b/src/input/input_ismv.h @@ -7,8 +7,8 @@ #include namespace Mist{ - struct seekPos{ - bool operator<(const seekPos &rhs) const{ + struct seekPosISMV{ + bool operator<(const seekPosISMV &rhs) const{ if (time < rhs.time){return true;} return (time == rhs.time && trackId < rhs.trackId); } @@ -40,7 +40,7 @@ namespace Mist{ bool readMoofSkipMdat(size_t &tId, std::vector &trunSamples); void bufferFragmentData(size_t trackId, uint32_t keyNum); - std::set buffered; + std::set buffered; std::map lastKeyNum; Util::ResizeablePointer dataPointer; From e7a3925b724778e616f9618aa8d1ff936ed868b9 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Thu, 16 May 2024 00:42:00 +0000 Subject: [PATCH 20/24] onebinary: flip on MistInSubRip --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 511ea27ab..5891424ee 100644 --- a/meson.build +++ b/meson.build @@ -226,7 +226,7 @@ onebinary_stuff += 'MistInOGG' onebinary_stuff += 'MistInPlaylist' onebinary_stuff += 'MistInRTSP' onebinary_stuff += 'MistInSDP' -# onebinary_stuff += 'MistInSubRip' +onebinary_stuff += 'MistInSubRip' onebinary_stuff += 'MistInTS' # onebinary_stuff += 'MistInTSRIST' # onebinary_stuff += 'MistInTSSRT' From 9482c46fe8637aea3db1a1539c2923aa5631e41b Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Thu, 16 May 2024 01:40:16 +0000 Subject: [PATCH 21/24] onebinary: fixes for various outputs --- lib/downloader.h | 1 + meson.build | 32 ++++++++++++++++++++++---- src/output/output_aac.h | 2 ++ src/output/output_cmaf.h | 2 ++ src/output/output_dtsc.h | 2 ++ src/output/output_ebml.h | 2 ++ src/output/output_flac.h | 2 ++ src/output/output_flv.h | 2 ++ src/output/output_h264.h | 2 ++ src/output/output_hds.h | 2 ++ src/output/output_hls.cpp | 2 +- src/output/output_http_internal.h | 2 ++ src/output/output_http_minimalserver.h | 2 ++ src/output/output_https.h | 2 ++ src/output/output_httpts.h | 2 ++ src/output/output_jpg.h | 2 ++ src/output/output_json.h | 2 ++ src/output/output_jsonline.h | 2 ++ src/output/output_mp3.h | 2 ++ src/output/output_mp4.h | 2 ++ src/output/output_ogg.h | 2 ++ src/output/output_raw.h | 2 ++ src/output/output_rtsp.h | 2 ++ src/output/output_sanitycheck.h | 2 ++ src/output/output_sdp.h | 2 ++ src/output/output_subrip.h | 2 ++ src/output/output_ts.h | 2 ++ src/output/output_tsrist.h | 2 ++ src/output/output_tssrt.h | 2 ++ src/output/output_wav.h | 2 ++ src/output/output_webrtc.h | 2 ++ 31 files changed, 86 insertions(+), 5 deletions(-) diff --git a/lib/downloader.h b/lib/downloader.h index 92bcca2c5..5e77383fb 100644 --- a/lib/downloader.h +++ b/lib/downloader.h @@ -1,3 +1,4 @@ +#pragma once #include "http_parser.h" #include "socket.h" #include "url.h" diff --git a/meson.build b/meson.build index 5891424ee..32af2fe0c 100644 --- a/meson.build +++ b/meson.build @@ -206,9 +206,6 @@ exec_tgts = [] make_header = find_program('scripts/make_header.sh') onebinary_stuff = [] -onebinary_stuff += 'MistOutRTMP' -onebinary_stuff += 'MistOutHLS' -onebinary_stuff += 'MistOutHTTP' onebinary_stuff += 'MistInAAC' onebinary_stuff += 'MistInBalancer' onebinary_stuff += 'MistInBuffer' @@ -230,6 +227,33 @@ onebinary_stuff += 'MistInSubRip' onebinary_stuff += 'MistInTS' # onebinary_stuff += 'MistInTSRIST' # onebinary_stuff += 'MistInTSSRT' +onebinary_stuff += 'MistOutAAC' +# onebinary_stuff += 'MistOutCMAF' +onebinary_stuff += 'MistOutDTSC' +onebinary_stuff += 'MistOutEBML' +onebinary_stuff += 'MistOutFLAC' +onebinary_stuff += 'MistOutFLV' +onebinary_stuff += 'MistOutH264' +onebinary_stuff += 'MistOutHDS' +# onebinary_stuff += 'MistOutHLS' +onebinary_stuff += 'MistOutHTTP' +onebinary_stuff += 'MistOutHTTPMinimalServer' +onebinary_stuff += 'MistOutHTTPS' +# onebinary_stuff += 'MistOutHTTPTS' +onebinary_stuff += 'MistOutJSON' +onebinary_stuff += 'MistOutJSONLine' +onebinary_stuff += 'MistOutMP3' +onebinary_stuff += 'MistOutMP4' +onebinary_stuff += 'MistOutOGG' +onebinary_stuff += 'MistOutRTMP' +onebinary_stuff += 'MistOutRTSP' +# onebinary_stuff += 'MistOutSDP' +# onebinary_stuff += 'MistOutSubRip' +onebinary_stuff += 'MistOutTS' +# onebinary_stuff += 'MistOutTSRIST' +# onebinary_stuff += 'MistOutTSSRT' +onebinary_stuff += 'MistOutWAV' +# onebinary_stuff += 'MistOutWebRTC' onebinary_tgts = [] onebinary_headers = [] @@ -296,7 +320,7 @@ onebinary = executable( onebinary_header, ], cpp_args: [ - '-DTS_BASECLASS=HTTPOutput', + '-DTS_BASECLASS=Output', '-DONE_BINARY=1', ], dependencies : [libmist_dep], diff --git a/src/output/output_aac.h b/src/output/output_aac.h index c7c0980ba..9f10530f1 100644 --- a/src/output/output_aac.h +++ b/src/output/output_aac.h @@ -15,4 +15,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutAAC mistOut; +#endif diff --git a/src/output/output_cmaf.h b/src/output/output_cmaf.h index 390549ccf..730f80323 100644 --- a/src/output/output_cmaf.h +++ b/src/output/output_cmaf.h @@ -81,4 +81,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutCMAF mistOut; +#endif diff --git a/src/output/output_dtsc.h b/src/output/output_dtsc.h index 4b92ec82c..a19f6aff3 100644 --- a/src/output/output_dtsc.h +++ b/src/output/output_dtsc.h @@ -27,4 +27,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutDTSC mistOut; +#endif diff --git a/src/output/output_ebml.h b/src/output/output_ebml.h index 292b5b33b..d90484ba7 100644 --- a/src/output/output_ebml.h +++ b/src/output/output_ebml.h @@ -39,4 +39,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutEBML mistOut; +#endif diff --git a/src/output/output_flac.h b/src/output/output_flac.h index 041231887..90d2476c9 100644 --- a/src/output/output_flac.h +++ b/src/output/output_flac.h @@ -14,4 +14,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutFLAC mistOut; +#endif diff --git a/src/output/output_flv.h b/src/output/output_flv.h index e03bd3cf9..d0e318cb2 100644 --- a/src/output/output_flv.h +++ b/src/output/output_flv.h @@ -17,4 +17,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutFLV mistOut; +#endif diff --git a/src/output/output_h264.h b/src/output/output_h264.h index c6fef5c46..8335ef557 100644 --- a/src/output/output_h264.h +++ b/src/output/output_h264.h @@ -30,4 +30,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutH264 mistOut; +#endif diff --git a/src/output/output_hds.h b/src/output/output_hds.h index e6e7e127e..ac7cec7d0 100644 --- a/src/output/output_hds.h +++ b/src/output/output_hds.h @@ -23,4 +23,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutHDS mistOut; +#endif diff --git a/src/output/output_hls.cpp b/src/output/output_hls.cpp index a9bd5c6be..b48d12cf6 100644 --- a/src/output/output_hls.cpp +++ b/src/output/output_hls.cpp @@ -165,7 +165,7 @@ namespace Mist{ return result.str(); } - OutHLS::OutHLS(Socket::Connection &conn) : TSOutput(conn){ + OutHLS::OutHLS(Socket::Connection &conn) : TSOutputHTTP(conn){ uaDelay = 0; realTime = 0; until = 0xFFFFFFFFFFFFFFFFull; diff --git a/src/output/output_http_internal.h b/src/output/output_http_internal.h index 30ad6130b..c8907204d 100644 --- a/src/output/output_http_internal.h +++ b/src/output/output_http_internal.h @@ -25,4 +25,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutHTTP mistOut; +#endif diff --git a/src/output/output_http_minimalserver.h b/src/output/output_http_minimalserver.h index fa84b7bd8..6e62cc106 100644 --- a/src/output/output_http_minimalserver.h +++ b/src/output/output_http_minimalserver.h @@ -13,4 +13,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutHTTPMinimalServer mistOut; +#endif diff --git a/src/output/output_https.h b/src/output/output_https.h index e38112162..bebf89cb3 100644 --- a/src/output/output_https.h +++ b/src/output/output_https.h @@ -40,4 +40,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutHTTPS mistOut; +#endif diff --git a/src/output/output_httpts.h b/src/output/output_httpts.h index 5a2d5cb3d..b676d5867 100644 --- a/src/output/output_httpts.h +++ b/src/output/output_httpts.h @@ -22,4 +22,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutHTTPTS mistOut; +#endif diff --git a/src/output/output_jpg.h b/src/output/output_jpg.h index e47b4d406..9d6ad4415 100644 --- a/src/output/output_jpg.h +++ b/src/output/output_jpg.h @@ -20,4 +20,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutJPG mistOut; +#endif diff --git a/src/output/output_json.h b/src/output/output_json.h index 40e1702ed..24e0d51be 100644 --- a/src/output/output_json.h +++ b/src/output/output_json.h @@ -34,4 +34,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutJSON mistOut; +#endif diff --git a/src/output/output_jsonline.h b/src/output/output_jsonline.h index 695d5ceff..e6d51450d 100644 --- a/src/output/output_jsonline.h +++ b/src/output/output_jsonline.h @@ -23,4 +23,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutJSONLine mistOut; +#endif diff --git a/src/output/output_mp3.h b/src/output/output_mp3.h index 3c93f3c19..6a4ad4609 100644 --- a/src/output/output_mp3.h +++ b/src/output/output_mp3.h @@ -15,4 +15,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutMP3 mistOut; +#endif diff --git a/src/output/output_mp4.h b/src/output/output_mp4.h index 294a7c650..37d4936d9 100644 --- a/src/output/output_mp4.h +++ b/src/output/output_mp4.h @@ -141,4 +141,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutMP4 mistOut; +#endif diff --git a/src/output/output_ogg.h b/src/output/output_ogg.h index f28f41385..384ee6c6e 100644 --- a/src/output/output_ogg.h +++ b/src/output/output_ogg.h @@ -21,4 +21,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutOGG mistOut; +#endif diff --git a/src/output/output_raw.h b/src/output/output_raw.h index b7ea5fdac..ed3f36489 100644 --- a/src/output/output_raw.h +++ b/src/output/output_raw.h @@ -11,4 +11,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutRaw mistOut; +#endif diff --git a/src/output/output_rtsp.h b/src/output/output_rtsp.h index 98bb0a864..cbc0de5ad 100644 --- a/src/output/output_rtsp.h +++ b/src/output/output_rtsp.h @@ -36,4 +36,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutRTSP mistOut; +#endif diff --git a/src/output/output_sanitycheck.h b/src/output/output_sanitycheck.h index 12b133fe3..d0afdeed0 100644 --- a/src/output/output_sanitycheck.h +++ b/src/output/output_sanitycheck.h @@ -19,4 +19,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutSanityCheck mistOut; +#endif diff --git a/src/output/output_sdp.h b/src/output/output_sdp.h index 6c466753b..e40c10da3 100644 --- a/src/output/output_sdp.h +++ b/src/output/output_sdp.h @@ -33,4 +33,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutSDP mistOut; +#endif diff --git a/src/output/output_subrip.h b/src/output/output_subrip.h index ec458a24b..d667f37b5 100644 --- a/src/output/output_subrip.h +++ b/src/output/output_subrip.h @@ -19,4 +19,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutSubRip mistOut; +#endif diff --git a/src/output/output_ts.h b/src/output/output_ts.h index 9edb5c028..4d890ff4a 100644 --- a/src/output/output_ts.h +++ b/src/output/output_ts.h @@ -37,4 +37,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutTS mistOut; +#endif diff --git a/src/output/output_tsrist.h b/src/output/output_tsrist.h index 80ee2376a..332f4263b 100644 --- a/src/output/output_tsrist.h +++ b/src/output/output_tsrist.h @@ -43,4 +43,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutTSRIST mistOut; +#endif diff --git a/src/output/output_tssrt.h b/src/output/output_tssrt.h index 9804c3e98..698677785 100644 --- a/src/output/output_tssrt.h +++ b/src/output/output_tssrt.h @@ -35,4 +35,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutTSSRT mistOut; +#endif diff --git a/src/output/output_wav.h b/src/output/output_wav.h index 9752cce31..d7ca964f2 100644 --- a/src/output/output_wav.h +++ b/src/output/output_wav.h @@ -18,4 +18,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutWAV mistOut; +#endif diff --git a/src/output/output_webrtc.h b/src/output/output_webrtc.h index 7f5873150..f1c63a1b9 100644 --- a/src/output/output_webrtc.h +++ b/src/output/output_webrtc.h @@ -219,4 +219,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutWebRTC mistOut; +#endif From 7b19b3d940d2b1ba8a79fbb423b7204324a86a58 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Thu, 16 May 2024 02:36:48 +0000 Subject: [PATCH 22/24] onebinary: refactor TSOutput and TSOutputHTTP --- meson.build | 4 +- src/output/meson.build | 1 + src/output/output_hls.cpp | 2 +- src/output/output_hls.h | 2 +- src/output/output_httpts.cpp | 2 +- src/output/output_httpts.h | 2 +- src/output/output_ts_base.cpp | 70 +++++++++++++++++++---------------- src/output/output_ts_base.h | 21 ++++++++--- 8 files changed, 61 insertions(+), 43 deletions(-) diff --git a/meson.build b/meson.build index 32af2fe0c..055d0d55c 100644 --- a/meson.build +++ b/meson.build @@ -235,11 +235,11 @@ onebinary_stuff += 'MistOutFLAC' onebinary_stuff += 'MistOutFLV' onebinary_stuff += 'MistOutH264' onebinary_stuff += 'MistOutHDS' -# onebinary_stuff += 'MistOutHLS' +onebinary_stuff += 'MistOutHLS' onebinary_stuff += 'MistOutHTTP' onebinary_stuff += 'MistOutHTTPMinimalServer' onebinary_stuff += 'MistOutHTTPS' -# onebinary_stuff += 'MistOutHTTPTS' +onebinary_stuff += 'MistOutHTTPTS' onebinary_stuff += 'MistOutJSON' onebinary_stuff += 'MistOutJSONLine' onebinary_stuff += 'MistOutMP3' diff --git a/src/output/meson.build b/src/output/meson.build index dd1eea7f1..3b84103f0 100644 --- a/src/output/meson.build +++ b/src/output/meson.build @@ -78,6 +78,7 @@ foreach output : outputs endif if extra.contains('ts') sources += files('output_ts_base.cpp') + sources += files('output_http.cpp') endif if extra.contains('with_rist') deps += librist diff --git a/src/output/output_hls.cpp b/src/output/output_hls.cpp index b48d12cf6..e04f9a114 100644 --- a/src/output/output_hls.cpp +++ b/src/output/output_hls.cpp @@ -445,7 +445,7 @@ namespace Mist{ return; } // Invoke the generic TS output sendNext handler - TSOutput::sendNext(); + TSOutputHTTP::sendNext(); } void OutHLS::sendTS(const char *tsData, size_t len){H.Chunkify(tsData, len, myConn);} diff --git a/src/output/output_hls.h b/src/output/output_hls.h index ff3fb6727..61cb1ef43 100644 --- a/src/output/output_hls.h +++ b/src/output/output_hls.h @@ -2,7 +2,7 @@ #include "output_ts_base.h" namespace Mist{ - class OutHLS : public TSOutput{ + class OutHLS : public TSOutputHTTP{ public: OutHLS(Socket::Connection &conn); ~OutHLS(); diff --git a/src/output/output_httpts.cpp b/src/output/output_httpts.cpp index bb34c5b4f..88f40062f 100644 --- a/src/output/output_httpts.cpp +++ b/src/output/output_httpts.cpp @@ -11,7 +11,7 @@ #include namespace Mist{ - OutHTTPTS::OutHTTPTS(Socket::Connection &conn) : TSOutput(conn){ + OutHTTPTS::OutHTTPTS(Socket::Connection &conn) : TSOutputHTTP(conn){ sendRepeatingHeaders = 500; // PAT/PMT every 500ms (DVB spec) HTTP::URL target(config->getString("target")); if (target.protocol == "srt"){ diff --git a/src/output/output_httpts.h b/src/output/output_httpts.h index b676d5867..35c299f2e 100644 --- a/src/output/output_httpts.h +++ b/src/output/output_httpts.h @@ -2,7 +2,7 @@ #include "output_ts_base.h" namespace Mist{ - class OutHTTPTS : public TSOutput{ + class OutHTTPTS : public TSOutputHTTP{ public: OutHTTPTS(Socket::Connection &conn); ~OutHTTPTS(); diff --git a/src/output/output_ts_base.cpp b/src/output/output_ts_base.cpp index 80d402381..1aa17aeb2 100644 --- a/src/output/output_ts_base.cpp +++ b/src/output/output_ts_base.cpp @@ -2,32 +2,34 @@ #include namespace Mist{ - TSOutput::TSOutput(Socket::Connection &conn) : TS_BASECLASS(conn){ + template + TSOutputTmpl::TSOutputTmpl(Socket::Connection &conn) : T(conn){ packCounter = 0; ts_from = 0; - setBlocking(true); + this->setBlocking(true); sendRepeatingHeaders = 0; lastHeaderTime = 0; } - void TSOutput::fillPacket(char const *data, size_t dataLen, bool &firstPack, bool video, + template + void TSOutputTmpl::fillPacket(char const *data, size_t dataLen, bool &firstPack, bool video, bool keyframe, size_t pkgPid, uint16_t &contPkg){ do{ if (!packData.getBytesFree()){ - if ((sendRepeatingHeaders && thisPacket.getTime() - lastHeaderTime > sendRepeatingHeaders) || !packCounter){ + if ((sendRepeatingHeaders && this->thisPacket.getTime() - lastHeaderTime > sendRepeatingHeaders) || !packCounter){ std::set selectedTracks; - for (std::map::iterator it = userSelect.begin(); it != userSelect.end(); it++){ + for (std::map::iterator it = this->userSelect.begin(); it != this->userSelect.end(); it++){ selectedTracks.insert(it->first); } - lastHeaderTime = thisPacket.getTime(); + lastHeaderTime = this->thisPacket.getTime(); TS::Packet tmpPack; tmpPack.FromPointer(TS::PAT); tmpPack.setContinuityCounter(++contPAT); sendTS(tmpPack.checkAndGetBuffer()); - sendTS(TS::createPMT(selectedTracks, M, ++contPMT)); - sendTS(TS::createSDT(streamName, ++contSDT)); + sendTS(TS::createPMT(selectedTracks, this->M, ++contPMT)); + sendTS(TS::createSDT(this->streamName, ++contSDT)); packCounter += 3; } sendTS(packData.checkAndGetBuffer()); @@ -48,7 +50,7 @@ namespace Mist{ packData.setRandomAccess(true); packData.setESPriority(true); } - packData.setPCR(thisPacket.getTime() * 27000); + packData.setPCR(this->thisPacket.getTime() * 27000); } firstPack = false; } @@ -60,29 +62,30 @@ namespace Mist{ }while (dataLen); } - void TSOutput::sendNext(){ + template + void TSOutputTmpl::sendNext(){ static uint64_t lastMeta = 0; if (Util::epoch() > lastMeta + 5){ lastMeta = Util::epoch(); - if (selectDefaultTracks()){ + if (this->selectDefaultTracks()){ INFO_MSG("Track selection changed - resending headers and continuing"); packCounter = 0; return; } } // Get ready some data to speed up accesses - std::string type = M.getType(thisIdx); - std::string codec = M.getCodec(thisIdx); + std::string type = this->M.getType(this->thisIdx); + std::string codec = this->M.getCodec(this->thisIdx); bool video = (type == "video"); - size_t pkgPid = TS::getUniqTrackID(M, thisIdx); - bool &firstPack = first[thisIdx]; + size_t pkgPid = TS::getUniqTrackID(this->M, this->thisIdx); + bool &firstPack = first[this->thisIdx]; uint16_t &contPkg = contCounters[pkgPid]; - uint64_t packTime = thisPacket.getTime(); - bool keyframe = thisPacket.getInt("keyframe"); + uint64_t packTime = this->thisPacket.getTime(); + bool keyframe = this->thisPacket.getInt("keyframe"); firstPack = true; char *dataPointer = 0; size_t dataLen = 0; - thisPacket.getString("data", dataPointer, dataLen); // data + this->thisPacket.getString("data", dataPointer, dataLen); // data if (codec == "rawts"){ for (size_t i = 0; i+188 <= dataLen; i+=188){sendTS(dataPointer+i, 188);} @@ -120,13 +123,13 @@ namespace Mist{ if (addInit){ if (codec == "H264"){ MP4::AVCC avccbox; - avccbox.setPayload(M.getInit(thisIdx)); + avccbox.setPayload(this->M.getInit(this->thisIdx)); bs = avccbox.asAnnexB(); extraSize += bs.size(); } if (codec == "HEVC"){ MP4::HVCC hvccbox; - hvccbox.setPayload(M.getInit(thisIdx)); + hvccbox.setPayload(this->M.getInit(this->thisIdx)); bs = hvccbox.asAnnexB(); extraSize += bs.size(); } @@ -135,12 +138,12 @@ namespace Mist{ const uint32_t MAX_PES_SIZE = 65490 - 13; uint32_t ThisNaluSize = 0; uint32_t i = 0; - uint64_t offset = thisPacket.getInt("offset") * 90; + uint64_t offset = this->thisPacket.getInt("offset") * 90; bs.clear(); TS::Packet::getPESVideoLeadIn(bs, (((dataLen + extraSize) > MAX_PES_SIZE) ? 0 : dataLen + extraSize), - packTime, offset, true, M.getBps(thisIdx)); + packTime, offset, true, this->M.getBps(this->thisIdx)); fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg); // End of previous nal unit, if not already present @@ -151,21 +154,21 @@ namespace Mist{ if (addInit){ if (codec == "H264"){ MP4::AVCC avccbox; - avccbox.setPayload(M.getInit(thisIdx)); + avccbox.setPayload(this->M.getInit(this->thisIdx)); bs = avccbox.asAnnexB(); fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg); } /*LTS-START*/ if (codec == "HEVC"){ MP4::HVCC hvccbox; - hvccbox.setPayload(M.getInit(thisIdx)); + hvccbox.setPayload(this->M.getInit(this->thisIdx)); bs = hvccbox.asAnnexB(); fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg); } /*LTS-END*/ } size_t lenSize = 4; - if (codec == "H264"){lenSize = (M.getInit(thisIdx)[4] & 3) + 1;} + if (codec == "H264"){lenSize = (this->M.getInit(this->thisIdx)[4] & 3) + 1;} while (i + lenSize < (unsigned int)dataLen){ if (lenSize == 4){ ThisNaluSize = Bit::btohl(dataPointer + i); @@ -184,9 +187,9 @@ namespace Mist{ i += ThisNaluSize + lenSize; } }else{ - uint64_t offset = thisPacket.getInt("offset") * 90; + uint64_t offset = this->thisPacket.getInt("offset") * 90; bs.clear(); - TS::Packet::getPESVideoLeadIn(bs, 0, packTime, offset, true, M.getBps(thisIdx)); + TS::Packet::getPESVideoLeadIn(bs, 0, packTime, offset, true, this->M.getBps(this->thisIdx)); fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg); fillPacket(dataPointer, dataLen, firstPack, video, keyframe, pkgPid, contPkg); @@ -196,7 +199,7 @@ namespace Mist{ if (codec == "AAC"){ tempLen += 7; // Make sure TS timestamp is sample-aligned, if possible - uint32_t freq = M.getRate(thisIdx); + uint32_t freq = this->M.getRate(this->thisIdx); if (freq){ uint64_t aacSamples = packTime * freq / 90000; //round to nearest packet, assuming all 1024 samples (probably wrong, but meh) @@ -208,7 +211,7 @@ namespace Mist{ } if (codec == "opus"){ tempLen += 3 + (dataLen/255); - bs = TS::Packet::getPESPS1LeadIn(tempLen, packTime, M.getBps(thisIdx)); + bs = TS::Packet::getPESPS1LeadIn(tempLen, packTime, this->M.getBps(this->thisIdx)); fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg); bs = "\177\340"; bs.append(dataLen/255, (char)255); @@ -216,10 +219,10 @@ namespace Mist{ fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg); }else{ bs.clear(); - TS::Packet::getPESAudioLeadIn(bs, tempLen, packTime, M.getBps(thisIdx)); + TS::Packet::getPESAudioLeadIn(bs, tempLen, packTime, this->M.getBps(this->thisIdx)); fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg); if (codec == "AAC"){ - bs = TS::getAudioHeader(dataLen, M.getInit(thisIdx)); + bs = TS::getAudioHeader(dataLen, this->M.getInit(this->thisIdx)); fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg); } } @@ -227,7 +230,7 @@ namespace Mist{ }else if (type == "meta"){ long unsigned int tempLen = dataLen; if (codec == "JSON"){tempLen += 2;} - bs = TS::Packet::getPESMetaLeadIn(tempLen, packTime, M.getBps(thisIdx)); + bs = TS::Packet::getPESMetaLeadIn(tempLen, packTime, this->M.getBps(this->thisIdx)); fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg); if (codec == "JSON"){ char dLen[2]; @@ -241,4 +244,7 @@ namespace Mist{ fillPacket(0, 0, firstPack, video, keyframe, pkgPid, contPkg); } } + + TSOutput::TSOutput(Socket::Connection &conn) : TSOutputTmpl(conn){} + TSOutputHTTP::TSOutputHTTP(Socket::Connection &conn) : TSOutputTmpl(conn){} }// namespace Mist diff --git a/src/output/output_ts_base.h b/src/output/output_ts_base.h index a6bf141d9..294d18230 100644 --- a/src/output/output_ts_base.h +++ b/src/output/output_ts_base.h @@ -1,3 +1,4 @@ +#pragma once #include "output.h" #include "output_http.h" #include @@ -10,17 +11,18 @@ namespace Mist{ - class TSOutput : public TS_BASECLASS{ + template + class TSOutputTmpl : public T{ public: - TSOutput(Socket::Connection &conn); - virtual ~TSOutput(){}; + TSOutputTmpl(Socket::Connection &conn); + virtual ~TSOutputTmpl(){}; virtual void sendNext(); virtual void sendTS(const char *tsData, size_t len = 188){}; void fillPacket(char const *data, size_t dataLen, bool &firstPack, bool video, bool keyframe, size_t pkgPid, uint16_t &contPkg); virtual void sendHeader(){ - sentHeader = true; - packCounter = 0; + this->sentHeader = true; + this->packCounter = 0; } protected: @@ -36,4 +38,13 @@ namespace Mist{ uint64_t lastHeaderTime; ///< Timestamp last PAT/PMT were sent. uint64_t ts_from; ///< Starting time to subtract from timestamps }; + + class TSOutput : public TSOutputTmpl{ + public: + TSOutput(Socket::Connection &conn); + }; + class TSOutputHTTP : public TSOutputTmpl{ + public: + TSOutputHTTP(Socket::Connection &conn); + }; }// namespace Mist From efa05928f756896b782c8b97eb36b42eca4e1f57 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Thu, 16 May 2024 02:40:44 +0000 Subject: [PATCH 23/24] onebinary: fix toUTF16 namespace conflict --- meson.build | 2 +- src/output/output_cmaf.cpp | 4 ++-- src/output/output_mp4.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/meson.build b/meson.build index 055d0d55c..d838d18c8 100644 --- a/meson.build +++ b/meson.build @@ -228,7 +228,7 @@ onebinary_stuff += 'MistInTS' # onebinary_stuff += 'MistInTSRIST' # onebinary_stuff += 'MistInTSSRT' onebinary_stuff += 'MistOutAAC' -# onebinary_stuff += 'MistOutCMAF' +onebinary_stuff += 'MistOutCMAF' onebinary_stuff += 'MistOutDTSC' onebinary_stuff += 'MistOutEBML' onebinary_stuff += 'MistOutFLAC' diff --git a/src/output/output_cmaf.cpp b/src/output/output_cmaf.cpp index 77d1b4101..78dc4ae0e 100644 --- a/src/output/output_cmaf.cpp +++ b/src/output/output_cmaf.cpp @@ -723,7 +723,7 @@ namespace Mist{ /* Smooth Streaming Manifest Generation */ /****************************************/ - std::string toUTF16(const std::string &original){ + std::string toUTF16CMAF(const std::string &original){ std::string result; result.append("\377\376", 2); for (std::string::const_iterator it = original.begin(); it != original.end(); it++){ @@ -845,7 +845,7 @@ namespace Mist{ smoothAdaptation("video", vTracks, r); r << "\n"; - return toUTF16(r.str()); + return toUTF16CMAF(r.str()); } /**********************************/ diff --git a/src/output/output_mp4.cpp b/src/output/output_mp4.cpp index f881befbe..82fd888d8 100644 --- a/src/output/output_mp4.cpp +++ b/src/output/output_mp4.cpp @@ -16,7 +16,7 @@ std::set supportedAudio; std::set supportedVideo; namespace Mist{ - std::string toUTF16(const std::string &original){ + std::string toUTF16MP4(const std::string &original){ std::stringstream result; result << (char)0xFF << (char)0xFE; for (std::string::const_iterator it = original.begin(); it != original.end(); it++){ @@ -90,7 +90,7 @@ namespace Mist{ std::string OutMP4::protectionHeader(size_t idx){ - std::string tmp = toUTF16(M.getPlayReady(idx)); + std::string tmp = toUTF16MP4(M.getPlayReady(idx)); tmp.erase(0, 2); // remove first 2 characters std::stringstream resGen; resGen << (char)((tmp.size() + 10) & 0xFF); From e306e79a62360e08c6e7346bf7a347c403a67c2a Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Tue, 21 May 2024 01:28:04 +0000 Subject: [PATCH 24/24] onebinary: rewrite program_invocation_short_name this is not very portable --- scripts/onebinary_gen.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/onebinary_gen.py b/scripts/onebinary_gen.py index 2094ddd50..05766c7f8 100644 --- a/scripts/onebinary_gen.py +++ b/scripts/onebinary_gen.py @@ -111,6 +111,7 @@ # '#include "src/controller/controller.cpp"', 'int main(int argc, char *argv[]){', ' if (argc < 2) {', + ' program_invocation_short_name = (char *)"MistController";' ' return ControllerMain(argc, argv);', ' }', ' // Create a new argv array without argv[1]', @@ -129,6 +130,7 @@ for cap in capabilities: entrypoint_lines.extend([ ' else if (strcmp(argv[1], "' + cap['binary_name'] + '") == 0) {', + ' program_invocation_short_name = argv[1];' ' return ' + cap['func_name'] +'<' + cap['class_name'] + '>(new_argc, new_argv);', ' }', ]) @@ -138,6 +140,7 @@ ' return SessionMain(new_argc, new_argv);', ' }', ' else {', + ' program_invocation_short_name = (char *)"MistController";', ' return ControllerMain(argc, argv);', ' }', ' INFO_MSG("binary not found: %s", argv[1]);',