Qt: Support switching webcams

This commit is contained in:
Vicki Pfau 2019-03-05 17:37:21 -08:00
parent 03aed12d28
commit 1fd8b1b299
7 changed files with 76 additions and 4 deletions

View File

@ -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:

View File

@ -15,7 +15,7 @@
#include <QTimer>
#include <QWidget>
#ifdef BUILD_QT_MULTIMEDIA
#include <QCamera>
#include <QCameraInfo>
#include <QVideoSurfaceFormat>
#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<int>(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<QPair<QByteArray, QString>> InputController::listCameras() const {
QList<QPair<QByteArray, QString>> out;
#ifdef BUILD_QT_MULTIMEDIA
QList<QCameraInfo> 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<QCamera>(name);
connect(m_camera.get(), &QCamera::statusChanged, this, &InputController::prepareCamSettings);
if (needsRestart) {
setupCam();
}
#endif
}

View File

@ -96,6 +96,8 @@ public:
void stealFocus(QWidget* focus);
void releaseFocus(QWidget* focus);
QList<QPair<QByteArray, QString>> 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);

View File

@ -180,12 +180,22 @@ SettingsView::SettingsView(ConfigController* controller, InputController* inputC
m_ui.cameraDriver->addItem(tr("None (Still Image)"), static_cast<int>(InputController::CameraDriver::NONE));
if (cameraDriver.isNull() || cameraDriver.toInt() == static_cast<int>(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<int>(InputController::CameraDriver::QT_MULTIMEDIA));
if (!cameraDriver.isNull() && cameraDriver.toInt() == static_cast<int>(InputController::CameraDriver::QT_MULTIMEDIA)) {
m_ui.cameraDriver->setCurrentIndex(m_ui.cameraDriver->count() - 1);
m_ui.camera->setEnabled(true);
}
QList<QPair<QByteArray, QString>> 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());

View File

@ -39,6 +39,7 @@ signals:
void audioDriverChanged();
void displayDriverChanged();
void cameraDriverChanged();
void cameraChanged(const QByteArray&);
void pathsChanged();
void languageChanged();
void libraryCleared();

View File

@ -1261,7 +1261,7 @@
<item row="0" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
<string>Game Boy model</string>
<string>Game Boy model:</string>
</property>
</widget>
</item>
@ -1297,7 +1297,7 @@
<item row="1" column="0">
<widget class="QLabel" name="label_32">
<property name="text">
<string>Super Game Boy model</string>
<string>Super Game Boy model:</string>
</property>
</widget>
</item>
@ -1333,7 +1333,7 @@
<item row="2" column="0">
<widget class="QLabel" name="label_33">
<property name="text">
<string>Game Boy Color model</string>
<string>Game Boy Color model:</string>
</property>
</widget>
</item>
@ -1672,6 +1672,26 @@
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_35">
<property name="text">
<string>Camera:</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QComboBox" name="camera">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</widget>

View File

@ -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