Skip to content

Camera#1815

Open
capitalistspz wants to merge 13 commits intocemu-project:mainfrom
capitalistspz:camera2
Open

Camera#1815
capitalistspz wants to merge 13 commits intocemu-project:mainfrom
capitalistspz:camera2

Conversation

@capitalistspz
Copy link
Contributor

Couldn't merge properly, so here's a new branch.
Mostly the same as the other one.

@capitalistspz capitalistspz marked this pull request as draft February 26, 2026 12:07
@capitalistspz capitalistspz marked this pull request as ready for review February 28, 2026 14:01
Copy link
Member

@Exzap Exzap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using std mutex will clash with Cafe OS primitives.
Any function that can block or resume a thread (OSJoinThread, OSSignalEvent, OSResumeThread, OSSleepTicks, OSLockMutex..) can yield the current fiber and start running other PPC threads.

Take this example:

// part of a HLE function
OSSleepTicks(ONE_SECOND);

Instead of blocking the host thread for one second, coreinit threading will instead suspend the host fiber (or ucontext in posix terms) assigned to the current PPC thread. Then the PPC scheduler picks the next PPC thread to run and continues doing work. Eventually after the sleep timeout occurs the scheduler will switch back and resume the fiber from within OSSleepTicks. From the code's perspective the 1 second delay happened, but the actual CPU emulation thread never actually slept. In multicore emulation it can even be a different host thread that returned from OSSleepTicks.

I hope this explanation makes sense. What currently happens is that you carry the std mutex into other PPC threads because you are calling OS functions which can context switch. It can easily lead to deadlocks or race conditions.

The solution is to use OSMutex over std::mutex in HLE code. OSMutex cannot be used outside of PPC contexts, so in that case you have to use std::mutex but need to make sure that you are not holding the lock while calling any OS* functions.

CapContext s_ctx;
std::optional<CapDeviceID> s_device;
std::optional<CapStream> s_stream;
std::array<uint8, CAMERA_RGB_BUFFER_SIZE> s_rgbBuffer;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For larger buffers it's better to use std::vector and resize on Init and then clear+shrink_to_fit on Deinit. Code should be designed so that if a system isn't active it should only use minimal memory.

CameraManager.h
Rgb2Nv12.cpp
Rgb2Nv12.h
CameraManager.h
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source files are listed twice here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants