From c3a09f5fe2e7ad6127d3cf63a9d0e9520368f4a4 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Wed, 9 Feb 2022 16:50:24 +0100 Subject: [PATCH] Fix RTMP push delay, specifically --- src/output/output.cpp | 24 +++++++++++++++++------- src/output/output_rtmp.cpp | 4 ++-- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/output/output.cpp b/src/output/output.cpp index 03d6bb74..c3a37230 100644 --- a/src/output/output.cpp +++ b/src/output/output.cpp @@ -1020,10 +1020,24 @@ namespace Mist{ } }else{ if (M.getLive() && targetParams.count("pushdelay")){ - INFO_MSG("Converting pushdelay syntax into corresponding startunix+realtime options"); - targetParams["startunix"] = std::string("-") + targetParams["pushdelay"]; + INFO_MSG("Converting pushdelay syntax into corresponding recstart+realtime options"); + + uint64_t delayTime = JSON::Value(targetParams["pushdelay"]).asInt()*1000; + if (endTime() - startTime() < delayTime){ + uint64_t waitTime = delayTime - (endTime() - startTime()); + INFO_MSG("Waiting for buffer to fill up: waiting %" PRIu64 "ms", waitTime); + Util::wait(waitTime); + if (endTime() - startTime() < delayTime){ + WARN_MSG("Waited for %" PRIu64 "ms, but buffer still too small for a push delay of %" PRIu64 "ms. Doing the best we can.", waitTime, delayTime); + } + } + if (endTime() < delayTime){ + INFO_MSG("Waiting for stream to reach playback starting point. Current last ms is '%" PRIu64 "'", endTime()); + while (endTime() < delayTime && keepGoing()){Util::wait(250);} + } + targetParams["start"] = JSON::Value(endTime() - delayTime).asString(); targetParams["realtime"] = "1"; //force real-time speed - targetParams["noskip"] = "1"; //disable rate control / skipping forward + maxSkipAhead = 1; } if (M.getLive() && (targetParams.count("startunix") || targetParams.count("stopunix"))){ uint64_t unixStreamBegin = Util::epoch() - endTime()/1000; @@ -1313,10 +1327,6 @@ namespace Mist{ if (!targetParams.count("realtime")){ realTime = 0; } - if (targetParams.count("noskip")){ - //Disable rate control systems for pushes; we want real-time speed - maxSkipAhead = 1; - } } // Handle CONN_OPEN trigger, if needed if (Triggers::shouldTrigger("CONN_OPEN", streamName)){ diff --git a/src/output/output_rtmp.cpp b/src/output/output_rtmp.cpp index 0c9efcdc..09572c68 100644 --- a/src/output/output_rtmp.cpp +++ b/src/output/output_rtmp.cpp @@ -21,6 +21,8 @@ namespace Mist{ rtmpOffset = 0; authAttempts = 0; maxbps = config->getInteger("maxkbps") * 128; + //Switch realtime tracking system to mode where it never skips ahead, but only changes playback speed + maxSkipAhead = 0; if (config->getString("target").size()){ streamName = config->getString("streamname"); pushUrl = HTTP::URL(config->getString("target")); @@ -72,8 +74,6 @@ namespace Mist{ } setBlocking(false); } - - maxSkipAhead = 0; } void OutRTMP::startPushOut(const char *args){