Moved inputBuffer::fillBufferDetails to DTSC::Meta::getHealthJSON
This commit is contained in:
parent
1f390561c2
commit
7d95a75492
3 changed files with 89 additions and 83 deletions
86
lib/dtsc.cpp
86
lib/dtsc.cpp
|
@ -3192,6 +3192,92 @@ namespace DTSC{
|
|||
return res;
|
||||
}
|
||||
|
||||
/// By reference, returns a JSON object with health information on the stream
|
||||
void Meta::getHealthJSON(JSON::Value &retRef) const{
|
||||
// clear the reference of old data, first
|
||||
retRef.null();
|
||||
bool hasH264 = false;
|
||||
bool hasAAC = false;
|
||||
std::stringstream issues;
|
||||
std::set<size_t> validTracks = getValidTracks();
|
||||
uint64_t jitter = 0;
|
||||
uint64_t buffer = 0;
|
||||
for (std::set<size_t>::iterator it = validTracks.begin(); it != validTracks.end(); it++){
|
||||
size_t i = *it;
|
||||
JSON::Value &track = retRef[getTrackIdentifier(i)];
|
||||
uint64_t minKeep = getMinKeepAway(*it);
|
||||
track["jitter"] = minKeep;
|
||||
if (jitter < minKeep){jitter = minKeep;}
|
||||
std::string codec = getCodec(i);
|
||||
std::string type = getType(i);
|
||||
track["kbits"] = getBps(i) * 8 / 1024;
|
||||
track["codec"] = codec;
|
||||
uint32_t shrtest_key = 0xFFFFFFFFul;
|
||||
uint32_t longest_key = 0;
|
||||
uint32_t shrtest_prt = 0xFFFFFFFFul;
|
||||
uint32_t longest_prt = 0;
|
||||
uint32_t shrtest_cnt = 0xFFFFFFFFul;
|
||||
uint32_t longest_cnt = 0;
|
||||
DTSC::Keys Mkeys(keys(i));
|
||||
uint32_t firstKey = Mkeys.getFirstValid();
|
||||
uint32_t endKey = Mkeys.getEndValid() - 1;
|
||||
for (int k = firstKey; k < endKey; k++){
|
||||
uint64_t kDur = Mkeys.getDuration(k);
|
||||
uint64_t kParts = Mkeys.getParts(k);
|
||||
if (!kDur){continue;}
|
||||
if (kDur > longest_key){longest_key = kDur;}
|
||||
if (kDur < shrtest_key){shrtest_key = kDur;}
|
||||
if (kParts > longest_cnt){longest_cnt = kParts;}
|
||||
if (kParts < shrtest_cnt){shrtest_cnt = kParts;}
|
||||
if ((kDur / kParts) > longest_prt){longest_prt = (kDur / kParts);}
|
||||
if ((kDur / kParts) < shrtest_prt){shrtest_prt = (kDur / kParts);}
|
||||
}
|
||||
track["keys"]["ms_min"] = shrtest_key;
|
||||
track["keys"]["ms_max"] = longest_key;
|
||||
track["keys"]["frame_ms_min"] = shrtest_prt;
|
||||
track["keys"]["frame_ms_max"] = longest_prt;
|
||||
track["keys"]["frames_min"] = shrtest_cnt;
|
||||
track["keys"]["frames_max"] = longest_cnt;
|
||||
uint64_t trBuffer = getLastms(i) - getFirstms(i);
|
||||
track["buffer"] = trBuffer;
|
||||
if (buffer < trBuffer){buffer = trBuffer;}
|
||||
if (longest_prt > 500){
|
||||
issues << "unstable connection (" << longest_prt << "ms " << codec << " frame)! ";
|
||||
}
|
||||
if (shrtest_cnt < 6){
|
||||
issues << "unstable connection (" << shrtest_cnt << " " << codec << " frame(s) in key)! ";
|
||||
}
|
||||
if (longest_key > shrtest_key*1.30){
|
||||
issues << "unstable key interval (" << (uint32_t)(((longest_key/shrtest_key)-1)*100) << "% " << codec << " variance)! ";
|
||||
}
|
||||
if (codec == "AAC"){hasAAC = true;}
|
||||
if (codec == "H264"){hasH264 = true;}
|
||||
if (type == "video"){
|
||||
track["width"] = getWidth(i);
|
||||
track["height"] = getHeight(i);
|
||||
track["fpks"] = getFpks(i);
|
||||
track["bframes"] = hasBFrames(i);
|
||||
}
|
||||
if (type == "audio"){
|
||||
track["rate"] = getRate(i);
|
||||
track["channels"] = getChannels(i);
|
||||
}
|
||||
}
|
||||
if (jitter > 500){
|
||||
issues << "High jitter (" << jitter << "ms)! ";
|
||||
}
|
||||
retRef["jitter"] = jitter;
|
||||
retRef["buffer"] = buffer;
|
||||
if (getMaxKeepAway()){
|
||||
retRef["maxkeepaway"] = getMaxKeepAway();
|
||||
}
|
||||
if ((hasAAC || hasH264) && validTracks.size() > 1){
|
||||
if (!hasAAC){issues << "HLS no audio!";}
|
||||
if (!hasH264){issues << "HLS no video!";}
|
||||
}
|
||||
if (issues.str().size()){retRef["issues"] = issues.str();}
|
||||
// return is by reference
|
||||
}
|
||||
|
||||
Parts::Parts(const Util::RelAccX &_parts) : parts(_parts){
|
||||
sizeField = parts.getFieldData("size");
|
||||
|
|
|
@ -467,6 +467,8 @@ namespace DTSC{
|
|||
|
||||
uint8_t version;
|
||||
|
||||
void getHealthJSON(JSON::Value & returnReference) const;
|
||||
|
||||
protected:
|
||||
void sBufMem(size_t trackCount = DEFAULT_TRACK_COUNT);
|
||||
void sBufShm(const std::string &_streamName, size_t trackCount = DEFAULT_TRACK_COUNT, bool master = true);
|
||||
|
|
|
@ -170,88 +170,6 @@ namespace Mist{
|
|||
}
|
||||
}
|
||||
|
||||
/// Fills the details variable with details about the current buffer contents
|
||||
void inputBuffer::fillBufferDetails(JSON::Value &details) const{
|
||||
// clear the reference of old data, first
|
||||
details.null();
|
||||
bool hasH264 = false;
|
||||
bool hasAAC = false;
|
||||
std::stringstream issues;
|
||||
std::set<size_t> validTracks = M.getValidTracks();
|
||||
uint64_t jitter = 0;
|
||||
for (std::set<size_t>::iterator it = validTracks.begin(); it != validTracks.end(); it++){
|
||||
size_t i = *it;
|
||||
JSON::Value &track = details[M.getTrackIdentifier(i)];
|
||||
uint64_t minKeep = M.getMinKeepAway(*it);
|
||||
track["jitter"] = minKeep;
|
||||
if (jitter < minKeep){jitter = minKeep;}
|
||||
std::string codec = M.getCodec(i);
|
||||
std::string type = M.getType(i);
|
||||
track["kbits"] = M.getBps(i) * 8 / 1024;
|
||||
track["codec"] = codec;
|
||||
uint32_t shrtest_key = 0xFFFFFFFFul;
|
||||
uint32_t longest_key = 0;
|
||||
uint32_t shrtest_prt = 0xFFFFFFFFul;
|
||||
uint32_t longest_prt = 0;
|
||||
uint32_t shrtest_cnt = 0xFFFFFFFFul;
|
||||
uint32_t longest_cnt = 0;
|
||||
DTSC::Keys keys(M.keys(i));
|
||||
uint32_t firstKey = keys.getFirstValid();
|
||||
uint32_t endKey = keys.getEndValid() - 1;
|
||||
for (int k = firstKey; k < endKey; k++){
|
||||
uint64_t kDur = keys.getDuration(k);
|
||||
uint64_t kParts = keys.getParts(k);
|
||||
if (!kDur){continue;}
|
||||
if (kDur > longest_key){longest_key = kDur;}
|
||||
if (kDur < shrtest_key){shrtest_key = kDur;}
|
||||
if (kParts > longest_cnt){longest_cnt = kParts;}
|
||||
if (kParts < shrtest_cnt){shrtest_cnt = kParts;}
|
||||
if ((kDur / kParts) > longest_prt){longest_prt = (kDur / kParts);}
|
||||
if ((kDur / kParts) < shrtest_prt){shrtest_prt = (kDur / kParts);}
|
||||
}
|
||||
track["keys"]["ms_min"] = shrtest_key;
|
||||
track["keys"]["ms_max"] = longest_key;
|
||||
track["keys"]["frame_ms_min"] = shrtest_prt;
|
||||
track["keys"]["frame_ms_max"] = longest_prt;
|
||||
track["keys"]["frames_min"] = shrtest_cnt;
|
||||
track["keys"]["frames_max"] = longest_cnt;
|
||||
if (longest_prt > 500){
|
||||
issues << "unstable connection (" << longest_prt << "ms " << codec << " frame)! ";
|
||||
}
|
||||
if (shrtest_cnt < 6){
|
||||
issues << "unstable connection (" << shrtest_cnt << " " << codec << " frame(s) in key)! ";
|
||||
}
|
||||
if (longest_key > shrtest_key*1.30){
|
||||
issues << "unstable key interval (" << (uint32_t)(((longest_key/shrtest_key)-1)*100) << "% " << codec << " variance)! ";
|
||||
}
|
||||
if (codec == "AAC"){hasAAC = true;}
|
||||
if (codec == "H264"){hasH264 = true;}
|
||||
if (type == "video"){
|
||||
track["width"] = M.getWidth(i);
|
||||
track["height"] = M.getHeight(i);
|
||||
track["fpks"] = M.getFpks(i);
|
||||
track["bframes"] = M.hasBFrames(i);
|
||||
}
|
||||
if (type == "audio"){
|
||||
track["rate"] = M.getRate(i);
|
||||
track["channels"] = M.getChannels(i);
|
||||
}
|
||||
}
|
||||
if (jitter > 500){
|
||||
issues << "High jitter (" << jitter << "ms)! ";
|
||||
}
|
||||
details["jitter"] = jitter;
|
||||
if (M.getMaxKeepAway()){
|
||||
details["maxkeepaway"] = M.getMaxKeepAway();
|
||||
}
|
||||
if ((hasAAC || hasH264) && validTracks.size() > 1){
|
||||
if (!hasAAC){issues << "HLS no audio!";}
|
||||
if (!hasH264){issues << "HLS no video!";}
|
||||
}
|
||||
if (issues.str().size()){details["issues"] = issues.str();}
|
||||
// return is by reference
|
||||
}
|
||||
|
||||
/*LTS-START*/
|
||||
static bool liveBW(const char *param, const void *bwPtr){
|
||||
if (!param || !bwPtr){return false;}
|
||||
|
@ -312,7 +230,7 @@ namespace Mist{
|
|||
}
|
||||
if (fragCount >= FRAG_BOOT && fragCount != 0xFFFFull && Triggers::shouldTrigger("STREAM_BUFFER", streamName)){
|
||||
JSON::Value stream_details;
|
||||
fillBufferDetails(stream_details);
|
||||
M.getHealthJSON(stream_details);
|
||||
if (lastFragCount == 0xFFFFull){
|
||||
std::string payload = streamName + "\nFULL\n" + stream_details.toString();
|
||||
Triggers::doTrigger("STREAM_BUFFER", payload, streamName);
|
||||
|
|
Loading…
Add table
Reference in a new issue