فهرست منبع

yuzu: Add webcam support and rebase to latest master

Narr the Reg 4 سال پیش
والد
کامیت
403bdc4daf

+ 2 - 2
src/common/settings.h

@@ -503,8 +503,8 @@ struct Values {
     Setting<bool> enable_ring_controller{true, "enable_ring_controller"};
     RingconRaw ringcon_analogs;
 
-    BasicSetting<bool> enable_ir_sensor{false, "enable_ir_sensor"};
-    BasicSetting<std::string> ir_sensor_device{"auto", "ir_sensor_device"};
+    Setting<bool> enable_ir_sensor{false, "enable_ir_sensor"};
+    Setting<std::string> ir_sensor_device{"auto", "ir_sensor_device"};
 
     // Data Storage
     Setting<bool> use_virtual_sd{true, "use_virtual_sd"};

+ 2 - 2
src/core/hle/service/hid/errors.h

@@ -22,7 +22,7 @@ constexpr Result NpadNotConnected{ErrorModule::HID, 710};
 
 namespace Service::IRS {
 
-constexpr ResultCode InvalidProcessorState{ErrorModule::Irsensor, 78};
-constexpr ResultCode InvalidIrCameraHandle{ErrorModule::Irsensor, 204};
+constexpr Result InvalidProcessorState{ErrorModule::Irsensor, 78};
+constexpr Result InvalidIrCameraHandle{ErrorModule::Irsensor, 204};
 
 } // namespace Service::IRS

+ 1 - 1
src/core/hle/service/hid/irs.cpp

@@ -529,7 +529,7 @@ void IRS::ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx) {
     rb.Push(ResultSuccess);
 }
 
-ResultCode IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const {
+Result IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const {
     if (camera_handle.npad_id >
         static_cast<u8>(NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld))) {
         return InvalidIrCameraHandle;

+ 1 - 1
src/core/hle/service/hid/irs.h

@@ -57,7 +57,7 @@ private:
     void StopImageProcessorAsync(Kernel::HLERequestContext& ctx);
     void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx);
 
-    ResultCode IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const;
+    Result IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const;
     Core::IrSensor::DeviceFormat& GetIrCameraSharedMemoryDeviceEntry(
         const Core::IrSensor::IrCameraHandle& camera_handle);
 

+ 15 - 4
src/yuzu/bootmanager.cpp

@@ -830,6 +830,10 @@ void GRenderWindow::InitializeCamera() {
     camera->unload();
     camera->setCaptureMode(QCamera::CaptureViewfinder);
     camera->load();
+    camera->start();
+
+    pending_camera_snapshots = 0;
+    is_virtual_camera = false;
 
     camera_timer = std::make_unique<QTimer>();
     connect(camera_timer.get(), &QTimer::timeout, [this] { RequestCameraCapture(); });
@@ -851,11 +855,17 @@ void GRenderWindow::RequestCameraCapture() {
         return;
     }
 
-    // Idealy one should only call capture but Qt refuses to take a second capture without
-    // stopping the camera
-    camera->stop();
-    camera->start();
+    // If the camera doesn't capture, test for virtual cameras
+    if (pending_camera_snapshots > 5) {
+        is_virtual_camera = true;
+    }
+    // Virtual cameras like obs need to reset the camera every capture
+    if (is_virtual_camera) {
+        camera->stop();
+        camera->start();
+    }
 
+    pending_camera_snapshots++;
     camera_capture->capture();
 }
 
@@ -870,6 +880,7 @@ void GRenderWindow::OnCameraCapture(int requestId, const QImage& img) {
     camera_data.resize(camera_width * camera_height);
     std::memcpy(camera_data.data(), converted.bits(), camera_width * camera_height * sizeof(u32));
     input_subsystem->GetCamera()->SetCameraData(camera_width, camera_height, camera_data);
+    pending_camera_snapshots = 0;
 }
 
 bool GRenderWindow::event(QEvent* event) {

+ 2 - 0
src/yuzu/bootmanager.h

@@ -240,6 +240,8 @@ private:
     bool first_frame = false;
     InputCommon::TasInput::TasState last_tas_state;
 
+    bool is_virtual_camera;
+    int pending_camera_snapshots;
     std::unique_ptr<QCamera> camera;
     std::unique_ptr<QCameraImageCapture> camera_capture;
     std::unique_ptr<QTimer> camera_timer;

+ 18 - 6
src/yuzu/configuration/configure_camera.cpp

@@ -39,8 +39,8 @@ void ConfigureCamera::PreviewCamera() {
     for (const QCameraInfo& cameraInfo : cameras) {
         if (input_devices[index] == cameraInfo.deviceName().toStdString() ||
             input_devices[index] == "Auto") {
-            LOG_ERROR(Frontend, "Selected Camera {} {}", cameraInfo.description().toStdString(),
-                      cameraInfo.deviceName().toStdString());
+            LOG_INFO(Frontend, "Selected Camera {} {}", cameraInfo.description().toStdString(),
+                     cameraInfo.deviceName().toStdString());
             camera = std::make_unique<QCamera>(cameraInfo);
             camera_found = true;
             break;
@@ -62,12 +62,23 @@ void ConfigureCamera::PreviewCamera() {
     camera->unload();
     camera->setCaptureMode(QCamera::CaptureViewfinder);
     camera->load();
+    camera->start();
+
+    pending_snapshots = 0;
+    is_virtual_camera = false;
 
     camera_timer = std::make_unique<QTimer>();
     connect(camera_timer.get(), &QTimer::timeout, [this] {
-        camera->stop();
-        camera->start();
-
+        // If the camera doesn't capture, test for virtual cameras
+        if (pending_snapshots > 5) {
+            is_virtual_camera = true;
+        }
+        // Virtual cameras like obs need to reset the camera every capture
+        if (is_virtual_camera) {
+            camera->stop();
+            camera->start();
+        }
+        pending_snapshots++;
         camera_capture->capture();
     });
 
@@ -75,10 +86,11 @@ void ConfigureCamera::PreviewCamera() {
 }
 
 void ConfigureCamera::DisplayCapturedFrame(int requestId, const QImage& img) {
-    LOG_ERROR(Frontend, "ImageCaptured {} {}", img.width(), img.height());
+    LOG_INFO(Frontend, "ImageCaptured {} {}", img.width(), img.height());
     const auto converted = img.scaled(320, 240, Qt::AspectRatioMode::IgnoreAspectRatio,
                                       Qt::TransformationMode::SmoothTransformation);
     ui->preview_box->setPixmap(QPixmap::fromImage(converted));
+    pending_snapshots = 0;
 }
 
 void ConfigureCamera::changeEvent(QEvent* event) {

+ 2 - 0
src/yuzu/configuration/configure_camera.h

@@ -44,6 +44,8 @@ private:
 
     InputCommon::InputSubsystem* input_subsystem;
 
+    bool is_virtual_camera;
+    int pending_snapshots;
     std::unique_ptr<QCamera> camera;
     std::unique_ptr<QCameraImageCapture> camera_capture;
     std::unique_ptr<QTimer> camera_timer;