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交付有效帧。排查路径如下:
- 确认Sensor是否已stream on:检查log中
[Sensor] streamOn是否成功返回,以及[Sensor] streamOff是否被误触发。 - 检查Stream配置是否完整:HAL层必须为Preview配置至少一个
StreamType::OUTPUT,且usage包含GRALLOC_USAGE_HW_COMPOSER或GRALLOC_USAGE_HW_TEXTURE。 - 验证Buffer流转:在
processCaptureRequest中检查buffer_handle_t是否有效,dequeueBuffer是否返回NO_ERROR。 - 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
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对齐错误引起。优先检查这两个参数。
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流转。