avatar

Nihil

Nichts Hsu

  • 首页
  • 子域
  • 分类
  • 标签
  • 归档
  • 关于
首页 抓包查看 UVC 设备选择的分辨率与帧率
文章

抓包查看 UVC 设备选择的分辨率与帧率

发表于 2023/05/29
作者 Nichts Hsu
3 分钟阅读

使用工具: Bus Hound, USB Device Tree Viewer

打开 Bus Hound,转到 Devices 选项卡,在设备列表中找到想抓包的 UVC 设备,勾选其 UVC interface。如果你不确定,可以把全部勾上,不影响:

Bus Hound Devices

通常,Video 帧数据通过 ISOC 传输,为了避免巨量的帧数据影响我们抓包,我们可以在 Settings 选项卡里把 ISOC 取消勾选。当然,一个更简单的方法是,除了必要的 CTL 和 OUT 以外其他的全部取消勾选:

Bus Hound Settings

回到 Capture 选项卡,点击右下角的 Run 按钮开始抓包,然后打开使用该 UVC 设备的程序,抓取 USB 数据包。

在抓到的 USB 数据包中,我们去寻找以 21 01 00 02 开头的 CTL 包以及它紧邻的 OUT 包:

Bus Hound Capture

该 CTL 包以下面的方式解析(注:都是小端序,即,先低字节,后高字节):

bmRequestType bRequest wValue wIndex wLength
0x21 0x01 0x00 0x02 0x01 0x00 0x1a 0x00
  1. bmRequestType 指示请求的方向(Direction),类型(Type)及接收者(Recipient),0x21 代表:Direction = Host to Device, Type = Class, Recipient = Interface。
  2. bRequest 指示请求的内容,0x01 代表 SET_CUR,即 Set Current 的缩写,设置当前属性。
  3. wValue 对于 UVC 而言,其低位必须为 0,高位用于指示 CS(Control Selector)。0x02 对应的 CS 为 VS_COMMIT_CONTROL,用于提交所选择的 UVC 属性(这些属性在随后的 OUT 包中配置)。
  4. wIndex 高位为 0,低位指示目标 interface 的 bInterfaceNumber,如果 UVC 设备有多个可选相机,可以以此进行区分。
  5. wLength 指示尾随的 OUT 包的大小,0x1a 即 26 字节。

之后尾随的 OUT 包的数据格式,可以在规格书 UVC 1.5 Class specification 中的 Table 4-75 Video Probe and Commit Controls 找到完整定义,我们这边不解释它所有字段的含义,仅介绍我们所感兴趣的那几个:

  1. 第三个字节 0x02,表示所选择的 UVC 格式类型描述符的 bFormatIndex,我们通过 USB Device Tree Viewer 可以找到该格式类型为 MJPEG:

    Device Tree View Format

  2. 第四个字节,0x04,表示所选择的 UVC 帧类型描述符的 bFrameIndex,我们通过 USB Device Tree Viewer 可以找到 MJPEG 格式对应的该帧类型为 1920x1080 分辨率:

    Device Tree View Frame

  3. 第五~八字节,0x15 0x16 0x05 0x00,表示所选的 dwFrameInterval,即帧间隔(单位是 100 ns)。由于是小端序,也就是说实际值是 0x00051615 即 333333 * 100ns,则对应的帧率为 30 帧。

教程, USB
usb 教程 uvc 抓包
本文由作者按照 CC BY 4.0 进行授权
分享

最近更新

  • 从另一个视角看 Rust HRTBs
  • C++ Coroutine VS Rust Async
  • Rust 不透明类型上的生命周期
  • USB 2.0 与 USB 3.2
  • Rust 中的闭包递归与 Y 组合子
外部链接
  • 996.icu
  •  此博客的 Github 仓库
  •  Olimi 的个人博客

相关文章

2022/11/01

在高版本系统上为 Qt6 生成 AppImage

前言 目前,大部分的 AppImage 的教程与工具都建议你在最低所支持的系统上进行编译打包,这是由于 Linux 系统的兼容性,在旧版本系统打包的软件可以正常在新版本系统中运行,反过来则不行。 但是这一点对于 Qt 用户尤其是 Qt6 用户而言很不友好:一方面,在旧版本的 Linux 系统上很难安装高版本的 Qt,另一方面,过于老旧的 GCC 不支持大量的 C++ 新特性,需要对代码进...

2022/11/23

C++20 Concept

模板 在为静态类型语言开发代码时,我们很经常遇到这样的情况:我们需要为多个数据类型实现相同的功能。放在 C 语言中,我们不得不为他们各自定义一个函数或结构体,例如: int add(int x, int y); unsigned addu(unsigned x, unsigned y); float addf(float x, float y); // ... struct Vecto...

2022/11/28

Android C++ 生成 compile_commands.json

Android C++ 程序开发现状 在 Android 下开发 C++ 程序,我见过绝大多数人都是不使用任何语法插件,就靠硬写,写完之后再根据编译报错来修改语法错误。这也怪不得程序员,一方面,Android 使用 Arm 平台的 clang 编译器,跟 x86 平台的开发环境并不是很兼容;另一方面,Android 要求我们将 C++ 程序放在 vendor 目录下,但是我们包含的头文件却...

C++ Coroutine VS Rust Async

[C++] 深入了解左值与右值

© 2025 Nichts Hsu. 保留部分权利。

本站采用 Jekyll 主题 Chirpy

热门标签

编程语言 教程 rust c++ android c++20 usb 翻译 linux qt

发现新版本的内容。