diff --git a/src/input/input_buffer.cpp b/src/input/input_buffer.cpp index 1345959c..4fac8a85 100644 --- a/src/input/input_buffer.cpp +++ b/src/input/input_buffer.cpp @@ -17,6 +17,11 @@ #define TIMEOUTMULTIPLIER 2 #endif +/*LTS-START*/ +//We consider a stream playable when this many fragments are available. +#define FRAG_BOOT 3 +/*LTS-END*/ + namespace Mist { inputBuffer::inputBuffer(Util::Config * cfg) : Input(cfg){ capa["name"] = "Buffer"; @@ -137,7 +142,7 @@ namespace Mist { config->is_active = false; if (myMeta.tracks.size()){ /*LTS-START*/ - if (myMeta.bufferWindow >= bufferTime /2){ + if (myMeta.bufferWindow){ if(Triggers::shouldTrigger("STREAM_BUFFER")){ std::string payload = config->getString("streamname")+"\nEMPTY"; Triggers::doTrigger("STREAM_BUFFER", payload, config->getString("streamname")); @@ -176,14 +181,16 @@ namespace Mist { } /// \triggers - /// The `"STREAM_BUFFER"` trigger is stream-specific, and is ran whenever the buffer changes state between mostly full or mostly emptu. It cannot be cancelled. Its payload is: + /// The `"STREAM_BUFFER"` trigger is stream-specific, and is ran whenever the buffer changes state between playable (FULL) or not (EMPTY). It cannot be cancelled. It is possible to receive multiple EMPTY calls without FULL calls in between, as EMPTY is always generated when a stream is unloaded from memory, even if this stream never reached playable state in the first place (e.g. a broadcast was cancelled before filling enough buffer to be playable). Its payload is: /// ~~~~~~~~~~~~~~~ /// streamname /// FULL or EMPTY (depending on current state) /// ~~~~~~~~~~~~~~~ void inputBuffer::updateMeta(){ + static long long unsigned int lastFragCount = 0xFFFFull; long long unsigned int firstms = 0xFFFFFFFFFFFFFFFFull; long long unsigned int lastms = 0; + long long unsigned int fragCount = 0xFFFFull; for (std::map::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++){ if (it->second.type == "meta" || !it->second.type.size()){continue;} if (it->second.init.size()){ @@ -195,6 +202,9 @@ namespace Mist { it->second.init = initData[it->first]; } } + if (it->second.fragments.size() < fragCount){ + fragCount = it->second.fragments.size(); + } if (it->second.firstms < firstms){ firstms = it->second.firstms; } @@ -203,18 +213,19 @@ namespace Mist { } } /*LTS-START*/ - if (myMeta.bufferWindow < bufferTime /2 && (lastms - firstms) >= bufferTime/2){ + if (fragCount >= FRAG_BOOT && fragCount != 0xFFFFull && (lastFragCount == 0xFFFFull || lastFragCount < FRAG_BOOT)){ if(Triggers::shouldTrigger("STREAM_BUFFER")){ std::string payload = config->getString("streamname")+"\nFULL"; Triggers::doTrigger("STREAM_BUFFER", payload, config->getString("streamname")); } } - if (myMeta.bufferWindow >= bufferTime /2 && (lastms - firstms) < bufferTime/2){ + if ((fragCount < FRAG_BOOT || fragCount == 0xFFFFull) && (lastFragCount >= FRAG_BOOT && lastFragCount != 0xFFFFull)){ if(Triggers::shouldTrigger("STREAM_BUFFER")){ std::string payload = config->getString("streamname")+"\nEMPTY"; Triggers::doTrigger("STREAM_BUFFER", payload, config->getString("streamname")); } } + lastFragCount = fragCount; /*LTS-END*/ myMeta.bufferWindow = lastms - firstms; myMeta.vod = false; diff --git a/src/output/output_hls.cpp b/src/output/output_hls.cpp index af4e2c15..2e452b56 100644 --- a/src/output/output_hls.cpp +++ b/src/output/output_hls.cpp @@ -164,14 +164,13 @@ namespace Mist { snprintf(lineBuf, 400, "#EXTINF:%lld, no desc\r\n%lld_%lld,ts\r\n", ((duration + 500) / 1000), starttime, starttime + duration); lines.push_back(lineBuf); } - //skip the first fragment if live and there are more than 2 fragments. unsigned int skippedLines = 0; if (myMeta.live) { //only print the last segment when VoD lines.pop_back(); /*LTS-START*/ - unsigned int skip = ((myMeta.tracks[tid].fragments.size() - 1) * config->getInteger("startpos")) / 1000u; - while (skippedLines < skip && lines.size()) { + unsigned int skip = (( myMeta.tracks[tid].fragments.size()-1) * config->getInteger("startpos")) / 1000u; + while (skippedLines < skip && lines.size() >= 3){ lines.pop_front(); skippedLines++; } @@ -297,16 +296,15 @@ namespace Mist { if (!myMeta.tracks.size()) { return 1; } - //loop trough all the tracks - for (std::map::iterator it = myMeta.tracks.begin(); it != myMeta.tracks.end(); it++) { - //return "too late" if one track is past this point - if (ms < it->second.firstms) { - return -1; - } - //return "too early" if one track is not yet at this point - if (ms > it->second.lastms) { - return 1; - } + //check main track + DTSC::Track & mainTrack = myMeta.tracks[*selectedTracks.begin()]; + //return "too late" if one track is past this point + if (ms < mainTrack.firstms){ + return -1; + } + //return "too early" if one track is not yet at this point + if (ms > mainTrack.lastms){ + return 1; } return 0; }