Various fixes, among which:

- Fixed segfault when attempting to initialseek on disconnected streams
- Fix 100% CPU bug in controller's stats code
- WebRTC UDP bind socket improvements
- Several segfault fixes
- Increased packet reordering buffer size from 30 to 150 packets
- Tweaks to default output/buffer behaviour for incoming pushes
- Added message for load balancer checks
- Fixed HLS content type
- Stats fixes
- Exit reason fixes
- Fixed socket IP address detection
- Fixed non-string arguments for stream settings
- Added caching for getConnectedBinHost()
- Added WebRTC playback rate control
- Added/completed VP8/VP9 support to WebRTC/RTSP
- Added live seek option to WebRTC
- Fixed seek to exactly newest timestamp
- Fixed HLS input

# Conflicts:
#	lib/defines.h
#	src/input/input.cpp
This commit is contained in:
Thulinma 2021-04-21 18:11:46 +02:00
parent 2b99f2f5ea
commit 0af992d405
75 changed files with 1512 additions and 790 deletions

View file

@ -9,7 +9,7 @@
#include <sys/types.h> //for stat
#include <unistd.h> //for stat
int pipein[2], pipeout[2], pipeerr[2];
int pipein[2], pipeout[2];
Util::Config co;
Util::Config conf;
@ -134,8 +134,14 @@ int main(int argc, char *argv[]){
}
// create pipe pair before thread
pipe(pipein);
pipe(pipeout);
if (pipe(pipein) || pipe(pipeout)){
FAIL_MSG("Could not create pipes for process!");
return 1;
}
Util::Procs::socketList.insert(pipeout[0]);
Util::Procs::socketList.insert(pipeout[1]);
Util::Procs::socketList.insert(pipein[0]);
Util::Procs::socketList.insert(pipein[1]);
// stream which connects to input
tthread::thread source(sourceThread, 0);
@ -188,9 +194,18 @@ namespace Mist{
int ffer = 2;
pid_t execd_proc = -1;
std::string streamName = opt["sink"].asString();
if (!streamName.size()){streamName = opt["source"].asStringRef();}
Util::streamVariables(streamName, opt["source"].asStringRef());
//Do variable substitution on command
std::string tmpCmd = opt["exec"].asStringRef();
Util::streamVariables(tmpCmd, streamName, opt["source"].asStringRef());
// exec command
char exec_cmd[10240];
strncpy(exec_cmd, opt["exec"].asString().c_str(), 10240);
strncpy(exec_cmd, tmpCmd.c_str(), 10240);
INFO_MSG("Executing command: %s", exec_cmd);
uint8_t argCnt = 0;
char *startCh = 0;

View file

@ -21,7 +21,9 @@ namespace Mist{
class ProcessSink : public InputEBML{
public:
ProcessSink(Util::Config *cfg) : InputEBML(cfg){};
ProcessSink(Util::Config *cfg) : InputEBML(cfg){
capa["name"] = "MKVExec";
};
void getNext(size_t idx = INVALID_TRACK_ID){
static bool recurse = false;
if (recurse){return InputEBML::getNext(idx);}
@ -52,7 +54,15 @@ namespace Mist{
class ProcessSource : public OutEBML{
public:
ProcessSource(Socket::Connection &c) : OutEBML(c){realTime = 1000;};
bool isRecording(){return false;}
ProcessSource(Socket::Connection &c) : OutEBML(c){
capa["name"] = "MKVExec";
realTime = 0;
};
void sendHeader(){
realTime = 0;
OutEBML::sendHeader();
};
void sendNext(){
extraKeepAway = 0;
needsLookAhead = 0;

View file

@ -13,7 +13,7 @@
int ofin = -1, ofout = 1, oferr = 2;
int ifin = -1, ifout = -1, iferr = 2;
int pipein[2], pipeout[2], pipeerr[2];
int pipein[2], pipeout[2];
Util::Config co;
Util::Config conf;
@ -307,8 +307,12 @@ int main(int argc, char *argv[]){
}
// create pipe pair before thread
pipe(pipein);
pipe(pipeout);
if (pipe(pipein) || pipe(pipeout)){
FAIL_MSG("Could not create pipes for process!");
return 1;
}
Util::Procs::socketList.insert(pipeout[0]);
Util::Procs::socketList.insert(pipein[1]);
// stream which connects to input
tthread::thread source(sourceThread, 0);
@ -384,14 +388,14 @@ namespace Mist{
std::string EncodeOutputEBML::getTrackType(int tid){return M.getType(tid);}
void EncodeOutputEBML::setVideoTrack(std::string tid){
std::set<size_t> tracks = Util::findTracks(M, "video", tid);
std::set<size_t> tracks = Util::findTracks(M, capa, "video", tid);
for (std::set<size_t>::iterator it = tracks.begin(); it != tracks.end(); it++){
userSelect[*it].reload(streamName, *it);
}
}
void EncodeOutputEBML::setAudioTrack(std::string tid){
std::set<size_t> tracks = Util::findTracks(M, "audio", tid);
std::set<size_t> tracks = Util::findTracks(M, capa, "audio", tid);
for (std::set<size_t>::iterator it = tracks.begin(); it != tracks.end(); it++){
userSelect[*it].reload(streamName, *it);
}
@ -571,7 +575,7 @@ namespace Mist{
if (!preset.empty()){options.append(" -preset " + preset);}
snprintf(ffcmd, 10240, "ffmpeg -hide_banner -loglevel warning -f lavfi -i color=c=black:s=%dx%d %s %s -c:v %s %s %s %s -an -f matroska - ",
snprintf(ffcmd, 10240, "ffmpeg -hide_banner -loglevel warning -f lavfi -i color=c=black:s=%dx%d %s %s -c:v %s %s %s %s -an -force_key_frames source -f matroska - ",
res_x, res_y, s_input.c_str(), s_overlay.c_str(), codec.c_str(), options.c_str(),
getBitrateSetting().c_str(), flags.c_str());
@ -681,16 +685,26 @@ namespace Mist{
}else{
// sources array missing, create empty object in array
opt["sources"][0u]["src"] = "-";
WARN_MSG("No stdin input set in config, adding input stream with default settings");
if (opt.isMember("resolution")){
opt["sources"][0u]["width"] = -1;
opt["sources"][0u]["height"] = res_y;
opt["sources"][0u]["anchor"] = "center";
}
INFO_MSG("Default source: input stream at preserved-aspect same height");
stdinSource = true;
}
if (!stdinSource){
// no stdin source item found in sources configuration, add source object at the beginning
opt["sources"].prepend(JSON::fromString("{\"src\':\"-\"}"));
WARN_MSG("No stdin input stream found in 'inputs' config, adding stdin input stream at the "
"beginning of the array");
JSON::Value nOpt;
nOpt["src"] = "-";
if (opt.isMember("resolution")){
nOpt["width"] = -1;
nOpt["height"] = res_y;
nOpt["anchor"] = "center";
}
opt["sources"].prepend(nOpt);
WARN_MSG("Source is not used: adding source stream at preserved-aspect same height");
}
return true;
@ -799,7 +813,6 @@ namespace Mist{
}
prepareCommand();
MEDIUM_MSG("Starting ffmpeg process...");
ffout = p.StartPiped(args, &pipein[0], &pipeout[1], &ffer);
while (conf.is_active && p.isRunning(ffout)){Util::sleep(200);}

View file

@ -52,6 +52,7 @@ namespace Mist{
class EncodeOutputEBML : public OutEBML{
public:
EncodeOutputEBML(Socket::Connection &c) : OutEBML(c){}; // realTime = 0;};
bool isRecording(){return false;}
void setVideoTrack(std::string tid);
void setAudioTrack(std::string tid);
void sendNext();