openharmony摄像头驱动到应用浏览显示 第7章异常挂点与主链归因
本文为《开源鸿蒙相机:驱动到应用预览显示》系列发布版。
当前章节:第7章 异常挂点与主链归因
代码基线:~/work/ohos5.1/nt_backclip_vendor(基于 OpenHarmony 5.1.0 Release 移植)
发布说明:使用ai codex移植调试开源鸿蒙摄像头的任务全流程在链接https://github.com/chenlong3388/codex_fix_OpenHarmony_Camera
第7章 异常挂点与主链归因
本章只解决一个问题
把“发散知识点”拆成可独立分析的故障点,再明确它和主线怎么连接、起什么作用、如何起作用。
本章方法
每个发散知识点都按同一模板展开:
- 独立分析:这个信号本身在说什么。
- 主线连接:它位于主线哪一段,前后节点分别是什么。
- 作用机制:它为什么会影响最终结果。
- 证据:源码节选 + 历史日志片段。
发散知识点1:createPreviewOutput failed: {"code":"7400101"}
独立分析
这是“输出对象创建参数不成立”信号,常见触发条件是:
- 选不到合法
previewProfile; surfaceId或尺寸格式语义不成立;- 传入
CreatePreviewOutput的 profile/surface 不满足门禁。
与主线怎么连接
主线位置:App 选 profile -> createPreviewOutput -> Framework CreatePreviewOutput
前置节点:outputCapability.previewProfiles 是否包含可用组合。
后继节点:只有 createPreviewOutput 成功,才可能进入有效 addOutput 与可见预览链。
作用与起作用方式
- 作用:决定“预览链能否起跑”。
- 起作用方式:在主线最前段直接阻断,导致后续会话日志可能出现“伴生推进”但预览对象为空。
源码证据
源码:applications/standard/camera/common/src/main/ets/default/camera/CameraService.ts
previewProfile = previewProfiles.find(item => item.size.width === size.width &&
item.size.height === size.height && item.format === 1003);
if (!previewProfile) {
previewProfile = previewProfiles.find(item => item.size.width === size.width && item.size.height === size.height);
}
if (!previewProfile && previewProfiles.length > 0) {
previewProfile = previewProfiles[0];
}
this.mPreviewOutput = this.mCameraManager.createPreviewOutput(previewProfile, surfaceId);
源码:foundation/multimedia/camera_framework/frameworks/native/camera/src/input/camera_manager.cpp
CHECK_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");
日志证据
日志:tmp_test/ov5648_api_debug_0402_091325/hilog_x.txt
04-02 09:13:35.701 ... createPreviewOutput failed: {"code":"7400101"}
04-02 09:13:35.725 ... mPreviewOutput: undefined
04-02 09:13:35.764 ... createSession failed: {"code":"7400101"}
发散知识点2:ValidateOutputProfile in mode(x) ... fail
独立分析
这是“会话输出准入失败”信号。核心含义:
- 当前
mode下,输出 profile 不在支持集合中; - 即使 fallback 到
NORMAL也可能仍不匹配。
与主线怎么连接
主线位置:createSession -> AddOutput -> ValidateOutputProfile
前置节点:能力注入(basic/extend/profile)是否与 mode/format/size 一致。
后继节点:校验失败会导致输出无法有效加入会话,或者进入“半成功”状态。
作用与起作用方式
- 作用:决定“输出对象能否被当前模式接受”。
- 起作用方式:在会话准入门禁处拒绝不匹配组合,触发后续黑屏或对象链异常。
源码证据
源码:foundation/multimedia/camera_framework/frameworks/native/camera/src/session/capture_session.cpp
auto modeName = GetMode();
...
bool result = std::any_of(profiles.begin(), profiles.end(), [&validateProfile](const auto& profile) {
return validateProfile == profile;
});
CHECK_ERROR_PRINT_LOG(!result, "CaptureSession::ValidateOutputProfile fail! Not in the profiles set.");
if (modeName != SceneMode::NORMAL) {
auto normalIt = profileMap.find(SceneMode::NORMAL);
...
}
日志证据
日志:tmp_test/ov5648_api_debug_0402_162846/hilog_x.txt
04-02 16:28:56.240 ... ValidateOutputProfile in mode(1): w(1280),h(960),f(2000), profiles size is:1
04-02 16:28:56.240 ... CaptureSession::ValidateOutputProfile fail!
发散知识点3:PreviewOutput::SetCameraApi() repeatStream is nullptr
独立分析
这是“预览输出对象链未闭环”信号。它不等于 open 失败,而是指:
AddOutput阶段没拿到可用IStreamRepeat;- 预览输出对象类型/绑定路径存在断点。
与主线怎么连接
主线位置:AddOutput -> GetStream -> (PREVIEW) SetCameraApi
前置节点:createPreviewOutput 是否产出有效预览输出对象。
后继节点:若此处为空,后续即使 Start 成功也可能无可见预览。
作用与起作用方式
- 作用:决定“预览流是否真正挂到会话里”。
- 起作用方式:在“会话看似继续”的情况下制造“显示侧无有效预览流”的假成功。
源码证据
源码:foundation/multimedia/camera_framework/frameworks/native/camera/src/session/capture_session.cpp
sptr<IStreamCommon> stream = output->GetStream();
IStreamRepeat* repeatStream = nullptr;
if (output->GetOutputType() == CAPTURE_OUTPUT_TYPE_PREVIEW) {
repeatStream = static_cast<IStreamRepeat*>(stream.GetRefPtr());
}
if (repeatStream) {
errItemCode = repeatStream->SetCameraApi(apiCompatibleVersion);
} else {
MEDIA_ERR_LOG("PreviewOutput::SetCameraApi() repeatStream is nullptr");
}
日志证据
日志:tmp_test/ov5648_api_debug_0402_162846/hilog_x.txt
04-02 16:28:56.241 ... CaptureSession::AddOutput StreamType = 1
04-02 16:28:56.241 ... PreviewOutput::SetCameraApi() repeatStream is nullptr
04-02 16:28:56.310 ... HCaptureSession::Start execute success, sessionID: 3
发散知识点4:ioctl VIDIOC_QUERYBUF failed: Invalid argument
独立分析
这是 V4L2 缓冲协商失败信号。常见原因:
bufferType/memoryType/plane/index与驱动能力不一致;- 建缓冲参数语义错误。
与主线怎么连接
主线位置:Start -> HDI Capture -> ReqBuffers -> QUERYBUF
前置节点:stream 配置和缓冲模型参数。
后继节点:QUERYBUF 失败后,后续无稳定帧进入显示链。
作用与起作用方式
- 作用:决定“底层是否能产出可用帧缓冲”。
- 起作用方式:在产帧前直接失败,导致上层看到黑屏或间歇失败。
源码证据
源码:drivers/peripheral/camera/vdi_base/common/adapter/platform/v4l2/src/driver_adapter/src/v4l2_buffer.cpp
buf.type = bufferType_;
buf.memory = memoryType_;
buf.index = (uint32_t)frameSpec->buffer_->GetIndex();
if (bufferType_ == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
buf.m.planes = planes;
buf.length = 1;
}
if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) {
CAMERA_LOGE("error: ioctl VIDIOC_QUERYBUF failed: %{public}s\n", strerror(errno));
return RC_ERROR;
}
日志证据
日志:tmp_test/ov5648_api_debug_0402_122831/hilog_x.txt
04-02 12:28:41.537 ... V4L2AllocBuffer() V4L2AllocBuffer enter fd 9
04-02 12:28:41.537 ... V4L2AllocBuffer() error: ioctl VIDIOC_QUERYBUF failed: Invalid argument
04-02 12:28:41.537 ... CreatBuffer() error: Creatbuffer: V4L2AllocBuffer error
发散知识点5:SetMetadata Failed with -5
独立分析
这是显示消费链失败信号。含义是:
- 显示层元数据写入失败;
- 即使控制链推进成功,显示侧仍可能不可见。
与主线怎么连接
主线位置:帧到达 Surface -> SetMetadata -> Render 消费
前置节点:上游输出流是否带来可消费元数据。
后继节点:显示链失败会直接表现为黑屏或不可见画面。
作用与起作用方式
- 作用:决定“最终画面能否在显示端被消费”。
- 起作用方式:在主线末段失败,制造“控制链成功但用户仍黑屏”的现象。
源码证据
源码:foundation/graphic/graphic_surface/surface/src/surface_buffer_impl.cpp
auto dRet = displayBuffer->SetMetadata(*handle_, key, value);
if (dRet == GRAPHIC_DISPLAY_SUCCESS) {
return GSERROR_OK;
}
BLOGE("SetMetadata Failed with %{public}d", dRet);
return GSERROR_HDI_ERROR;
日志证据
日志:tmp_test/ov5648_api_debug_0402_091325/hilog_x.txt
04-02 09:13:35.757 ... Bufferqueue: <surface_buffer_impl.cpp:610-SetMetadata>: SetMetadata Failed with -5
04-02 09:13:35.763 ... PreviewOutput::SetCameraApi() repeatStream is nullptr
发散知识点与主线的统一结论
7400101:主线前段(输入语义)断点。ValidateOutputProfile fail:主线中段(模式能力)断点。repeatStream is nullptr:主线中后段(对象绑定)断点。VIDIOC_QUERYBUF failed:主线底层(缓冲协商)断点。SetMetadata Failed with -5:主线末段(显示消费)断点。
本章最小动作
选择一个真实日志窗口,按“这5个知识点”逐条写:
- 独立分析;
- 主线连接;
- 作用机制;
- 源码与日志双证据。
知识点依赖与跨章连接
| 本章挂点 | 前置章节 | 后续章节 | 跳转理由 |
|---|---|---|---|
7400101 参数门禁 |
第5章 输出创建与显示绑定 | 第6章 函数级链路走读 | 先确认 profile/surface 语义,再落到函数级门禁 |
ValidateOutputProfile fail |
第3章 能力注入与流桥接 | 第4章 会话编排与门禁 | 能力来源决定 mode/profile 是否可被会话接受 |
repeatStream is nullptr |
第5章 输出创建与显示绑定 | 第6章 函数级链路走读 | 输出对象链路与 AddOutput/SetCameraApi 强关联 |
VIDIOC_QUERYBUF failed |
第2章 驱动与硬件基线 | 第8章 调试方法与证据模板 | 先收敛底层缓冲语义,再固化命令剧本 |
SetMetadata Failed with -5 |
第5章 输出创建与显示绑定 | 第9章 实战演练与复盘 | 控制链与显示链并行结论需在复盘中显式落地 |
信号 -> 判断 -> 动作
| 信号 | 判断 | 动作 |
|---|---|---|
createPreviewOutput failed: 7400101 |
输出创建参数不成立 | 回查 previewProfile + surfaceId,再核 CreatePreviewOutput 门禁 |
ValidateOutputProfile ... fail |
mode/profile 能力不匹配 | 对齐 HCS basic/extend 与当前 mode 能力表 |
repeatStream is nullptr |
预览输出对象链断裂 | 按 createPreviewOutput -> AddOutput -> SetCameraApi 回溯 |
VIDIOC_QUERYBUF failed |
缓冲语义不匹配 | 先核 type/memory/plane/index,必要时先降档验证 |
SetMetadata Failed with -5 |
显示消费链失败 | 与控制链结果并列输出,不把它误判为 open 失败 |
发布后补链
- 上一篇:https://laval.csdn.net/69d8b96854b52172bc6860cd.html
- 下一篇:https://laval.csdn.net/69d8ba1454b52172bc6860e4.html
全章导航
- 第0章 导读学习指南:https://laval.csdn.net/69d77a0554b52172bc6802aa.html
- 第1章 主链调用总览(图表):https://laval.csdn.net/69d8b75f54b52172bc686020.html
- 第2章 驱动与硬件基线:https://laval.csdn.net/69d8b7fd0a2f6a37c59e6f33.html
- 第3章 能力注入与流桥接(HDF/HDI/VDI):https://laval.csdn.net/69d8b86154b52172bc68609a.html
- 第4章 会话编排与门禁(Framework/Service):https://laval.csdn.net/69d8b8d154b52172bc6860ae.html
- 第5章 输出创建与显示绑定(ArkTS/HAP):https://laval.csdn.net/69d8b91954b52172bc6860be.html
- 第6章 函数级链路走读(驱动到显示):https://laval.csdn.net/69d8b96854b52172bc6860cd.html
- 第7章 异常挂点与主链归因:https://laval.csdn.net/69d8b9d054b52172bc6860dc.html
- 第8章 调试方法与证据模板:https://laval.csdn.net/69d8ba1454b52172bc6860e4.html
- 第9章 实战演练与复盘:https://laval.csdn.net/69d8ba4754b52172bc6860f3.html
更多推荐
所有评论(0)