From 1fd8b1b299e785ee75df6ec45bfb6a8d434af684 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 5 Mar 2019 17:37:21 -0800 Subject: [PATCH] Qt: Support switching webcams --- CHANGES | 1 + src/platform/qt/InputController.cpp | 31 ++++++++++++++++++++++++++++- src/platform/qt/InputController.h | 4 ++++ src/platform/qt/SettingsView.cpp | 16 +++++++++++++++ src/platform/qt/SettingsView.h | 1 + src/platform/qt/SettingsView.ui | 26 +++++++++++++++++++++--- src/platform/qt/Window.cpp | 1 + 7 files changed, 76 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index e644bca84..52b42650c 100644 --- a/CHANGES +++ b/CHANGES @@ -25,6 +25,7 @@ Misc: - Qt: Add missing HEVC NVENC option (fixes mgba.io/i/1323) - LR35902: Support PC-relative opcode decoding - Qt: Improve camera initialization + - Qt: Support switching webcams 0.7.1: (2019-02-24) Bugfixes: diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index 8869dac82..b655e86d9 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -15,7 +15,7 @@ #include #include #ifdef BUILD_QT_MULTIMEDIA -#include +#include #include #endif @@ -98,6 +98,10 @@ InputController::InputController(int playerId, QWidget* topLevel, QObject* paren } #ifdef BUILD_QT_MULTIMEDIA if (image->p->m_config->getQtOption("cameraDriver").toInt() == static_cast(CameraDriver::QT_MULTIMEDIA)) { + QByteArray camera = image->p->m_config->getQtOption("camera").toByteArray(); + if (!camera.isNull()) { + QMetaObject::invokeMethod(image->p, "setCamera", Q_ARG(QByteArray, camera)); + } QMetaObject::invokeMethod(image->p, "setupCam"); } #endif @@ -691,6 +695,17 @@ void InputController::setCamImage(const QImage& image) { m_image.outOfDate = true; } +QList> InputController::listCameras() const { + QList> out; +#ifdef BUILD_QT_MULTIMEDIA + QList cams = QCameraInfo::availableCameras(); + for (const auto& cam : cams) { + out.append(qMakePair(cam.deviceName().toLatin1(), cam.description())); + } +#endif + return out; +} + void InputController::increaseLuminanceLevel() { setLuminanceLevel(m_luxLevel + 1); } @@ -783,3 +798,17 @@ void InputController::teardownCam() { } #endif } + +void InputController::setCamera(const QByteArray& name) { +#ifdef BUILD_QT_MULTIMEDIA + bool needsRestart = false; + if (m_camera) { + needsRestart = m_camera->state() == QCamera::ActiveState; + } + m_camera = std::make_unique(name); + connect(m_camera.get(), &QCamera::statusChanged, this, &InputController::prepareCamSettings); + if (needsRestart) { + setupCam(); + } +#endif +} \ No newline at end of file diff --git a/src/platform/qt/InputController.h b/src/platform/qt/InputController.h index d15bd0e22..6418343c1 100644 --- a/src/platform/qt/InputController.h +++ b/src/platform/qt/InputController.h @@ -96,6 +96,8 @@ public: void stealFocus(QWidget* focus); void releaseFocus(QWidget* focus); + QList> listCameras() const; + mRumble* rumble(); mRotationSource* rotationSource(); mImageSource* imageSource() { return &m_image; } @@ -122,6 +124,8 @@ public slots: void loadCamImage(const QString& path); void setCamImage(const QImage& image); + void setCamera(const QByteArray& id); + private slots: #ifdef BUILD_QT_MULTIMEDIA void prepareCamSettings(QCamera::Status); diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 271c59652..1dbf92d35 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -180,12 +180,22 @@ SettingsView::SettingsView(ConfigController* controller, InputController* inputC m_ui.cameraDriver->addItem(tr("None (Still Image)"), static_cast(InputController::CameraDriver::NONE)); if (cameraDriver.isNull() || cameraDriver.toInt() == static_cast(InputController::CameraDriver::NONE)) { m_ui.cameraDriver->setCurrentIndex(m_ui.cameraDriver->count() - 1); + m_ui.camera->setEnabled(false); } #ifdef BUILD_QT_MULTIMEDIA m_ui.cameraDriver->addItem(tr("Qt Multimedia"), static_cast(InputController::CameraDriver::QT_MULTIMEDIA)); if (!cameraDriver.isNull() && cameraDriver.toInt() == static_cast(InputController::CameraDriver::QT_MULTIMEDIA)) { m_ui.cameraDriver->setCurrentIndex(m_ui.cameraDriver->count() - 1); + m_ui.camera->setEnabled(true); + } + QList> cameras = inputController->listCameras(); + QByteArray currentCamera = m_controller->getQtOption("camera").toByteArray(); + for (const auto& camera : cameras) { + m_ui.camera->addItem(camera.second, camera.first); + if (camera.first == currentCamera) { + m_ui.camera->setCurrentIndex(m_ui.camera->count() - 1); + } } #endif @@ -442,6 +452,12 @@ void SettingsView::updateConfig() { emit cameraDriverChanged(); } + QVariant camera = m_ui.camera->itemData(m_ui.camera->currentIndex()); + if (camera != m_controller->getQtOption("camera")) { + m_controller->setQtOption("camera", camera); + emit cameraChanged(camera.toByteArray()); + } + QLocale language = m_ui.languages->itemData(m_ui.languages->currentIndex()).toLocale(); if (language != m_controller->getQtOption("language").toLocale() && !(language.bcp47Name() == QLocale::system().bcp47Name() && m_controller->getQtOption("language").isNull())) { m_controller->setQtOption("language", language.bcp47Name()); diff --git a/src/platform/qt/SettingsView.h b/src/platform/qt/SettingsView.h index 017b55693..b04d21805 100644 --- a/src/platform/qt/SettingsView.h +++ b/src/platform/qt/SettingsView.h @@ -39,6 +39,7 @@ signals: void audioDriverChanged(); void displayDriverChanged(); void cameraDriverChanged(); + void cameraChanged(const QByteArray&); void pathsChanged(); void languageChanged(); void libraryCleared(); diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index 41fb9a7de..792d4b4e8 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -1261,7 +1261,7 @@ - Game Boy model + Game Boy model: @@ -1297,7 +1297,7 @@ - Super Game Boy model + Super Game Boy model: @@ -1333,7 +1333,7 @@ - Game Boy Color model + Game Boy Color model: @@ -1672,6 +1672,26 @@ + + + + Camera: + + + + + + + false + + + + 0 + 0 + + + + diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 7a8c97dfc..aef833f42 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -443,6 +443,7 @@ void Window::openSettingsWindow() { connect(settingsWindow, &SettingsView::displayDriverChanged, this, &Window::reloadDisplayDriver); connect(settingsWindow, &SettingsView::audioDriverChanged, this, &Window::reloadAudioDriver); connect(settingsWindow, &SettingsView::cameraDriverChanged, this, &Window::mustRestart); + connect(settingsWindow, &SettingsView::cameraChanged, &m_inputController, &InputController::setCamera); connect(settingsWindow, &SettingsView::languageChanged, this, &Window::mustRestart); connect(settingsWindow, &SettingsView::pathsChanged, this, &Window::reloadConfig); #ifdef USE_SQLITE3