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:
parent
2b99f2f5ea
commit
0af992d405
75 changed files with 1512 additions and 790 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue