yuzu: Add webcam support and rebase to latest master

This commit is contained in:
Narr the Reg 2022-06-28 19:35:51 -05:00 committed by german77
parent 097785e19e
commit 403bdc4daf
8 changed files with 43 additions and 16 deletions

View file

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

View file

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

View file

@ -529,7 +529,7 @@ void IRS::ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx) {
rb.Push(ResultSuccess); 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 > if (camera_handle.npad_id >
static_cast<u8>(NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld))) { static_cast<u8>(NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld))) {
return InvalidIrCameraHandle; return InvalidIrCameraHandle;

View file

@ -57,7 +57,7 @@ private:
void StopImageProcessorAsync(Kernel::HLERequestContext& ctx); void StopImageProcessorAsync(Kernel::HLERequestContext& ctx);
void ActivateIrsensorWithFunctionLevel(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( Core::IrSensor::DeviceFormat& GetIrCameraSharedMemoryDeviceEntry(
const Core::IrSensor::IrCameraHandle& camera_handle); const Core::IrSensor::IrCameraHandle& camera_handle);

View file

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

View file

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

View file

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

View file

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