• Home
Name Date Size #Lines LOC

..--

figures/12-May-2024-

hal_c/12-May-2024-2,0641,341

hdi_service/v1_0/12-May-2024-1,4821,045

interfaces/12-May-2024-1,202772

test/12-May-2024-30,62722,643

vdi_base/12-May-2024-39,47631,221

.gitignoreD12-May-202428 54

BUILD.gnD12-May-20242 KiB6862

README_zh.mdD12-May-202417.5 KiB361289

bundle.jsonD12-May-20241 KiB5049

camera.gniD12-May-20241.1 KiB3731

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        ![](figures/Camera模块驱动模型.png)
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/test目录下有一个关于Camera的demo,该demo可以完成Camera的预览,拍照等基础功能。下面我们就以此demo为例讲述怎样用HDI接口去编写预览PreviewOn()和拍照CaptureOn()的用例,可参考[ohos_camera_demo](https://gitee.com/openharmony/drivers_peripheral/tree/master/camera/hal/test)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