Select proportional screen and advertised camera stream modes
This commit is contained in:
1 parent
6228873ce2
commit
9bacde3bc1
2 files changed
+279
-25
No files matched your search
@@ -3,6 +3,12 @@
|
||||
#include <QtTest>
|
||||
#include <QTimer>
|
||||
#include <QLabel>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QButtonGroup>
|
||||
#include <QPushButton>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QScreen>
|
||||
#include <QLoggingCategory>
|
||||
#include <atomic>
|
||||
@@ -117,6 +123,120 @@ private slots:
|
||||
sqlite3_finalize(statement); QVERIFY(group); QVERIFY(gui_stream_attach(inst)); uasync_mark_running(ua);
|
||||
connect(&poll, &QTimer::timeout, this, [this] { uasync_poll(ua, 0); }); poll.start(1);
|
||||
}
|
||||
void captureSettingsSurviveReopening() {
|
||||
QString saved;
|
||||
QVariantList selectedMode;
|
||||
{
|
||||
StreamPublishEngine engine;
|
||||
StreamPublishWindow controls(&engine, group);
|
||||
connect(&controls, &StreamPublishWindow::settingsChanged, this, [&saved](const QString& value) { saved = value; });
|
||||
auto boxes = controls.findChildren<QComboBox*>(); QCOMPARE(boxes.size(), 5);
|
||||
if (StreamPublishEngine::supported()) QTRY_VERIFY_WITH_TIMEOUT(boxes[2]->count() > 0, 15000);
|
||||
auto sources = StreamPublishEngine::sources();
|
||||
int screen = -1;
|
||||
for (int i = 0; i < sources.size(); i++) if (sources[i].kind == StreamVideoSource::Screen && !sources[i].size.isEmpty()) { screen = i; break; }
|
||||
if (screen < 0) QSKIP("No enumerated screen for capture settings");
|
||||
boxes[0]->setCurrentIndex(screen);
|
||||
QSize maximum = stream_video_screen_size(sources[screen].size);
|
||||
QCOMPARE(boxes[1]->currentData().toList(), (QVariantList{maximum.width(), maximum.height(), 30}));
|
||||
QVERIFY(boxes[1]->count() >= 6);
|
||||
boxes[1]->setCurrentIndex(boxes[1]->count() - 1); // Меньший размер сохраняется при повторном открытии.
|
||||
selectedMode = boxes[1]->currentData().toList();
|
||||
boxes[3]->setCurrentIndex(boxes[3]->findData(4000000));
|
||||
controls.findChild<QButtonGroup*>()->button(270)->click();
|
||||
controls.findChildren<QCheckBox*>().first()->setChecked(false);
|
||||
if (boxes[2]->count() > 1) boxes[2]->setCurrentIndex(boxes[2]->count() - 1);
|
||||
QVERIFY(!saved.isEmpty());
|
||||
}
|
||||
const auto stored = QJsonDocument::fromJson(saved.toUtf8()).object();
|
||||
QCOMPARE(stored.value("width").toInt(), selectedMode[0].toInt()); QCOMPARE(stored.value("fps").toInt(), 60);
|
||||
QVERIFY(!stored.value("native_size").toBool());
|
||||
QCOMPARE(stored.value("bitrate").toInt(), 4000000); QCOMPARE(stored.value("rotation").toInt(), 270);
|
||||
QVERIFY(!stored.value("audio").toBool());
|
||||
StreamPublishEngine reopenedEngine;
|
||||
StreamPublishWindow reopened(&reopenedEngine, group, nullptr, saved);
|
||||
QSignalSpy changes(&reopened, &StreamPublishWindow::settingsChanged);
|
||||
if (StreamPublishEngine::supported()) QTRY_VERIFY_WITH_TIMEOUT(!reopenedEngine.codecs().isEmpty(), 15000);
|
||||
auto boxes = reopened.findChildren<QComboBox*>();
|
||||
QCOMPARE(boxes[1]->currentData().toList(), selectedMode);
|
||||
QCOMPARE(boxes[3]->currentData().toInt(), 4000000);
|
||||
if (StreamPublishEngine::supported()) QTRY_COMPARE(boxes[2]->currentData().toInt(), stored.value("codec").toInt());
|
||||
QCOMPARE(reopened.findChild<QButtonGroup*>()->checkedId(), 270);
|
||||
QVERIFY(!reopened.findChildren<QCheckBox*>().first()->isChecked());
|
||||
QVERIFY(changes.isEmpty()); // Асинхронный список кодеков не перезаписывает сохранённый выбор.
|
||||
boxes[3]->setCurrentIndex(0);
|
||||
QCOMPARE(changes.size(), 1);
|
||||
auto automatic = changes.takeFirst().front().toString();
|
||||
QCOMPARE(QJsonDocument::fromJson(automatic.toUtf8()).object().value("bitrate").toInt(-1), 0);
|
||||
StreamPublishWindow restoredAuto(&reopenedEngine, group, nullptr, automatic);
|
||||
QCOMPARE(restoredAuto.findChildren<QComboBox*>()[3]->currentIndex(), 0);
|
||||
}
|
||||
void proportionalScreenModes_data() {
|
||||
QTest::addColumn<QSize>("source"); QTest::addColumn<QSize>("maximum"); QTest::addColumn<QSize>("reduced");
|
||||
QTest::newRow("full-hd") << QSize(1920, 1080) << QSize(1920, 1080) << QSize(1280, 720);
|
||||
QTest::newRow("16-10") << QSize(1920, 1200) << QSize(1920, 1200) << QSize(1152, 720);
|
||||
QTest::newRow("ultrawide") << QSize(3440, 1440) << QSize(3440, 1440) << QSize(1720, 720);
|
||||
QTest::newRow("limited") << QSize(5120, 1440) << QSize(4096, 1152) << QSize(2560, 720);
|
||||
QTest::newRow("retina") << QSize(5120, 2880) << QSize(4096, 2304) << QSize(1280, 720);
|
||||
QTest::newRow("portrait") << QSize(1440, 5120) << QSize(1152, 4096) << QSize(720, 2560);
|
||||
QTest::newRow("odd") << QSize(1365, 767) << QSize(1364, 766) << QSize(1280, 720);
|
||||
}
|
||||
void proportionalScreenModes() {
|
||||
QFETCH(QSize, source); QFETCH(QSize, maximum); QFETCH(QSize, reduced);
|
||||
auto modes = stream_video_screen_modes(source); QVERIFY(!modes.isEmpty()); QCOMPARE(modes.front().size, maximum);
|
||||
QVERIFY(modes.contains({reduced, 30}));
|
||||
QList<StreamVideoMode> seen;
|
||||
for (const auto& mode : modes) {
|
||||
QVERIFY(mode.size.width() <= 4096 && mode.size.height() <= 4096);
|
||||
QVERIFY(mode.size.width() <= source.width() && mode.size.height() <= source.height());
|
||||
QVERIFY(!(mode.size.width() % 2) && !(mode.size.height() % 2));
|
||||
double scale = std::min(double(mode.size.width()) / source.width(), double(mode.size.height()) / source.height());
|
||||
QVERIFY(std::abs(mode.size.width() - source.width() * scale) < 8);
|
||||
QVERIFY(std::abs(mode.size.height() - source.height() * scale) < 8);
|
||||
QVERIFY(!seen.contains(mode)); seen.append(mode);
|
||||
}
|
||||
int selected = stream_video_select_mode(modes, {reduced, 60}, true);
|
||||
QCOMPARE(modes[selected].size, maximum); QCOMPARE(modes[selected].fps, 60);
|
||||
selected = stream_video_select_mode(modes, {reduced, 60}, false);
|
||||
QCOMPARE(modes[selected].size, reduced); QCOMPARE(modes[selected].fps, 60);
|
||||
}
|
||||
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);
|
||||
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}));
|
||||
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);
|
||||
QVERIFY(!stream_video_camera_supports({640, 480}, 30, 30, {{1280, 720}, 30}));
|
||||
}
|
||||
void screenSelectionAndRefresh() {
|
||||
StreamPublishEngine engine; StreamPublishWindow controls(&engine, group);
|
||||
auto* sourceBox = controls.findChild<QComboBox*>("streamVideoSource");
|
||||
auto* modeBox = controls.findChild<QComboBox*>("streamVideoMode");
|
||||
auto sources = StreamPublishEngine::sources();
|
||||
QSignalSpy changes(&controls, &StreamPublishWindow::settingsChanged);
|
||||
unsigned screens = 0;
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
if (sources[i].kind != StreamVideoSource::Screen || sources[i].size.isEmpty()) continue;
|
||||
screens++; sourceBox->setCurrentIndex(-1); changes.clear(); sourceBox->setCurrentIndex(i);
|
||||
QSize size = stream_video_screen_size(sources[i].size);
|
||||
auto mode = modeBox->currentData().toList();
|
||||
QCOMPARE(mode[0].toInt(), size.width()); QCOMPARE(mode[1].toInt(), size.height());
|
||||
QVERIFY(modeBox->currentData(Qt::UserRole + 1).toBool()); QCOMPARE(changes.size(), 1);
|
||||
QVERIFY(sourceBox->currentText().contains(sources[i].name));
|
||||
modeBox->setCurrentIndex(modeBox->count() - 1); mode = modeBox->currentData().toList(); changes.clear();
|
||||
emit engine.sourcesChanged(); QCOMPARE(modeBox->currentData().toList(), mode); QVERIFY(changes.isEmpty());
|
||||
}
|
||||
if (!screens) QSKIP("No enumerated screens");
|
||||
}
|
||||
void broadcastAllowsRadioMicrophone() {
|
||||
AudioCaptureLease call, radio(AudioCaptureLease::Mode::Radio), recorder, publisher(AudioCaptureLease::Mode::Exclusive);
|
||||
QVERIFY(call.acquire()); QVERIFY(radio.acquire()); QVERIFY(recorder.acquire()); QVERIFY(!publisher.acquire());
|
||||
|
||||
Reference in new issue
Block a user