Refresh call camera modes on device changes outside the GUI

This commit is contained in:
evgeny committed 2026-10-19 22:47:45 +02:00
1 parent 6e0d3f3022
commit fcdc098415
3 files changed
+23 -13

No files matched your search

+1
View File
@@ -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);
};
+18 -12
View File
@@ -25,8 +25,12 @@ class QtCallCameraSource : public CallCameraSource {
std::unique_ptr<QCamera> camera;
std::unique_ptr<QMediaCaptureSession> session;
std::unique_ptr<QVideoSink> 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<CallCameraSource> 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);
+4 -1
View File
@@ -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();