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/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/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/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/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/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 e82969953..d838d18c8 100644 --- a/meson.build +++ b/meson.build @@ -203,18 +203,130 @@ subdir('test') exec_tgts = [] +make_header = find_program('scripts/make_header.sh') + +onebinary_stuff = [] +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_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 = [] +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 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 + onebinary_headers += exec.get('headers') + onebinary_sources += exec.get('sources_debased') + endif endforeach +prog_python = find_program('python3') +script = files('scripts/onebinary_gen.py') + +onebinary_header = custom_target('onebinary', + 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] +) + +onebinary = executable( + 'MistServer', + [ + files( + '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', + 'src/session.cpp', + 'src/controller/controller.cpp', + ), + onebinary_sources, + io_cpp, + header_tgts, + embed_tgts, + server_html, + onebinary_header, + ], + cpp_args: [ + '-DTS_BASECLASS=Output', + '-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..05766c7f8 --- /dev/null +++ b/scripts/onebinary_gen.py @@ -0,0 +1,152 @@ +#!/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() + +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 json_files: + path = Path(name) + stem = path.stem + text = path.read_text().strip("\n") + json_str = json.dumps(text) + category = '' + connector = '' + class_name = '' + if stem.startswith(MIST_IN): + category = "inputs" + connector = stem[len(MIST_IN):] + 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({ + 'json_str': json_str, + 'category': category, + 'connector': connector, + 'class_name': class_name, + 'binary_name' : stem, + 'func_name': func_name, + }) + +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)) + +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"', +]) + + +entrypoint_lines.extend([ + # '#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) {', + ' program_invocation_short_name = (char *)"MistController";' + ' 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) {', + ' program_invocation_short_name = argv[1];' + ' return ' + cap['func_name'] +'<' + cap['class_name'] + '>(new_argc, new_argv);', + ' }', + ]) + +entrypoint_lines.extend([ + ' else if (strcmp(argv[1], "MistSession") == 0) {', + ' 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]);', + ' return 202;', + '}', +]) + +entrypoint_fullpath = os.path.join(os.getcwd(), args.entrypoint) +Path(entrypoint_fullpath).write_text('\n'.join(entrypoint_lines)) diff --git a/src/controller/controller.cpp b/src/controller/controller.cpp index e05b99d52..ec41a3bdc 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)); @@ -614,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; @@ -673,3 +677,8 @@ int main(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.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/controller/controller_capabilities.cpp b/src/controller/controller_capabilities.cpp index 426edea2d..34a695128 100644 --- a/src/controller/controller_capabilities.cpp +++ b/src/controller/controller_capabilities.cpp @@ -1,4 +1,7 @@ #include "controller_capabilities.h" +#ifdef ONE_BINARY +#include "controller_capabilities_static.h" +#endif #include #include #include @@ -249,6 +252,7 @@ namespace Controller{ /// Aquire list of available protocols, storing in global 'capabilities' JSON::Value. void checkAvailProtocols(){ + #ifndef ONE_BINARY std::deque execs; Util::getMyExec(execs); std::string arg_one; @@ -313,6 +317,10 @@ namespace Controller{ } } } + #else + // produced with e.g. `./MistOutHLS -j | jq '. | tostring'` + Controller::addStaticCapabilities(capabilities); + #endif } ///\brief A class storing information about the cpu the server is running on. 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/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..305853625 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -1,3 +1,4 @@ +#pragma once #include #include #include @@ -54,6 +55,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 +107,6 @@ namespace Mist{ uint64_t activityCounter; - JSON::Value capa; - std::map > keyTimes; std::map keyLoadPriority; 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 9e53b26ba..544e49f7e 100644 --- a/src/input/input_buffer.h +++ b/src/input/input_buffer.h @@ -59,4 +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.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 0afbd6f78..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,11 +40,13 @@ 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; }; }// 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.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_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.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){ 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/input/meson.build b/src/input/meson.build index b4e72f27b..23b66f47b 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' : [ @@ -72,9 +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', 'input_'+input.get('format')+'.h') + string_opt.format('INPUTTYPE', inputtype_header) + ], + 'headers': [ + files(inputtype_header) ] } endforeach diff --git a/src/input/mist_in.cpp b/src/input/mist_in.cpp index 8ca95daeb..c79e0e453 100644 --- a/src/input/mist_in.cpp +++ b/src/input/mist_in.cpp @@ -1,9 +1,19 @@ +#ifndef ONE_BINARY #include INPUTTYPE +#endif #include +#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); } + +#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 43c40a041..33db51a31 100644 --- a/src/meson.build +++ b/src/meson.build @@ -13,4 +13,3 @@ executables += { 'defines': [], 'deps' : [libmist_dep] } - diff --git a/src/output/meson.build b/src/output/meson.build index 4d7777281..3b84103f0 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']}, @@ -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') @@ -81,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 @@ -98,20 +96,40 @@ 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 + outputtype_header = 'output_'+output.get('format')+'.h' + executables += { 'name': 'MistOut'+output.get('name'), 'sources' : [ sources, header_tgts ], + 'sources_debased' : [ + sources_debased + ], '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 diff --git a/src/output/mist_out.cpp b/src/output/mist_out.cpp index 454106a08..61d84fd5b 100644 --- a/src/output/mist_out.cpp +++ b/src/output/mist_out.cpp @@ -1,10 +1,13 @@ +#ifndef ONE_BINARY #include OUTPUTTYPE +#endif #include #include #include #include #include +template int spawnForked(Socket::Connection &S){ { struct sigaction new_action; @@ -13,26 +16,27 @@ int spawnForked(Socket::Connection &S){ new_action.sa_flags = 0; sigaction(SIGUSR1, &new_action, NULL); } - mistOut tmp(S); + T tmp(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"); Util::Config::is_active = false; } -int main(int argc, char *argv[]){ +template +int OutputMain(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,15 +54,15 @@ int main(int argc, char *argv[]){ } } conf.activate(); - if (mistOut::listenMode()){ + 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); } - 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 +70,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 +78,8 @@ int main(int argc, char *argv[]){ return 0; } +#ifndef ONE_BINARY +int main(int argc, char *argv[]){ + return OutputMain(argc, argv); +} +#endif 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.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_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..e04f9a114 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; @@ -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 129873f92..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(); @@ -26,4 +26,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutHLS mistOut; +#endif 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.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 5a2d5cb3d..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(); @@ -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.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); 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_rtmp.h b/src/output/output_rtmp.h index e2b571f00..ba65112f5 100644 --- a/src/output/output_rtmp.h +++ b/src/output/output_rtmp.h @@ -55,4 +55,6 @@ namespace Mist{ }; }// namespace Mist +#ifndef ONE_BINARY typedef Mist::OutRTMP 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_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 65% rename from src/output/output_srt.h rename to src/output/output_subrip.h index 4901dc30e..d667f37b5 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,6 @@ namespace Mist{ }; }// namespace Mist -typedef Mist::OutSRT mistOut; +#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_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 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 diff --git a/src/session.cpp b/src/session.cpp index 6eebc16d6..cdd3f03e2 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(); @@ -429,3 +429,9 @@ int main(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 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