Merge branch 'master' into fake-move

This commit is contained in:
Megamouse 2024-12-18 03:54:40 +01:00 committed by GitHub
commit fdb2df0cc7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 78 additions and 41 deletions

View file

@ -784,26 +784,26 @@ s32 cellCameraIsAttached(s32 dev_num)
if (g_cfg.io.camera == camera_handler::null) if (g_cfg.io.camera == camera_handler::null)
{ {
return false; return 0;
} }
auto& g_camera = g_fxo->get<camera_thread>(); auto& g_camera = g_fxo->get<camera_thread>();
if (!g_camera.init) if (!g_camera.init)
{ {
return false; return 0;
} }
if (!check_dev_num(dev_num)) if (!check_dev_num(dev_num))
{ {
return false; return 0;
} }
vm::var<s32> type; vm::var<s32> type;
if (cellCameraGetType(dev_num, type) != CELL_OK) if (cellCameraGetType(dev_num, type) != CELL_OK)
{ {
return false; return 0;
} }
std::lock_guard lock(g_camera.mutex); std::lock_guard lock(g_camera.mutex);
@ -821,12 +821,12 @@ s32 cellCameraIsAttached(s32 dev_num)
} }
} }
return is_attached; return is_attached ? 1 : 0;
} }
s32 cellCameraIsOpen(s32 dev_num) s32 cellCameraIsOpen(s32 dev_num)
{ {
cellCamera.notice("cellCameraIsOpen(dev_num=%d)", dev_num); cellCamera.trace("cellCameraIsOpen(dev_num=%d)", dev_num);
if (g_cfg.io.camera == camera_handler::null) if (g_cfg.io.camera == camera_handler::null)
{ {
@ -852,7 +852,7 @@ s32 cellCameraIsOpen(s32 dev_num)
s32 cellCameraIsStarted(s32 dev_num) s32 cellCameraIsStarted(s32 dev_num)
{ {
cellCamera.notice("cellCameraIsStarted(dev_num=%d)", dev_num); cellCamera.trace("cellCameraIsStarted(dev_num=%d)", dev_num);
if (g_cfg.io.camera == camera_handler::null) if (g_cfg.io.camera == camera_handler::null)
{ {

View file

@ -7,10 +7,10 @@ class null_camera_handler final : public camera_handler_base
public: public:
null_camera_handler() : camera_handler_base() {} null_camera_handler() : camera_handler_base() {}
void open_camera() override { m_state = camera_handler_state::open; } void open_camera() override { set_state(camera_handler_state::open); }
void close_camera() override { m_state = camera_handler_state::closed; } void close_camera() override { set_state(camera_handler_state::closed); }
void start_camera() override { m_state = camera_handler_state::running; } void start_camera() override { set_state(camera_handler_state::running); }
void stop_camera() override { m_state = camera_handler_state::open; } void stop_camera() override { set_state(camera_handler_state::open); }
void set_format(s32 format, u32 bytesize) override void set_format(s32 format, u32 bytesize) override
{ {
@ -45,6 +45,6 @@ public:
height = 0; height = 0;
frame_number = 0; frame_number = 0;
bytes_read = 0; bytes_read = 0;
return m_state; return get_state();
} }
}; };

View file

@ -30,22 +30,29 @@ public:
virtual u64 frame_number() const = 0; // Convenience function to check if there's a new frame. virtual u64 frame_number() const = 0; // Convenience function to check if there's a new frame.
virtual camera_handler_state get_image(u8* buf, u64 size, u32& width, u32& height, u64& frame_number, u64& bytes_read) = 0; virtual camera_handler_state get_image(u8* buf, u64 size, u32& width, u32& height, u64& frame_number, u64& bytes_read) = 0;
camera_handler_state get_state() const { return m_state.load(); }; camera_handler_state get_state() const { return m_state.load(); }
void set_state(camera_handler_state state) { m_state = m_state_expected = state; }
bool mirrored() const { return m_mirrored; }; camera_handler_state get_expected_state() const { return m_state_expected.load(); }
s32 format() const { return m_format; }; void set_expected_state(camera_handler_state state) { m_state_expected = state; }
u32 bytesize() const { return m_bytesize; };
u32 width() const { return m_width; }; bool mirrored() const { return m_mirrored; }
u32 height() const { return m_height; }; s32 format() const { return m_format; }
u32 frame_rate() const { return m_frame_rate; }; u32 bytesize() const { return m_bytesize; }
u32 width() const { return m_width; }
u32 height() const { return m_height; }
u32 frame_rate() const { return m_frame_rate; }
protected: protected:
std::mutex m_mutex; std::mutex m_mutex;
atomic_t<camera_handler_state> m_state = camera_handler_state::closed;
bool m_mirrored = false; bool m_mirrored = false;
s32 m_format = 2; // CELL_CAMERA_RAW8 s32 m_format = 2; // CELL_CAMERA_RAW8
u32 m_bytesize = 0; u32 m_bytesize = 0;
u32 m_width = 640; u32 m_width = 640;
u32 m_height = 480; u32 m_height = 480;
u32 m_frame_rate = 30; u32 m_frame_rate = 30;
private:
atomic_t<camera_handler_state> m_state = camera_handler_state::closed;
atomic_t<camera_handler_state> m_state_expected = camera_handler_state::closed;
}; };

View file

@ -47,6 +47,7 @@ void qt_camera_handler::set_camera(const QCameraDevice& camera_info)
{ {
if (camera_info.isNull()) if (camera_info.isNull())
{ {
set_expected_state(camera_handler_state::closed);
reset(); reset();
return; return;
} }
@ -57,9 +58,9 @@ void qt_camera_handler::set_camera(const QCameraDevice& camera_info)
camera_log.success("Using camera: id=\"%s\", description=\"%s\", front_facing=%d", camera_info.id().toStdString(), camera_info.description(), front_facing); camera_log.success("Using camera: id=\"%s\", description=\"%s\", front_facing=%d", camera_info.id().toStdString(), camera_info.description(), front_facing);
// Create camera and video surface // Create camera and video surface
m_media_capture_session.reset(new QMediaCaptureSession(nullptr)); m_media_capture_session = std::make_unique<QMediaCaptureSession>(nullptr);
m_video_sink.reset(new qt_camera_video_sink(front_facing, nullptr)); m_video_sink = std::make_unique<qt_camera_video_sink>(front_facing, nullptr);
m_camera.reset(new QCamera(camera_info)); m_camera = std::make_unique<QCamera>(camera_info);
connect(m_camera.get(), &QCamera::activeChanged, this, &qt_camera_handler::handle_camera_active); connect(m_camera.get(), &QCamera::activeChanged, this, &qt_camera_handler::handle_camera_active);
connect(m_camera.get(), &QCamera::errorOccurred, this, &qt_camera_handler::handle_camera_error); connect(m_camera.get(), &QCamera::errorOccurred, this, &qt_camera_handler::handle_camera_error);
@ -76,14 +77,37 @@ void qt_camera_handler::handle_camera_active(bool is_active)
{ {
camera_log.notice("Camera active status changed to %d", is_active); camera_log.notice("Camera active status changed to %d", is_active);
if (is_active) // Check if the camera does what it's supposed to do.
const camera_handler_state expected_state = get_expected_state();
switch (expected_state)
{ {
m_state = camera_handler_state::running; case camera_handler_state::closed:
} case camera_handler_state::open:
else
{ {
m_state = camera_handler_state::closed; if (is_active)
{
// This is not supposed to happen and indicates an unexpected QCamera issue
camera_log.error("Camera started unexpectedly");
set_state(camera_handler_state::running);
return;
}
break;
} }
case camera_handler_state::running:
{
if (!is_active)
{
// This is not supposed to happen and indicates an unexpected QCamera issue
camera_log.error("Camera stopped unexpectedly");
set_state(camera_handler_state::open);
return;
}
break;
}
}
set_state(expected_state);
} }
void qt_camera_handler::handle_camera_error(QCamera::Error error, const QString& errorString) void qt_camera_handler::handle_camera_error(QCamera::Error error, const QString& errorString)
@ -100,7 +124,11 @@ void qt_camera_handler::open_camera()
{ {
camera_log.notice("Switching camera from %s to %s", m_camera_id, camera_id); camera_log.notice("Switching camera from %s to %s", m_camera_id, camera_id);
camera_log.notice("Stopping old camera..."); camera_log.notice("Stopping old camera...");
if (m_camera) m_camera->stop(); if (m_camera)
{
set_expected_state(camera_handler_state::open);
m_camera->stop();
}
m_camera_id = camera_id; m_camera_id = camera_id;
} }
@ -129,7 +157,7 @@ void qt_camera_handler::open_camera()
{ {
if (m_camera_id.empty()) camera_log.notice("Camera disabled"); if (m_camera_id.empty()) camera_log.notice("Camera disabled");
else camera_log.error("No camera found"); else camera_log.error("No camera found");
m_state = camera_handler_state::closed; set_state(camera_handler_state::closed);
return; return;
} }
@ -148,7 +176,7 @@ void qt_camera_handler::open_camera()
// Update camera and view finder settings // Update camera and view finder settings
update_camera_settings(); update_camera_settings();
m_state = camera_handler_state::open; set_state(camera_handler_state::open);
} }
void qt_camera_handler::close_camera() void qt_camera_handler::close_camera()
@ -159,11 +187,12 @@ void qt_camera_handler::close_camera()
{ {
if (m_camera_id.empty()) camera_log.notice("Camera disabled"); if (m_camera_id.empty()) camera_log.notice("Camera disabled");
else camera_log.error("No camera found"); else camera_log.error("No camera found");
m_state = camera_handler_state::closed; set_state(camera_handler_state::closed);
return; return;
} }
// Unload/close camera // Unload/close camera
set_expected_state(camera_handler_state::closed);
m_camera->stop(); m_camera->stop();
} }
@ -175,7 +204,7 @@ void qt_camera_handler::start_camera()
{ {
if (m_camera_id.empty()) camera_log.notice("Camera disabled"); if (m_camera_id.empty()) camera_log.notice("Camera disabled");
else camera_log.error("No camera found"); else camera_log.error("No camera found");
m_state = camera_handler_state::closed; set_state(camera_handler_state::closed);
return; return;
} }
@ -206,6 +235,7 @@ void qt_camera_handler::start_camera()
#endif #endif
// Start camera. We will start receiving frames now. // Start camera. We will start receiving frames now.
set_expected_state(camera_handler_state::running);
m_camera->start(); m_camera->start();
} }
@ -217,7 +247,7 @@ void qt_camera_handler::stop_camera()
{ {
if (m_camera_id.empty()) camera_log.notice("Camera disabled"); if (m_camera_id.empty()) camera_log.notice("Camera disabled");
else camera_log.error("No camera found"); else camera_log.error("No camera found");
m_state = camera_handler_state::closed; set_state(camera_handler_state::closed);
return; return;
} }
@ -228,6 +258,7 @@ void qt_camera_handler::stop_camera()
} }
// Stop camera. The camera will still be drawing power. // Stop camera. The camera will still be drawing power.
set_expected_state(camera_handler_state::open);
m_camera->stop(); m_camera->stop();
} }
@ -284,26 +315,26 @@ camera_handler_base::camera_handler_state qt_camera_handler::get_image(u8* buf,
m_camera_id != camera_id) m_camera_id != camera_id)
{ {
camera_log.notice("Switching cameras"); camera_log.notice("Switching cameras");
m_state = camera_handler_state::closed; set_state(camera_handler_state::closed);
return camera_handler_state::closed; return camera_handler_state::closed;
} }
if (m_camera_id.empty()) if (m_camera_id.empty())
{ {
camera_log.notice("Camera disabled"); camera_log.notice("Camera disabled");
m_state = camera_handler_state::closed; set_state(camera_handler_state::closed);
return camera_handler_state::closed; return camera_handler_state::closed;
} }
if (!m_camera || !m_video_sink) if (!m_camera || !m_video_sink)
{ {
camera_log.fatal("Error: camera invalid"); camera_log.fatal("Error: camera invalid");
m_state = camera_handler_state::closed; set_state(camera_handler_state::closed);
return camera_handler_state::closed; return camera_handler_state::closed;
} }
// Backup current state. State may change through events. // Backup current state. State may change through events.
const camera_handler_state current_state = m_state; const camera_handler_state current_state = get_state();
if (current_state == camera_handler_state::running) if (current_state == camera_handler_state::running)
{ {

View file

@ -17,8 +17,6 @@ public:
qt_camera_handler(); qt_camera_handler();
virtual ~qt_camera_handler(); virtual ~qt_camera_handler();
void set_camera(const QCameraDevice& camera_info);
void open_camera() override; void open_camera() override;
void close_camera() override; void close_camera() override;
void start_camera() override; void start_camera() override;
@ -31,11 +29,12 @@ public:
camera_handler_state get_image(u8* buf, u64 size, u32& width, u32& height, u64& frame_number, u64& bytes_read) override; camera_handler_state get_image(u8* buf, u64 size, u32& width, u32& height, u64& frame_number, u64& bytes_read) override;
private: private:
void set_camera(const QCameraDevice& camera_info);
void reset(); void reset();
void update_camera_settings(); void update_camera_settings();
std::string m_camera_id; std::string m_camera_id;
std::shared_ptr<QCamera> m_camera; std::unique_ptr<QCamera> m_camera;
std::unique_ptr<QMediaCaptureSession> m_media_capture_session; std::unique_ptr<QMediaCaptureSession> m_media_capture_session;
std::unique_ptr<qt_camera_video_sink> m_video_sink; std::unique_ptr<qt_camera_video_sink> m_video_sink;