TheImagingSource / tiscamera

The Linux SDK for The Imaging Source cameras.
https://www.theimagingsource.com
Apache License 2.0
299 stars 148 forks source link

Degraded performance when using USB SuperSpeed+ #521

Closed hitimr closed 1 year ago

hitimr commented 1 year ago

Describe the bug USB defines multiple bandwidth speeds:

When connecting a camera to a SuperSpeed+ system the camera shows degraded performance and connections issues despite offering twice the bandwidth.

To Reproduce

  1. Plug in a DFK 33UX547 (requires 5Gb/s)
  2. Using TCAM-Ctrl set the resolution and framerate to maximum (2448x2048, 74 FPS)
  3. Enable stream mode and observe FPS counter in the bottom left corner
  4. Depending on your host device:
    • SuperSpeed: Framerate = 74FSP
    • SuperSpeed+: Framerate = 40 - 60FPS (depends on HW and how many devices are connected)

Expected behavior SuperSpeed+ connections should achieve at least the same performance as SuperSpeed

computer used (please complete the following information):

Root cause libus.h uses the following enumeration for the different standards:

enum libusb_speed {
    /** The OS doesn't report or know the device speed. */
    LIBUSB_SPEED_UNKNOWN = 0,

    /** The device is operating at low speed (1.5MBit/s). */
    LIBUSB_SPEED_LOW = 1,

    /** The device is operating at full speed (12MBit/s). */
    LIBUSB_SPEED_FULL = 2,

    /** The device is operating at high speed (480MBit/s). */
    LIBUSB_SPEED_HIGH = 3,

    /** The device is operating at super speed (5000MBit/s). */
    LIBUSB_SPEED_SUPER = 4,

    /** The device is operating at super speed plus (10000MBit/s). */
    LIBUSB_SPEED_SUPER_PLUS = 5
};

The SDK uses the following check to determine whether SuperSpeed is supported.

https://github.com/TheImagingSource/tiscamera/blob/ee45fcf7da4e952cb529194b9f470e9dd5cf3e61/src/libusb/LibusbDevice.cpp#L127-L139

Note that the check uses ==. Hence if SuperSpeed+ (LIBUSB_SPEED_SUPER_PLUS = 5) or any other future standard is used, the function will always return false and perform as if SuperSpeed is not available.

Replacing the == with >= and recompiling the SDK solves the problem (see linked PR)

TIS-Edgar commented 1 year ago

Hi,

Thank you for your report and merge request.

The DFK 33UX547 can be opened via v4l2 or aravis. Neither uses code in src/libusb.

v4l2 does not use libusb Usb3Vision in aravis does not check for speed limitations to adjust behavior, at least to my understanding.

How does the patch exactly solve your issue?

It is still a valid patch for the AFU420, which is the only camera currently using the is_superspeed function, so I have no problem accepting the patch once we could clear up any missunderstandings.

hitimr commented 1 year ago

Hi Edgar,

thank you for your Reply.

I tested the camera again with the official release version (both 1.0.0 and 1.1.1). This time I was not able to reproduce the problem I described above. The camera achieved full performance using v4l2. Why I was observing the issue in the first place a cannot tell unfortunately. My best guess is that there was some issue with my setup (OS, driver or SDK) and it was fixed by reinstalling the SDK (which I did after compiling the patched code)

I would still like to point out that I can only achieve full performance using v4l2. Using aravis the connection is unstable. Is this a known issue?

TIS-Edgar commented 1 year ago

USB on laptops can be weird. Especially when considering power saving modes and similar behaviors. We disabled power saving for our cameras with 1.1.0, see this commit. Maybe that has something to do with your observations.

I would still like to point out that I can only achieve full performance using v4l2. Using aravis the connection is unstable. Is this a known issue?

I suspect that the performance issues arise from the fact that aravis uses user space image acquisition. Since aravis, in comparison to v4l2, does not have a kernel module it is much more prone to interrupts and such, which may cause problems. As a remedy you can set the priority of threads as described here: https://www.theimagingsource.com/en-us/documentation/tiscamera/optimizations.html?highlight=thread#real-time-threading

The capture thread already tries to get the highest priority possible so enabling that should be all you have to do.

EmmanuelP commented 1 year ago

Hi,

I suspect that the performance issues arise from the fact that aravis uses user space image acquisition. Since aravis, in comparison to v4l2, does not have a kernel module it is much more prone to interrupts and such, which may cause problems. As a remedy you can set the priority of threads as described here: https://www.theimagingsource.com/en-us/documentation/tiscamera/optimizations.html?highlight=thread#real-time-threading

Aravis default behavior is to use the libusb synchronous API, which does not offer the best performance. You may want to try the asynchronous mode. I don't know if TIS software has a knob for it, but meanwhile, you can try and see if things improve when you switch to asynchronous mode using arv-camera-test-0.8.

arv-camera-test-0.8 --usb-mode=async
TIS-Edgar commented 1 year ago

I have merged your commit. If you have additional information concerning the behavior you are seeing reopen this issue.