From 341c07156ac02f213e14c18ca2e28d119df7719f Mon Sep 17 00:00:00 2001
From: zhupengfei <zhupengfei321@sina.cn>
Date: Sat, 2 Jun 2018 22:13:54 +0800
Subject: [PATCH] camera: Single/Double (QtMultimediaCamera)

---
 src/citra_qt/camera/qt_multimedia_camera.cpp | 20 +++++++++++++++++---
 src/citra_qt/camera/qt_multimedia_camera.h   |  4 +++-
 src/citra_qt/camera/still_image_camera.cpp   |  5 ++---
 src/citra_qt/camera/still_image_camera.h     |  2 +-
 4 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/src/citra_qt/camera/qt_multimedia_camera.cpp b/src/citra_qt/camera/qt_multimedia_camera.cpp
index abf2ff25e..05bcbd4f8 100644
--- a/src/citra_qt/camera/qt_multimedia_camera.cpp
+++ b/src/citra_qt/camera/qt_multimedia_camera.cpp
@@ -48,7 +48,7 @@ bool QtCameraSurface::present(const QVideoFrame& frame) {
 
 QtMultimediaCamera::QtMultimediaCamera(const std::string& camera_name,
                                        const Service::CAM::Flip& flip)
-    : QtCameraInterface(flip), handler(QtMultimediaCameraHandler::GetHandler()) {
+    : QtCameraInterface(flip), handler(QtMultimediaCameraHandler::GetHandler(camera_name)) {
     if (handler->thread() == QThread::currentThread()) {
         handler->CreateCamera(camera_name);
     } else {
@@ -94,7 +94,7 @@ void QtMultimediaCamera::SetFrameRate(Service::CAM::FrameRate frame_rate) {
     auto framerate = FrameRateList[static_cast<int>(frame_rate)];
 
     handler->settings.setMinimumFrameRate(framerate.minimumFrameRate);
-    handler->settings.setMinimumFrameRate(framerate.maximumFrameRate);
+    handler->settings.setMaximumFrameRate(framerate.maximumFrameRate);
 }
 
 QImage QtMultimediaCamera::QtReceiveFrame() {
@@ -115,17 +115,25 @@ std::array<std::shared_ptr<QtMultimediaCameraHandler>, 3> QtMultimediaCameraHand
 
 std::array<bool, 3> QtMultimediaCameraHandler::status;
 
+std::unordered_map<std::string, std::shared_ptr<QtMultimediaCameraHandler>>
+    QtMultimediaCameraHandler::loaded;
+
 void QtMultimediaCameraHandler::Init() {
     for (auto& handler : handlers) {
         handler = std::make_shared<QtMultimediaCameraHandler>();
     }
 }
 
-std::shared_ptr<QtMultimediaCameraHandler> QtMultimediaCameraHandler::GetHandler() {
+std::shared_ptr<QtMultimediaCameraHandler> QtMultimediaCameraHandler::GetHandler(
+    const std::string& camera_name) {
+    if (loaded.count(camera_name)) {
+        return loaded.at(camera_name);
+    }
     for (int i = 0; i < handlers.size(); i++) {
         if (!status[i]) {
             NGLOG_INFO(Service_CAM, "Successfully got handler {}", i);
             status[i] = true;
+            loaded.emplace(camera_name, handlers[i]);
             return handlers[i];
         }
     }
@@ -140,6 +148,12 @@ void QtMultimediaCameraHandler::ReleaseHandler(
             NGLOG_INFO(Service_CAM, "Successfully released handler {}", i);
             status[i] = false;
             handlers[i]->started = false;
+            for (auto it = loaded.begin(); it != loaded.end(); it++) {
+                if (it->second == handlers[i]) {
+                    loaded.erase(it);
+                    break;
+                }
+            }
             break;
         }
     }
diff --git a/src/citra_qt/camera/qt_multimedia_camera.h b/src/citra_qt/camera/qt_multimedia_camera.h
index 41024214c..e6d7b6b6d 100644
--- a/src/citra_qt/camera/qt_multimedia_camera.h
+++ b/src/citra_qt/camera/qt_multimedia_camera.h
@@ -6,6 +6,7 @@
 
 #include <array>
 #include <string>
+#include <unordered_map>
 #include <vector>
 #include <QAbstractVideoSurface>
 #include <QCamera>
@@ -62,7 +63,7 @@ class QtMultimediaCameraHandler final : public QObject {
 public:
     /// Creates the global handler. Must be called in UI thread.
     static void Init();
-    static std::shared_ptr<QtMultimediaCameraHandler> GetHandler();
+    static std::shared_ptr<QtMultimediaCameraHandler> GetHandler(const std::string& camera_name);
     static void ReleaseHandler(const std::shared_ptr<QtMultimediaCameraHandler>& handler);
 
     /**
@@ -92,6 +93,7 @@ private:
 
     static std::array<std::shared_ptr<QtMultimediaCameraHandler>, 3> handlers;
     static std::array<bool, 3> status;
+    static std::unordered_map<std::string, std::shared_ptr<QtMultimediaCameraHandler>> loaded;
 
     friend class QtMultimediaCamera; // For access to camera_surface (and camera)
 };
diff --git a/src/citra_qt/camera/still_image_camera.cpp b/src/citra_qt/camera/still_image_camera.cpp
index 2b9f4e54b..a166e3336 100644
--- a/src/citra_qt/camera/still_image_camera.cpp
+++ b/src/citra_qt/camera/still_image_camera.cpp
@@ -24,7 +24,7 @@ bool StillImageCamera::IsPreviewAvailable() {
     return !image.isNull();
 }
 
-const std::string StillImageCameraFactory::getFilePath() {
+const std::string StillImageCameraFactory::GetFilePath() {
     QList<QByteArray> types = QImageReader::supportedImageFormats();
     QList<QString> temp_filters;
     for (QByteArray type : types) {
@@ -32,7 +32,6 @@ const std::string StillImageCameraFactory::getFilePath() {
     }
 
     QString filter = QObject::tr("Supported image files (%1)").arg(temp_filters.join(" "));
-
     return QFileDialog::getOpenFileName(nullptr, QObject::tr("Open File"), ".", filter)
         .toStdString();
 }
@@ -41,7 +40,7 @@ std::unique_ptr<CameraInterface> StillImageCameraFactory::Create(
     const std::string& config, const Service::CAM::Flip& flip) const {
     std::string real_config = config;
     if (config.empty()) {
-        real_config = getFilePath();
+        real_config = GetFilePath();
     }
     QImage image(QString::fromStdString(real_config));
     if (image.isNull()) {
diff --git a/src/citra_qt/camera/still_image_camera.h b/src/citra_qt/camera/still_image_camera.h
index 11011622f..80e43ba17 100644
--- a/src/citra_qt/camera/still_image_camera.h
+++ b/src/citra_qt/camera/still_image_camera.h
@@ -31,7 +31,7 @@ public:
                                             const Service::CAM::Flip& flip) const override;
 
 private:
-    static const std::string getFilePath();
+    static const std::string GetFilePath();
 };
 
 } // namespace Camera