UVC (USB Video Class) Camera
This post was migrated from Tistory. You can find the original here.
Most USB cameras sold on the market follow the UVC (USB Video Class) standard.
There are cases where the descriptor response doesn’t quite match the actual behavior,
but overall, the general structure and behavior still tend to follow the UVC spec.
Let’s take a look at UVC.
Overall UVC Operation Structure
System Layer Perspective
1
2
3
4
5
6
7
8
9
10
11
12
13
[Application]
↓
[UVC Handling Layer]
↓
[USB Transport Layer]
↓
================ USB =================
↓
[UVC Device Firmware]
├─ Control Interface
└─ Streaming Interface (video)
↓
[Sensor + ISP + Image Processing]
Device-Internal Perspective
1
2
3
4
5
6
7
8
9
10
11
[Image Sensor] ← HW
↓
[ISP / Image Processing] ← HW + FW
↓
[CT / PU] ← FW (handles UVC control)
↓
[Encoder] ← FW
↓
[Frame Buffer] ← FW
↓
[USB Endpoint] ← HW + FW
UVC Structure
Control Interface (control channel)
Host → Device (Control Transfer)
Low speed (control transfer)
Descriptor-based
CT (Camera Terminal)
Control items: Exposure, Focus, Zoom, Tilt, …., optical-related settings
PU (Processing Unit)
Control items: Brightness, Contrast, White Balance, Gain, …., ISP (image signal processing) related settings
XU (Extension Unit)
Vendor-specific custom features
VS (Video Streaming) Interface
Through streaming-related information such as format (MJPEG, YUV, etc.), resolution, and FPS, you can determine which streaming modes the device supports.
Device → Host (Isochronous / Bulk Transfer)
High speed, continuous streaming, bandwidth matters
Format Descriptor: MJPEG / YUY2 / H264
Frame Descriptor: resolution / FPS
Endpoint: data transfer channel
1
2
3
4
5
6
7
8
9
10
11
12
VideoStreaming Interface
├─ VS_INPUT_HEADER
├─ VS_FORMAT_MJPEG (bFormatIndex = 1)
│ ├─ VS_FRAME_MJPEG (bFrameIndex = 1) → 640x480 + fps list
│ ├─ VS_FRAME_MJPEG (bFrameIndex = 2) → 1280x720 + fps list
│ ├─ VS_FRAME_MJPEG (bFrameIndex = 3) → 1920x1080 + fps list
│
├─ VS_FORMAT_UNCOMPRESSED (bFormatIndex = 2)
│ ├─ VS_FRAME_UNCOMPRESSED (bFrameIndex = 1)
│ ├─ VS_FRAME_UNCOMPRESSED (bFrameIndex = 2)
└─ Endpoint Descriptor
└─ bmAttributes → determines Iso / Bulk
(Transfer methods)
Isochronous
Guarantees real-time delivery, data loss possible, used by most cameras
Bulk
Higher reliability, has latency, used by some specialized cameras
VS_FRAME_MJPEG (Descriptor) example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bLength 0x1E
bDescriptorType 0x24 (CS_INTERFACE)
bDescriptorSubType 0x07 (VS_FRAME_MJPEG)
bFrameIndex 0x01
bmCapabilities 0x00
wWidth 0x0280 (640)
wHeight 0x01E0 (480)
dwMinBitRate 0x000E1000
dwMaxBitRate 0x002DC6C0
dwMaxVideoFrameBufferSize 0x0004B000
dwDefaultFrameInterval 0x00051615 (333333 → 30fps)
bFrameIntervalType 0x03 (3 fps values)
dwFrameInterval[0] 0x00051615 (333333 → 30fps)
dwFrameInterval[1] 0x000A2C2A (666666 → 15fps)
dwFrameInterval[2] 0x000F4240 (1000000 → 10fps)
USB Device Structure
1
2
3
4
5
6
7
8
9
10
Device
├─ Configuration
│ ├─ Interface
│ │ ├─ Endpoint
│ │ ├─ Endpoint
│ │
│ ├─ Interface
│ ├─ Endpoint
│
└─ Endpoint 0 (Control) ← exception (device-level)
The USB spec defines that Control Transfers go through Endpoint 0.
The UVC spec also uses Control Transfers for negotiation and control.
So CT/PU control is carried out over Control Transfer (EP0),
while video streaming, such as MJPEG, goes through a separate Endpoint.
Endpoint 0 (Control)
Used for initial device communication, UVC control (CT/PU)
Other Endpoints
Used for specific functions (video streaming, audio, HID, …)
UVC Control Flow
CT/PU Descriptor
The GET/SET control request flow based on the CT/PU Descriptor (other descriptors follow the same flow)
1
2
3
4
5
6
7
8
9
10
11
Host (libuvc / libusb)
↓
Read descriptor
↓
Check bmControls
↓
"Ah, brightness is supported"
↓
UVC control request (GET/SET)
↓
Handled by firmware
Check support for a given control by looking at the bmControls value bit by bit
1
2
3
4
5
6
7
8
9
10
11
12
bmControls: 0x17 0x00 (2bytes little Endian)
↓
0x0017 = 23 (decimal)
↓
23 = 0000 0000 0001 0111 (binary)
bit | Feature | Value
0 | Brightness | 1
1 | Contrast | 1
2 | Hue | 1
3 | Saturation | 0
4 | Sharpness | 1
PU Descriptor example
1
2
3
4
5
6
7
8
bLength 0x0B
bDescriptorType 0x24
bDescriptorSubType 0x05 (PROCESSING_UNIT)
bUnitID 0x02
bSourceID 0x01
wMaxMultiplier 0x0000
bmControls 0x17 0x00
iProcessing 0x00
CT Descriptor example
1
2
3
4
5
6
7
8
9
10
11
12
bLength 0x12
bDescriptorType 0x24
bDescriptorSubType 0x02 (CAMERA_TERMINAL)
bTerminalID 0x01
wTerminalType 0x0201 (Camera)
bAssocTerminal 0x00
iTerminal 0x00
wObjectiveFocalLengthMin 0x0000
wObjectiveFocalLengthMax 0x0000
wOcularFocalLength 0x0000
bControlSize 0x03
bmControls 0x0F 0x00 0x00
