diff --git a/tools/chatgui/src/call_camera_source.h b/tools/chatgui/src/call_camera_source.h index 448c4c8e..c55fe666 100644 --- a/tools/chatgui/src/call_camera_source.h +++ b/tools/chatgui/src/call_camera_source.h @@ -13,6 +13,7 @@ public: virtual bool start(const QByteArray& device, int width, int height) = 0; virtual void stop() = 0; signals: + void devicesChanged(); void frame(const QVideoFrame& frame); void error(const QString& message); }; diff --git a/tools/chatgui/src/call_camera_worker.cpp b/tools/chatgui/src/call_camera_worker.cpp index 29f6e6ab..83983c2e 100644 --- a/tools/chatgui/src/call_camera_worker.cpp +++ b/tools/chatgui/src/call_camera_worker.cpp @@ -25,8 +25,12 @@ class QtCallCameraSource : public CallCameraSource { std::unique_ptr camera; std::unique_ptr session; std::unique_ptr sink; + QMediaDevices devicesMonitor; CallCameraRate rate; public: + QtCallCameraSource() { + connect(&devicesMonitor, &QMediaDevices::videoInputsChanged, this, &CallCameraSource::devicesChanged); + } ~QtCallCameraSource() override { stop(); } CallCameraDevices devices() override { CallCameraDevices result; @@ -112,6 +116,18 @@ class CameraWorker : public QObject { socket.flush(); // Стадия должна уйти до потенциально блокирующего вызова драйвера. } void stage(const QString& name) { send(packet(Stage, generation, [&](QDataStream& out) { out << name; })); } + void enumerate() { + stage(QStringLiteral("enumerate")); + const auto devices = source->devices(); + send(packet(Devices, 0, [&](QDataStream& out) { + out << quint32(devices.size()); + for (const auto& device : devices) { + out << device.name << device.id << quint32(device.modes.size()); + for (const auto& mode : device.modes) out << qint32(mode.size.width()) << qint32(mode.size.height()); + } + })); + stage(pending ? QStringLiteral("running") : QStringLiteral("idle")); + } void stop() { stage(QStringLiteral("stop")); disconnect(captureConnection); disconnect(errorConnection); source->stop(); pending.reset(); @@ -201,18 +217,8 @@ class CameraWorker : public QObject { } public: explicit CameraWorker(std::unique_ptr backend) : source(std::move(backend)) { - connect(&socket, &QLocalSocket::connected, this, [this] { - stage(QStringLiteral("enumerate")); - const auto devices = source->devices(); - send(packet(Devices, 0, [&](QDataStream& out) { - out << quint32(devices.size()); - for (const auto& device : devices) { - out << device.name << device.id << quint32(device.modes.size()); - for (const auto& mode : device.modes) out << qint32(mode.size.width()) << qint32(mode.size.height()); - } - })); - stage(QStringLiteral("idle")); - }); + connect(&socket, &QLocalSocket::connected, this, &CameraWorker::enumerate); + connect(source.get(), &CallCameraSource::devicesChanged, this, &CameraWorker::enumerate); connect(&socket, &QLocalSocket::readyRead, this, [this] { if (!reader.read(socket, [this](quint8 type, quint64 revision, QDataStream& in) { return receive(type, revision, in); })) { DEBUG_ERROR(DEBUG_CATEGORY_CALL, "camera worker invalid command"); QCoreApplication::exit(2); diff --git a/tools/chatgui/src/callwindow.cpp b/tools/chatgui/src/callwindow.cpp index bf3fbf66..684721fc 100644 --- a/tools/chatgui/src/callwindow.cpp +++ b/tools/chatgui/src/callwindow.cpp @@ -366,7 +366,10 @@ CallWindow::CallWindow(QWidget* parent) m_camera->addItem(camera.name, camera.id); m_camera->setItemData(m_camera->count() - 1, sizes, Qt::UserRole + 1); } - const int index = m_camera->findData(selected); + int index = m_camera->findData(selected); + if (index < 0) for (int i = 0; i < m_camera->count(); ++i) { + if (!m_camera->itemData(i, Qt::UserRole + 1).toList().isEmpty()) { index = i; break; } + } if (index >= 0) m_camera->setCurrentIndex(index); refreshModes(); if (m_videoEnabled->isChecked()) applyVideo();