On Tue, Oct 13, 2026 at 02:15:36PM -0700, Avichal Rakesh wrote: > > On 10/11/26 8:40 PM, Daehwan Jung wrote: > > uvc_video_prep_requests() spreads a frame over every service interval of > > the negotiated frame interval: > > > > nreq = DIV_ROUND_UP(video->interval, interval_duration); > > > > and uvc_buffer_prepare() then splits every buffer into exactly > > reqs_per_frame requests - only the request size varies, never the count. > > So transmitting one frame always occupies nreq service intervals, 100% of > > the frame interval, with nothing left over. > > > > That budget cannot be met. While no video buffer is available, > > uvcg_video_hw_submit() deliberately keeps a backlog of zero length > > requests queued to the endpoint: > > > > if (list_empty(&video->req_free) || > > (atomic_read(&video->queued) > UVCG_REQ_MAX_ZERO_COUNT)) { > > > > Up to UVCG_REQ_MAX_ZERO_COUNT + 1 of them are in flight whenever the > > encoder is late, each occupying a service interval that carries no > > payload, and the ring is FIFO so they all drain before the next frame's > > payload moves. The frame period is therefore reqs_per_frame plus that > > backlog, always longer than the frame interval the host asked for. The > > UVCG_REQ_MAX_ZERO_COUNT compensation already in this function only sizes > > the request pool; it buys the backlog no time. > > > > At 60fps over SuperSpeed with bInterval 1 the backlog is 33 of the 133 > > intervals a frame interval has - 4.125ms, a quarter of the budget. The > > waste is a fixed count, so it hurts in inverse proportion to the frame > > interval: 24.8% at 60fps down to 6.2% at 15fps. > > > > Reserve it. Measured on a SuperSpeed gadget (isoc IN, wMaxPacketSize > > 1024, bMaxBurst 2, bInterval 1) running the Android DeviceAsWebcam > > service, as reported by the CTS Verifier "Camera - Webcam" test, next to > > the rate the microframe accounting predicts: > > > > target predicted measured | predicted measured > > (before) (before) | (after) (after) > > 60 47.9 46 | 59.7 56 > > 30 26.7 26 | 30.0 28 > > 24 21.8 22 | 24.5 22 > > 15 14.1 13 | 16.0 13 > > We recently fixed this exact issue in Android's DeviceAsWebcam client. In > our case, DeviceAsWebcam was only queuing a frame when the previous one was > returned. > > With the changes to uvc_video_prep_requests(), a frame stays queued for one > frame interval, and subsequent ioctl/scheduling delays meant that the gadget > driver had to insert empty requests between two frames bringing down the > effective FPS. > > Our fix was to maintain two queued buffers to UVC Gadget Driver ensuring > that the UVC gadget driver has a frame ready to send immediately after one > is complete. This prevents insertion of zero length requests between two > consecutive frames (fixing the FPS degradation you see) and gives > DeviceAsWebcam a little bit of breathing room for ioctl and scheduling > delays. > > It is not clear if you are working with Android or not. If not, it is well > worth checking if you have the same issue as us instead of adding an > arbitrary headroom here. The numbers you report are extremely similar to > what we were seeing. > > If this was motivated from Android's DeviceAsWebcam, take a look at > https://android-review.googlesource.com/c/platform/packages/services/DeviceAsWebcam/+/4353888 > and the comments in that change. > > The change itself has been abandoned but it has context on the underlying > issue, fix, and where to find the fix until it makes its way to AOSP. > > Best Regards, > Avi > Thanks for sharing it. I'm working with Android. Let me check AOSP. Best Regards, Daehwan Jung