RK3568 USB Camera

UVC

Posted by LXG on December 10, 2025

相机曝光

曝光(Exposure)= 传感器接收的光量

影响曝光的因素主要有三项:

  1. 曝光时间(Exposure Time / Shutter) — 像素采集光的时间,越长越亮。

  2. 增益(Gain / ISO) — 电路放大信号,越高越亮,但噪点越大。

  3. 光圈(Aperture) — UVC USB 摄像头一般 没有可变光圈,所以不考虑

名称 英文 控制对象 物理含义 影响效果 对应 Camera2 对应 V4L2(UVC)
曝光时间 Exposure Time / Shutter 时间 图像传感器曝光光的时长 亮度变化大、动态模糊 ANDROID_SENSOR_EXPOSURE_TIME(单位 ns) V4L2_CID_EXPOSURE_ABSOLUTE(单位 100µs)
曝光增益 ISO / Gain 电子放大 把传感器采集的信号放大 亮度增加但噪点变多 ANDROID_SENSOR_SENSITIVITY V4L2_CID_GAINV4L2_CID_ISO_SENSITIVITY
曝光补偿 EV Compensation 自动曝光算法 让 AE(自动曝光)往亮/暗偏移 AE 自动调节曝光时间和增益 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION 一般没有(UVC 几乎不支持)

自动曝光 VS 手动曝光

对比项 自动曝光(AE) 手动曝光(Manual Exposure)
曝光控制方式 由摄像头 ISP 或 UVC 固件根据画面亮度动态调节曝光时间 + 增益 程序员直接设置曝光时间(shutter)和增益(gain/ISO)
亮度稳定性 低,亮度随着场景变化波动 极高,亮度稳定不变
响应光线变化 快速 or 慢(UVC 常常慢) 不响应外界光线变化,完全固定
适用场景 视频聊天、拍照、直播、一般预览 OCR(快递面单)、条码、工业视觉、机器人
UVC 支持情况 100% 支持(所有相机必须支持 AE) 有些 UVC 摄像头不支持 manual,尤其是廉价方案
Android Camera2 支持情况 CONTROL_AE_MODE_ON 即可 需要 CONTROL_AE_MODE_OFF + 设置 SENSOR_EXPOSURE_TIMESENSOR_SENSITIVITY
调节参数 AE bias、AE compensation shutter、gain、frame duration
对画面噪点影响 动态变化,光线弱时噪点暴增 你自行控制 gain,噪点可控
抗闪烁能力(50/60Hz) AE 可能出现明暗跳动(尤其在 LED 灯下) 可固定曝光到频率整数倍,彻底避免闪烁
白平衡(AWB)依赖 AE 调节会影响 AWB 曲线 独立于曝光,画面更稳定
亮度跳变现象 常见(快/暗场景切换时特别明显) 完全无,亮度不会突然变化
曝光过程平滑性 ISP 硬件决定,有时出现“呼吸效应” 无呼吸效应,因为曝光不变
帧率影响 AE 可能降低帧率(为提高亮度自动拉长曝光) 可强制锁定 FPS,不被曝光干扰
逆光场景表现 背光严重时整体变暗或人物过曝 固定曝光但可能欠曝,需要补光
算法适配难度(AI 识别) 难,模型输入亮度变化大 极低,模型输入稳定一致
开发复杂度 简单 中等,需要调曝光参数
调试成本 需要用示波仪/光功率计或反复拍照调参
对机器视觉的价值 ❌ 不推荐,容易导致识别不稳定 ✔ 强烈推荐,识别成功率大幅提升
在你 UVC 崩溃场景中 AE 高频调节可能导致驱动压力变大 手动更稳定,一般不会触发频繁 ioctl
在光线非常弱时 AE 会自动把 gain 调得很高(噪点爆炸) 你可以限制 gain 上限,牺牲亮度换质量
是否可冻结曝光 AE 模式不能冻结(即使 lock 也会部分变化) 完全冻结
是否需要 ISP 支持 需要 不需要
适合的相机参数文件(PID/VID) 普通摄像头即可 推荐有手动曝光控件的 UVC 摄像头
是否影响自动对焦(AF) AE 变化会让 AF 算法误判 手动曝光更适合固定焦距摄像头

RK3568 dumpsys camera


rk3568_r:/ $ dumpsys media.camera | grep -A 1 ae
      android.control.aeAvailableAntibandingModes (10012): byte[1]
        [3 ]   # 支持的抗频闪模式只有一种:3 = AUTO(自动抗频闪)
--
      android.control.aeAvailableModes (10013): byte[1]
        [1 ]   # 仅支持 AE_MODE_ON(自动曝光),不支持手动曝光(AE=OFF)
--
      android.control.aeCompensationRange (10015): int32[2]
        [0 0 ] # 曝光补偿范围固定为 0~0,表示不支持曝光补偿(EV 调节无效)
      android.control.aeCompensationStep (10016): rational[1]
        [(0 / 1) ] # 曝光补偿步进为 0,进一步说明 EV 功能完全不可用
--
      android.control.aeLockAvailable (10024): byte[1]
        [FALSE ]  # 不支持 AE 锁定(无法锁住自动曝光,亮度会一直自动变化)
--
      android.control.aeAvailableTargetFpsRanges (10014): int32[12]
        [1 2 1 3 ] # FPS 范围异常(正常应为 15–30、30–30 等),说明相机未正确上报帧率能力

RK3568 上 Camera HAL 对外接 UVC 相机只开放了自动曝光(AE_MODE_ON),没有开放手动曝光和 AE 锁定功能,而不是摄像头本身完全不支持手动曝光

Camera HAL


rk3568_android_11/hardware/interfaces/camera$ adb shell dumpsys media.camera | grep "== Camera"
== Camera Provider HAL legacy/0 (v2.5, remote) static info: 0 devices: ==
== Camera Provider HAL external/0 (v2.5, remote) static info: 1 devices: ==
== Camera HAL device device@3.4/external/100 (v3.4) static information: ==
== Camera HAL device device@3.4/external/100 (v3.4) dumpState: ==

lxg@lxg:~/code/project/rk3568_android_11/hardware/interfaces/camera$ tree -L 2
.
├── common
│   ├── 1.0
│   └── README.md
├── device
│   ├── 1.0
│   ├── 3.2
│   ├── 3.3
│   ├── 3.4
│   ├── 3.5
│   ├── 3.6
│   └── README.md
├── metadata
│   ├── 3.2
│   ├── 3.3
│   ├── 3.4
│   │   ├── Android.bp
│   │   ├── default
│   │   │   ├── Android.bp
│   │   │   ├── Android.go
│   │   │   ├── CameraDevice.cpp
│   │   │   ├── CameraDeviceSession.cpp
│   │   │   ├── convert.cpp
│   │   │   ├── ExternalCameraDevice.cpp
│   │   │   ├── ExternalCameraDeviceSession.cpp
│   │   │   ├── ExternalCameraGralloc4.cpp
│   │   │   ├── ExternalCameraGralloc.cpp
│   │   │   ├── ExternalCameraMemManager.cpp
│   │   │   ├── ExternalCameraUtils.cpp
│   │   │   ├── ExternalFakeCameraDevice.cpp
│   │   │   ├── ExternalFakeCameraDeviceSession.cpp
│   │   │   ├── include
│   │   │   │   ├── convert.h
│   │   │   │   ├── device_v3_4_impl
│   │   │   │   ├── ext_device_v3_4_impl
│   │   │   │   └── vpu_inc
│   │   │   ├── OWNERS
│   │   │   ├── RgaCropScale.cpp
│   │   │   └── rkvpu_dec_api.cpp
│   │   ├── ICameraDeviceCallback.hal
│   │   ├── ICameraDeviceSession.hal
│   │   └── types.hal
│   ├── 3.5
│   └── README.md
├── provider
│   ├── 2.4
│   ├── 2.5
│   │   ├── Android.bp
│   │   ├── default
│   │   │   ├── Android.bp
│   │   │   ├── android.hardware.camera.provider@2.5-external-service.rc
│   │   │   ├── android.hardware.camera.provider@2.5-service_64.rc
│   │   │   ├── android.hardware.camera.provider@2.5-service-lazy_64.rc
│   │   │   ├── android.hardware.camera.provider@2.5-service-lazy.rc
│   │   │   ├── android.hardware.camera.provider@2.5-service.rc
│   │   │   ├── CameraProvider_2_5.h
│   │   │   ├── ExternalCameraProviderImpl_2_5.cpp
│   │   │   ├── ExternalCameraProviderImpl_2_5.h
│   │   │   ├── external-service.cpp
│   │   │   ├── LegacyCameraProviderImpl_2_5.cpp
│   │   │   ├── LegacyCameraProviderImpl_2_5.h
│   │   │   ├── OWNERS
│   │   │   └── service.cpp
│   │   ├── ICameraProvider.hal
│   │   └── types.hal
│   ├── 2.6
│   └── README.md
└── README.md

HAL 类型 版本 源码目录
Camera Provider HAL 2.5 hardware/interfaces/camera/provider/2.5/default/ExternalCameraProviderImpl_2_5.cpp
Camera Device HAL 3.4 hardware/interfaces/camera/metadata/3.4/default/ExternalCameraDevice.cpp (USB/外部摄像头实现)

源码中曝光配置

函数 作用
initDefaultCharsKeys 默认值/模式,比如 AE、AWB 默认开启
initCameraControlsCharsKeys 静态特性,硬件支持什么,比如 ISO/曝光范围
initOutputCharsKeys 输出能力,如分辨率、帧率、format
initAvailableCapabilities Camera API 可用能力列表,告知上层支持哪些模式(RAW/JPEG/Video)

status_t ExternalCameraDevice::initCameraCharacteristics() {
    if (mCameraCharacteristics.isEmpty()) {
        // init camera characteristics
        unique_fd fd(::open(mDevicePath.c_str(), O_RDWR));
        if (fd.get() < 0) {
            ALOGE("%s: v4l2 device open %s failed", __FUNCTION__, mDevicePath.c_str());
            return DEAD_OBJECT;
        }

        status_t ret;
        ret = initDefaultCharsKeys(&mCameraCharacteristics);
        if (ret != OK) {
            ALOGE("%s: init default characteristics key failed: errorno %d", __FUNCTION__, ret);
            mCameraCharacteristics.clear();
            return ret;
        }

        ret = initCameraControlsCharsKeys(fd.get(), &mCameraCharacteristics);
        if (ret != OK) {
            ALOGE("%s: init camera control characteristics key failed: errorno %d", __FUNCTION__, ret);
            mCameraCharacteristics.clear();
            return ret;
        }

        ret = initOutputCharsKeys(fd.get(), &mCameraCharacteristics);
        if (ret != OK) {
            ALOGE("%s: init output characteristics key failed: errorno %d", __FUNCTION__, ret);
            mCameraCharacteristics.clear();
            return ret;
        }

        ret = initAvailableCapabilities(&mCameraCharacteristics);
        if (ret != OK) {
            ALOGE("%s: init available capabilities key failed: errorno %d", __FUNCTION__, ret);
            mCameraCharacteristics.clear();
            return ret;
        }
    }
    return OK;
}


status_t ExternalCameraDevice::initDefaultCharsKeys(
        ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
    const uint8_t hardware_level = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL;
    UPDATE(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &hardware_level, 1);

    // android.control
    const uint8_t antibandingMode =
        ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
    UPDATE(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
           &antibandingMode, 1);

    const int32_t controlMaxRegions[] = {/*AE*/ 0, /*AWB*/ 0, /*AF*/ 0};
    UPDATE(ANDROID_CONTROL_MAX_REGIONS, controlMaxRegions,
           ARRAY_SIZE(controlMaxRegions));

    const uint8_t aeAvailableMode = ANDROID_CONTROL_AE_MODE_ON;
    UPDATE(ANDROID_CONTROL_AE_AVAILABLE_MODES, &aeAvailableMode, 1);


}


status_t ExternalCameraDevice::initCameraControlsCharsKeys(int,
        ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
    // android.control
    // No AE compensation support for now.
    // TODO: V4L2_CID_EXPOSURE_BIAS
    const int32_t controlAeCompensationRange[] = {0, 0};
    UPDATE(ANDROID_CONTROL_AE_COMPENSATION_RANGE, controlAeCompensationRange,
           ARRAY_SIZE(controlAeCompensationRange));
    const camera_metadata_rational_t controlAeCompensationStep[] = 0;
    UPDATE(ANDROID_CONTROL_AE_COMPENSATION_STEP, controlAeCompensationStep,
           ARRAY_SIZE(controlAeCompensationStep));
}

函数 作用 影响曝光的地方
initDefaultCharsKeys 初始化默认相机特性、模式 设置 ANDROID_CONTROL_AE_AVAILABLE_MODES = ON,表示自动曝光默认开启。它只告诉上层“AE模式可用”,但不包含范围信息。
initCameraControlsCharsKeys 初始化硬件控制能力(静态信息) 设置 ANDROID_CONTROL_AE_COMPENSATION_RANGE = {0,0}AE_COMPENSATION_STEP = {0,1},告诉上层没有手动曝光能力

曝光设置流程图


[Camera App / Camera2 API]
          |
          |  setExposureCompensation / setAeMode
          v
[Camera Framework (CameraService / CameraDevice)]
          |
          |  读取 CameraMetadata
          |  AE mode: ON
          |  AE compensation range: 0~0 (不支持手动曝光)
          v
[ExternalCameraDevice HAL]
          |
          |  initDefaultCharsKeys()  -> 设置 AE mode ON
          |  initCameraControlsCharsKeys() -> AE compensation range {0,0}
          |  接收到 setExposureCompensation 时:
          |       如果 range={0,0} -> 忽略,无法修改
          v
[V4L2 Driver / /dev/videoX]
          |
          |  V4L2_CID_EXPOSURE_ABSOLUTE  V4L2_CID_EXPOSURE_AUTO
          |  如果 HAL 没映射 -> 硬件曝光无法修改
          v
[Camera Sensor Hardware]

判断摄像头是否支持手动曝光

控制名 类型 说明
exposure_auto menu min=0 max=3 default=3 value=3 自动曝光模式,常见值:
0=关闭,1=自动,2=快门优先,3=光圈优先(或者厂商定义)
exposure_absolute int min=50 max=10000 step=1 default=166 value=166 flags=inactive 曝光时间(单位通常为 100µs 或 µs,具体看驱动),目前 inactive,说明当前 exposure_auto 没关闭
exposure_auto_priority bool default=0 value=0 AE 优先级控制

1|rk3568_r:/ # v4l2-ctl --all -d /dev/video0
Driver Info:
	Driver name      : uvcvideo
	Card type        : USB Camera: 
	Bus info         : usb-fd880000.usb-1
	Driver version   : 4.19.255
	Capabilities     : 0x84a00001
		Video Capture
		Metadata Capture
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps      : 0x04200001
		Video Capture
		Streaming
		Extended Pix Format
Media Driver Info:
	Driver name      : uvcvideo
	Model            : USB Camera: 
	Serial           : 200901010001
	Bus info         : usb-fd880000.usb-1
	Media version    : 4.19.255
	Hardware revision: 0x00000007 (7)
	Driver version   : 4.19.255
Interface Info:
	ID               : 0x03000002
	Type             : V4L Video
Entity Info:
	ID               : 0x00000001 (1)
	Name             : USB Camera: 
	Function         : V4L2 I/O
	Pad 0x01000007   : Sink
	  Link 0x02000010: from remote pad 0x100000a of entity 'Extension 4': Data, Enabled, Immutable
Priority: 2
Video input : 0 (Camera 1: ok)
Format Video Capture:
	Width/Height      : 1920/1080
	Pixel Format      : 'MJPG'
	Field             : None
	Bytes per Line    : 0
	Size Image        : 4147200
	Colorspace        : sRGB
	Transfer Function : Default (maps to sRGB)
	YCbCr/HSV Encoding: Default (maps to ITU-R 601)
	Quantization      : Default (maps to Full Range)
	Flags             : 
Crop Capability Video Capture:
	Bounds      : Left 0, Top 0, Width 1920, Height 1080
	Default     : Left 0, Top 0, Width 1920, Height 1080
	Pixel Aspect: 1/1
Selection: crop_default, Left 0, Top 0, Width 1920, Height 1080, Flags: 
Selection: crop_bounds, Left 0, Top 0, Width 1920, Height 1080, Flags: 
Streaming Parameters Video Capture:
	Capabilities     : timeperframe
	Frames per second: 30.000 (30/1)
	Read buffers     : 0
                     brightness 0x00980900 (int)    : min=-64 max=64 step=1 default=0 value=0
                       contrast 0x00980901 (int)    : min=0 max=100 step=1 default=50 value=50
                     saturation 0x00980902 (int)    : min=0 max=100 step=1 default=64 value=64
                            hue 0x00980903 (int)    : min=-180 max=180 step=1 default=0 value=0
 white_balance_temperature_auto 0x0098090c (bool)   : default=1 value=1
                          gamma 0x00980910 (int)    : min=100 max=500 step=1 default=300 value=320
           power_line_frequency 0x00980918 (menu)   : min=0 max=2 default=1 value=1
      white_balance_temperature 0x0098091a (int)    : min=2800 max=6500 step=10 default=4600 value=4600 flags=inactive
                      sharpness 0x0098091b (int)    : min=0 max=100 step=1 default=55 value=50
         backlight_compensation 0x0098091c (int)    : min=0 max=2 step=1 default=0 value=0
                  exposure_auto 0x009a0901 (menu)   : min=0 max=3 default=3 value=3
              exposure_absolute 0x009a0902 (int)    : min=50 max=10000 step=1 default=166 value=166 flags=inactive
         exposure_auto_priority 0x009a0903 (bool)   : default=0 value=0
                   pan_absolute 0x009a0908 (int)    : min=-57600 max=57600 step=3600 default=0 value=0
                  tilt_absolute 0x009a0909 (int)    : min=-43200 max=43200 step=3600 default=0 value=0
                  zoom_absolute 0x009a090d (int)    : min=0 max=3 step=1 default=0 value=0


可以看出当前摄像头是支持手动曝光的, 但是不支持曝光增益和曝光补偿

控制类别 是否支持 说明
曝光时间(Shutter) ✔ 支持 exposure_absolute 可调(前提:auto=1)
曝光增益(ISO / Gain) ❌ 不支持 控件列表中无相关控制
曝光补偿(EV) ❌ 不支持 无 V4L2_CID_EXPOSURE_COMPENSATION

手动关闭自动曝光时间


rk3568_r:/ # v4l2-ctl -d /dev/video0 -c exposure_auto=1 

rk3568_r:/ # v4l2-ctl --all -d /dev/video0

                  exposure_auto 0x009a0901 (menu)   : min=0 max=3 default=3 value=1
              exposure_absolute 0x009a0902 (int)    : min=50 max=10000 step=1 default=166 value=995   //可以看到变化了
         exposure_auto_priority 0x009a0903 (bool)   : default=0 value=0

最终修改方案


commit f90a45717a69ca6f8d694449e631623690cb748e (HEAD -> main_k5_wif)
Author: lxg <xiaogang.li>
Date:   Wed Dec 10 13:42:49 2025 +0800

    支持手动设置曝光

 hardware/interfaces/camera/device/3.4/default/ExternalCameraDevice.cpp                                       |  54 +++++++++++++++++++++++++++++++++++++++---
 hardware/interfaces/camera/device/3.4/default/ExternalCameraDeviceSession.cpp                                | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hardware/interfaces/camera/device/3.4/default/ExternalFakeCameraDevice.cpp                                   |  56 +++++++++++++++++++++++++++++++++++++++++---
 hardware/interfaces/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h     |   4 ++++
 hardware/interfaces/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession_3.4.h |   4 ++++
 hardware/interfaces/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h        |   2 ++
 6 files changed, 215 insertions(+), 6 deletions(-)