4. Preview流程常见问题:黑屏、花屏、帧率异常与分辨率不匹配

Preview(预览)是Camera HAL层最核心的实时通路,任何环节的异常都会直接表现为黑屏、花屏、帧率抖动或画面尺寸错误。本章从HAL层视角梳理四大类问题的根因定位方法,并给出对应的log分析要点。

4.1 问题分类与根因概览

现象 典型根因(HAL层) 关键log关键字
Preview黑屏 Stream未配置、Buffer未dequeue、Sensor未stream on、ISP pipeline挂死 [Stream] [Buffer] [Sensor] [ISP]
Preview花屏 MIPI CSI lane配置错误、Pixel format不匹配、Stride/width对齐错误、DMA地址异常 [MIPI] [Format] [DMA] [Corrupt]
帧率异常 FPS range协商失败、Vblank/Hblank配置错误、Buffer dequeue超时、CPU/GPU瓶颈 [FPS] [Vblank] [Timeout] [Throttle]
分辨率不匹配 App请求尺寸与Sensor output尺寸不一致、Crop/Scale参数错误、Stream配置未同步 [Resolution] [Crop] [Scale] [Mismatch]
调试原则:先确认底层Sensor是否正常出图(通过raw dump验证),再逐级排查ISP、HAL Stream、Buffer流转。不要一开始就怀疑App层。

4.2 Preview黑屏排查思路

黑屏是最常见的Preview问题,通常意味着HAL层没有向framework交付有效帧。排查路径如下:

  1. 确认Sensor是否已stream on:检查log中 [Sensor] streamOn 是否成功返回,以及 [Sensor] streamOff 是否被误触发。
  2. 检查Stream配置是否完整:HAL层必须为Preview配置至少一个 StreamType::OUTPUT,且 usage 包含 GRALLOC_USAGE_HW_COMPOSER 或 GRALLOC_USAGE_HW_TEXTURE。
  3. 验证Buffer流转:在 processCaptureRequest 中检查 buffer_handle_t 是否有效,dequeueBuffer 是否返回 NO_ERROR。
  4. ISP pipeline状态:查看 [ISP] 相关log,确认3A(AE/AWB/AF)是否收敛,RAW数据是否正常进入ISP。
关键log片段示例:
// 正常stream on log
[CameraSensor] streamOn: sensor_id=0, mode=1920x1080@30fps, status=OK

// Buffer dequeue失败
[BufferQueue] dequeueBuffer: timeout, buffer count=0

// ISP pipeline挂死
[ISP] 3A: AE converge failed, frame drop count=15
Preview黑屏排查流程图 黑屏现象 Sensor stream on? Stream配置完整? Buffer流转正常? ISP pipeline正常? 逐级修复 问题解决

4.3 Preview花屏排查思路

花屏通常与数据通路中的格式或地址错误有关。HAL层排查重点:

  • MIPI CSI Lane配置:检查 mipi_csi_config 中的lane数、data type是否与Sensor输出一致。常见错误:4-lane sensor配成2-lane。
  • Pixel Format不匹配:HAL层配置的 android.scaler.availableFormats 必须与ISP output format一致。例如Sensor输出 RAW10,但HAL配置为 YUV420 会导致花屏。
  • Stride/Width对齐:MTK平台要求 stride 为16字节对齐。若 width=640 但 stride=640(未对齐),DMA传输会错位。
  • DMA地址异常:检查 [DMA] log中是否有 address error 或 page fault。
避坑提示:花屏问题中,约60%由format不匹配引起,30%由stride对齐错误引起。优先检查这两个参数。
花屏根因定位:数据通路逐级检查 Sensor RAW MIPI CSI ISP处理 DMA输出 检查: raw dump 检查: lane数/data type 检查: format/3A 检查: stride/地址 定位到异常节点后修复

4.4 帧率异常排查思路

帧率异常表现为预览卡顿、掉帧或帧率不稳定。HAL层排查路径:

  • FPS range协商:检查 android.control.aeAvailableTargetFpsRanges 是否包含App请求的fps range。例如App请求 [15,30],但HAL只支持 [30,30] 会导致降帧。
  • Vblank/Hblank配置:在 sensor_timing 中检查 vt_pixel_clk、line_length_pclk、frame_length_lines 是否正确。错误的blanking会导致实际帧率偏离目标。
  • Buffer dequeue超时:查看 [BufferQueue] log中是否有 dequeueBuffer timeout,通常意味着consumer(如SurfaceFlinger)处理过慢。
  • CPU/GPU瓶颈:在 [Perf] log中查看CPU频率是否被限制,或GPU渲染帧率是否低于Sensor输出帧率。
帧率计算参考公式:
实际帧率 = vt_pixel_clk / (line_length_pclk * frame_length_lines)

示例:
vt_pixel_clk = 120 MHz
line_length_pclk = 2200
frame_length_lines = 1125
实际帧率 = 120,000,000 / (2200 * 1125) ≈ 48.5 fps

4.5 分辨率不匹配排查思路

分辨率不匹配通常表现为预览画面被拉伸、裁剪或显示区域错误。HAL层排查重点:

场景 HAL层检查点 常见错误
App请求尺寸与Sensor output不一致 configureStreams 中的 width/height 是否与 sensor_output_size 匹配 App请求640x480,但Sensor只支持1920x1080,HAL未做crop/scale
Crop/Scale参数错误 android.scaler.cropRegion 是否在有效范围内 cropRegion超出Sensor output尺寸,导致黑边或花屏
Stream配置未同步 多个Stream(Preview+Video)的尺寸是否在 android.scaler.availableStreamConfigurations 中同时支持 Preview用1920x1080,Video用1280x720,但HAL未配置同时支持
关键log关键字:
[Stream] configureStreams: width=1920, height=1080, format=YUV420
[Scaler] cropRegion: left=0, top=0, width=1920, height=1080
[Resolution] mismatch: request=640x480, actual=1920x1080

4.6 综合log分析技巧

在MTK平台HAL层调试中,以下log分析技巧可快速缩小问题范围:

  • 使用 adb logcat -s CameraHAL 过滤HAL层log,避免被其他模块log淹没。
  • 开启perfetto trace,同时抓取HAL层、SurfaceFlinger、GPU的timeline,定位帧率瓶颈。
  • 对比正常与异常log:在相同场景下抓取两份log,用diff工具对比 [Stream]、[Buffer]、[ISP] 关键节点的时序差异。
  • 使用MTK专属工具:MetaTool 可dump Sensor raw图,CameraProfiler 可分析每一帧的HAL处理耗时。
经验总结:Preview问题中,黑屏和花屏通常与底层配置相关,帧率异常和分辨率不匹配更多与HAL层Stream管理相关。建议按“底层→上层”的顺序排查,先确保Sensor和ISP正常,再检查HAL Stream和Buffer流转。