Name |
Date |
Size |
#Lines |
LOC |
||
---|---|---|---|---|---|---|
.. | - | - | ||||
figures/ | 12-May-2024 | - | ||||
hal/ | 12-May-2024 | - | 57,831 | 43,384 | ||
hal_c/ | 12-May-2024 | - | 2,043 | 1,320 | ||
interfaces/ | 12-May-2024 | - | 5,184 | 3,724 | ||
.gitignore | D | 12-May-2024 | 28 | 5 | 4 | |
README_zh.md | D | 12-May-2024 | 17.5 KiB | 361 | 289 | |
bundle.json | D | 12-May-2024 | 1.5 KiB | 61 | 60 |
README_zh.md
1# Camera 2 3## 概述 4 5OpenHarmony相机驱动框架模型对上实现相机HDI(Hardware Device Interface)接口,对下实现相机Pipeline模型,管理相机各个硬件设备。 6该驱动框架模型内部分为三层,依次为HDI实现层、框架层和设备适配层,各层基本概念如下: 7 8+ HDI实现层:实现OHOS(OpenHarmony Operation System)相机标准南向接口。 9+ 框架层:对接HDI实现层的控制、流的转发,实现数据通路的搭建,管理相机各个硬件设备等功能。 10+ 设备适配层:屏蔽底层芯片和OS(Operation System)差异,支持多平台适配。 11 12**图 1** Camera驱动模块架构图 13 14 15  16 17## 目录 18 19- Camera模块目录表如下: 20 21 ``` 22 /drivers/peripheral/camera 23 ├── hal # camera模块的hal层代码 24 │ ├── adapter # camera hal平台适配层的实现 25 │ ├── buffer_manager # camera hal统一的Buffer管理 26 │ ├── device_manager # 提供camera hal层设备管理能力,包括设备枚举、设备能力查询等 27 │ ├── hdi_impl # camera hal HDI的具体实现 28 │ ├── include # camera hal层内部的头文件 29 │ ├── init # camera hal层HDI接口使用样例实现 30 │ ├── pipeline_core # camera hal层pipeline核心代码 31 │ ├── test # camera hal层测试代码实现 32 │ └── utils # camera hal层工具类代码,目前提供的是watchdog 33 ├── hal_c # 提供C实现的HAL接口 34 │ ├── hdi_cif # C实现的HDI接口适配代码 35 │ └── include # C形式的HDI接口 36 └── interfaces # camera hal对上层服务提供的驱动能力接口 37 ├── hdi_ipc # IPC模式的HDI实现 38 ├── hdi_passthrough # 直通模式的HDI实现 39 └── include # camera hal对外提供的HDI定义 40 ``` 41 42 43 44## 接口说明 45 46- icamera_device.h 47 48 | 功能描述 | 接口名称 | 49 | ---------------------------- | ------------------------------------------------------------ | 50 | 获取流控制器 | CamRetCode GetStreamOperator(<br/> const OHOS::sptr\<IStreamOperatorCallback\> &callback,<br/> OHOS::sptr\<IStreamOperator\> &streamOperator) | 51 | 更新设备控制参数 | CamRetCode UpdateSettings(const std::shared_ptr\<CameraSetting\> &settings) | 52 | 设置Result回调模式和回调函数 | CamRetCode SetResultMode(const ResultCallbackMode &mode) | 53 | 获取使能的ResultMeta | CamRetCode GetEnabledResults(std::vector\<MetaType\> &results) | 54 | 使能具体的ResultMeta | CamRetCode EnableResult(const std::vector\<MetaType\> &results) | 55 | 禁止具体的ResultMeta | CamRetCode DisableResult(const std::vector\<MetaType\> &results) | 56 | 关闭Camera设备 | void Close() | 57 58- icamera_device_callback.h 59 60 | 功能描述 | 接口名称 | 61 | ---------------------------------------------------------- | ------------------------------------------------------------ | 62 | 设备发生错误时调用,由调用者实现,用于返回错误信息给调用者 | void OnError(ErrorType type, int32_t errorCode) | 63 | 上报camera设备相关的metadata的回调 | void OnResult(uint64_t timestamp, const std::shared_ptr\<CameraMetadata\> &result) | 64 65 66- icamera_host.h 67 68 | 功能描述 | 接口名称 | 69 | ------------------------------ | ------------------------------------------------------------ | 70 | 设置ICameraHost回调接口 | CamRetCode SetCallback(const OHOS::sptr\<ICameraHostCallback\> &callback) | 71 | 获取当前可用的Camera设备ID列表 | CamRetCode GetCameraIds(std::vector\<std::string\> &cameraIds) | 72 | 获取Camera设备能力集合 | CamRetCode GetCameraAbility(const std::string &cameraId,<br/> std::shared_ptr\<CameraAbility\> &ability) | 73 | 打开Camera设备 | CamRetCode OpenCamera(const std::string &cameraId,<br/> const OHOS::sptr\<ICameraDeviceCallback\> &callback,<br/> OHOS::sptr\<ICameraDevice\> &device) | 74 | 打开或关闭闪光灯 | CamRetCode SetFlashlight(const std::string &cameraId, bool &isEnable) | 75 76- icamera_host_callback.h 77 78 | 功能描述 | 接口名称 | 79 | ---------------------- | ------------------------------------------------------------ | 80 | Camera设备状态变化上报 | void OnCameraStatus(const std::string &cameraId, CameraStatus status) | 81 | 闪光灯状态变化回调 | void OnFlashlightStatus(const std::string &cameraId, FlashlightStatus status) | 82 83- ioffline_stream_operator.h 84 85 | 功能描述 | 接口名称 | 86 | -------------- | ------------------------------------------------------------ | 87 | 取消捕获请求 | CamRetCode CancelCapture(int captureId) | 88 | 释放流 | CamRetCode ReleaseStreams(const std::vector\<int\> &streamIds) | 89 | 释放所有离线流 | CamRetCode Release() | 90 91- istream_operator.h 92 93 | 功能描述 | 接口名称 | 94 | -------------------------------- | ------------------------------------------------------------ | 95 | 查询是否支持添加参数对应的流 | CamRetCode IsStreamsSupported(<br/> OperationMode mode,<br/> const std::shared_ptr\<CameraMetadata> &modeSetting,<br/> const std::vector\<std::shared_ptr\<StreamInfo\>\> &info,<br/> StreamSupportType &type) | 96 | 创建流 | CamRetCode CreateStreams(const std::vector\<std::shared_ptr\<StreamInfo\>\> &streamInfos) | 97 | 释放流 | CamRetCode ReleaseStreams(const std::vector\<int\> &streamIds) | 98 | 配置流 | CamRetCode CommitStreams(OperationMode mode,<br/> const std::shared_ptr\<CameraMetadata\> &modeSetting) | 99 | 获取流的属性 | CamRetCode GetStreamAttributes(<br/> std::vector\<std::shared_ptr\<StreamAttribute\>\> &attributes) | 100 | 绑定生产者句柄和指定流 | CamRetCode AttachBufferQueue(int streamId, const OHOS::sptr\<OHOS::IBufferProducer\> &producer) | 101 | 解除生产者句柄和指定流的绑定关系 | CamRetCode DetachBufferQueue(int streamId) | 102 | 捕获图像 | CamRetCode Capture(int captureId,<br/> const std::shared_ptr\<CaptureInfo\> &info, bool isStreaming) | 103 | 取消捕获 | CamRetCode CancelCapture(int captureId) | 104 | 将指定流转换成离线流 | CamRetCode ChangeToOfflineStream(const std::vector\<int\> &streamIds,<br/> OHOS::sptr\<IStreamOperatorCallback\> &callback,<br/> OHOS::sptr\<IOfflineStreamOperator\> &offlineOperator) | 105 106- istream_operator_callback.h 107 108 | 功能描述 | 接口名称 | 109 | ---------------------------------------- | ------------------------------------------------------------ | 110 | 捕获开始回调,在捕获开始时调用 | void OnCaptureStarted(int32_t captureId, const std::vector\<int32_t\> &streamIds) | 111 | 捕获结束回调,在捕获结束时调用 | void OnCaptureEnded(int32_t captureId,<br/> const std::vector\<std::shared_ptr\<CaptureEndedInfo\>\> &infos) | 112 | 捕获错误回调,在捕获过程中发生错误时调用 | void OnCaptureError(int32_t captureId,<br/> const std::vector\<std::shared_ptr\<CaptureErrorInfo\>\> &infos) | 113 | 帧捕获回调 | void OnFrameShutter(int32_t captureId,<br/> const std::vector\<int32_t\> &streamIds, uint64_t timestamp) | 114 115 116 117## 使用方法 118 119在/drivers/peripheral/camera/hal/init目录下有一个关于Camera的demo,该demo可以完成Camera的预览,拍照等基础功能。下面我们就以此demo为例讲述怎样用HDI接口去编写预览PreviewOn()和拍照CaptureOn()的用例,可参考[ohos_camera_demo](https://gitee.com/openharmony/drivers_peripheral/tree/master/camera/hal/init)。 120 1211. 在main函数中构造一个CameraDemo 对象,该对象中有对Camera初始化、启停流、释放等控制的方法。下面mainDemo->InitSensors()函数为初始化CameraHost,mainDemo->InitCameraDevice()函数为初始化CameraDevice。 122 123 ``` 124 int main(int argc, char** argv) 125 { 126 RetCode rc = RC_OK; 127 auto mainDemo = std::make_shared<CameraDemo>(); 128 rc = mainDemo->InitSensors(); // 初始化CameraHost 129 if (rc == RC_ERROR) { 130 CAMERA_LOGE("main test: mainDemo->InitSensors() error\n"); 131 return RC_ERROR; 132 } 133 134 rc = mainDemo->InitCameraDevice(); // 初始化CameraDevice 135 if (rc == RC_ERROR) { 136 CAMERA_LOGE("main test: mainDemo->InitCameraDevice() error\n"); 137 return RC_ERROR; 138 } 139 140 rc = PreviewOn(0, mainDemo); // 配流和启流 141 if (rc != RC_OK) { 142 CAMERA_LOGE("main test: PreviewOn() error demo exit"); 143 return RC_ERROR; 144 } 145 146 ManuList(mainDemo, argc, argv); // 打印菜单到控制台 147 148 return RC_OK; 149 } 150 ``` 151 152 初始化CameraHost函数实现如下,这里调用了HDI接口ICameraHost::Get()去获取demoCameraHost,并对其设置回调函数。 153 154 ``` 155 RetCode CameraDemo::InitSensors() 156 { 157 demoCameraHost_ = ICameraHost::Get(DEMO_SERVICE_NAME); 158 if (demoCameraHost_ == nullptr) { 159 CAMERA_LOGE("demo test: ICameraHost::Get error"); 160 return RC_ERROR; 161 } 162 163 hostCallback_ = new CameraHostCallback(); 164 rc = demoCameraHost_->SetCallback(hostCallback_); 165 return RC_OK; 166 } 167 ``` 168 169 初始化CameraDevice函数实现如下,这里调用了GetCameraIds(cameraIds),GetCameraAbility(cameraId, ability),OpenCamera(cameraIds.front(), callback, demoCameraDevice_)等接口实现了demoCameraHost的获取。 170 171 ``` 172 RetCode CameraDemo::InitCameraDevice() 173 { 174 (void)demoCameraHost_->GetCameraIds(cameraIds_); 175 const std::string cameraId = cameraIds_.front(); 176 demoCameraHost_->GetCameraAbility(cameraId, ability_); 177 178 sptr<CameraDeviceCallback> callback = new CameraDeviceCallback(); 179 rc = demoCameraHost_->OpenCamera(cameraIds_.front(), callback, demoCameraDevice_); 180 return RC_OK; 181 } 182 ``` 183 1842. PreviewOn()接口包含配置流、开启预览流和启动Capture动作。该接口执行完成后Camera预览通路已经开始运转并开启了两路流,一路流是preview,另外一路流是capture或者video,两路流中仅对preview流进行capture动作。 185 186 ``` 187 static RetCode PreviewOn(int mode, const std::shared_ptr<CameraDemo> &mainDemo) 188 { 189 rc = mainDemo->StartPreviewStream(); // 配置preview流 190 if (mode == 0) { 191 rc = mainDemo->StartCaptureStream(); // 配置capture流 192 } else { 193 rc = mainDemo->StartVideoStream(); // 配置video流 194 } 195 196 rc = mainDemo->CaptureOn(STREAM_ID_PREVIEW, CAPTURE_ID_PREVIEW, CAPTURE_PREVIEW); // 将preview流capture 197 return RC_OK; 198 } 199 ``` 200 201 StartCaptureStream()、StartVideoStream()和StartPreviewStream()接口都会调用CreateStream()接口,只是传入的参数不同。 202 203 ``` 204 RetCode CameraDemo::StartVideoStream() 205 { 206 RetCode rc = RC_OK; 207 if (!isVideoOn_) { 208 isVideoOn_ = true; 209 rc = CreateStream(STREAM_ID_VIDEO, streamCustomerVideo_, VIDEO); // 如需启preview或者capture流更改该接口参数即可。 210 } 211 return RC_OK; 212 } 213 ``` 214 215 CreateStream()方法调用HDI接口去配置和创建流,首先调用HDI接口去获取StreamOperation对象,然后创建一个StreamInfo。调用CreateStreams()和CommitStreams()实际创建流并配置流。 216 217 ``` 218 RetCode CameraDemo::CreateStreams() 219 { 220 std::vector<std::shared_ptr<StreamInfo>> streamInfos; 221 GetStreamOpt(); // 获取StreamOperator对象 222 223 rc = streamOperator_->CreateStreams(streamInfos); // 创建流 224 rc = streamOperator_->CommitStreams(Camera::NORMAL, ability_); 225 226 return RC_OK; 227 } 228 ``` 229 230 CaptureOn()接口调用streamOperator的Capture()方法获取Camera数据并轮转buffer,拉起一个线程接收相应类型的数据。 231 232 ``` 233 RetCode CameraDemo::CaptureOn(const int streamId, const int captureId, CaptureMode mode) 234 { 235 std::shared_ptr<Camera::CaptureInfo> captureInfo = std::make_shared<Camera::CaptureInfo>(); // 创建并填充CaptureInfo 236 captureInfo->streamIds_ = {streamId}; 237 captureInfo->captureSetting_ = ability_; 238 captureInfo->enableShutterCallback_ = false; 239 240 int rc = streamOperator_->Capture(captureId, captureInfo, true); // 实际capture开始,buffer轮转开始 241 if (mode == CAPTURE_PREVIEW) { 242 streamCustomerPreview_->ReceiveFrameOn(nullptr); // 创建预览线程接收递上来的buffer 243 } else if (mode == CAPTURE_SNAPSHOT) { 244 streamCustomerCapture_->ReceiveFrameOn([this](void* addr, const uint32_t size) { // 创建capture线程通过StoreImage回调接收递上来的buffer 245 StoreImage(addr, size); 246 }); 247 } else if (mode == CAPTURE_VIDEO) { 248 OpenVideoFile(); 249 streamCustomerVideo_->ReceiveFrameOn([this](void* addr, const uint32_t size) {// 创建Video线程通过StoreVideo回调接收递上来的buffer 250 StoreVideo(addr, size); 251 }); 252 } 253 return RC_OK; 254 } 255 ``` 256 2573. ManuList()函数从控制台通过fgets()接口获取字符,不同字符所对应demo支持的功能不同,并打印出该demo所支持功能的菜单。 258 259 ``` 260 static void ManuList(const std::shared_ptr<CameraDemo> &mainDemo, 261 const int argc, char** argv) 262 { 263 int idx, c; 264 int awb = 1; 265 constexpr char shortOptions[] = "h:cwvaqof:"; 266 c = getopt_long(argc, argv, shortOptions, longOptions, &idx); 267 while(1) { 268 switch (c) { 269 case 'h': 270 c = PutMenuAndGetChr(); // 打印菜单 271 break; 272 case 'f': 273 FlashLightTest(mainDemo); // 手电筒功能测试 274 c = PutMenuAndGetChr(); 275 break; 276 case 'o': 277 OfflineTest(mainDemo); // Offline功能测试 278 c = PutMenuAndGetChr(); 279 break; 280 case 'c': 281 CaptureTest(mainDemo); // Capture功能测试 282 c = PutMenuAndGetChr(); 283 break; 284 case 'w': // AWB功能测试 285 if (awb) { 286 mainDemo->SetAwbMode(OHOS_CAMERA_AWB_MODE_INCANDESCENT); 287 } else { 288 mainDemo->SetAwbMode(OHOS_CAMERA_AWB_MODE_OFF); 289 } 290 awb = !awb; 291 c = PutMenuAndGetChr(); 292 break; 293 case 'a': // AE功能测试 294 mainDemo->SetAeExpo(); 295 c = PutMenuAndGetChr(); 296 break; 297 case 'v': // Video功能测试 298 VideoTest(mainDemo); 299 c = PutMenuAndGetChr(); 300 break; 301 case 'q': // 退出demo 302 PreviewOff(mainDemo); 303 mainDemo->QuitDemo(); 304 exit(EXIT_SUCCESS); 305 306 default: 307 CAMERA_LOGE("main test: command error please retry input command"); 308 c = PutMenuAndGetChr(); 309 break; 310 } 311 } 312 } 313 ``` 314 315 316PutMenuAndGetChr()接口打印了demo程序的菜单,并调用fgets()等待从控制台输入命令,内容如下: 317 318``` 319 static int PutMenuAndGetChr(void) 320 { 321 constexpr uint32_t inputCount = 50; 322 int c = 0; 323 char strs[inputCount]; 324 Usage(stdout); 325 CAMERA_LOGD("pls input command(input -q exit this app)\n"); 326 fgets(strs, inputCount, stdin); 327 328 for (int i = 0; i < inputCount; i++) { 329 if (strs[i] != '-') { 330 c = strs[i]; 331 break; 332 } 333 } 334 return c; 335 } 336``` 337 338控制台输出菜单详情如下: 339 340``` 341 "Options:\n" 342 "-h | --help Print this message\n" 343 "-o | --offline stream offline test\n" 344 "-c | --capture capture one picture\n" 345 "-w | --set WB Set white balance Cloudy\n" 346 "-v | --video capture Video of 10s\n" 347 "-a | --Set AE Set Auto exposure\n" 348 "-f | --Set Flashlight Set flashlight ON 5s OFF\n" 349 "-q | --quit stop preview and quit this app\n"); 350``` 351 352 353 354## 相关链接 355 [驱动子系统](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/%E9%A9%B1%E5%8A%A8%E5%AD%90%E7%B3%BB%E7%BB%9F.md) 356 357 [vendor_hisilicon/tree/master/Hi3516DV300/hdf_config](https://gitee.com/openharmony/vendor_hisilicon/blob/master/README_zh.md) 358 359 360 361