Added H264 baseline 3.0 checks. Stream configurations are now robust and will no longer accept nonsense values.

This commit is contained in:
Thulinma 2013-10-29 16:55:03 +01:00
parent 3dfa133f7f
commit becd0341ac

View file

@ -17,7 +17,10 @@ namespace Controller {
///\param two The second stream for the comparison.
///\return True if the streams are equal, false otherwise.
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 true;
@ -54,6 +57,7 @@ namespace Controller {
Log("BUFF", "(re)starting stream buffer " + name + " for push data from " + pusher);
}else{
if (URL.substr(0, 1) == "/"){
data.removeMember("error");
struct stat fileinfo;
if (stat(URL.c_str(), &fileinfo) != 0 || S_ISDIR(fileinfo.st_mode)){
Log("BUFF", "Warning for VoD stream " + name + "! File not found: " + URL);
@ -61,7 +65,38 @@ namespace Controller {
data["online"] = 0;
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};
std::string mistinfo = Util::getMyPath() + "MistInfo";
tmp_cmd[0] = (char*)mistinfo.c_str();
@ -77,11 +112,12 @@ namespace Controller {
data.removeMember("meta");
}
if (Util::epoch() - lastBuffer[name] > 5){
if ( !data.isMember("error")){
data["error"] = "Available";
}
data["online"] = 2;
}else{
data["online"] = 1;
data.removeMember("error");
}
return; //MistPlayer handles VoD
}else{
@ -112,6 +148,9 @@ namespace Controller {
if ( !Util::Procs::isActive(jit->first)){
startStream(jit->first, jit->second);
}
if (!jit->second.isMember("name")){
jit->second["name"] = jit->first;
}
if (currTime - lastBuffer[jit->first] > 5){
if (jit->second.isMember("source") && jit->second["source"].asString().substr(0, 1) == "/" && jit->second.isMember("error")
&& jit->second["error"].asString() == "Available"){
@ -171,23 +210,38 @@ namespace Controller {
for (JSON::ObjIter jit = in.ObjBegin(); jit != in.ObjEnd(); jit++){
if (out.isMember(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);
Util::Procs::Stop(jit->first);
startStream(jit->first, jit->second);
startStream(jit->first, out[jit->first]);
}
}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);
startStream(jit->first, jit->second);
startStream(jit->first, out[jit->first]);
}
}
//check for deleted streams
std::set<std::string> toDelete;
for (JSON::ObjIter jit = out.ObjBegin(); jit != out.ObjEnd(); jit++){
if ( !in.isMember(jit->first)){
toDelete.insert(jit->first);
Log("STRM", std::string("Deleted stream ") + 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
for (JSON::ObjIter jit = in.ObjBegin(); jit != in.ObjEnd(); jit++){
@ -202,7 +256,6 @@ namespace Controller {
}
}
out = in;
}
} //Controller namespace