openharmony摄像头驱动到应用浏览显示 第9章 实战演练与复盘

张开发
2026/4/16 14:03:27 15 分钟阅读

分享文章

openharmony摄像头驱动到应用浏览显示 第9章 实战演练与复盘
本文为《开源鸿蒙相机驱动到应用预览显示》系列发布版。当前章节第9章 实战演练与复盘代码基线~/work/ohos5.1/nt_backclip_vendor基于 OpenHarmony 5.1.0 Release 移植发布说明源码路径与命令可直接用于复现。第9章 实战演练与复盘本章只解决一个问题完整复盘这条问题链最初问题是什么为什么那样分析与修复每一轮引入了什么新问题又是如何继续收敛。0. 起点问题起点现象v4l2-ctl已可录像说明底层链路不是完全断开。默认相机 App 出现黑屏与7400101系统 API 路径不稳定。核心矛盾同时出现“部分成功”与“最终不可见”。单看任意一层都会误判。1. 第一轮先证明确实是参数门禁不是驱动挂死1.1 当时为什么先看这里7400101是高优先级参数门禁信号必须先确认发生点。1.2 源码证据源码foundation/multimedia/camera_framework/frameworks/native/camera/src/input/camera_manager.cppCHECK_ERROR_RETURN_RET_LOG((serviceProxy nullptr) || (surface nullptr), CameraErrorCode::INVALID_ARGUMENT,CreatePreviewOutput serviceProxy is null or previewOutputSurface/profile is null);CHECK_ERROR_RETURN_RET_LOG((profile.GetCameraFormat() CAMERA_FORMAT_INVALID) || (profile.GetSize().width 0) || (profile.GetSize().height 0), CameraErrorCode::INVALID_ARGUMENT,CreatePreviewOutput invalid fomrat or width or height is zero);分析这里明确把surface/profile/size/format当成硬门禁。一旦不满足直接返回INVALID_ARGUMENT。1.3 历史日志证据日志tmp_test/ov5648_api_debug_0402_091325/hilog_x.txt04-0209:13:35.701... createPreviewOutput failed: {code:7400101}04-0209:13:35.725... mPreviewOutput: undefined04-0209:13:35.764... createSession failed: {code:7400101}1.4 本轮结论这轮优先结论是“预览输出创建参数不成立”。不是“驱动完全不可用”。2. 第二轮进入模式能力错配定位2.1 为什么会进入第二轮第一轮解释了7400101但没有解释所有黑屏窗口。2.2 源码证据源码foundation/multimedia/camera_framework/frameworks/native/camera/src/session/capture_session.cppauto modeName GetMode();...CHECK_ERROR_PRINT_LOG(!result,CaptureSession::ValidateOutputProfile fail! Not in the profiles set.);if(modeName ! SceneMode::NORMAL) { auto normalIt profileMap.find(SceneMode::NORMAL);...}分析当前mode下 profile 先匹配。失败后才尝试NORMALfallback。说明该问题本质是“能力语义错配”。2.3 历史日志证据日志tmp_test/ov5648_api_debug_0402_162846/hilog_x.txt04-0216:28:56.240... ValidateOutputProfile in mode(1): w(1280),h(960),f(2000), profiles size is:104-0216:28:56.240... CaptureSession::ValidateOutputProfile fail!2.4 本轮动作与结果动作收敛 HCS 能力定义mode/format/size 组合。结果参数非法类问题下降但仍出现“会话半成功”。3. 第三轮定位输出对象链断点3.1 为什么转到对象链mode fail收敛后仍出现黑屏说明还存在“对象绑定问题”。3.2 源码证据源码foundation/multimedia/camera_framework/frameworks/native/camera/src/session/capture_session.cppif (output-GetOutputType()CAPTURE_OUTPUT_TYPE_PREVIEW) { repeatStreamstatic_castIStreamRepeat*(stream.GetRefPtr());} if (repeatStream) { errItemCoderepeatStream-SetCameraApi(apiCompatibleVersion);} else { MEDIA_ERR_LOG(PreviewOutput::SetCameraApi() repeatStream is nullptr);}分析预览输出必须能转成IStreamRepeat。转换失败就会出现repeatStream is nullptr。3.3 历史日志证据日志tmp_test/ov5648_api_debug_0402_162846/hilog_x.txt04-0216:28:56.241... CaptureSession::AddOutput StreamType 104-0216:28:56.241... PreviewOutput::SetCameraApi() repeatStream is nullptr04-0216:28:56.310... HCaptureSession::Start execute success, sessionID:33.4 本轮结论“Start 成功”和“预览绑定失败”可以同时出现。这正是黑屏“假成功”窗口。4. 第四轮确认底层缓冲是否也在出错4.1 为什么查到 V4L2有些窗口里显示问题前还伴随建缓冲异常。4.2 源码证据源码drivers/peripheral/camera/vdi_base/common/adapter/platform/v4l2/src/driver_adapter/src/v4l2_buffer.cppbuf.typebufferType_;buf.memory memoryType_; ... if (ioctl(fd, VIDIOC_QUERYBUF, buf)0) { CAMERA_LOGE(error: ioctl VIDIOC_QUERYBUF failed: %{public}s\n, strerror(errno)); return RC_ERROR; }分析type/memory/plane/index任一语义错配都会在QUERYBUF失败。这是“产帧前失败”会直接影响后续可见性。4.3 历史日志证据日志tmp_test/ov5648_api_debug_0402_122831/hilog_x.txt04-0212:28:41.537... V4L2AllocBuffer() V4L2AllocBuffer enter fd904-0212:28:41.537... ioctl VIDIOC_QUERYBUF failed: Invalid argument04-0212:28:41.537... Creatbuffer: V4L2AllocBuffer error4.4 本轮结论该类窗口不是单纯 App 层问题底层缓冲协商也可能成为并行风险。5. 第五轮明确显示消费链独立失败5.1 为什么要单拉显示链只盯控制链会忽略“帧到了显示侧但消费失败”的窗口。5.2 源码证据源码foundation/graphic/graphic_surface/surface/src/surface_buffer_impl.cppauto dRet displayBuffer-SetMetadata(*handle_,key,value);if(dRetGRAPHIC_DISPLAY_SUCCESS) { return GSERROR_OK; }BLOGE(SetMetadata Failed with %{public}d,dRet); return GSERROR_HDI_ERROR;分析显示元数据写入失败会直接返回错误。这类失败不要求控制链同时失败。5.3 历史日志证据日志tmp_test/ov5648_api_debug_0402_091325/hilog_x.txt04-0209:13:35.757... Bufferqueue: surface_buffer_impl.cpp:610-SetMetadata: SetMetadata Failed with -504-0209:13:35.763... PreviewOutput::SetCameraApi() repeatStream is nullptr5.4 本轮结论黑屏结论必须拆成双链控制链可推进。显示链可单独失败。6. 最终收敛方法不是“一次修完”而是“可重复收敛”最终形成的有效路径先判createPreviewOutput/7400101输入语义。再判ValidateOutputProfile模式能力。再判repeatStream is nullptr对象绑定。并行观察VIDIOC_QUERYBUF failed缓冲协商风险。最后单独判SetMetadata Failed with -5显示消费链。这个顺序的价值每一层都有明确源码锚点。每一层都有历史日志证据。每一步都能解释“为什么下一步这样做”。7. 关键注意点复盘必须写Start execute success不是终局成功信号。同窗共现不自动等于直接因果。没有源码锚点的结论不能升级为主结论。运行时路径与仓内源路径必须对照避免“改了源码但跑的是旧包”。8. 可直接复用的复盘模板8.1 阶段模板阶段问题为什么先看这里源码证据文件片段日志证据文件时间行动作新问题阶段结论8.2 总结模板控制链结论显示链结论联合结论下一轮最小动作本章最小动作从tmp_test任取一个历史窗口按“阶段模板”写至少 3 个连续阶段不允许跳过“为什么先看这里”。知识点依赖与跨章连接本章阶段前置章节回跳章节连接理由阶段1 参数门禁收敛第5章 输出创建与显示绑定第8章 调试方法与证据模板先确认输入语义再套命令模板复核阶段2 模式能力收敛第3章 能力注入与流桥接 第4章 会话编排与门禁第6章 函数级链路走读能力来源与会话门禁需函数级核验阶段3 输出对象链收敛第5章 输出创建与显示绑定第7章 异常挂点与主链归因输出链断点需挂回主链节点防误判阶段4 缓冲协商收敛第2章 驱动与硬件基线第8章 调试方法与证据模板先判底层语义再固化排障命令阶段5 显示消费收敛第1章 主链调用总览第0章 导读学习指南最终回到双链并行结论与通用判据信号 - 判断 - 动作信号判断动作createPreviewOutput failed: 7400101输出创建参数不成立回到阶段1核profile/surface与门禁函数ValidateOutputProfile ... failmode/profile 能力错配回到阶段2对齐 HCS 能力并核 fallbackrepeatStream is nullptr预览输出对象链未闭环回到阶段3按AddOutput - SetCameraApi定点VIDIOC_QUERYBUF failed缓冲协商失败回到阶段4先做type/memory/plane/index收敛SetMetadata Failed with -5显示消费链失败回到阶段5并列输出双链结论禁止单链覆盖发布后补链上一篇待回填下一篇待回填

更多文章