Moved inputBuffer::fillBufferDetails to DTSC::Meta::getHealthJSON

This commit is contained in:
Thulinma 2021-07-26 16:31:52 +02:00
parent 1f390561c2
commit 7d95a75492
3 changed files with 89 additions and 83 deletions

View file

@ -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");

View file

@ -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);

View file

@ -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);