Hi Terence, (CC'ing Paul Elder, Kieran Bingham and Felipe Balbi) On Saturday, 3 November 2018 23:07:33 EET Terence Neill wrote: > Hi folks, > > Thanks for the replies, I really appreciate them. I've made some progress > on this. I'm new to USB so apologies if the following text is incorrect or > is just bizarre!: > > 1. The problem with streaming_maxpacket set to 2048 seemed to be caused by > not enough requests being queued with the dwc3 driver at one time, resulting > in request starvation at higher bandwidths. Increasing the value of the > UVC_NUM_REQUESTS macro from 4 to 16 (in drivers/usb/gadget/function/uvc.h) > seemed to fix this problem. This clearly needs to be fixed. I wonder if we should try to compute a good value at runtime, or go for a large enough fixed value for all cases. > 2. It looks like the problem that was happening with max_packet set to 3072 > was caused by the isochronous transfer being queued for a microframe number > in the past (the assumption is that there is the code just wasn't getting > the first microframe queued in time). To get around this problem, I changed > the DWC3_ALIGN_FRAME() macro to add an offset of one video frame (the video > is running at 10fps so about 800 microframes). This fixed the startup > problem at high bandwidth. At the moment, the objective of the > investigation is to prove throughput, so some latency can be accommodated. Felipe has worked on this recently, but if I recall correctly there were still issues that prevented patches from being upstreamed. > With these two changes, the video streams at higher bandwidth but freezes > sporadically. This problem seems to be caused by the following (there's a > bit of guesswork going on in this explanation): > > a. The video stream that is being transmitted has less bandwidth than > available on the USB link (1280x720@10fps uncompressed). It looks like > about 150Mbps versus the 192Mbps for the USB link. That's a good start, it would be more troublesome if we were trying to transmit video that required more bandwidth than available :-) > b. The video is not transmitted evenly and, at the end of each video frame > time there are a number of microframes where there is no data to transmit. > c. When the next video packet is queued with the dwc3 driver after the gap > in transmission, the driver generates a string of missed isoc events (it > looks like a missed isoc event for every previous microframe that has been > missed). These events come as a burst into the driver (after every new > frame is queued into the dwc3). > d. This is reported back to the f_uvc driver via the uvc_video_complete() > function call. The f_uvc tidies up it's queues based on the callback, but > the dwc3 driver hasn't transmitted any data (it is reporting the missed isoc > from previously). This seems to cause the video to freeze (dumping frames > before they are transmitted). The UVC gadget driver indeed doesn't handle the missed interval errors correctly. That's the known issue I mentioned previously, and unfortunately haven't had time to handle :-( > As a quick hack, I changed uvc_video_complete() so that it requeued the > request on receipt of the -EXDEV. This has fixed the freezing video but > there is video corruption (not surprised as the fix was just to prove that > the freezing was caused by the missed isocs). I think that this tallies > with what you are saying Laurent about the handling of missed isocs. > > From reading some more about USB, it looks like isochronous transfers may > have the option sending zero length packets whenever there is no data to > send? Is this true? If so, would this be a possible option to move forward > with this issue - eliminating the need to handle missed isocs at the f_uvc > layer? We will always have to handle the missed intervals, as something could go wrong and result in such a situation, and we don't want to freeze the stream in that case. Transmitting 0-length packets could be an option, but I wonder how much CPU overhead it would generate (both on the gadget and host side). Felipe, do you have any experience with this and/or recommendation ? > In addition, I've moved on to testing at superspeed (with the same video > source 1280x720@10fps uncompressed). At the moment, with the superspeed > link set to a burst size of 16 and an interval of 8, the dwc3 driver will > not stream at all, it continuously reports missed isoc events for all > microframes despite having the delay added in (2) above. Has anyone any > experience using isochronous transfers with the dwc3 driver at superspeed? Not much on our side, we had to stop before getting to SS (I was testing on a TI Beagleboard-x15 which is limited to HS, and Kieran on another SoC that supported SS). > I was reading the summary of the dwc3 driver features at > https://github.com/torvalds/linux/blob/master/Documentation/driver-api/usb/d > wc3.rst and point 7 mentions support for "Superspeed Bulk Streams" but I > was unsure if this meant that ONLY bulk streams were supported or whether > isochronous streams were also supported? That's a question for Felipe :-) -- Regards, Laurent Pinchart