OpenHarmony鸿蒙开发 (5.0 ) Camera外设驱动模型

  鸿蒙开发往期必看:

HarmonyOS NEXT应用开发性能实践总结

一分钟了解”纯血版!鸿蒙HarmonyOS Next应用开发!

“非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线!(从零基础入门到精通)

 “一杯冰美式的时间” 了解鸿蒙HarmonyOS Next应用开发路径!


功能简介

OpenHarmony相机驱动框架模型对上实现相机HDI(Hardware Device Interface)接口,对下实现相机Pipeline模型,管理相机各个硬件设备。 该驱动框架模型内部分为三层,依次为HDI实现层、框架层和设备适配层。各层基本概念如下:

  • HDI实现层:实现OHOS(OpenHarmony Operation System)相机标准南向接口。
  • 框架层:对接HDI实现层的控制、流的转发,实现数据通路的搭建,管理相机各个硬件设备等功能。
  • 设备适配层:屏蔽底层芯片和OS(Operation System)差异,支持多平台适配。

运作机制

Camera模块主要包含服务、设备的初始化,数据通路的搭建,流的配置、创建、下发、捕获等,具体运作机制参考以下图文解析:

图 1 基于HDF驱动框架的Camera驱动模型

  1. 系统启动时创建camera_host进程。进程创建后,首先枚举底层设备,创建(也可以通过配置表创建)管理设备树的DeviceManager类及其内部各个底层设备的对象,创建对应的CameraHost类实例并且将其注册到UHDF(用户态HDF驱动框架)服务中,方便相机服务层通过UHDF服务获取底层CameraDeviceHost的服务,从而操作硬件设备。

  2. Service通过CameraDeviceHost服务获取CameraHost实例,CameraHost可以获取底层的Camera能力,开启闪光灯、调用Open接口打开Camera创建连接、创建DeviceManager(负责底层硬件模块上电)、创建CameraDevice(向上提供设备控制接口)。创建CameraDevice时会实例化PipelineCore的各个子模块,其中StreamPipelineCore负责创建Pipeline,MetaQueueManager负责上报metaData。

  3. Service通过CameraDevice模块配置流、创建Stream类。StreamPipelineStrategy模块通过上层下发的模式和查询配置表创建对应流的Node连接方式,StreamPipelineBuilder模块创建Node实例并且连接返回该Pipeline给StreamPipelineDispatcher。StreamPipelineDispatcher提供统一的Pipeline调用管理。

  4. Service通过Stream控制整个流的操作,AttachBufferQueue接口将从显示模块申请的BufferQueue下发到底层,由CameraDeviceDriverModel自行管理buffer,当Capture接口下发命令后,底层开始向上传递buffer。Pipeline的IspNode依次从BufferQueue获取指定数量buffer,然后下发到底层ISP(Image Signal Processor,图像信号处理器)硬件,ISP填充完之后将buffer传递给CameraDeviceDriverModel,CameraDeviceDriverModel通过循环线程将buffer填充到已经创建好的Pipeline中,各个Node处理后通过回调传递给上层,同时buffer返回BufferQueue等待下一次下发。

  5. Service通过Capture接口下发拍照命令。ChangeToOfflineStream接口查询拍照buffer位置,如果ISP已经出图,并且图像数据已经送到IPP node,可以将普通拍照流转换为离线流,否则直接走关闭流程。ChangeToOfflineStream接口通过传递StreamInfo使离线流获取到普通流的流信息,并且通过配置表确认离线流的具体Node连接方式,创建离线流的Node连接(如果已创建则通过CloseCamera释放非离线流所需的Node),等待buffer从底层Pipeline回传到上层再释放持有的Pipeline相关资源。

  6. Service通过CameraDevice的UpdateSettings接口向下发送CaptureSetting参数,CameraDeviceDriverModel通过StreamPipelineDispatcher模块向各个Node转发,StartStreamingCapture和Capture接口携带的CaptureSetting通过StreamPipelineDispatcher模块向该流所属的Node转发。

  7. Service通过EnableResult和DisableResult接口控制底层metaData的上报。如果需要底层metaData上报,pipeline会创建CameraDeviceDriverModel内部的一个Bufferqueue用来收集和传递metaData,根据StreamPipelineStrategy模块查询配置表并通过StreamPipelineBuilder创建和连接Node,MetaQueueManager下发buffer至底层,底层相关Node填充数据,MetaQueueManager模块再调用上层回调传递给上层。

  8. Service调用CameraDevice的Close接口,CameraDevice调用对应的DeviceManager模块对各个硬件下电;如果此时在Ipp的SubPipeline中存在OfflineStream,则需要保留OfflineStream,直到执行完毕。

  9. 动态帧率控制。在StreamOperator中起一个CollectBuffer线程,CollectBuffer线程从每一路stream的BufferQueue中获取buffer,如果某一路流的帧率需要控制(为sensor出帧帧率的1/n),可以根据需求控制每一帧的buffer打包,并决定是否collect此路流的buffer(比如sensor出帧帧率为120fps,预览流的帧率为30fps,CollectBuffer线程collect预览流的buffer时,每隔4fps collect一次)。

开发指导

场景介绍

Camera模块主要针对相机预览、拍照、视频流等场景,对这些场景下的相机操作进行封装,使开发者更易操作相机硬件,提高开发效率。

接口说明

注:以下接口列举的为IDL接口描述生成的对应C++语言函数接口,接口声明见idl文件/drivers/interface/camera/v1_1/,获取路径为:drivers_interface: 暂无描述 - Gitee.com。 在HDI使用中下发的配置参数不能超出GetCameraAbility上报的能力范围。即使通过UpdateSettings、CommitStreams、Capture等接口可以下发超出该范围的配置参数,且接口调用不会返回失败,但设置后的行为是不确定的。

  • icamera_device.h

    功能描述 接口名称
    获取流控制器 int32_t GetStreamOperator_V1_1(
    const sptr<OHOS::HDI::Camera::V1_0::IStreamOperatorCallback>& callbackObj,
    sptr<OHOS::HDI::Camera::V1_1::IStreamOperator>& streamOperator
    )
  • icamera_host.h

    功能描述 接口名称
    打开Camera设备 int32_t OpenCamera_V1_1(
    const std::string& cameraId,
    const sptr<OHOS::HDI::Camera::V1_0::ICameraDeviceCallback>& callbackObj,
    sptr<OHOS::HDI::Camera::V1_1::ICameraDevice>& device
    )
    预启动摄像头设备 int32_t PreLaunch(const PrelaunchConfig& config)
  • istream_operator.h

    功能描述 接口名称
    查询是否支持添加参数对应的流 int32_t IsStreamsSupported_V1_1(
    OperationMode mode,
    const std::vector<uint8_t>& modeSetting,
    const std::vector<StreamInfo_V1_1>& infos,
    StreamSupportType& type
    )
    创建流 int32_t CreateStreams_V1_1(const std::vector<StreamInfo_V1_1>& streamInfos)

开发步骤

Camera驱动的开发过程主要包含以下步骤:

  1. 注册CameraHost

    定义Camera的HdfDriverEntry结构体,该结构体中定义了CameraHost初始化的方法(代码目录drivers/peripheral/camera/interfaces/hdi_ipc/camera_host_driver.cpp)。

    struct HdfDriverEntry g_cameraHostDriverEntry = {
       .moduleVersion = 1,
       .moduleName = "camera_service",
       .Bind = HdfCameraHostDriverBind,
       .Init = HdfCameraHostDriverInit,
       .Release = HdfCameraHostDriverRelease,
    };
    HDF_INIT(g_cameraHostDriverEntry); // 将Camera的HdfDriverEntry结构体注册到HDF上
    c++
  2. 初始化Host服务

    步骤1中提到的HdfCameraHostDriverBind接口提供了CameraServiceDispatch和CameraHostStubInstance的注册。CameraServiceDispatch接口是远端调用CameraHost的方法,如OpenCamera(),SetFlashlight()等,CameraHostStubInstance接口是Camera设备的初始化,在开机时被调用。

    static int HdfCameraHostDriverBind(struct HdfDeviceObject *deviceObject)
    {
        HDF_LOGI("HdfCameraHostDriverBind enter");
     
        auto *hdfCameraHostHost = new (std::nothrow) HdfCameraHostHost;
        if (hdfCameraHostHost == nullptr) {
            HDF_LOGE("%{public}s: failed to create HdfCameraHostHost object", __func__);
            return HDF_FAILURE;
        }
     
        hdfCameraHostHost->ioService.Dispatch = CameraHostDriverDispatch; // 提供远端CameraHost调用方法
        hdfCameraHostHost->ioService.Open = NULL;
        hdfCameraHostHost->ioService.Release = NULL;
     
        auto serviceImpl = ICameraHost::Get(true);
        if (serviceImpl == nullptr) {
            HDF_LOGE("%{public}s: failed to get of implement service", __func__);
            delete hdfCameraHostHost;
            return HDF_FAILURE;
        }
     
        hdfCameraHostHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl,
            ICameraHost::GetDescriptor()); // 初始化Camera设备
        if (hdfCameraHostHost->stub == nullptr) {
            HDF_LOGE("%{public}s: failed to get stub object", __func__);
            delete hdfCameraHostHost;
            return HDF_FAILURE;
        }
     
        deviceObject->service = &hdfCameraHostHost->ioService;
        retu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值