Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions src/utils/ps4_camera_firmware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,21 @@ upload_firmware(libusb_context *context, libusb_device *dev, const std::vector<c
int res;

PSMOVE_VERIFY((res = libusb_open(dev, &handle)) == 0, "res = %d", res);
#if !defined(__APPLE__)
// On macOS, libusb_reset_device() triggers a re-enumeration that drops
// the device off the bus and invalidates the handle, so skip it there.
PSMOVE_VERIFY((res = libusb_reset_device(handle)) == 0, "res = %d", res);
PSMOVE_VERIFY((res = libusb_set_configuration(handle, 1)) == 0, "res = %d", res);
#endif
res = libusb_set_configuration(handle, 1);
#if defined(__APPLE__)
// macOS already selects configuration 1 via AppleUSBHostCompositeDevice;
// tolerate a set_configuration failure as long as we can claim interface 0.
if (res != 0) {
PSMOVE_WARNING("libusb_set_configuration failed (res = %d), continuing", res);
}
#else
PSMOVE_VERIFY(res == 0, "res = %d", res);
#endif
Comment on lines +107 to +121

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Maybe this becomes clearer if there's only a single #if defined(__APPLE__) and an else branch instead of two separated by the libusb_set_configuration() call, especially since it seems like the call isn't necessary (or is it?) on macOS systems?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I wasn't able to reproduce the issue you were seeing in macOS 26.6 on a 2021 M1 Max MacBook Pro.

The only problem that sporadically happens is that the call to libusb_exit() hangs (possibly to be expected, with the device disconnecting and us not calling libusb_close()), but that seems to not be an issue, as the camera already enumerated as UVC device, and Ctrl+C'ing the process works around the hang. If we know the tool is always called as command-line utility, it would probably be fine to skip the call to libusb_exit() and just let the operating system take care of cleaning up after us.

I tried connecting both ways:

  • PS5 camera directly (via USB-C-to-USB-A-3.0 adapter) on the MacBook Pro
  • PS5 camera via a USB 3.0 hub (and that via USB-C-to-USB-A-3.0 adapter) on the MacBook Pro

The firmware file I'm using has a SHA-1 hash of 0fa4da31a12b662a9a80abc8b84932770df8f7e1.

A subsequent run of psmove test-camera (making sure PSMOVE_USE_PS3EYE_DRIVER=OFF in CMake) properly uses the camera and crops its image accordingly.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

For the libusb_exit() hang, there's now #525

PSMOVE_VERIFY((res = libusb_claim_interface(handle, 0)) == 0, "res = %d", res);

static constexpr const size_t CHUNK_SIZE = 512;
Expand Down Expand Up @@ -220,10 +233,12 @@ Optional parameters:
const char *model = nullptr;

libusb_device *parent_dev = libusb_get_parent(dev);
struct libusb_device_descriptor pdesc;
libusb_get_device_descriptor(parent_dev, &pdesc);
struct libusb_device_descriptor pdesc = {};
if (parent_dev != nullptr) {
libusb_get_device_descriptor(parent_dev, &pdesc);
}

if (PS4_TO_PS5_ADAPTER_ID.matches(pdesc)) {
if (parent_dev != nullptr && PS4_TO_PS5_ADAPTER_ID.matches(pdesc)) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The parent_dev != nullptr check is also in line 237 above, can be combined, and pdesc scan be scoped in the if block that has checked parent_dev != nullptr already.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This is now #524

model = "PS4 camera w/ PS4 Camera Adapter (CFI-ZAA1)";
camera_is_ps4 = true;
} else if (camera_is_ps4) {
Expand Down