Finalize shared frame rate selection and deterministic call control verification
This commit is contained in:
1 parent
bb0fa13c8b
commit
264a13705f
3 files changed
+7
-12
No files matched your search
@@ -15,10 +15,7 @@
|
||||
#include <QActionGroup>
|
||||
#include <QWidgetAction>
|
||||
#include <QToolButton>
|
||||
#include <QProxyStyle>
|
||||
#include <QStyleOptionMenuItem>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QSignalBlocker>
|
||||
#include <QJsonDocument>
|
||||
#include <QScopedValueRollback>
|
||||
@@ -189,7 +186,9 @@ StreamPublishWindow::StreamPublishWindow(StreamPublishEngine* engine, uint64_t g
|
||||
refreshModes(previous, previous.source.kind == StreamVideoSource::Screen); apply();
|
||||
if (!m_engine->active()) synchronize();
|
||||
});
|
||||
connect(m_resolution, &QMenu::triggered, this, [this] { refreshFrameRates(value(m_fps).toInt()); apply(); });
|
||||
connect(m_resolution, &QMenu::triggered, this, [this] {
|
||||
populateFrameRates(m_fps, m_modes, value(m_resolution).toSize(), value(m_fps).toInt()); apply();
|
||||
});
|
||||
for (auto* menu : {m_fps, m_codec, m_bitrate, m_maxQp, m_rotation, m_microphone})
|
||||
connect(menu, &QMenu::triggered, this, &StreamPublishWindow::apply);
|
||||
for (auto* menu : {m_codec, m_maxQp}) connect(menu, &QMenu::triggered, this, [this] { if (!m_updating) synchronize(); });
|
||||
@@ -368,7 +367,7 @@ void StreamPublishWindow::refreshModes(const StreamPublishConfig& previous, bool
|
||||
m_resolution->menuAction()->setToolTip(text("No supported video modes")); return;
|
||||
}
|
||||
const auto& mode = m_modes[selected];
|
||||
select(m_resolution, mode.size); refreshFrameRates(mode.fps);
|
||||
select(m_resolution, mode.size); populateFrameRates(m_fps, m_modes, mode.size, mode.fps);
|
||||
if (!maximum && wanted != mode) DEBUG_WARN(DEBUG_CATEGORY_VIDEO,
|
||||
"desktop video mode adjusted source=%s requested=%dx%d/%d selected=%dx%d/%d",
|
||||
qPrintable(source.name), wanted.size.width(), wanted.size.height(), wanted.fps, mode.size.width(), mode.size.height(), mode.fps);
|
||||
@@ -377,9 +376,6 @@ void StreamPublishWindow::refreshModes(const StreamPublishConfig& previous, bool
|
||||
source.kind == StreamVideoSource::Screen && mode.size == m_modes.front().size);
|
||||
}
|
||||
|
||||
void StreamPublishWindow::refreshFrameRates(int previous) {
|
||||
populateFrameRates(m_fps, m_modes, value(m_resolution).toSize(), previous);
|
||||
}
|
||||
void StreamPublishWindow::refreshCodecs() {
|
||||
QScopedValueRollback<bool> updating(m_updating, true);
|
||||
int previous = selected(m_codec) ? value(m_codec).toInt() : m_settings.value("codec").toInt();
|
||||
|
||||
@@ -49,7 +49,6 @@ private:
|
||||
void refreshSources(); // Сохраняет выбранный handle; пропавший active-source не подменяется другим, до start возможен первый доступный.
|
||||
// Режимы camera/screen; выбирает близкий previous либо native screen.
|
||||
void refreshModes(const StreamPublishConfig& previous, bool maximum = false);
|
||||
void refreshFrameRates(int previous); // Все стандартные и аппаратные FPS; недоступные для выбранного размера видимы и отключены.
|
||||
void updateMenuButtons(); // Обновляет иконки со значениями и подсказки верхнего ряда после выбора/синхронизации.
|
||||
void refreshCodecs(); // Перечитывает engine.codecs(), сохраняет текущий/saved codec, недоступный заменяет первым.
|
||||
void synchronize(); // Читает engine config/state без apply; настраивает controls и ограничения изменения audio/cursor/QP.
|
||||
|
||||
@@ -162,14 +162,13 @@ private slots:
|
||||
void videoSettingsMenus() {
|
||||
CallWindow window; window.setCallId(77); window.setPeerName(QStringLiteral("Video call")); window.setState(CallWindow::Active);
|
||||
auto* engine = window.findChild<CallVideoEngine*>(); QVERIFY(engine);
|
||||
auto* capture = engine->findChild<CallCameraCapture*>(); QVERIFY(capture);
|
||||
QObject::disconnect(capture, nullptr, engine, nullptr); // Детерминированные режимы, без открытия камеры/звонка.
|
||||
CallCameraDevice first{QStringLiteral("Main camera"), QByteArray("main"), {}};
|
||||
stream_video_add_camera_modes(first.modes, QSize(1920, 1080), 29.97, 29.97);
|
||||
stream_video_add_camera_modes(first.modes, QSize(1280, 720), 15, 60);
|
||||
CallCameraDevice second{QStringLiteral("Secondary camera"), QByteArray("secondary"), {}};
|
||||
stream_video_add_camera_modes(second.modes, QSize(640, 480), 7, 7);
|
||||
emit engine->camerasChanged({first, second});
|
||||
QSignalBlocker blocked(engine); // Аппаратные события не меняют тестовые режимы; камера/звонок не открываются.
|
||||
auto getMenu = [&window](const char* name) { return window.findChild<QMenu*>(name); };
|
||||
auto chosen = [](QMenu* menu) { auto* action = menu->findChild<QActionGroup*>()->checkedAction(); return action ? action->data() : QVariant(); };
|
||||
auto choose = [](QMenu* menu, const QVariant& value) {
|
||||
@@ -185,7 +184,8 @@ private slots:
|
||||
for (auto* action : fps->actions()) if (action->isCheckable())
|
||||
QCOMPARE(action->isEnabled(), action->data().toInt() <= 30);
|
||||
choose(camera, second.id); QCOMPARE(chosen(resolution).toSize(), QSize(640, 480)); QCOMPARE(chosen(fps).toInt(), 7);
|
||||
emit engine->camerasChanged({second, first}); QCOMPARE(chosen(camera).toByteArray(), second.id); QCOMPARE(chosen(fps).toInt(), 7);
|
||||
blocked.unblock(); emit engine->camerasChanged({second, first}); blocked.reblock();
|
||||
QCOMPARE(chosen(camera).toByteArray(), second.id); QCOMPARE(chosen(fps).toInt(), 7);
|
||||
choose(camera, first.id); choose(resolution, QSize(1920, 1080)); choose(getMenu("callVideoCodec"), 1);
|
||||
auto* minimum = window.findChild<QSpinBox*>("callVideoMinimumBitrate"); QVERIFY(minimum);
|
||||
auto* maximum = window.findChild<QSpinBox*>("callVideoMaximumBitrate"); QVERIFY(maximum);
|
||||
|
||||
Reference in new issue
Block a user