← 返回课程

常见问题排查

Camera全栈开发(Qcom Camx) 第 27 / 30 节

第 25 章:常见问题排查


本章导读

遇到 Camera 问题,第一步做什么、第二步做什么。这一章给出系统化的排查方法。


25.1 Raw/YUV 数据 Dump

25.1.1 Sensor Raw Dump(查看 IFE 输出)

# 开启 Raw dump(IFE 节点的所有 raw 输出)
adb root
adb remount
adb shell setprop persist.vendor.camera.autoImageDump 1
adb shell setprop persist.vendor.camera.autoImageDumpMask 0x1        # IFE Node
adb shell setprop persist.vendor.camera.autoImageDumpIFEoutputPortMask 0xFB8 # IFE 全部 raw 输出
adb shell setprop persist.vendor.camera.offlineImageDumpOnly 0
adb shell setprop persist.vendor.camera.reprocessDump 0
adb reboot

# dump 文件位置
adb shell ls -lh /data/vendor/camera/
adb pull /data/vendor/camera/

25.1.2 各节点 dump mask

autoImageDumpMask 对应节点:
  0x1       → IFE
  0x2       → IPE
  0x4       → BPS
  0x8       → JPEG
  0x10      → FD
  0x20      → LRME
  0x40      → RANSAC
  0x80      → ChiNode(自定义节点)
  0x100     → CVP
  0x40000000 → 其他未列出的节点

autoImageDumpIFEoutputPortMask(IFE 输出端口):
  0x1       → IFEOutputPortFull
  0xFB8     → IFE 全部 raw 输出

25.1.3 拍照 Raw Dump(只 dump BPS 输入)

adb root
adb remount
adb shell setprop persist.vendor.camera.autoImageDump 1
adb shell setprop persist.vendor.camera.autoImageDumpMask 0x4        # BPS Node
adb shell setprop persist.vendor.camera.autoInputImageDumpMask 0x04  # BPS Node
adb shell setprop persist.vendor.camera.autoImageDumpBPSouputPortMask 0x0 # 只 dump 输入
adb shell setprop persist.vendor.camera.reprocessDump 1
adb reboot

25.1.4 MFNR 多帧 dump

adb root
adb remount
adb shell setprop persist.vendor.camera.autoImageDump 1
adb shell setprop persist.vendor.camera.autoImageDumpMask 0x6        # BPS + IPE
adb shell setprop persist.vendor.camera.offlineImageDumpOnly 1
adb shell setprop persist.vendor.camera.reprocessDump 1
adb reboot

25.1.5 LDC 校准 YUV dump

adb root
adb remount
adb shell setprop persist.vendor.camera.autoImageDump 1
adb shell setprop persist.vendor.camera.autoImageDumpMask 0x1        # IFE Node
adb shell setprop persist.vendor.camera.autoImageDumpIFEoutputPortMask 0x1 # IFEOutputPortFull
adb reboot

25.1.6 dump 文件位置和命名

位置: /data/vendor/camera/
命名: dump 文件名包含 Node 名称、Instance ID、端口信息和时间戳

查看 dump 文件:
  YUV 格式 → 用 7yuv / RawViewer / ImageJ 打开
  RAW 格式 → 用 DCRAW / Photoshop 打开

25.1.7 dump 数据怎么用

Raw Dump:
  Raw 正常 → sensor 和 IFE 前端工作正常
  Raw 全黑 → sensor/电源/MCLK/I2C 问题
  Raw 有条纹 → MIPI 链路问题
  Raw 偏色 → AWB/CCM 参数或 OTP 数据问题

YUV Dump:
  YUV 正常 → ISP 处理链路正常
  YUV 全黑 → ISP 配置问题(chromatix 未加载)
  YUV 花屏 → Buffer 地址或 RowStride 配置错误
  YUV 噪声大 → chromatix Denoise 参数需要调整

25.2 日志排查

25.2.1 从 logcat 快速定位

# 一看错误
adb logcat -d | grep -E "ERROR|FATAL|failed|timeout|abort"

# 二看流程(有没有帧出来)
adb logcat -d | grep -E "CSLMessageHandler|ProcessCaptureRequest"

# 三看帧率
adb logcat -d | grep "CSLMessageHandler" | head -5
# 10:00:00.000 - requestID=1, timestamp=1000000000
# 10:00:00.033 - requestID=2, timestamp=1000033000  ← 33ms = 30fps
# 10:00:00.066 - requestID=3, timestamp=1000066000  ← 正常

# 四看 Node 耗时
adb logcat -d | grep "processingTime"
# [NodeProcessing] IFE: 2.1ms  ← 正常
# [NodeProcessing] Stats: 15.2ms  ← 太慢!

# 五看 Pipeline 状态
adb logcat -d | grep "PipelineStatus"
# PipelineStatus::STREAM_ON ← 正常
# PipelineStatus::STREAM_OFF ← 意外关闭

25.2.2 从 dmesg 定位 kernel 问题

# sensor probe 是否成功
adb shell dmesg | grep -E "cam_sensor|sensor_id"
# [cam_sensor_probe] camera sensor probe success ✓
# [cam_sensor_probe] i2c read failed ✗

# MIPI 链路是否有错误
adb shell dmesg | grep -E "csiphy|csid|ECC"
# [cam_csid] CSID_ERR_ECC detected ← MIPI 链路不稳定

# 电源是否正常
adb shell dmesg | grep -E "regulator|cam_vana|cam_vio"

25.2.3 从 dumpsys 看内部状态

adb shell dumpsys media.camera > dump.txt

# Pipeline 状态
grep -A 5 "Pipeline" dump.txt
# Status: STREAM_ON ← 检查是否在正常状态

# Buffer 使用
grep -A 5 "Buffer" dump.txt
# Total: 4, InUse: 4, Free: 0 ← Buffer 泄漏

25.3 排查案例

案例 1:预览黑屏

日志:
  [CamX] CSLMessageHandler() requestID=0, frameCount=0, timestamp=...
  → requestID=0 表示 KMD 丢弃了帧

dmesg:
  [cam_csid] CSID_ERR_ECC detected!  ← MIPI 链路有 ECC 错误

原因: MIPI Lane 速率配置和 sensor 输出不匹配
      → CSIPHY 收到错误数据 → CSID ECC 校验失败 → KMD 丢帧

解决: 检查 CSIPHY 的 Lane 速率配置是否和 sensor datasheet 一致

案例 2:拍照 JPEG 全黑

症状: 预览正常,拍照后 JPEG 全黑

排查:
  ① Raw Dump → Raw 正常(sensor 有输出)
  ② ISP Dump → YUV 正常(ISP 处理正确)
  ③ JPEG Dump → JPEG Node 在 Offline Pipeline 中

原因: Offline Pipeline 的 JPEG Node 配置了错误的 Buffer 地址
      → JPEG 编码器写入的是空 Buffer

解决: 检查 JPEG Pipeline 的 BufferProperties 配置

案例 3:拍照 JPEG 偏绿

症状: JPEG 照片整体偏绿

排查:
  ① ISP Dump 看 YUV → YUV 正常(ISP 处理正确)
  ② JPEG Dump 对比 → JPEG 偏绿(JPEG 编码问题)

原因: JPEG 编码器的颜色空间转换参数配置错误
      YUV→RGB 转换矩阵系数不对

解决: 检查 JPEG Node 的 YUV→RGB 转换参数

案例 4:启动时间过慢

logcat:
  10:00:00.000 - openCamera()
  10:00:00.250 - onOpened()           ← 250ms
  10:00:00.380 - onConfigured()       ← 130ms
  10:00:00.480 - CSLMessageHandler    ← 100ms

dmesg:
  [EEPROM] read completed: 45ms       ← EEPROM I2C 读取耗时

原因: EEPROM 读取阻塞了 open 流程
解决: 提高 I2C 速度(1MHz 代替 400KHz)

25.4 本章总结

Raw/YUV Dump:
  autoImageDump=1 + autoImageDumpMask(IFE/BPS/IPE...) + 对应端口 mask

日志排查:
  logcat: ERROR → CSLMessageHandler → processingTime → PipelineStatus
  dmesg:  cam_sensor → csiphy/ECC → regulator
  dumpsys: Pipeline Status → Buffer Free

案例速查:
  预览全黑 + requestID=0 → CSID ECC 错误 → MIPI 配置
  JPEG 全黑 + Raw 正常     → Buffer 地址问题
  JPEG 偏绿 + YUV 正常     → JPEG 颜色转换参数
  启动慢 + EEPROM 45ms     → I2C 优化