From efcb038a26f2aed0e9687a85b576617ee6679fc5 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Sat, 15 Jul 2017 14:07:28 +0200 Subject: [PATCH 1/8] Made Util::Procs::childRunning a public function --- lib/procs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/procs.h b/lib/procs.h index 25d78e5a..c0f7bb7f 100644 --- a/lib/procs.h +++ b/lib/procs.h @@ -15,7 +15,6 @@ namespace Util { /// Deals with spawning, monitoring and stopping child processes class Procs { private: - static bool childRunning(pid_t p); static tthread::mutex plistMutex; static std::set plist; ///< Holds active process list. static bool thread_handler;///< True while thread handler should be running. @@ -25,6 +24,7 @@ namespace Util { static char* const* dequeToArgv(std::deque & argDeq); static void grim_reaper(void * n); public: + static bool childRunning(pid_t p); static tthread::thread * reaper_thread; static bool handler_set; ///< If true, the sigchld handler has been setup. static void setHandler(); From a0d54e1a9554dc7b464c7ba2dcfba272ddf39365 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Sat, 22 Jul 2017 18:49:57 +0200 Subject: [PATCH 2/8] Added H264 Annex B stream input --- CMakeLists.txt | 1 + src/input/input_h264.cpp | 127 +++++++++++++++++++++++++++++++++++++++ src/input/input_h264.h | 33 ++++++++++ 3 files changed, 161 insertions(+) create mode 100644 src/input/input_h264.cpp create mode 100644 src/input/input_h264.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3162985f..cbf7be2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -282,6 +282,7 @@ makeInput(MP3 mp3) makeInput(FLV flv) makeInput(OGG ogg) makeInput(Buffer buffer) +makeInput(H264 h264) ######################################## # MistServer - Outputs # diff --git a/src/input/input_h264.cpp b/src/input/input_h264.cpp new file mode 100644 index 00000000..0068008d --- /dev/null +++ b/src/input/input_h264.cpp @@ -0,0 +1,127 @@ +#include "input_h264.h" +#include +#include + +namespace Mist{ + InputH264::InputH264(Util::Config *cfg) : Input(cfg){ + capa["name"] = "H264"; + capa["desc"] = "H264 Annex B input"; + capa["source_match"] = "h264-exec:*"; + //May be set to always-on mode + capa["always_match"].append("h264-exec:*"); + capa["priority"] = 0ll; + capa["codecs"][0u][0u].append("H264"); + frameCount = 0; + startTime = Util::bootMS(); + inputProcess = 0; + } + + int InputH264::run(){ + if (config->getString("input") != "-"){ + std::string input = config->getString("input"); + const char *argv[2]; + input = input.substr(10); + + char *args[128]; + uint8_t argCnt = 0; + char *startCh = 0; + for (char *i = (char*)input.c_str(); i <= input.data() + input.size(); ++i){ + if (!*i){ + if (startCh){args[argCnt++] = startCh;} + break; + } + if (*i == ' '){ + if (startCh){ + args[argCnt++] = startCh; + startCh = 0; + *i = 0; + } + }else{ + if (!startCh){startCh = i;} + } + } + args[argCnt] = 0; + + int fin = -1, fout = -1, ferr = -1; + inputProcess = Util::Procs::StartPiped(args, &fin, &fout, &ferr); + myConn = Socket::Connection(-1, fout); + }else{ + myConn = Socket::Connection(fileno(stdout), fileno(stdin)); + } + myConn.Received().splitter.assign("\000\000\001", 3); + myMeta.vod = false; + myMeta.live = true; + myMeta.tracks[1].type = "video"; + myMeta.tracks[1].codec = "H264"; + myMeta.tracks[1].trackID = 1; + waitsSinceData = 0; + return Input::run(); + } + + bool InputH264::setup(){ + std::string input = config->getString("input"); + if (input != "-" && input.substr(0, 10) != "h264-exec:"){ + FAIL_MSG("Unsupported input type: %s", input.c_str()); + return false; + } + return true; + } + + void InputH264::getNext(bool smart){ + do{ + if (!myConn.spool()){ + Util::sleep(25); + ++waitsSinceData; + if (waitsSinceData > 5000 / 25 && (waitsSinceData % 40) == 0){ + WARN_MSG("No H264 data received for > 5s, killing source process"); + Util::Procs::Stop(inputProcess); + } + continue; + } + waitsSinceData = 0; + uint32_t bytesToRead = myConn.Received().bytesToSplit(); + if (!bytesToRead){continue;} + std::string NAL = myConn.Received().remove(bytesToRead); + uint32_t nalSize = NAL.size() - 3; + while (nalSize && NAL.data()[nalSize - 1] == 0){--nalSize;} + if (!nalSize){continue;} + uint8_t nalType = NAL.data()[0] & 0x1F; + INSANE_MSG("NAL unit, type %u, size %lu", nalType, nalSize); + if (nalType == 7 || nalType == 8){ + if (nalType == 7){spsInfo = NAL.substr(0, nalSize);} + if (nalType == 8){ppsInfo = NAL.substr(0, nalSize);} + if (!myMeta.tracks[1].init.size() && spsInfo.size() && ppsInfo.size()){ + h264::sequenceParameterSet sps(spsInfo.data(), spsInfo.size()); + h264::SPSMeta spsChar = sps.getCharacteristics(); + myMeta.tracks[1].width = spsChar.width; + myMeta.tracks[1].height = spsChar.height; + myMeta.tracks[1].fpks = spsChar.fps * 1000; + if (myMeta.tracks[1].fpks < 100 || myMeta.tracks[1].fpks > 1000000){ + myMeta.tracks[1].fpks = 0; + } + MP4::AVCC avccBox; + avccBox.setVersion(1); + avccBox.setProfile(spsInfo[1]); + avccBox.setCompatibleProfiles(spsInfo[2]); + avccBox.setLevel(spsInfo[3]); + avccBox.setSPSNumber(1); + avccBox.setSPS(spsInfo); + avccBox.setPPSNumber(1); + avccBox.setPPS(ppsInfo); + myMeta.tracks[1].init = std::string(avccBox.payload(), avccBox.payloadSize()); + } + continue; + } + if (myMeta.tracks[1].init.size()){ + uint64_t ts = Util::bootMS() - startTime; + if (myMeta.tracks[1].fpks){ts = frameCount * (1000000 / myMeta.tracks[1].fpks);} + thisPacket.genericFill(ts, 0, 1, 0, 0, 0, h264::isKeyframe(NAL.data(), nalSize)); + thisPacket.appendNal(NAL.data(), nalSize, nalSize); + ++frameCount; + return; + } + }while (myConn && (inputProcess == 0 || Util::Procs::childRunning(inputProcess))); + if (inputProcess){myConn.close();} + } +} + diff --git a/src/input/input_h264.h b/src/input/input_h264.h new file mode 100644 index 00000000..7b2f7b3c --- /dev/null +++ b/src/input/input_h264.h @@ -0,0 +1,33 @@ +#include "input.h" +#include +#include + +namespace Mist{ + class InputH264 : public Input{ + public: + InputH264(Util::Config *cfg); + int run(); + + protected: + bool setup(); + void getNext(bool smart = true); + Socket::Connection myConn; + std::string ppsInfo; + std::string spsInfo; + uint64_t frameCount; + // Empty defaults + bool readHeader(){return true;} + bool openStreamSource(){return true;} + void closeStreamSource(){} + void parseStreamHeader(){} + void seek(int seekTime){} + void trackSelect(std::string trackSpec){} + bool needsLock(){return false;} + uint64_t startTime; + pid_t inputProcess; + uint32_t waitsSinceData; + }; +} + +typedef Mist::InputH264 mistIn; + From 72a6816ec1b571e9b22889fd8a5385cce73e76d0 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Sat, 3 Sep 2016 14:19:49 +0200 Subject: [PATCH 3/8] Added DTSC stdin input --- src/input/input_dtsc.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/input/input_dtsc.cpp b/src/input/input_dtsc.cpp index 6a5dee61..5cd5e52a 100644 --- a/src/input/input_dtsc.cpp +++ b/src/input/input_dtsc.cpp @@ -43,7 +43,7 @@ namespace Mist { } bool inputDTSC::needsLock(){ - return config->getString("input").substr(0, 7) != "dtsc://"; + return config->getString("input").substr(0, 7) != "dtsc://" && config->getString("input") != "-"; } void parseDTSCURI(const std::string & src, std::string & host, uint16_t & port, std::string & password, std::string & streamName) { @@ -106,7 +106,7 @@ namespace Mist { } void inputDTSC::parseStreamHeader() { - while (srcConn.connected()){ + while (srcConn.connected() && config->is_active){ srcConn.spool(); if (srcConn.Received().available(8)){ if (srcConn.Received().copy(4) == "DTCM" || srcConn.Received().copy(4) == "DTSC") { @@ -143,6 +143,10 @@ namespace Mist { bool inputDTSC::openStreamSource() { std::string source = config->getString("input"); + if (source == "-"){ + srcConn = Socket::Connection(fileno(stdout),fileno(stdin)); + return true; + } if (source.find("dtsc://") == 0) { source.erase(0, 7); } @@ -183,10 +187,6 @@ namespace Mist { if (!needsLock()) { return true; } else { - if (config->getString("input") == "-") { - std::cerr << "Input from stdin not yet supported" << std::endl; - return false; - } if (!config->getString("streamname").size()) { if (config->getString("output") == "-") { std::cerr << "Output to stdout not yet supported" << std::endl; From 74acdedeb24bbcf32faec2830dccf2146e8c3bea Mon Sep 17 00:00:00 2001 From: Thulinma Date: Sat, 10 Jun 2017 12:28:43 +0200 Subject: [PATCH 4/8] Added HTTP::Downloader class --- CMakeLists.txt | 2 + lib/downloader.cpp | 117 ++++++++++++++++++++++++++++++++++++++++++++ lib/downloader.h | 27 ++++++++++ lib/http_parser.cpp | 2 +- lib/http_parser.h | 2 +- 5 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 lib/downloader.cpp create mode 100644 lib/downloader.h diff --git a/CMakeLists.txt b/CMakeLists.txt index cbf7be2e..85850a08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,6 +109,7 @@ set(libHeaders ${SOURCE_DIR}/lib/flv_tag.h ${SOURCE_DIR}/lib/h264.h ${SOURCE_DIR}/lib/http_parser.h + ${SOURCE_DIR}/lib/downloader.h ${SOURCE_DIR}/lib/json.h ${SOURCE_DIR}/lib/langcodes.h ${SOURCE_DIR}/lib/mp4_adobe.h @@ -146,6 +147,7 @@ set(libSources ${SOURCE_DIR}/lib/flv_tag.cpp ${SOURCE_DIR}/lib/h264.cpp ${SOURCE_DIR}/lib/http_parser.cpp + ${SOURCE_DIR}/lib/downloader.cpp ${SOURCE_DIR}/lib/json.cpp ${SOURCE_DIR}/lib/langcodes.cpp ${SOURCE_DIR}/lib/mp4_adobe.cpp diff --git a/lib/downloader.cpp b/lib/downloader.cpp new file mode 100644 index 00000000..2a07f654 --- /dev/null +++ b/lib/downloader.cpp @@ -0,0 +1,117 @@ +#include "downloader.h" +#include "defines.h" +#include "timing.h" + +namespace HTTP{ + + /// Returns a reference to the internal HTTP::Parser body element + std::string &Downloader::data(){return H.body;} + + /// Returns the status text of the HTTP Request. + std::string &Downloader::getStatusText(){return H.method;} + + /// Returns the status code of the HTTP Request. + uint32_t Downloader::getStatusCode(){return atoi(H.url.c_str());} + + /// Returns true if the HTTP Request is OK + bool Downloader::isOk(){return (getStatusCode() == 200);} + + /// Returns the given header from the response, or empty string if it does not exist. + std::string Downloader::getHeader(const std::string &headerName){ + return H.GetHeader(headerName); + } + + /// Simply turns link into a HTTP::URL and calls get(const HTTP::URL&) + bool Downloader::get(const std::string &link){ + HTTP::URL uri(link); + return get(uri); + } + + /// Sets an extra (or overridden) header to be sent with outgoing requests. + void Downloader::setHeader(const std::string &name, const std::string &val){ + extraHeaders[name] = val; + } + + /// Clears all extra/override headers for outgoing requests. + void Downloader::clearHeaders(){extraHeaders.clear();} + + /// Downloads the given URL into 'H', returns true on success. + /// Makes at most 5 attempts, and will wait no longer than 5 seconds without receiving data. + bool Downloader::get(const HTTP::URL &link, uint8_t maxRecursiveDepth){ + if (!link.host.size()){return false;} + if (link.protocol != "http"){ + FAIL_MSG("Protocol not supported: %s", link.protocol.c_str()); + return false; + } + INFO_MSG("Retrieving %s", link.getUrl().c_str()); + unsigned int loop = 6; // max 5 attempts + + while (--loop){// loop while we are unsuccessful + H.Clean(); + // Reconnect if needed + if (!S || link.host != connectedHost || link.getPort() != connectedPort){ + S.close(); + connectedHost = link.host; + connectedPort = link.getPort(); + S = Socket::Connection(connectedHost, connectedPort, true); + } + H.url = "/" + link.path; + if (link.args.size()){H.url += "?" + link.args;} + if (link.port.size()){ + H.SetHeader("Host", link.host + ":" + link.port); + }else{ + H.SetHeader("Host", link.host); + } + H.SetHeader("User-Agent", "MistServer " PACKAGE_VERSION); + H.SetHeader("X-Version", PACKAGE_VERSION); + H.SetHeader("Accept", "*/*"); + if (extraHeaders.size()){ + for (std::map::iterator it = extraHeaders.begin(); + it != extraHeaders.end(); ++it){ + H.SetHeader(it->first, it->second); + } + } + H.SendRequest(S); + H.Clean(); + uint64_t reqTime = Util::bootSecs(); + while (S && Util::bootSecs() < reqTime + 5){ + // No data? Wait for a second or so. + if (!S.spool()){ + if (progressCallback != 0){ + if (!progressCallback()){ + WARN_MSG("Download aborted by callback"); + return false; + } + } + Util::sleep(250); + continue; + } + // Data! Check if we can parse it... + if (H.Read(S)){ + if (getStatusCode() >= 300 && getStatusCode() < 400){ + // follow redirect + std::string location = getHeader("Location"); + if (maxRecursiveDepth == 0){ + FAIL_MSG("Maximum redirect depth reached: %s", location.c_str()); + return false; + }else{ + FAIL_MSG("Following redirect to %s", location.c_str()); + return get(link.link(location), maxRecursiveDepth--); + } + } + return true; // Success! + } + // reset the 5 second timeout + reqTime = Util::bootSecs(); + } + if (S){ + FAIL_MSG("Timeout while retrieving %s", link.getUrl().c_str()); + return false; + } + Util::sleep(500); // wait a bit before retrying + } + FAIL_MSG("Could not retrieve %s", link.getUrl().c_str()); + return false; + } +} + diff --git a/lib/downloader.h b/lib/downloader.h new file mode 100644 index 00000000..0c40b707 --- /dev/null +++ b/lib/downloader.h @@ -0,0 +1,27 @@ +#include "http_parser.h" +#include "socket.h" + +namespace HTTP{ + class Downloader{ + public: + Downloader(){progressCallback = 0;} + std::string &data(); + bool get(const std::string &link); + bool get(const HTTP::URL &link, uint8_t maxRecursiveDepth = 6); + std::string getHeader(const std::string &headerName); + std::string &getStatusText(); + uint32_t getStatusCode(); + bool isOk(); + bool (*progressCallback)(); ///< Called every time the socket stalls, up to 4X per second. + void setHeader(const std::string &name, const std::string &val); + void clearHeaders(); + + private: + std::map extraHeaders; ///< Holds extra headers to sent with request + std::string connectedHost; ///< Currently connected host name + uint32_t connectedPort; ///< Currently connected port number + Parser H; ///< HTTP parser for downloader + Socket::Connection S; ///< TCP socket for downloader + }; +} + diff --git a/lib/http_parser.cpp b/lib/http_parser.cpp index 188bdf77..3b4bf7dc 100644 --- a/lib/http_parser.cpp +++ b/lib/http_parser.cpp @@ -158,7 +158,7 @@ std::string HTTP::URL::getBareUrl() const{ } ///Returns a URL object for the given link, resolved relative to the current URL object. -HTTP::URL HTTP::URL::link(const std::string &l){ +HTTP::URL HTTP::URL::link(const std::string &l) const{ //Full link if (l.find("://") < l.find('/') && l.find('/' != std::string::npos)){ DONTEVEN_MSG("Full link: %s", l.c_str()); diff --git a/lib/http_parser.h b/lib/http_parser.h index 692febd8..fdeb32d1 100644 --- a/lib/http_parser.h +++ b/lib/http_parser.h @@ -83,7 +83,7 @@ namespace HTTP { std::string path;/// Date: Sat, 1 Jul 2017 12:34:39 +0200 Subject: [PATCH 5/8] Added raw data payload printing in hex to DTSC analyser --- src/analysers/analyser_dtsc.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/analysers/analyser_dtsc.cpp b/src/analysers/analyser_dtsc.cpp index c52381eb..9bc3aab5 100644 --- a/src/analysers/analyser_dtsc.cpp +++ b/src/analysers/analyser_dtsc.cpp @@ -1,5 +1,6 @@ #include "analyser_dtsc.h" #include +#include void AnalyserDTSC::init(Util::Config &conf){ Analyser::init(conf); @@ -34,6 +35,15 @@ bool AnalyserDTSC::parsePacket(){ std::cout << "DTSCv2 packet (Track " << P.getTrackId() << ", time " << P.getTime() << "): " << P.getScan().toPrettyString() << std::endl; } + if (detail >= 8){ + char * payDat; + unsigned int payLen; + P.getString("data", payDat, payLen); + for (uint64_t i = 0; i < payLen; ++i){ + if ((i % 32) == 0){std::cout << std::endl;} + std::cout << std::hex << std::setw(2) << std::setfill('0') << (unsigned int)payDat[i]; + } + } break; } case DTSC::DTSC_HEAD:{ From f9a0ec5b782240b599f1b189c56880a667722286 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Sat, 1 Jul 2017 12:34:54 +0200 Subject: [PATCH 6/8] Fixed overflow problems when reading corrupt AVCC box --- lib/mp4_generic.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/mp4_generic.cpp b/lib/mp4_generic.cpp index 8b3d3f14..c08b5e70 100644 --- a/lib/mp4_generic.cpp +++ b/lib/mp4_generic.cpp @@ -574,7 +574,12 @@ namespace MP4 { } uint32_t AVCC::getSPSLen() { - return getInt16(6); + uint16_t len = getInt16(6); + if (len > payloadSize() - 8){ + WARN_MSG("SPS length of %u is more than AVCC box size %lu", len, payloadSize()); + return 0; + } + return len; } char * AVCC::getSPS() { @@ -621,7 +626,16 @@ namespace MP4 { uint32_t AVCC::getPPSLen() { int offset = 8 + getSPSLen() + 1; - return getInt16(offset); + if (offset > payloadSize() - 2){ + WARN_MSG("Invalid PPS length offset! Aborting PPS read."); + return 0; + } + uint16_t len = getInt16(offset); + if (len > payloadSize() - offset - 2){ + WARN_MSG("PPS length of %u is more than AVCC box size %lu", len, payloadSize()); + return 0; + } + return len; } char * AVCC::getPPS() { From 169830bd1503674aa5b5a8c2d1a11271acd5cd0a Mon Sep 17 00:00:00 2001 From: Thulinma Date: Tue, 18 Jul 2017 12:42:10 +0200 Subject: [PATCH 7/8] Added SO_KEEPALIVE to all socket connections by default. --- lib/socket.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/socket.cpp b/lib/socket.cpp index d12c3edb..6fe91200 100644 --- a/lib/socket.cpp +++ b/lib/socket.cpp @@ -548,6 +548,9 @@ Socket::Connection::Connection(std::string host, int port, bool nonblock){ flags |= O_NONBLOCK; fcntl(sock, F_SETFL, flags); } + int optval = 1; + int optlen = sizeof(optval); + setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen); } }// Socket::Connection TCP Contructor @@ -985,6 +988,11 @@ Socket::Connection Socket::Server::accept(bool nonblock){ flags |= O_NONBLOCK; fcntl(r, F_SETFL, flags); } + if (r >= 0){ + int optval = 1; + int optlen = sizeof(optval); + setsockopt(r, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen); + } Socket::Connection tmp(r); tmp.remoteaddr = tmpaddr; if (r < 0){ From 45e4cddec9a387740fc3762a1892ff072010f8a2 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Sat, 22 Jul 2017 18:53:05 +0200 Subject: [PATCH 8/8] Updated Input class with preRun() and checkArguments() instead of single setup() function --- src/input/input.cpp | 3 ++- src/input/input.h | 11 ++++++----- src/input/input_buffer.cpp | 2 +- src/input/input_buffer.h | 3 ++- src/input/input_dtsc.cpp | 2 +- src/input/input_dtsc.h | 2 +- src/input/input_flv.cpp | 5 ++++- src/input/input_flv.h | 3 ++- src/input/input_h264.cpp | 6 +++--- src/input/input_h264.h | 4 ++-- src/input/input_mp3.cpp | 5 ++++- src/input/input_mp3.h | 3 ++- src/input/input_ogg.cpp | 5 ++++- src/input/input_ogg.h | 3 ++- 14 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/input/input.cpp b/src/input/input.cpp index b991cae3..f6833e40 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -100,7 +100,7 @@ namespace Mist { return 0; } - if (!setup()) { + if (!checkArguments()) { FAIL_MSG("Setup failed - exiting"); return 0; } @@ -125,6 +125,7 @@ namespace Mist { pid_t pid = fork(); if (pid == 0){ if (needsLock()){playerLock.close();} + if (!preRun()){return 0;} return run(); } if (pid == -1){ diff --git a/src/input/input.h b/src/input/input.h index de117e83..e274e086 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -27,17 +27,18 @@ namespace Mist { virtual bool needsLock(){return true;} protected: static void callbackWrapper(char * data, size_t len, unsigned int id); - virtual bool setup() = 0; + virtual bool checkArguments() = 0; virtual bool readHeader() = 0; + virtual bool preRun(){return true;} virtual bool readExistingHeader(); virtual bool atKeyFrame(); - virtual void getNext(bool smart = true) {}; + virtual void getNext(bool smart = true) {} virtual void seek(int seekTime){}; virtual void finish(); virtual bool keepRunning(); - virtual bool openStreamSource() { return false; }; - virtual void closeStreamSource() {}; - virtual void parseStreamHeader() {}; + virtual bool openStreamSource() { return false; } + virtual void closeStreamSource() {} + virtual void parseStreamHeader() {} void play(int until = 0); void playOnce(); void quitPlay(); diff --git a/src/input/input_buffer.cpp b/src/input/input_buffer.cpp index 53a714cc..ff6c6272 100644 --- a/src/input/input_buffer.cpp +++ b/src/input/input_buffer.cpp @@ -720,7 +720,7 @@ namespace Mist { } } - bool inputBuffer::setup() { + bool inputBuffer::preRun() { std::string strName = config->getString("streamname"); Util::sanitizeName(strName); strName = strName.substr(0, (strName.find_first_of("+ "))); diff --git a/src/input/input_buffer.h b/src/input/input_buffer.h index 21ff4446..96cc8898 100644 --- a/src/input/input_buffer.h +++ b/src/input/input_buffer.h @@ -16,7 +16,8 @@ namespace Mist { IPC::semaphore * liveMeta; protected: //Private Functions - bool setup(); + bool preRun(); + bool checkArguments(){return true;} void updateMeta(); bool readHeader(); void getNext(bool smart = true); diff --git a/src/input/input_dtsc.cpp b/src/input/input_dtsc.cpp index 5cd5e52a..7836487e 100644 --- a/src/input/input_dtsc.cpp +++ b/src/input/input_dtsc.cpp @@ -183,7 +183,7 @@ namespace Mist { srcConn.close(); } - bool inputDTSC::setup() { + bool inputDTSC::checkArguments() { if (!needsLock()) { return true; } else { diff --git a/src/input/input_dtsc.h b/src/input/input_dtsc.h index 8d1e5991..496d6b5a 100644 --- a/src/input/input_dtsc.h +++ b/src/input/input_dtsc.h @@ -11,7 +11,7 @@ namespace Mist { bool openStreamSource(); void closeStreamSource(); void parseStreamHeader(); - bool setup(); + bool checkArguments(); bool readHeader(); void getNext(bool smart = true); void seek(int seekTime); diff --git a/src/input/input_flv.cpp b/src/input/input_flv.cpp index 01163471..a60f3b60 100644 --- a/src/input/input_flv.cpp +++ b/src/input/input_flv.cpp @@ -27,7 +27,7 @@ namespace Mist { capa["codecs"][0u][1u].append("MP3"); } - bool inputFLV::setup() { + bool inputFLV::checkArguments() { if (config->getString("input") == "-") { std::cerr << "Input from stdin not yet supported" << std::endl; return false; @@ -43,7 +43,10 @@ namespace Mist { return false; } } + return true; + } + bool inputFLV::preRun() { //open File inFile = fopen(config->getString("input").c_str(), "r"); if (!inFile) { diff --git a/src/input/input_flv.h b/src/input/input_flv.h index d2c438f1..8d36d0db 100644 --- a/src/input/input_flv.h +++ b/src/input/input_flv.h @@ -8,7 +8,8 @@ namespace Mist { inputFLV(Util::Config * cfg); protected: //Private Functions - bool setup(); + bool checkArguments(); + bool preRun(); bool readHeader(); void getNext(bool smart = true); void seek(int seekTime); diff --git a/src/input/input_h264.cpp b/src/input/input_h264.cpp index 0068008d..eb3995b1 100644 --- a/src/input/input_h264.cpp +++ b/src/input/input_h264.cpp @@ -16,7 +16,7 @@ namespace Mist{ inputProcess = 0; } - int InputH264::run(){ + bool InputH264::preRun(){ if (config->getString("input") != "-"){ std::string input = config->getString("input"); const char *argv[2]; @@ -55,10 +55,10 @@ namespace Mist{ myMeta.tracks[1].codec = "H264"; myMeta.tracks[1].trackID = 1; waitsSinceData = 0; - return Input::run(); + return true; } - bool InputH264::setup(){ + bool InputH264::checkArguments(){ std::string input = config->getString("input"); if (input != "-" && input.substr(0, 10) != "h264-exec:"){ FAIL_MSG("Unsupported input type: %s", input.c_str()); diff --git a/src/input/input_h264.h b/src/input/input_h264.h index 7b2f7b3c..43956314 100644 --- a/src/input/input_h264.h +++ b/src/input/input_h264.h @@ -6,10 +6,10 @@ namespace Mist{ class InputH264 : public Input{ public: InputH264(Util::Config *cfg); - int run(); protected: - bool setup(); + bool checkArguments(); + bool preRun(); void getNext(bool smart = true); Socket::Connection myConn; std::string ppsInfo; diff --git a/src/input/input_mp3.cpp b/src/input/input_mp3.cpp index c59c924e..ebeb89ef 100644 --- a/src/input/input_mp3.cpp +++ b/src/input/input_mp3.cpp @@ -21,7 +21,7 @@ namespace Mist { timestamp = 0; } - bool inputMP3::setup() { + bool inputMP3::checkArguments() { if (config->getString("input") == "-") { std::cerr << "Input from stdin not yet supported" << std::endl; return false; @@ -37,7 +37,10 @@ namespace Mist { return false; } } + return true; + } + bool inputMP3::preRun() { //open File inFile = fopen(config->getString("input").c_str(), "r"); if (!inFile) { diff --git a/src/input/input_mp3.h b/src/input/input_mp3.h index bd2afa1d..14bc7e4f 100644 --- a/src/input/input_mp3.h +++ b/src/input/input_mp3.h @@ -16,7 +16,8 @@ namespace Mist { inputMP3(Util::Config * cfg); protected: //Private Functions - bool setup(); + bool checkArguments(); + bool preRun(); bool readHeader(); void getNext(bool smart = true); void seek(int seekTime); diff --git a/src/input/input_ogg.cpp b/src/input/input_ogg.cpp index 56a364ce..9725cccf 100644 --- a/src/input/input_ogg.cpp +++ b/src/input/input_ogg.cpp @@ -53,12 +53,15 @@ namespace Mist { capa["codecs"][0u][1u].append("opus"); } - bool inputOGG::setup(){ + bool inputOGG::checkArguments(){ if (config->getString("input") == "-"){ std::cerr << "Input from stream not yet supported" << std::endl; return false; } + return true; + } + bool inputOGG::preRun(){ //open File inFile = fopen(config->getString("input").c_str(), "r"); if (!inFile){ diff --git a/src/input/input_ogg.h b/src/input/input_ogg.h index 2d9960d6..c03b11b0 100644 --- a/src/input/input_ogg.h +++ b/src/input/input_ogg.h @@ -70,7 +70,8 @@ namespace Mist { inputOGG(Util::Config * cfg); protected: //Private Functions - bool setup(); + bool checkArguments(); + bool preRun(); bool readHeader(); position seekFirstData(long long unsigned int tid); void getNext(bool smart = true);