Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: one ./MistServer binary that contains everything #195

Open
wants to merge 24 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
bb6c707
refactor: MistOutSRT --> MistOutSubRip
iameli May 21, 2024
fead246
onebinary: MistServer!
iameli May 9, 2024
28c1652
onebinary: combine MistOutHLS and MistOutHTTP
iameli May 9, 2024
67c97c7
onebinary: move up to mistserver.cpp
iameli May 9, 2024
3097f2b
onebinary: add MistInBuffer
iameli May 9, 2024
cbcc864
onebinary: add MistOutHTTP
iameli May 9, 2024
17086a7
onebinary: add MistSession
iameli May 9, 2024
fcbc98d
controller: add MIST_NO_PRETTY_LOGGING
iameli Feb 2, 2022
a9d7e6f
onebinary: it almost works!
iameli May 10, 2024
f07bea0
onebinary: no arguments == MistController
iameli May 14, 2024
f9b46b8
onebinary: integrate with MistIn and MistSession
iameli May 14, 2024
a82333c
onebinary: working header generation
iameli May 15, 2024
f92f261
onebinary: working entrypoint generation
iameli May 15, 2024
23f6dd3
onebinary: entrypoint dynamically gets headers too
iameli May 15, 2024
5ed95b5
onebinary: sources and stuff populated dynamically
iameli May 15, 2024
7f4f9cc
onebinary: add #pragma once to input.h
iameli May 15, 2024
e90d6ae
onebinary: modify inputs to be friends
iameli May 16, 2024
287f893
onebinary: fix global state collisions in RTSP and SDP
iameli May 16, 2024
ddd65fe
onebinary: fix global name collisions in InputISMV
iameli May 16, 2024
e7a3925
onebinary: flip on MistInSubRip
iameli May 16, 2024
9482c46
onebinary: fixes for various outputs
iameli May 16, 2024
7b19b3d
onebinary: refactor TSOutput and TSOutputHTTP
iameli May 16, 2024
efa0592
onebinary: fix toUTF16 namespace conflict
iameli May 16, 2024
e306e79
onebinary: rewrite program_invocation_short_name
iameli May 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/checksum.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#pragma once
#include <stddef.h>
#include "defines.h"

Expand Down
3 changes: 2 additions & 1 deletion lib/comms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,8 @@ namespace Comms{
Socket::hostBytesToStr(ip.data(), ip.size(), host);
pid_t thisPid;
std::deque<std::string> 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
Expand Down
1 change: 1 addition & 0 deletions lib/downloader.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#pragma once
#include "http_parser.h"
#include "socket.h"
#include "url.h"
Expand Down
1 change: 1 addition & 0 deletions lib/sdp.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#pragma once
#include "dtsc.h"
#include "h265.h"
#include "http_parser.h"
Expand Down
7 changes: 4 additions & 3 deletions lib/stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions lib/ts_stream.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#pragma once
#include "adts.h"
#include "h265.h"
#include "ts_packet.h"
Expand Down
114 changes: 113 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
13 changes: 13 additions & 0 deletions scripts/make_header.sh
Original file line number Diff line number Diff line change
@@ -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
152 changes: 152 additions & 0 deletions scripts/onebinary_gen.py
Original file line number Diff line number Diff line change
@@ -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 <mist/config.h>',
'#include <mist/defines.h>',
'#include <mist/socket.h>',
'#include <mist/util.h>',
'#include <mist/stream.h>',
'#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))
13 changes: 11 additions & 2 deletions src/controller/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
1 change: 1 addition & 0 deletions src/controller/controller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int ControllerMain(int argc, char **argv);
Loading