From 2ea5250c15fbe2c5828e2b2a45148d36d1db2c76 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Tue, 1 May 2012 23:56:13 +0200 Subject: [PATCH] Added support for pulling media files through ffmpeg, added MistFLV2DTSC converter to binaries. --- Controller/main.cpp | 13 +++-- Makefile | 4 +- tools/FLV2DTSC/Makefile | 9 +-- util/procs.cpp | 125 +++++++++++++++++++++++++++++++++++++++- util/procs.h | 1 + 5 files changed, 139 insertions(+), 13 deletions(-) diff --git a/Controller/main.cpp b/Controller/main.cpp index bf8f5afb..0aaf4fdd 100644 --- a/Controller/main.cpp +++ b/Controller/main.cpp @@ -222,19 +222,24 @@ void startStream(std::string name, JSON::Value & data){ Log("BUFF", "(re)starting stream buffer "+name); std::string URL = data["channel"]["URL"]; std::string preset = data["preset"]["cmd"]; - std::string cmd1, cmd2; + std::string cmd1, cmd2, cmd3; if (URL.substr(0, 4) == "push"){ std::string pusher = URL.substr(7); cmd2 = "MistBuffer "+name+" "+pusher; Util::Procs::Start(name, cmd2); }else{ - if (preset == "" || preset == "copy"){ + if (URL.substr(0, 1) == "/"){ cmd1 = "cat "+URL; }else{ cmd1 = "ffmpeg -re -async 2 -i "+URL+" "+preset+" -f flv -"; + cmd2 = "MistFLV2DTSC"; + } + cmd3 = "MistBuffer 500 "+name; + if (cmd2 != ""){ + Util::Procs::Start(name, cmd1, cmd2, cmd3); + }else{ + Util::Procs::Start(name, cmd1, cmd3); } - cmd2 = "MistBuffer 500 "+name; - Util::Procs::Start(name, cmd1, cmd2); } } diff --git a/Makefile b/Makefile index 60ab6f4f..6d6faf3c 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ client-debug: prepare cd Connector_RAW; $(MAKE) cd Buffer; $(MAKE) cd Controller; $(MAKE) + cd tools/FLV2DTSC; $(MAKE) client: client-debug client-clean: cd Connector_HTTP; $(MAKE) clean @@ -17,6 +18,7 @@ client-clean: cd Connector_RAW; $(MAKE) clean cd Buffer; $(MAKE) clean cd Controller; $(MAKE) clean + cd tools/FLV2DTSC; $(MAKE) clean clean: client-clean rm -rf ./bin client-release: prepare @@ -25,6 +27,7 @@ client-release: prepare cd Connector_RAW; $(MAKE) DEBUG=0 OPTIMIZE=-O2 cd Buffer; $(MAKE) DEBUG=0 OPTIMIZE=-O2 cd Controller; $(MAKE) DEBUG=0 OPTIMIZE=-O2 + cd tools/FLV2DTSC; $(MAKE) DEBUG=0 OPTIMIZE=-O2 release: client-release release-install: client-clean client-release cp ./bin/Mist* /usr/bin/ @@ -33,4 +36,3 @@ debug-install: client-clean client-debug install: debug-install docs: doxygen ./Doxyfile > /dev/null - diff --git a/tools/FLV2DTSC/Makefile b/tools/FLV2DTSC/Makefile index 6598d44a..87e30d40 100644 --- a/tools/FLV2DTSC/Makefile +++ b/tools/FLV2DTSC/Makefile @@ -1,6 +1,6 @@ SRC = main.cpp ../../util/flv_tag.cpp ../../util/dtsc.cpp ../../util/amf.cpp ../../util/socket.cpp OBJ = $(SRC:.cpp=.o) -OUT = DDV_FLV2DTSC +OUT = MistFLV2DTSC INCLUDES = DEBUG = 4 OPTIMIZE = -g @@ -15,9 +15,6 @@ default: $(OUT) .cpp.o: $(CC) $(INCLUDES) $(CCFLAGS) $(LIBS) -c $< -o $@ $(OUT): $(OBJ) - $(CC) $(LIBS) -o $(OUT) $(OBJ) + $(CC) $(LIBS) -o ../../bin/$(OUT) $(OBJ) clean: - rm -rf $(OBJ) $(OUT) Makefile.bak *~ -install: $(OUT) - cp -f ./$(OUT) /usr/bin/ - + rm -rf $(OBJ) ../../bin/$(OUT) Makefile.bak *~ diff --git a/util/procs.cpp b/util/procs.cpp index 83e3047d..1512849d 100644 --- a/util/procs.cpp +++ b/util/procs.cpp @@ -32,7 +32,7 @@ void Util::Procs::childsig_handler(int signum){ plist.erase(ret); #if DEBUG >= 1 if (isActive(pname)){ - std::cerr << "Process " << pname << " half-terminated." << std::endl; + std::cerr << "Process " << pname << " part-terminated." << std::endl; Stop(pname); }else{ std::cerr << "Process " << pname << " fully terminated." << std::endl; @@ -101,7 +101,7 @@ pid_t Util::Procs::Start(std::string name, std::string cmd){ } /// Starts two piped processes if the name is not already active. -/// \return 0 if process was not started, main (receiving) process PID otherwise. +/// \return 0 if process was not started, sub (sending) process PID otherwise. /// \arg name Name for this process - only used internally. /// \arg cmd Commandline for sub (sending) process. /// \arg cmd2 Commandline for main (receiving) process. @@ -174,6 +174,127 @@ pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2){ return ret; } +/// Starts three piped processes if the name is not already active. +/// \return 0 if process was not started, sub (sending) process PID otherwise. +/// \arg name Name for this process - only used internally. +/// \arg cmd Commandline for sub (sending) process. +/// \arg cmd2 Commandline for sub (middle) process. +/// \arg cmd3 Commandline for main (receiving) process. +pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2, std::string cmd3){ + if (isActive(name)){return getPid(name);} + if (!handler_set){ + struct sigaction new_action; + new_action.sa_handler = Util::Procs::childsig_handler; + sigemptyset(&new_action.sa_mask); + new_action.sa_flags = 0; + sigaction(SIGCHLD, &new_action, NULL); + handler_set = true; + } + + int pfildes[2]; + int pfildes2[2]; + if (pipe(pfildes) == -1){ + #if DEBUG >= 1 + std::cerr << "Process " << name << " could not be started. Pipe creation failed." << std::endl; + #endif + return 0; + } + if (pipe(pfildes2) == -1){ + #if DEBUG >= 1 + std::cerr << "Process " << name << " could not be started. Pipe creation failed." << std::endl; + #endif + return 0; + } + + int devnull = open("/dev/null", O_RDWR); + pid_t ret = fork(); + if (ret == 0){ + close(pfildes[0]); + dup2(pfildes[1],STDOUT_FILENO); + close(pfildes[1]); + dup2(devnull, STDIN_FILENO); + dup2(devnull, STDERR_FILENO); + close(pfildes2[1]); + close(pfildes2[0]); + runCmd(cmd); + }else{ + if (ret > 0){ + plist.insert(std::pair(ret, name)); + }else{ + #if DEBUG >= 1 + std::cerr << "Process " << name << " could not be started. fork() failed." << std::endl; + #endif + close(pfildes[1]); + close(pfildes[0]); + close(pfildes2[1]); + close(pfildes2[0]); + return 0; + } + } + + pid_t ret2 = fork(); + if (ret2 == 0){ + close(pfildes[1]); + close(pfildes2[0]); + dup2(pfildes[0],STDIN_FILENO); + close(pfildes[0]); + dup2(pfildes2[1],STDOUT_FILENO); + close(pfildes2[1]); + dup2(devnull, STDERR_FILENO); + runCmd(cmd2); + }else{ + if (ret2 > 0){ + #if DEBUG >= 1 + std::cerr << "Process " << name << " started, PIDs (" << ret << ", " << ret2 << "): " << cmd << " | " << cmd2 << std::endl; + #endif + plist.insert(std::pair(ret2, name)); + }else{ + #if DEBUG >= 1 + std::cerr << "Process " << name << " could not be started. fork() failed." << std::endl; + #endif + Stop(name); + close(pfildes[1]); + close(pfildes[0]); + close(pfildes2[1]); + close(pfildes2[0]); + return 0; + } + } + close(pfildes[1]); + close(pfildes[0]); + + pid_t ret3 = fork(); + if (ret3 == 0){ + close(pfildes[1]); + close(pfildes[0]); + close(pfildes2[1]); + dup2(pfildes2[0],STDIN_FILENO); + close(pfildes2[0]); + dup2(devnull, STDOUT_FILENO); + dup2(devnull, STDERR_FILENO); + runCmd(cmd3); + }else{ + if (ret3 > 0){ + #if DEBUG >= 1 + std::cerr << "Process " << name << " started, PIDs (" << ret << ", " << ret2 << ", " << ret3 << "): " << cmd << " | " << cmd2 << " | " << cmd3 << std::endl; + #endif + plist.insert(std::pair(ret3, name)); + }else{ + #if DEBUG >= 1 + std::cerr << "Process " << name << " could not be started. fork() failed." << std::endl; + #endif + Stop(name); + close(pfildes[1]); + close(pfildes[0]); + close(pfildes2[1]); + close(pfildes2[0]); + return 0; + } + } + + return ret3; +} + /// Stops the named process, if running. /// \arg name (Internal) name of process to stop void Util::Procs::Stop(std::string name){ diff --git a/util/procs.h b/util/procs.h index 3ec60902..c10620b8 100644 --- a/util/procs.h +++ b/util/procs.h @@ -18,6 +18,7 @@ namespace Util{ public: static pid_t Start(std::string name, std::string cmd); static pid_t Start(std::string name, std::string cmd, std::string cmd2); + static pid_t Start(std::string name, std::string cmd, std::string cmd2, std::string cmd3); static void Stop(std::string name); static void Stop(pid_t name); static void StopAll();