Question on USB webcams and filter drivers

I am trying to develop a webcam filter driver (upper filter driver) that just monitors streams as they pass by but I want to extend the functionality.

I have written something that loads and is able to read the streams. I have done basic verification with the built in camera app (So I run camera app, driver attaches a read completion routine and can read the stream data). I also have code to deal with camera app (or higher app) changing camera capture resolution. It is not bullet proof but that is WIP and I am sure it does not handle everything. I have verified I can capture streams when running camera app, google meet, msft teams.

I have 2 USB cameras Logitech C920 and Logitech C720. When i plug them into my system running Windows 10 (20H2), I notice that C920 shows up in Imaging devices and C720 shows up in cameras. My INF file for my driver only installs as upper filter for imaging devices class guid. This class GUID is documented by Microsoft.

When I open the Device Manager for C920, I can see my driver installed there. My driver installs as an upper filter driver for ksthunk.sys to monitor streams.
I think if I installed as an upper filter driver for usbvideo.sys, I would not know how to decode the streams unless I am willing to read the USB video class specification.

Since my INF file does not have the class GUID for cameras, my driver does not install as an upper filter driver on the device stack for C720.

My questions are:
a) What causes 2 similar looking USB cameras (both of which presumably implement the USB video specification) to show up differently?
I have not decoded the USB descriptors using USBView to see what is different but I am curious.

b) Since I want my driver to support both types of cameras, I need to modify my INF file to support both class GUIDs.
Is it possible to have one single INF file to install with more than one class GUID?. I cannot find any samples in windows driver samples
I can obviously modify my INF file to create another for the new class GUID but I would need to maintain 2 INF files.

c) Currently, my driver is just reading the streams on their way up and sampling the video streams at a constant resolution.
If I wanted my driver to send a command to the camera to take a snapshot, where would I find the documentation for sending such a command?
I am not sure if a “sample” of the video stream is the same as a snapshot.

Here are the 2 class GUIDs from microsoft documentation.

C720 logitech falls under the first GUID and C920 falls under the second guid. The guids are retrieved from the device manager.

Camera Device
Class = Camera
ClassGuid = {ca3e7ab9-b4c3-4ae6-8251-579ef933890f}
(Windows 10 version 1709 and later versions of Windows) This class includes universal camera drivers.

Imaging Device
Class = Image
ClassGuid = {6bdd1fc6-810f-11d0-bec7-08002be2092f}
This class includes still-image capture devices, digital cameras, and scanners.

I am not a video or camera type of guy but I am quite comfortable with drivers.

Thanks,
RK

An INF can belong to one and only one device class. If you want to filter both Imaging and Camera device classes, you need an INF per class. As to why there are two device classes, I can only guess as to why there is a change (my guess @Tim_Roberts knows in detail). My guess is that imagine is the older class that encompasses scanners, digital cameras, etc and the Camera class is meant for webcams and live cameras you can attach to the PC. As to how they match to a different class, open the properties of each device in device manager and go to the Details tab and look at the Matching device id value. If it is an inbox INF match, it will most be compatible ID derived from a usb defined device class code. I attached a logitech c925e and it matches on USB\Class_0e

@Doron_Holan thank you very much for the answer. Much appreciated. I see the same behavior if I passthrough the 2 cameras onto my Virtualbox VM running Windows 10 so I am thinking this behavior is due to property of the cameras not the underlying hardware. I will have to look at the device class code but it looks like I will need 2 INF files. Yuck but oh well!!!

The “Camera” class is relatively new (WIndows 8? Windows 10? I don’t recall). Before that cameras were all in the “Image” class. The “Camera” class makes more sense, but it’s unfortunate that it was such a late arrival.

Despite appearances, the two devices must be installed differently. One of them must have a custom INF. Don’t assume they’re both UVC.

Installing a class filter is easy. There’s no reason not to do both.

If you are an upper filter, then you are seeing the Kernel Streaming interface. Commands are sent as KS properties. KSPROPERTY_VIDEOCONTROL_CAPS has a caps bit (KS_VideoControlFlag_Trigger) that triggers a snapshot, assuming the camera supports them. Not all of them do. The only reason to support snapshot is if the camera is capable of higher resolutions for stills. Otherwise, you’d just grab a frame from the stream. You’d have to check the descriptors for that, and the still format would have to be configured.

@Tim_Roberts thank you very much. I think I will just settle for grabbing a frame from the stream (in the interest of not making this too complex than it has to be).

Dumb question. I have an INF file for the image class upper filter. Can I not just repurpose that for the upper filter for the camera class?. I guess I am trying to parse your statement that says “One of them must have a custom INF”. According to Doron, I will need one INF file per one classGUID. I do want to support both types of devices (image and camera)

Can I assume that ksthunk.sys will be the upper filter on top of all cameras that Windows supports (USB, some other interface…)?. My INF file installs my driver as upper filter of ksthunk.sys. I only have 2 cameras to test. I am sure the universe of cameras that Windows supports is much higher (USB, PCIe, thunderbolt?).

How do you install as an upper filter of ksthunk? You can certainly be a class filter for both classes (using two INFs).

@Tim_Roberts I should correct myself here. I have an install program that just creates the registry entry as HKLM,SYSTEM\CurrentControlSet\Control\Class{6BDD1FC6-810F-11D0-BEC7-08002BE2092F},UpperFilters,0x00010008,. I also have the INF file but I am sure I do not need the INF file for installation.

1 Like

You don’t need the inf if you are using an installer to update the registry. The installer can update both classes. With no INF, the installer is responsible for copying the files and registering the service for your filter driver.

1 Like