On Fri, Mar 22, 2024 at 09:32:56AM +0100, Ricardo Ribalda wrote: > On Fri, 22 Mar 2024 at 00:44, Laurent Pinchart wrote: > > On Wed, Mar 15, 2023 at 02:30:14PM +0100, Ricardo Ribalda wrote: > > > Logitech C922 internal SOF does not increases at a stable rate of 1kHz. > > > > The next thing you know they will redefine to value of pi to be 3. > > > > > This causes that the device_sof and the host_sof run at different rates, > > > breaking the clock domain conversion algorithm. Eg: > > > > > > 30 (6) [-] none 30 614400 B 21.245557 21.395214 34.133 fps ts mono/SoE > > > 31 (7) [-] none 31 614400 B 21.275327 21.427246 33.591 fps ts mono/SoE > > > 32 (0) [-] none 32 614400 B 21.304739 21.459256 34.000 fps ts mono/SoE > > > 33 (1) [-] none 33 614400 B 21.334324 21.495274 33.801 fps ts mono/SoE > > > * 34 (2) [-] none 34 614400 B 21.529237 21.527297 5.130 fps ts mono/SoE > > > * 35 (3) [-] none 35 614400 B 21.649416 21.559306 8.321 fps ts mono/SoE > > > 36 (4) [-] none 36 614400 B 21.678789 21.595320 34.045 fps ts mono/SoE > > > ... > > > 99 (3) [-] none 99 614400 B 23.542226 23.696352 33.541 fps ts mono/SoE > > > 100 (4) [-] none 100 614400 B 23.571578 23.728404 34.069 fps ts mono/SoE > > > 101 (5) [-] none 101 614400 B 23.601425 23.760420 33.504 fps ts mono/SoE > > > * 102 (6) [-] none 102 614400 B 23.798324 23.796428 5.079 fps ts mono/SoE > > > * 103 (7) [-] none 103 614400 B 23.916271 23.828450 8.478 fps ts mono/SoE > > > 104 (0) [-] none 104 614400 B 23.945720 23.860479 33.957 fps ts mono/SoE > > > > > > Instead of disabling completely the hardware timestamping for such > > > hardware we take the assumption that the packet handling jitter is > > > under 2ms and use the host_sof as dev_sof. > > > > > > We can think of the UVC hardware clock as a system with a coarse clock > > > (the SOF) and a fine clock (the PTS). The coarse clock can be replaced > > > with a clock on the same frequency, if the jitter of such clock is > > > smaller than its sampling rate. That way we can save some of the > > > precision of the fine clock. > > > > > > To probe this point we have run three experiments on the Logitech C922. > > > On that experiment we run the camera at 33fps and we analyse the > > > difference in msec between a frame and its predecessor. If we display > > > the histogram of that value, a thinner histogram will mean a better > > > meassurement. The results for: > > > - original hw timestamp: https://ibb.co/D1HJJ4x > > > - pure software timestamp: https://ibb.co/QC9MgVK > > > - modified hw timestamp: https://ibb.co/8s9dBdk > > > > > > This bug in the camera firmware has been confirmed by the vendor. > > > > > > lsusb -v > > > > > > Bus 001 Device 044: ID 046d:085c Logitech, Inc. C922 Pro Stream Webcam > > > Device Descriptor: > > > bLength 18 > > > bDescriptorType 1 > > > bcdUSB 2.00 > > > bDeviceClass 239 Miscellaneous Device > > > bDeviceSubClass 2 > > > bDeviceProtocol 1 Interface Association > > > bMaxPacketSize0 64 > > > idVendor 0x046d Logitech, Inc. > > > idProduct 0x085c C922 Pro Stream Webcam > > > bcdDevice 0.16 > > > iManufacturer 0 > > > iProduct 2 C922 Pro Stream Webcam > > > iSerial 1 80B912DF > > > bNumConfigurations 1 > > > > > > Reviewed-by: Sergey Senozhatsky <senozhatsky@xxxxxxxxxxxx> > > > Signed-off-by: Ricardo Ribalda <ribalda@xxxxxxxxxxxx> > > > --- > > > drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++ > > > drivers/media/usb/uvc/uvc_video.c | 8 ++++++++ > > > drivers/media/usb/uvc/uvcvideo.h | 1 + > > > 3 files changed, 18 insertions(+) > > > > > > diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c > > > index 7aefa76a42b3..678a5736c9df 100644 > > > --- a/drivers/media/usb/uvc/uvc_driver.c > > > +++ b/drivers/media/usb/uvc/uvc_driver.c > > > @@ -2549,6 +2549,15 @@ static const struct usb_device_id uvc_ids[] = { > > > .bInterfaceSubClass = 1, > > > .bInterfaceProtocol = 0, > > > .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_RESTORE_CTRLS_ON_INIT) }, > > > + /* Logitech HD Pro Webcam C922 */ > > > + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE > > > + | USB_DEVICE_ID_MATCH_INT_INFO, > > > + .idVendor = 0x046d, > > > + .idProduct = 0x085c, > > > + .bInterfaceClass = USB_CLASS_VIDEO, > > > + .bInterfaceSubClass = 1, > > > + .bInterfaceProtocol = 0, > > > + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_INVALID_DEVICE_SOF) }, > > > /* Chicony CNF7129 (Asus EEE 100HE) */ > > > { .match_flags = USB_DEVICE_ID_MATCH_DEVICE > > > | USB_DEVICE_ID_MATCH_INT_INFO, > > > diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c > > > index 1f416c494acc..4d566edb73e7 100644 > > > --- a/drivers/media/usb/uvc/uvc_video.c > > > +++ b/drivers/media/usb/uvc/uvc_video.c > > > @@ -547,6 +547,14 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, > > > stream->clock.last_sof = dev_sof; > > > > > > host_sof = usb_get_current_frame_number(stream->dev->udev); > > > + > > > + /* > > > + * On some devices, like the Logitech C922, the device SOF does not run > > > + * at a stable rate of 1kHz. For those devices use the host SOF instead. > > > > I'm still not very convinced, as without a formal proof I think there's > > some luck involved, and it may break later. This being said, given that > > this is gated by a quirk, it won't impact other devices, and we can deal > > with regressions when they happen. Could we record it here: > > > > * On some devices, like the Logitech C922, the device SOF does not run > > * at a stable rate of 1kHz. For those devices use the host SOF instead. > > * This improves the timestamp precision in the tests performed so far, > > * even if the exact reason hasn't been fully determined. > > > > or something along those lines ? > > How does this sound: > > /* > * On some devices, like the Logitech C922, the device SOF does not run > * at a stable rate of 1kHz. For those devices use the host SOF instead. > + * In the tests performed so far, this improves the timestamp precision. > + * This is probably explained by a small packet handling jitter from the > + * host, but the exact reason hasn't been fully determined. > */ Sounds nicer than my text :-) > > Reviewed-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx> > > > > > + */ > > > + if (stream->dev->quirks & UVC_QUIRK_INVALID_DEVICE_SOF) > > > + dev_sof = host_sof; > > > + > > > time = uvc_video_get_time(); > > > > > > /* > > > diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h > > > index 9a596c8d894a..07b2fdb80adf 100644 > > > --- a/drivers/media/usb/uvc/uvcvideo.h > > > +++ b/drivers/media/usb/uvc/uvcvideo.h > > > @@ -73,6 +73,7 @@ > > > #define UVC_QUIRK_FORCE_Y8 0x00000800 > > > #define UVC_QUIRK_FORCE_BPP 0x00001000 > > > #define UVC_QUIRK_WAKE_AUTOSUSPEND 0x00002000 > > > +#define UVC_QUIRK_INVALID_DEVICE_SOF 0x00004000 > > > > > > /* Format flags */ > > > #define UVC_FMT_FLAG_COMPRESSED 0x00000001 > > > -- Regards, Laurent Pinchart