alliedvision / VimbaPython

Old Allied Vision Vimba Python API. The successor to this API is VmbPy
BSD 2-Clause "Simplified" License
93 stars 40 forks source link

Async grab for 2 cameras results in incomplete frames being grabbed #26

Open cnavarrete opened 3 years ago

cnavarrete commented 3 years ago

Hello, my problem is the following: First I connected an ALVIUM 1800 U-501M NIR to a jetson Xavier nx without any problems. I can reach 67fps without any incomplete frames (I had to change the MaxTransferSize to the windows value). Now the problem appears when I connect 2 cameras, when I do that I only recieve incomplete frames.

What I tried so far: I modified the height and width of the cameras to capture 1920x1080 frames, this way I can actually recieve frames, but some incomplete frames are still mixed in (30% of the total frames aprox). Trying to work with the full image (2592 x 1944) I changed the DeviceLinkThrougputLimit to the default value, which of course reduced the fps, but now I can recieve complete frames, but again some incomplete frames are still being delivered.

NiklasKroeger-AlliedVision commented 3 years ago

Connecting a second camera to the same USB root hub probably saturates the throughput of that device. Taking a look at the datasheet for the camera you mentioned the maximum framerate is given as 67 fps at ≥350 MByte/s, Mono8. The 350 MByte/s are equivalent to 350*8 = 2800 Mbit/s. If I am not mistaken the USB3 ports of the Jetson devices have advertised transfer rates of 5 Gbits/s (USB 3.1 Super Speed Gen 1). So connecting two cameras of this type to the same USB device does indeed exceed the available transfer rate. You would need to either reduce the fps you wish to transmit or reduce the image size as you already suggested you tried.

Another thing to keep in mind is that the transmission of the camera frames might not be evenly distributed over time. Depending on the acquisition settings of your connected cameras there might be times where the bus is not carrying any data, and other times where both cameras wish to transfer an image at the same time. This uneven load distribution could be another factor in the number of incomplete frames you are seeing, as one of the devices will not be able to send out it's frame data fast enough in that case.

One thing you might do is reduce the DeviceLinkThroughputLimit for both cameras such that their sum is less than the transfer rate of your USB device. I would also suggest you reduce it enough to allow for some overhead (~5 to 10%).

Some quick math to get a rough estimate for the DeviceLinkThroughputLimit assuming two cameras with approximately equal bandwidth requirements:

Theoretical Available Bandwidth (maximum):  5000 MBit/s
Target Bandwidth for transmission:          0.9 * 5000 = 4500 MBit/s
Available Bandwidth per device:             0.5 * 4500 = 2250 MBit/s
Change units to MByte/s:                    2250 / 8 = 281.25 MByte/s
Suggested setting for DeviceLinkThroughputLimit (unit for this is Byte/s): 281250000

Additionally you might be able to improve your USB streaming experience if you increase the usbfs buffer size of your system as described in our application note regarding usb camera handling on Linux.

One more thing I noticed:

I had to change the MaxTransferSize to the windows value

This suggests that you are not using the newest Vimba version currently available. Vimba 4.2 was released earlier this month and does include some changes to the USB transport layer. Among them is the change of the default value for MaxTransferSize on Linux to the value you chose. Perhaps you could try to use this newer version and see if that brings additional improvements.

If you have further questions feel free to also contact our support via the form on our website. As this issue is not strictly related to VimbaPython but instead a more general support request our support team might have additional input for you and be better able to help you.

cnavarrete commented 3 years ago

Thanks, while doing everything you suggested surely helped the rate at which I can capture complete images, in the end I'm still recivieng some incomplete frames. I also tested 1080p@60fps but in the end it's the same even if the DeviceLinkThroughputLimit value is 130636800 Bytes/s way lower than the value you suggested.

Another thing to keep in mind is that the transmission of the camera frames might not be evenly distributed over time. Depending on the acquisition settings of your connected cameras there might be times where the bus is not carrying any data, and other times where both cameras wish to transfer an image at the same time. This uneven load distribution could be another factor in the number of incomplete frames you are seeing, as one of the devices will not be able to send out it's frame data fast enough in that case.

Will try to undestand what you mean by this, since a have a hunch that here lies the final problem. Perhaps it's about the acquisition settings values. Guess I need to find a way to evenly distribute the frames.