Frame limiter v2 - better frame pacing
This commit is contained in:
+15
-8
@@ -1902,10 +1902,6 @@ namespace video {
|
|||||||
// set minimum frame time, avoiding violation of client-requested target framerate
|
// set minimum frame time, avoiding violation of client-requested target framerate
|
||||||
auto minimum_frame_time = std::chrono::milliseconds(1000 / std::min(config.framerate, (config::video.min_fps_factor * 10)));
|
auto minimum_frame_time = std::chrono::milliseconds(1000 / std::min(config.framerate, (config::video.min_fps_factor * 10)));
|
||||||
auto frame_threshold = std::chrono::milliseconds(1000 / config.encodingFramerate);
|
auto frame_threshold = std::chrono::milliseconds(1000 / config.encodingFramerate);
|
||||||
// Leave 1ms headroom for slight variations
|
|
||||||
if (frame_threshold >= 2ms) {
|
|
||||||
frame_threshold -= 1ms;
|
|
||||||
}
|
|
||||||
BOOST_LOG(debug) << "Minimum frame time set to "sv << minimum_frame_time.count() << "ms, based on min fps factor of "sv << config::video.min_fps_factor << "."sv;
|
BOOST_LOG(debug) << "Minimum frame time set to "sv << minimum_frame_time.count() << "ms, based on min fps factor of "sv << config::video.min_fps_factor << "."sv;
|
||||||
BOOST_LOG(info) << "Frame threshold: "sv << frame_threshold;
|
BOOST_LOG(info) << "Frame threshold: "sv << frame_threshold;
|
||||||
|
|
||||||
@@ -1939,7 +1935,7 @@ namespace video {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point last_frame_timestamp;
|
std::chrono::steady_clock::time_point next_frame_start;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// Break out of the encoding loop if any of the following are true:
|
// Break out of the encoding loop if any of the following are true:
|
||||||
@@ -1977,7 +1973,7 @@ namespace video {
|
|||||||
if (auto img = images->pop(minimum_frame_time)) {
|
if (auto img = images->pop(minimum_frame_time)) {
|
||||||
frame_timestamp = img->frame_timestamp;
|
frame_timestamp = img->frame_timestamp;
|
||||||
// If new frame comes in way too fast, just drop
|
// If new frame comes in way too fast, just drop
|
||||||
if (*frame_timestamp - last_frame_timestamp < frame_threshold) {
|
if (*frame_timestamp < next_frame_start) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (session->convert(*img)) {
|
if (session->convert(*img)) {
|
||||||
@@ -1989,13 +1985,24 @@ namespace video {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frame_timestamp) {
|
||||||
|
auto frame_diff = *frame_timestamp - next_frame_start;
|
||||||
|
if (frame_diff < 2ms) {
|
||||||
|
auto this_frame_timestamp = next_frame_start;
|
||||||
|
next_frame_start = *frame_timestamp;
|
||||||
|
frame_timestamp = this_frame_timestamp;
|
||||||
|
} else if (frame_diff > frame_threshold) {
|
||||||
|
next_frame_start = *frame_timestamp - frame_threshold / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
next_frame_start += frame_threshold;
|
||||||
|
}
|
||||||
|
|
||||||
if (encode(frame_nr++, *session, packets, channel_data, frame_timestamp)) {
|
if (encode(frame_nr++, *session, packets, channel_data, frame_timestamp)) {
|
||||||
BOOST_LOG(error) << "Could not encode video packet"sv;
|
BOOST_LOG(error) << "Could not encode video packet"sv;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_frame_timestamp = *frame_timestamp;
|
|
||||||
|
|
||||||
session->request_normal_frame();
|
session->request_normal_frame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user