Accept faster camera capture modes and pace up to 60 fps
This commit is contained in:
1 parent
9d6dc1b469
commit
74a4135cdc
3 files changed
+22
-17
No files matched your search
@@ -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;
|
||||
}
|
||||
};
|
||||
@@ -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. */
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in new issue
Block a user