mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-06 00:40:11 +00:00
cellCamera: try to fix internal state on stop
When stopping, the camera is supposed to be open still. Add an expected state to check the camera signal does what it should.
This commit is contained in:
parent
73a62b4bf6
commit
f3ef4f3658
@ -784,26 +784,26 @@ s32 cellCameraIsAttached(s32 dev_num)
|
||||
|
||||
if (g_cfg.io.camera == camera_handler::null)
|
||||
{
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto& g_camera = g_fxo->get<camera_thread>();
|
||||
|
||||
if (!g_camera.init)
|
||||
{
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!check_dev_num(dev_num))
|
||||
{
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
vm::var<s32> type;
|
||||
|
||||
if (cellCameraGetType(dev_num, type) != CELL_OK)
|
||||
{
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
cellCamera.notice("cellCameraIsOpen(dev_num=%d)", dev_num);
|
||||
cellCamera.trace("cellCameraIsOpen(dev_num=%d)", dev_num);
|
||||
|
||||
if (g_cfg.io.camera == camera_handler::null)
|
||||
{
|
||||
@ -852,7 +852,7 @@ s32 cellCameraIsOpen(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)
|
||||
{
|
||||
|
@ -7,10 +7,10 @@ class null_camera_handler final : public camera_handler_base
|
||||
public:
|
||||
null_camera_handler() : camera_handler_base() {}
|
||||
|
||||
void open_camera() override { m_state = camera_handler_state::open; }
|
||||
void close_camera() override { m_state = camera_handler_state::closed; }
|
||||
void start_camera() override { m_state = camera_handler_state::running; }
|
||||
void stop_camera() override { m_state = camera_handler_state::open; }
|
||||
void open_camera() override { set_state(camera_handler_state::open); }
|
||||
void close_camera() override { set_state(camera_handler_state::closed); }
|
||||
void start_camera() override { set_state(camera_handler_state::running); }
|
||||
void stop_camera() override { set_state(camera_handler_state::open); }
|
||||
|
||||
void set_format(s32 format, u32 bytesize) override
|
||||
{
|
||||
@ -45,6 +45,6 @@ public:
|
||||
height = 0;
|
||||
frame_number = 0;
|
||||
bytes_read = 0;
|
||||
return m_state;
|
||||
return get_state();
|
||||
}
|
||||
};
|
||||
|
@ -30,22 +30,29 @@ public:
|
||||
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;
|
||||
|
||||
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; };
|
||||
s32 format() const { return m_format; };
|
||||
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; };
|
||||
camera_handler_state get_expected_state() const { return m_state_expected.load(); }
|
||||
void set_expected_state(camera_handler_state state) { m_state_expected = state; }
|
||||
|
||||
bool mirrored() const { return m_mirrored; }
|
||||
s32 format() const { return m_format; }
|
||||
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:
|
||||
std::mutex m_mutex;
|
||||
atomic_t<camera_handler_state> m_state = camera_handler_state::closed;
|
||||
bool m_mirrored = false;
|
||||
s32 m_format = 2; // CELL_CAMERA_RAW8
|
||||
u32 m_bytesize = 0;
|
||||
u32 m_width = 640;
|
||||
u32 m_height = 480;
|
||||
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;
|
||||
};
|
||||
|
@ -47,6 +47,7 @@ void qt_camera_handler::set_camera(const QCameraDevice& camera_info)
|
||||
{
|
||||
if (camera_info.isNull())
|
||||
{
|
||||
set_expected_state(camera_handler_state::closed);
|
||||
reset();
|
||||
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);
|
||||
|
||||
// Create camera and video surface
|
||||
m_media_capture_session.reset(new QMediaCaptureSession(nullptr));
|
||||
m_video_sink.reset(new qt_camera_video_sink(front_facing, nullptr));
|
||||
m_camera.reset(new QCamera(camera_info));
|
||||
m_media_capture_session = std::make_unique<QMediaCaptureSession>(nullptr);
|
||||
m_video_sink = std::make_unique<qt_camera_video_sink>(front_facing, nullptr);
|
||||
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::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);
|
||||
|
||||
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;
|
||||
}
|
||||
else
|
||||
case camera_handler_state::closed:
|
||||
case camera_handler_state::open:
|
||||
{
|
||||
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)
|
||||
@ -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("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;
|
||||
}
|
||||
|
||||
@ -129,7 +157,7 @@ void qt_camera_handler::open_camera()
|
||||
{
|
||||
if (m_camera_id.empty()) camera_log.notice("Camera disabled");
|
||||
else camera_log.error("No camera found");
|
||||
m_state = camera_handler_state::closed;
|
||||
set_state(camera_handler_state::closed);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -148,7 +176,7 @@ void qt_camera_handler::open_camera()
|
||||
// Update camera and view finder settings
|
||||
update_camera_settings();
|
||||
|
||||
m_state = camera_handler_state::open;
|
||||
set_state(camera_handler_state::open);
|
||||
}
|
||||
|
||||
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");
|
||||
else camera_log.error("No camera found");
|
||||
m_state = camera_handler_state::closed;
|
||||
set_state(camera_handler_state::closed);
|
||||
return;
|
||||
}
|
||||
|
||||
// Unload/close camera
|
||||
set_expected_state(camera_handler_state::closed);
|
||||
m_camera->stop();
|
||||
}
|
||||
|
||||
@ -175,7 +204,7 @@ void qt_camera_handler::start_camera()
|
||||
{
|
||||
if (m_camera_id.empty()) camera_log.notice("Camera disabled");
|
||||
else camera_log.error("No camera found");
|
||||
m_state = camera_handler_state::closed;
|
||||
set_state(camera_handler_state::closed);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -206,6 +235,7 @@ void qt_camera_handler::start_camera()
|
||||
#endif
|
||||
|
||||
// Start camera. We will start receiving frames now.
|
||||
set_expected_state(camera_handler_state::running);
|
||||
m_camera->start();
|
||||
}
|
||||
|
||||
@ -217,7 +247,7 @@ void qt_camera_handler::stop_camera()
|
||||
{
|
||||
if (m_camera_id.empty()) camera_log.notice("Camera disabled");
|
||||
else camera_log.error("No camera found");
|
||||
m_state = camera_handler_state::closed;
|
||||
set_state(camera_handler_state::closed);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -228,6 +258,7 @@ void qt_camera_handler::stop_camera()
|
||||
}
|
||||
|
||||
// Stop camera. The camera will still be drawing power.
|
||||
set_expected_state(camera_handler_state::open);
|
||||
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)
|
||||
{
|
||||
camera_log.notice("Switching cameras");
|
||||
m_state = camera_handler_state::closed;
|
||||
set_state(camera_handler_state::closed);
|
||||
return camera_handler_state::closed;
|
||||
}
|
||||
|
||||
if (m_camera_id.empty())
|
||||
{
|
||||
camera_log.notice("Camera disabled");
|
||||
m_state = camera_handler_state::closed;
|
||||
set_state(camera_handler_state::closed);
|
||||
return camera_handler_state::closed;
|
||||
}
|
||||
|
||||
if (!m_camera || !m_video_sink)
|
||||
{
|
||||
camera_log.fatal("Error: camera invalid");
|
||||
m_state = camera_handler_state::closed;
|
||||
set_state(camera_handler_state::closed);
|
||||
return camera_handler_state::closed;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
|
@ -17,8 +17,6 @@ public:
|
||||
qt_camera_handler();
|
||||
virtual ~qt_camera_handler();
|
||||
|
||||
void set_camera(const QCameraDevice& camera_info);
|
||||
|
||||
void open_camera() override;
|
||||
void close_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;
|
||||
|
||||
private:
|
||||
void set_camera(const QCameraDevice& camera_info);
|
||||
void reset();
|
||||
void update_camera_settings();
|
||||
|
||||
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<qt_camera_video_sink> m_video_sink;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user