Added debug level options.

This commit is contained in:
Thulinma 2014-05-29 13:26:16 +02:00
parent 407d2e344d
commit 3810330343
19 changed files with 66 additions and 60 deletions

View file

@ -691,6 +691,10 @@ namespace Connector_HTTP {
int main(int argc, char ** argv){ int main(int argc, char ** argv){
Util::Config conf(argv[0], PACKAGE_VERSION); Util::Config conf(argv[0], PACKAGE_VERSION);
JSON::Value capa; JSON::Value capa;
capa["optional"]["debug"]["name"] = "debug";
capa["optional"]["debug"]["help"] = "The debug level at which messages need to be printed.";
capa["optional"]["debug"]["option"] = "--debug";
capa["optional"]["debug"]["type"] = "uint";
capa["desc"] = "Enables the generic HTTP listener, required by all other HTTP protocols. Needs other HTTP protocols enabled to do much of anything."; capa["desc"] = "Enables the generic HTTP listener, required by all other HTTP protocols. Needs other HTTP protocols enabled to do much of anything.";
capa["deps"] = ""; capa["deps"] = "";
conf.addConnectorOptions(8080, capa); conf.addConnectorOptions(8080, capa);

View file

@ -231,9 +231,6 @@ namespace Controller {
Log("CONF", std::string("New configuration value ") + jit->first); Log("CONF", std::string("New configuration value ") + jit->first);
} }
} }
if (out["config"]["basepath"].asString()[out["config"]["basepath"].asString().size() - 1] == '/'){
out["config"]["basepath"] = out["config"]["basepath"].asString().substr(0, out["config"]["basepath"].asString().size() - 1);
}
for (JSON::ObjIter jit = out.ObjBegin(); jit != out.ObjEnd(); jit++){ for (JSON::ObjIter jit = out.ObjBegin(); jit != out.ObjEnd(); jit++){
if (jit->first == "version" || jit->first == "time"){ if (jit->first == "version" || jit->first == "time"){
continue; continue;
@ -243,6 +240,12 @@ namespace Controller {
} }
} }
out = in; out = in;
if (out["basepath"].asString()[out["basepath"].asString().size() - 1] == '/'){
out["basepath"] = out["basepath"].asString().substr(0, out["basepath"].asString().size() - 1);
}
if (out.isMember("debug")){
Util::Config::printDebugLevel = out["debug"].asInt();
}
} }
} //Controller namespace } //Controller namespace
@ -350,6 +353,12 @@ int main(int argc, char ** argv){
//Input custom config here //Input custom config here
Controller::Storage = JSON::fromFile(Controller::conf.getString("configFile")); Controller::Storage = JSON::fromFile(Controller::conf.getString("configFile"));
if (Controller::conf.getOption("debug",true).size() > 1){
Controller::Storage["config"]["debug"] = Controller::conf.getInteger("debug");
}
if (Controller::Storage.isMember("config") && Controller::Storage["config"].isMember("debug")){
Util::Config::printDebugLevel = Controller::Storage["config"]["debug"].asInt();
}
//check for port, interface and username in arguments //check for port, interface and username in arguments
//if they are not there, take them from config file, if there //if they are not there, take them from config file, if there
if (Controller::conf.getOption("listen_port", true).size() <= 1){ if (Controller::conf.getOption("listen_port", true).size() <= 1){

View file

@ -6,10 +6,12 @@
#include <mist/config.h> #include <mist/config.h>
#include <mist/procs.h> #include <mist/procs.h>
#include <mist/timing.h> #include <mist/timing.h>
#include <mist/tinythread.h>
#include "controller_storage.h" #include "controller_storage.h"
#include "controller_connectors.h" #include "controller_connectors.h"
#include <iostream> #include <iostream>
#include <unistd.h>
///\brief Holds everything unique to the controller. ///\brief Holds everything unique to the controller.
@ -71,6 +73,21 @@ namespace Controller {
if (pipedCapa.isMember("optional")){builPipedPart(p, argarr, argnum, pipedCapa["optional"]);} if (pipedCapa.isMember("optional")){builPipedPart(p, argarr, argnum, pipedCapa["optional"]);}
} }
void handleMsg(void * err){
char buf[1024];
FILE * output = fdopen((long long int)err, "r");
while (fgets(buf, 1024, output)){
for (unsigned int i = 0; i < 9 && buf[i] != ' '; i++){}
if(i < 9){
buf[i] = NULL;
Log(buf,buf+i+1);
}else{
printf("%s\n",buf);
}
}
}
///\brief Checks current protocol coguration, updates state of enabled connectors if neccesary. ///\brief Checks current protocol coguration, updates state of enabled connectors if neccesary.
///\param p An object containing all protocols. ///\param p An object containing all protocols.
///\param capabilities An object containing the detected capabilities. ///\param capabilities An object containing the detected capabilities.
@ -141,7 +158,13 @@ namespace Controller {
// get args for this connector // get args for this connector
buildPipedArguments(p[(long long unsigned)iter->first], (char **)&argarr, capabilities); buildPipedArguments(p[(long long unsigned)iter->first], (char **)&argarr, capabilities);
// start piped w/ generated args // start piped w/ generated args
Util::Procs::StartPiped(toConn(iter->first), argarr, &zero, &out, &err); err = -1;
Util::Procs::StartPiped(toConn(iter->first), argarr, &zero, &out, &err);//redirects output to out. Must make a new pipe, redirect std err
if(err != -1){
//spawn new thread where err is read, it reads err until there is nothing more to be read
tthread::thread * msghandler = new tthread::thread(handleMsg, (void*) err);
msghandler->detach();
}
} }
} }

View file

@ -7,24 +7,12 @@
namespace Controller { namespace Controller {
JSON::Value Storage; ///< Global storage of data. JSON::Value Storage; ///< Global storage of data.
tthread::mutex logMutex;///< Mutex for log thread.
///\brief Store and print a log message. ///\brief Store and print a log message.
///\param kind The type of message. ///\param kind The type of message.
///\param message The message to be logged. ///\param message The message to be logged.
void Log(std::string kind, std::string message){ void Log(std::string kind, std::string message){
//if last log message equals this one, do not log. tthread::lock_guard<tthread::mutex> guard(logMutex);
if (Storage["log"].size() > 0){
JSON::ArrIter it = Storage["log"].ArrEnd();
int repeats = Storage["log"].size();
if (repeats > 10){repeats = 10;}
do{
it--;
if (( *it)[2] == message && ( *it)[1] == kind){
return;
}
repeats--;
}while (repeats > 0);
}
JSON::Value m; JSON::Value m;
m.append(Util::epoch()); m.append(Util::epoch());
m.append(kind); m.append(kind);

View file

@ -1,10 +1,13 @@
#include <string> #include <string>
#include <mist/json.h> #include <mist/json.h>
#include <mist/tinythread.h>
namespace Controller { namespace Controller {
extern JSON::Value Storage; ///< Global storage of data. extern JSON::Value Storage; ///< Global storage of data.
extern tthread::mutex logMutex;///< Mutex for log thread.
/// Store and print a log message. /// Store and print a log message.
void Log(std::string kind, std::string message); void Log(std::string kind, std::string message);

View file

@ -88,28 +88,6 @@ namespace Controller {
} }
} }
if ( !getMeta && data.isMember("meta") && data["meta"].isMember("tracks")){ if ( !getMeta && data.isMember("meta") && data["meta"].isMember("tracks")){
for (JSON::ObjIter trIt = data["meta"]["tracks"].ObjBegin(); trIt != data["meta"]["tracks"].ObjEnd(); trIt++){
if (trIt->second["codec"] == "H264"){
if ( !trIt->second.isMember("init")){
getMeta = true;
}else{
if (trIt->second["init"].asString().size() < 4){
Log("WARN", "Source file "+URL+" does not contain H264 init data that MistServer can interpret.");
data["error"] = "Stream offline: Invalid?";
}else{
if (trIt->second["init"].asString().c_str()[1] != 0x42){
Log("WARN", "Source file "+URL+" is not H264 Baseline - convert to baseline profile for best compatibility.");
data["error"] = "Not optimal (details in log)";
}else{
if (trIt->second["init"].asString().c_str()[3] > 30){
Log("WARN", "Source file "+URL+" is higher than H264 level 3.0 - convert to a level <= 3.0 for best compatibility.");
data["error"] = "Not optimal (details in log)";
}
}
}
}
}
}
if ( !data["meta"] || !data["meta"]["tracks"]){ if ( !data["meta"] || !data["meta"]["tracks"]){
Log("WARN", "Source file " + URL + " seems to be corrupt."); Log("WARN", "Source file " + URL + " seems to be corrupt.");
data["error"] = "Stream offline: Corrupt file?"; data["error"] = "Stream offline: Corrupt file?";
@ -212,24 +190,7 @@ namespace Controller {
checker[jit->first].lastms = trIt->second["lastms"].asInt(); checker[jit->first].lastms = trIt->second["lastms"].asInt();
checker[jit->first].last_active = currTime; checker[jit->first].last_active = currTime;
} }
if (trIt->second["codec"] == "H264"){
if (trIt->second.isMember("init")){
if (trIt->second["init"].asString().size() < 4){
Log("WARN", "Live stream "+jit->first+" does not contain H264 init data that MistServer can interpret.");
jit->second["error"] = "Stream offline: Invalid?";
}else{
if (trIt->second["init"].asString().c_str()[1] != 0x42){
Log("WARN", "Live stream "+jit->first+" is not H264 Baseline - convert to baseline profile for best compatibility.");
jit->second["error"] = "Not optimal (details in log)";
}else{
if (trIt->second["init"].asString().c_str()[3] > 30){
Log("WARN", "Live stream "+jit->first+" is higher than H264 level 3.0 - convert to a level <= 3.0 for best compatibility.");
jit->second["error"] = "Not optimal (details in log)";
}
}
}
}
}
} }
} }
// mark stream as offline if no activity for 5 seconds // mark stream as offline if no activity for 5 seconds

View file

@ -25,6 +25,13 @@ namespace Mist {
return ((long long int)timePoint[0] << 56) | ((long long int)timePoint[1] << 48) | ((long long int)timePoint[2] << 40) | ((long long int)timePoint[3] << 32) | ((long long int)timePoint[4] << 24) | ((long long int)timePoint[5] << 16) | ((long long int)timePoint[6] << 8) | timePoint[7]; return ((long long int)timePoint[0] << 56) | ((long long int)timePoint[1] << 48) | ((long long int)timePoint[2] << 40) | ((long long int)timePoint[3] << 32) | ((long long int)timePoint[4] << 24) | ((long long int)timePoint[5] << 16) | ((long long int)timePoint[6] << 8) | timePoint[7];
} }
void Output::init(Util::Config * cfg){
capa["optional"]["debug"]["name"] = "debug";
capa["optional"]["debug"]["help"] = "The debug level at which messages need to be printed.";
capa["optional"]["debug"]["option"] = "--debug";
capa["optional"]["debug"]["type"] = "uint";
}
Output::Output(Socket::Connection & conn) : myConn(conn) { Output::Output(Socket::Connection & conn) : myConn(conn) {
firstTime = 0; firstTime = 0;
parseData = false; parseData = false;

View file

@ -37,7 +37,7 @@ namespace Mist {
Output(Socket::Connection & conn); Output(Socket::Connection & conn);
virtual ~Output(); virtual ~Output();
//static members for initialization and capabilities //static members for initialization and capabilities
static void init(Util::Config * cfg) {} static void init(Util::Config * cfg);
static JSON::Value capa; static JSON::Value capa;
//non-virtual generic functions //non-virtual generic functions
int run(); int run();

View file

@ -135,6 +135,7 @@ namespace Mist {
OutHDS::~OutHDS() {} OutHDS::~OutHDS() {}
void OutHDS::init(Util::Config * cfg){ void OutHDS::init(Util::Config * cfg){
Output::init(cfg);
capa["desc"] = "Enables HTTP protocol Adobe-specific dynamic streaming (also known as HDS)."; capa["desc"] = "Enables HTTP protocol Adobe-specific dynamic streaming (also known as HDS).";
capa["deps"] = "HTTP"; capa["deps"] = "HTTP";
capa["url_rel"] = "/dynamic/$/manifest.f4m"; capa["url_rel"] = "/dynamic/$/manifest.f4m";

View file

@ -87,6 +87,7 @@ namespace Mist {
} }
void OutHLS::init(Util::Config * cfg){ void OutHLS::init(Util::Config * cfg){
Output::init(cfg);
capa["name"] = "HTTP_Live"; capa["name"] = "HTTP_Live";
capa["desc"] = "Enables HTTP protocol Apple-specific streaming (also known as HLS)."; capa["desc"] = "Enables HTTP protocol Apple-specific streaming (also known as HLS).";
capa["deps"] = "HTTP"; capa["deps"] = "HTTP";

View file

@ -49,6 +49,7 @@ namespace Mist {
OutHSS::~OutHSS() {} OutHSS::~OutHSS() {}
void OutHSS::init(Util::Config * cfg) { void OutHSS::init(Util::Config * cfg) {
Output::init(cfg);
capa["name"] = "HTTP_Smooth"; capa["name"] = "HTTP_Smooth";
capa["desc"] = "Enables HTTP protocol Microsoft-specific smooth streaming through silverlight (also known as HSS)."; capa["desc"] = "Enables HTTP protocol Microsoft-specific smooth streaming through silverlight (also known as HSS).";
capa["deps"] = "HTTP"; capa["deps"] = "HTTP";

View file

@ -11,6 +11,7 @@ namespace Mist {
OutJSON::~OutJSON() {} OutJSON::~OutJSON() {}
void OutJSON::init(Util::Config * cfg){ void OutJSON::init(Util::Config * cfg){
Output::init(cfg);
capa["desc"] = "Enables HTTP protocol JSON streaming."; capa["desc"] = "Enables HTTP protocol JSON streaming.";
capa["deps"] = "HTTP"; capa["deps"] = "HTTP";
capa["url_rel"] = "/$.json"; capa["url_rel"] = "/$.json";

View file

@ -8,6 +8,7 @@ namespace Mist {
OutProgressiveFLV::~OutProgressiveFLV() {} OutProgressiveFLV::~OutProgressiveFLV() {}
void OutProgressiveFLV::init(Util::Config * cfg){ void OutProgressiveFLV::init(Util::Config * cfg){
Output::init(cfg);
capa["name"] = "HTTP_Progressive_FLV"; capa["name"] = "HTTP_Progressive_FLV";
capa["desc"] = "Enables HTTP protocol progressive streaming."; capa["desc"] = "Enables HTTP protocol progressive streaming.";
capa["deps"] = "HTTP"; capa["deps"] = "HTTP";

View file

@ -8,6 +8,7 @@ namespace Mist {
OutProgressiveMP3::~OutProgressiveMP3() {} OutProgressiveMP3::~OutProgressiveMP3() {}
void OutProgressiveMP3::init(Util::Config * cfg){ void OutProgressiveMP3::init(Util::Config * cfg){
Output::init(cfg);
capa["name"] = "HTTP_Progressive_MP3"; capa["name"] = "HTTP_Progressive_MP3";
capa["desc"] = "Enables HTTP protocol progressive streaming."; capa["desc"] = "Enables HTTP protocol progressive streaming.";
capa["deps"] = "HTTP"; capa["deps"] = "HTTP";

View file

@ -9,6 +9,7 @@ namespace Mist {
OutProgressiveMP4::~OutProgressiveMP4() {} OutProgressiveMP4::~OutProgressiveMP4() {}
void OutProgressiveMP4::init(Util::Config * cfg){ void OutProgressiveMP4::init(Util::Config * cfg){
Output::init(cfg);
capa["name"] = "HTTP_Progressive_MP4"; capa["name"] = "HTTP_Progressive_MP4";
capa["desc"] = "Enables HTTP protocol progressive streaming."; capa["desc"] = "Enables HTTP protocol progressive streaming.";
capa["deps"] = "HTTP"; capa["deps"] = "HTTP";

View file

@ -30,6 +30,7 @@ namespace Mist {
OutRaw::~OutRaw() {} OutRaw::~OutRaw() {}
void OutRaw::init(Util::Config * cfg){ void OutRaw::init(Util::Config * cfg){
Output::init(cfg);
capa["name"] = "RAW"; capa["name"] = "RAW";
capa["desc"] = "Enables raw DTSC over TCP."; capa["desc"] = "Enables raw DTSC over TCP.";
capa["deps"] = ""; capa["deps"] = "";

View file

@ -39,6 +39,7 @@ namespace Mist {
OutRTMP::~OutRTMP() {} OutRTMP::~OutRTMP() {}
void OutRTMP::init(Util::Config * cfg) { void OutRTMP::init(Util::Config * cfg) {
Output::init(cfg);
capa["name"] = "RTMP"; capa["name"] = "RTMP";
capa["desc"] = "Enables the RTMP protocol which is used by Adobe Flash Player."; capa["desc"] = "Enables the RTMP protocol which is used by Adobe Flash Player.";
capa["deps"] = ""; capa["deps"] = "";

View file

@ -19,6 +19,7 @@ namespace Mist {
OutProgressiveSRT::~OutProgressiveSRT() {} OutProgressiveSRT::~OutProgressiveSRT() {}
void OutProgressiveSRT::init(Util::Config * cfg){ void OutProgressiveSRT::init(Util::Config * cfg){
Output::init(cfg);
capa["desc"] = "Enables HTTP protocol subtitle streaming."; capa["desc"] = "Enables HTTP protocol subtitle streaming.";
capa["deps"] = "HTTP"; capa["deps"] = "HTTP";
capa["url_rel"] = "/$.srt"; capa["url_rel"] = "/$.srt";

View file

@ -34,6 +34,7 @@ namespace Mist {
OutTS::~OutTS() {} OutTS::~OutTS() {}
void OutTS::init(Util::Config * cfg){ void OutTS::init(Util::Config * cfg){
Output::init(cfg);
capa["name"] = "TS"; capa["name"] = "TS";
capa["desc"] = "Enables the raw MPEG Transport Stream protocol over TCP."; capa["desc"] = "Enables the raw MPEG Transport Stream protocol over TCP.";
capa["deps"] = ""; capa["deps"] = "";