Accept faster camera capture modes and pace up to 60 fps

This commit is contained in:
evgeny committed 2026-10-20 00:01:13 +02:00
1 parent 9d6dc1b469
commit 74a4135cdc
3 files changed
+22 -17

No files matched your search

+9 -11
View File
@@ -1,21 +1,19 @@
#pragma once
#include <cstdint>
// Бюджет 30 fps с запасом одного кадра; интервал >=25мс запрещает burst после паузы.
// Выбор исходных кадров по фазе 1..60 fps, до encode. Дробный период не накапливает ошибку.
// Допуск четверти периода сохраняет кадры при дрожании PTS; опоздание сбрасывает фазу без burst.
class CallVideoCadence {
int64_t lastPts = -1, lastAccepted = -1, credit = 1250000;
int fps;
int64_t lastPts = -1, next = -1;
public:
explicit CallVideoCadence(int rate = 30) : fps(rate) {}
bool accept(int64_t pts) {
if (lastPts >= 0) {
if (pts <= lastPts) return false;
const int64_t elapsed = pts - lastPts;
credit = elapsed >= 66667 ? 2000000 : credit + elapsed * 30;
if (credit > 2000000) credit = 2000000;
}
if (fps < 1 || fps > 60 || pts < 0 || pts <= lastPts || pts > INT64_MAX / fps) return false;
lastPts = pts;
if (credit < 1000000 || (lastAccepted >= 0 && pts - lastAccepted < 25000)) return false;
credit -= 1000000;
lastAccepted = pts;
const int64_t scaled = pts * fps;
if (next >= 0 && scaled < next - 250000) return false;
next = next < 0 || scaled - next > 250000 ? scaled + 1000000 : next + 1000000;
return true;
}
};
+3 -2
View File
@@ -40,12 +40,13 @@ inline QList<StreamVideoMode> stream_video_screen_modes(QSize source) {
return modes;
}
/* 29.97/59.94 соответствуют пределам 30/60; фактический диапазон камеры не округляется. */
/* FPS режима — предел передачи, не команда драйверу. Быстрый capture ограничивается до encode.
* 29.97/59.94 соответствуют пределам 30/60; фактический диапазон камеры не округляется. */
inline bool stream_video_camera_supports(QSize size, double minimum, double maximum, const StreamVideoMode& mode) {
return size == mode.size && size.width() >= 16 && size.height() >= 16 && size.width() <= 4096 && size.height() <= 4096
&& !(size.width() % 2) && !(size.height() % 2) && std::isfinite(minimum) && std::isfinite(maximum)
&& minimum >= 0 && maximum > 0 && minimum <= maximum && mode.fps >= 1 && mode.fps <= 60
&& mode.fps + 0.1 >= minimum && mode.fps <= maximum + 0.1;
&& mode.fps <= maximum + 0.1;
}
/* Объединяем одинаковые режимы разных pixel format, сохраняя границы необычных диапазонов FPS. */
+10 -4
View File
@@ -376,18 +376,24 @@ private slots:
void cameraAdvertisedModes() {
QList<StreamVideoMode> modes;
stream_video_add_camera_modes(modes, {1920, 1080}, 29.97, 29.97);
QCOMPARE(modes.size(), 1); QCOMPARE(modes.front().fps, 30);
stream_video_add_camera_modes(modes, {1920, 1080}, 29.97, 29.97); QCOMPARE(modes.size(), 1);
QCOMPARE(modes.size(), 4); QVERIFY(modes.contains({{1920, 1080}, 30}));
stream_video_add_camera_modes(modes, {1920, 1080}, 29.97, 29.97); QCOMPARE(modes.size(), 4);
stream_video_add_camera_modes(modes, {1280, 720}, 15, 60);
QVERIFY(modes.contains({{1280, 720}, 15})); QVERIFY(modes.contains({{1280, 720}, 60}));
QVERIFY(!modes.contains({{1920, 1080}, 60})); QVERIFY(!modes.contains({{1920, 1080}, 15}));
QVERIFY(!modes.contains({{1920, 1080}, 60})); QVERIFY(modes.contains({{1920, 1080}, 15}));
stream_video_add_camera_modes(modes, {640, 480}, 7, 7); QVERIFY(modes.contains({{640, 480}, 7}));
int count = modes.size();
stream_video_add_camera_modes(modes, {5120, 2880}, 30, 30);
stream_video_add_camera_modes(modes, {1281, 720}, 30, 30);
stream_video_add_camera_modes(modes, {1280, 720}, 120, 120);
stream_video_add_camera_modes(modes, {1280, 720}, 60, 30);
QCOMPARE(modes.size(), count);
stream_video_add_camera_modes(modes, {1280, 720}, 100, 100);
QVERIFY(modes.contains({{1280, 720}, 60}));
stream_video_add_camera_modes(modes, {1920, 1080}, 50, 50);
QVERIFY(modes.contains({{1920, 1080}, 30})); QVERIFY(modes.contains({{1920, 1080}, 50}));
QVERIFY(!modes.contains({{1920, 1080}, 60}));
stream_video_add_camera_modes(modes, {640, 360}, 330, 330);
QVERIFY(modes.contains({{640, 360}, 60})); QVERIFY(modes.contains({{640, 360}, 30}));
QVERIFY(!stream_video_camera_supports({640, 480}, 30, 30, {{1280, 720}, 30}));
}
void screenSelectionAndRefresh() {