diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 2d9b2d954b..4306fe9658 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -111,6 +111,7 @@ struct EmuCallbacks std::function display_sleep_control_supported; std::function enable_display_sleep; std::function check_microphone_permissions; + std::function()> make_video_source; }; namespace utils diff --git a/rpcs3/headless_application.cpp b/rpcs3/headless_application.cpp index ee7cd42cee..0d0eb8d834 100644 --- a/rpcs3/headless_application.cpp +++ b/rpcs3/headless_application.cpp @@ -8,6 +8,7 @@ #include "Emu/Cell/Modules/sceNpTrophy.h" #include "Emu/Io/Null/null_camera_handler.h" #include "Emu/Io/Null/null_music_handler.h" +#include "util/video_source.h" #include @@ -173,6 +174,8 @@ void headless_application::InitializeCallbacks() callbacks.check_microphone_permissions = [](){}; + callbacks.make_video_source = [](){ return nullptr; }; + Emu.SetCallbacks(std::move(callbacks)); } diff --git a/rpcs3/rpcs3qt/gui_application.cpp b/rpcs3/rpcs3qt/gui_application.cpp index 077e05ca68..b170737e43 100644 --- a/rpcs3/rpcs3qt/gui_application.cpp +++ b/rpcs3/rpcs3qt/gui_application.cpp @@ -27,6 +27,7 @@ #include "Emu/vfs_config.h" #include "util/init_mutex.hpp" #include "util/console.h" +#include "qt_video_source.h" #include "trophy_notification_helper.h" #include "save_data_dialog.h" #include "msg_dialog_frame.h" @@ -955,6 +956,8 @@ void gui_application::InitializeCallbacks() }); }; + callbacks.make_video_source = [](){ return std::make_unique(); }; + Emu.SetCallbacks(std::move(callbacks)); } diff --git a/rpcs3/rpcs3qt/qt_video_source.cpp b/rpcs3/rpcs3qt/qt_video_source.cpp index 2338c09bf8..9537f89127 100644 --- a/rpcs3/rpcs3qt/qt_video_source.cpp +++ b/rpcs3/rpcs3qt/qt_video_source.cpp @@ -14,9 +14,9 @@ qt_video_source::~qt_video_source() stop_movie(); } -void qt_video_source::set_video_path(const std::string& path) +void qt_video_source::set_video_path(const std::string& video_path) { - m_video_path = QString::fromStdString(path); + m_video_path = QString::fromStdString(video_path); } void qt_video_source::set_active(bool active) @@ -209,14 +209,14 @@ qt_video_source_wrapper::~qt_video_source_wrapper() }); } -void qt_video_source_wrapper::set_video_path(const std::string& path) +void qt_video_source_wrapper::set_video_path(const std::string& video_path) { - Emu.BlockingCallFromMainThread([this, &path]() + Emu.CallFromMainThread([this, path = video_path]() { m_qt_video_source = std::make_unique(); m_qt_video_source->m_image_change_callback = [this](const QVideoFrame& frame) { - std::lock_guard lock(m_qt_video_source->m_image_mutex); + std::unique_lock lock(m_qt_video_source->m_image_mutex); if (m_qt_video_source->m_movie) { @@ -236,12 +236,30 @@ void qt_video_source_wrapper::set_video_path(const std::string& path) { m_qt_video_source->m_image.convertTo(QImage::Format_RGBA8888); } + + lock.unlock(); + + notify_update(); }; m_qt_video_source->set_video_path(path); + }); +} + +void qt_video_source_wrapper::set_active(bool active) +{ + Emu.CallFromMainThread([this, active]() + { m_qt_video_source->set_active(true); }); } +bool qt_video_source_wrapper::get_active() const +{ + ensure(m_qt_video_source); + + return m_qt_video_source->get_active(); +} + void qt_video_source_wrapper::get_image(std::vector& data, int& w, int& h, int& ch, int& bpp) { ensure(m_qt_video_source); diff --git a/rpcs3/rpcs3qt/qt_video_source.h b/rpcs3/rpcs3qt/qt_video_source.h index f8b2267e5f..aa6e61af94 100644 --- a/rpcs3/rpcs3qt/qt_video_source.h +++ b/rpcs3/rpcs3qt/qt_video_source.h @@ -17,17 +17,14 @@ public: qt_video_source(); virtual ~qt_video_source(); - void set_video_path(const std::string& path) override; + void set_video_path(const std::string& video_path) override; const QString& video_path() const { return m_video_path; } void get_image(std::vector& data, int& w, int& h, int& ch, int& bpp) override; bool has_new() const override { return m_has_new; } virtual void set_active(bool active); - [[nodiscard]] bool get_active() const - { - return m_active; - } + bool get_active() const override { return m_active; } void start_movie(); void stop_movie(); @@ -67,9 +64,11 @@ public: qt_video_source_wrapper() : video_source() {} virtual ~qt_video_source_wrapper(); - void set_video_path(const std::string& path) override; - void get_image(std::vector& data, int& w, int& h, int& ch, int& bpp) override; + void set_video_path(const std::string& video_path) override; + void set_active(bool active) override; + bool get_active() const override; bool has_new() const override { return m_qt_video_source && m_qt_video_source->has_new(); } + void get_image(std::vector& data, int& w, int& h, int& ch, int& bpp) override; private: std::unique_ptr m_qt_video_source; diff --git a/rpcs3/util/video_source.h b/rpcs3/util/video_source.h index b5737bccc0..9449ed238e 100644 --- a/rpcs3/util/video_source.h +++ b/rpcs3/util/video_source.h @@ -1,20 +1,33 @@ #pragma once #include "types.hpp" +#include class video_source { public: video_source() {}; virtual ~video_source() {}; - virtual void set_video_path(const std::string& path) { static_cast(path); } - virtual bool has_new() const { return false; }; - virtual void get_image(std::vector& data, int& w, int& h, int& ch, int& bpp) + virtual void set_video_path(const std::string& video_path) = 0; + virtual void set_active(bool active) = 0; + virtual bool get_active() const = 0; + virtual bool has_new() const = 0; + virtual void get_image(std::vector& data, int& w, int& h, int& ch, int& bpp) = 0; + + void set_update_callback(std::function callback) { - static_cast(data); - static_cast(w); - static_cast(h); - static_cast(ch); - static_cast(bpp); + m_update_callback = callback; } + +protected: + void notify_update() + { + if (m_update_callback) + { + m_update_callback(); + } + } + +private: + std::function m_update_callback; };