Added H264 baseline 3.0 checks. Stream configurations are now robust and will no longer accept nonsense values.
This commit is contained in:
parent
3dfa133f7f
commit
becd0341ac
1 changed files with 60 additions and 7 deletions
|
@ -17,7 +17,10 @@ namespace Controller {
|
||||||
///\param two The second stream for the comparison.
|
///\param two The second stream for the comparison.
|
||||||
///\return True if the streams are equal, false otherwise.
|
///\return True if the streams are equal, false otherwise.
|
||||||
bool streamsEqual(JSON::Value & one, JSON::Value & two){
|
bool streamsEqual(JSON::Value & one, JSON::Value & two){
|
||||||
if ( !one.isMember("source") || !two.isMember("source") || one["source"] != two["source"]){
|
if (one.isMember("source") != two.isMember("source") || one["source"] != two["source"]){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (one.isMember("DVR") != two.isMember("DVR") || one["DVR"] != two["DVR"]){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -54,6 +57,7 @@ namespace Controller {
|
||||||
Log("BUFF", "(re)starting stream buffer " + name + " for push data from " + pusher);
|
Log("BUFF", "(re)starting stream buffer " + name + " for push data from " + pusher);
|
||||||
}else{
|
}else{
|
||||||
if (URL.substr(0, 1) == "/"){
|
if (URL.substr(0, 1) == "/"){
|
||||||
|
data.removeMember("error");
|
||||||
struct stat fileinfo;
|
struct stat fileinfo;
|
||||||
if (stat(URL.c_str(), &fileinfo) != 0 || S_ISDIR(fileinfo.st_mode)){
|
if (stat(URL.c_str(), &fileinfo) != 0 || S_ISDIR(fileinfo.st_mode)){
|
||||||
Log("BUFF", "Warning for VoD stream " + name + "! File not found: " + URL);
|
Log("BUFF", "Warning for VoD stream " + name + "! File not found: " + URL);
|
||||||
|
@ -61,7 +65,38 @@ namespace Controller {
|
||||||
data["online"] = 0;
|
data["online"] = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( !data.isMember("meta") || !data["meta"].isMember("tracks")){
|
bool getMeta = false;
|
||||||
|
if ( !data.isMember("l_meta") || fileinfo.st_mtime != data["l_meta"].asInt()){
|
||||||
|
getMeta = true;
|
||||||
|
data["l_meta"] = (long long)fileinfo.st_mtime;
|
||||||
|
}
|
||||||
|
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"] = "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)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
getMeta = true;
|
||||||
|
}
|
||||||
|
if (getMeta){
|
||||||
char * tmp_cmd[3] = {0, 0, 0};
|
char * tmp_cmd[3] = {0, 0, 0};
|
||||||
std::string mistinfo = Util::getMyPath() + "MistInfo";
|
std::string mistinfo = Util::getMyPath() + "MistInfo";
|
||||||
tmp_cmd[0] = (char*)mistinfo.c_str();
|
tmp_cmd[0] = (char*)mistinfo.c_str();
|
||||||
|
@ -77,11 +112,12 @@ namespace Controller {
|
||||||
data.removeMember("meta");
|
data.removeMember("meta");
|
||||||
}
|
}
|
||||||
if (Util::epoch() - lastBuffer[name] > 5){
|
if (Util::epoch() - lastBuffer[name] > 5){
|
||||||
|
if ( !data.isMember("error")){
|
||||||
data["error"] = "Available";
|
data["error"] = "Available";
|
||||||
|
}
|
||||||
data["online"] = 2;
|
data["online"] = 2;
|
||||||
}else{
|
}else{
|
||||||
data["online"] = 1;
|
data["online"] = 1;
|
||||||
data.removeMember("error");
|
|
||||||
}
|
}
|
||||||
return; //MistPlayer handles VoD
|
return; //MistPlayer handles VoD
|
||||||
}else{
|
}else{
|
||||||
|
@ -112,6 +148,9 @@ namespace Controller {
|
||||||
if ( !Util::Procs::isActive(jit->first)){
|
if ( !Util::Procs::isActive(jit->first)){
|
||||||
startStream(jit->first, jit->second);
|
startStream(jit->first, jit->second);
|
||||||
}
|
}
|
||||||
|
if (!jit->second.isMember("name")){
|
||||||
|
jit->second["name"] = jit->first;
|
||||||
|
}
|
||||||
if (currTime - lastBuffer[jit->first] > 5){
|
if (currTime - lastBuffer[jit->first] > 5){
|
||||||
if (jit->second.isMember("source") && jit->second["source"].asString().substr(0, 1) == "/" && jit->second.isMember("error")
|
if (jit->second.isMember("source") && jit->second["source"].asString().substr(0, 1) == "/" && jit->second.isMember("error")
|
||||||
&& jit->second["error"].asString() == "Available"){
|
&& jit->second["error"].asString() == "Available"){
|
||||||
|
@ -171,23 +210,38 @@ namespace Controller {
|
||||||
for (JSON::ObjIter jit = in.ObjBegin(); jit != in.ObjEnd(); jit++){
|
for (JSON::ObjIter jit = in.ObjBegin(); jit != in.ObjEnd(); jit++){
|
||||||
if (out.isMember(jit->first)){
|
if (out.isMember(jit->first)){
|
||||||
if ( !streamsEqual(jit->second, out[jit->first])){
|
if ( !streamsEqual(jit->second, out[jit->first])){
|
||||||
|
out[jit->first].null();
|
||||||
|
out[jit->first]["name"] = jit->first;
|
||||||
|
out[jit->first]["source"] = jit->second["source"];
|
||||||
|
out[jit->first]["DVR"] = jit->second["DVR"];
|
||||||
Log("STRM", std::string("Updated stream ") + jit->first);
|
Log("STRM", std::string("Updated stream ") + jit->first);
|
||||||
Util::Procs::Stop(jit->first);
|
Util::Procs::Stop(jit->first);
|
||||||
startStream(jit->first, jit->second);
|
startStream(jit->first, out[jit->first]);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
out[jit->first]["name"] = jit->first;
|
||||||
|
out[jit->first]["source"] = jit->second["source"];
|
||||||
|
out[jit->first]["DVR"] = jit->second["DVR"];
|
||||||
Log("STRM", std::string("New stream ") + jit->first);
|
Log("STRM", std::string("New stream ") + jit->first);
|
||||||
startStream(jit->first, jit->second);
|
startStream(jit->first, out[jit->first]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//check for deleted streams
|
//check for deleted streams
|
||||||
|
std::set<std::string> toDelete;
|
||||||
for (JSON::ObjIter jit = out.ObjBegin(); jit != out.ObjEnd(); jit++){
|
for (JSON::ObjIter jit = out.ObjBegin(); jit != out.ObjEnd(); jit++){
|
||||||
if ( !in.isMember(jit->first)){
|
if ( !in.isMember(jit->first)){
|
||||||
|
toDelete.insert(jit->first);
|
||||||
Log("STRM", std::string("Deleted stream ") + jit->first);
|
Log("STRM", std::string("Deleted stream ") + jit->first);
|
||||||
Util::Procs::Stop(jit->first);
|
Util::Procs::Stop(jit->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//actually delete the streams
|
||||||
|
while (toDelete.size() > 0){
|
||||||
|
std::string deleting = *(toDelete.begin());
|
||||||
|
out.removeMember(deleting);
|
||||||
|
toDelete.erase(deleting);
|
||||||
|
}
|
||||||
|
|
||||||
//update old-style configurations to new-style
|
//update old-style configurations to new-style
|
||||||
for (JSON::ObjIter jit = in.ObjBegin(); jit != in.ObjEnd(); jit++){
|
for (JSON::ObjIter jit = in.ObjBegin(); jit != in.ObjEnd(); jit++){
|
||||||
|
@ -202,7 +256,6 @@ namespace Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out = in;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} //Controller namespace
|
} //Controller namespace
|
||||||
|
|
Loading…
Add table
Reference in a new issue