1e41f4b71Sopenharmony_ci# Camera
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Overview
4e41f4b71Sopenharmony_ci### Function
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ciThe OpenHarmony camera driver model provides the camera hardware device interface (HDI) and the camera pipeline model to manage camera devices. The camera driver model is divided into three layers:
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ci+ HDI implementation layer: implements standard ohos (OpenHarmony operating system) APIs for cameras.
9e41f4b71Sopenharmony_ci+ Framework layer: interacts with the HDI implementation layer to set up data channels and operate camera devices.
10e41f4b71Sopenharmony_ci+ Device adaptation layer: supports different platforms by shielding the differences in underlying chips and operating systems.
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci### Working Principles
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ciThe camera module is used to initialize services and devices, set up data channels, and configure, create, deliver, and capture streams. The following figure shows the camera driver model.
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ci**Figure 1** HDF-based camera driver model
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ci![](figures/camera-driver-model-architecture.png)
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ci1. When the system starts, the camera_host process is created. The process enumerates underlying devices, creates a **DeviceManager** instance (to manage the device tree), an object for each underlying device, and a **CameraHost** instance, and registers the **CameraHost** instance with the user-mode HDF (UHDF) service. Through the UHDF service, the camera service can obtain the underlying **CameraDeviceHost** services to operate the hardware devices. The **DeviceManager** instance can also be created by using the configuration table.
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci2. The Camera Service obtains the **CameraHost** instance through the CameraDeviceHost service.
23e41f4b71Sopenharmony_ci   
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ciThe **CameraHost** instance can be used to obtain the underlying camera capabilities, turn on the flashlight, call **Open()** to start a camera and set up a connection with the camera, create a **DeviceManager** instance (to power on the hardware modules), and create a **CameraDevice** instance (to provide the device control interface for the upper layer). 
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ci   When the **CameraDevice** instance is created, the PipelineCore modules will be instantiated. The StreamPipelineCore module creates pipelines, and the MetaQueueManager module reports metadata.
28e41f4b71Sopenharmony_ci
29e41f4b71Sopenharmony_ci3. The Camera Service configures stream and creates a **Stream** class through the CameraDevice module. The StreamPipelineStrategy module creates the node connection mode of the corresponding stream by using the mode issued by the upper layer and querying the configuration table. The StreamPipelineBuilder module creates a node and returns the pipeline to the StreamPipelineDispatcher module through the connection. The StreamPipelineDispatcher module dispatches pipelines.
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ci4. The Camera Service controls the stream operations through the **Stream** instance.
32e41f4b71Sopenharmony_ci
33e41f4b71Sopenharmony_ci   **AttachBufferQueue()** delivers the buffer queue requested from the display module to the bottom layer. The CameraDeviceDriverModel manages the buffer. After **Capture()** is called to deliver commands, the bottom layer transfers the buffer to the upper layer. The Image Signal Processor (ISP) node obtains a specified number of buffers from the buffer queue and delivers the buffers to the bottom-layer ISP hardware. After filling the buffers, the ISP hardware transfers the buffers to the CameraDeviceDriverModel. The CameraDeviceDriverModel fills the created pipeline with the received buffers by using a loop thread. Each node processes the pipeline data and transfers the data to the upper layer in a callback. At the same time, the buffers are freed to the buffer queue for reuse.
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_ci5. The Camera Service delivers the photographing command through **Capture()**. **ChangeToOfflineStream()** is used to query the position of the photographing buffer. If the ISP hardware has output an image and sent the image data to the IPP node, the common photographing stream can be converted into an offline stream. Otherwise, the close process is executed. **ChangeToOfflineStream()** passes **StreamInfo** to enable the offline stream to obtain the stream information of the common stream, determines the node connection mode of the offline stream based on the configuration table, and creates the node connection for the offline stream (if the node connection has been created, the node required by the non-offline stream will be closed by **CloseCamera**.) When the buffer is transferred from the  pipeline to the upper layer, the pipeline resources are released.
36e41f4b71Sopenharmony_ci
37e41f4b71Sopenharmony_ci6. The Camera Service sends the **CaptureSetting** parameter to the CameraDeviceDriverModel through **UpdateSettings()** of the **CameraDevice** instance. The CameraDeviceDriverModel forwards the parameter to each node through the StreamPipelineDispatcher module. The **CaptureSetting** parameter carried in **StartStreamingCapture()** and **Capture()** is forwarded to the node to which the stream belongs through the StreamPipelineDispatcher module.
38e41f4b71Sopenharmony_ci
39e41f4b71Sopenharmony_ci7. The Camera Service uses **EnableResult()** and **DisableResult()** to control the reporting of underlying metadata. If the underlying metadata needs to be reported, the pipeline creates a buffer queue in the CameraDeviceDriverModel to collect and transfer metadata, queries the configuration table based on the StreamPipelineStrategy module, and creates and connects to the specified node through the StreamPipelineBuilder module. The MetaQueueManager module delivers the buffer to the bottom layer, and the bottom-layer node fills in data. The MetaQueueManager module then invokes the upper-layer callback to transfer the data to the upper layer.
40e41f4b71Sopenharmony_ci
41e41f4b71Sopenharmony_ci8. The Camera Service calls **Close()** of the **CameraDevice** class, and the **CameraDevice** instance calls the corresponding DeviceManager module to power off each hardware. If an offline stream exists in the subpipeline of the IPP node, the offline stream must be reserved until the execution is complete.
42e41f4b71Sopenharmony_ci
43e41f4b71Sopenharmony_ci9. To implement dynamic frame control, a CollectBuffer thread is started in the StreamOperator. The CollectBuffer thread obtains a buffer from the buffer queue of each stream. If the frame rate of a stream needs to be controlled (1/n of the sensor output frame rate), the CollectBuffer thread can control the buffer packaging of each frame as required, and determine whether to collect the buffer of the stream. For example, if the output frame rate of the sensor is 120 fps and the preview stream frame rate is 30 fps, the CollectBuffer thread collects the buffer of the preview stream every 4 fps.
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ci   
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ci## Development Guidelines
48e41f4b71Sopenharmony_ci
49e41f4b71Sopenharmony_ci
50e41f4b71Sopenharmony_ci### When to Use
51e41f4b71Sopenharmony_ci
52e41f4b71Sopenharmony_ciThe camera module encapsulates camera operations in camera preview, photographing, and video streams to implement camera hardware operations and improve development efficiency.
53e41f4b71Sopenharmony_ci
54e41f4b71Sopenharmony_ci### Available APIs
55e41f4b71Sopenharmony_ci
56e41f4b71Sopenharmony_ciThe following table describes the C++ APIs generated from the Interface Definition Language (IDL). For details about the interface declaration, see the IDL files in [https://gitee.com/openharmony/drivers_interface/tree/master/camera/v1_1/](https://gitee.com/openharmony/drivers_interface/tree/master/camera).
57e41f4b71Sopenharmony_ci
58e41f4b71Sopenharmony_ciThe parameters passed in the HDI cannot exceed the capability range obtained by **GetCameraAbility**. Even if the parameters beyond the capability range can be passed in APIs such as **UpdateSettings**, **CommitStreams**, and **Capture** with no error returned, unexpected behavior may be caused.
59e41f4b71Sopenharmony_ci
60e41f4b71Sopenharmony_ci- icamera_device.h
61e41f4b71Sopenharmony_ci
62e41f4b71Sopenharmony_ci  | API                                                    | Description                                         |
63e41f4b71Sopenharmony_ci  | ------------------------------------------------------------ | ------------------------------------------------------------ |
64e41f4b71Sopenharmony_ci  | int32_t GetStreamOperator_V1_1(const sptr\<OHOS::HDI::Camera::V1_0::IStreamOperatorCallback\>& callbackObj,sptr\<OHOS::HDI::Camera::V1_1::IStreamOperator\>& streamOperator) | Obtains the stream controller. |
65e41f4b71Sopenharmony_ci
66e41f4b71Sopenharmony_ci- icamera_host.h
67e41f4b71Sopenharmony_ci
68e41f4b71Sopenharmony_ci  | API                                                    | Description                                         |
69e41f4b71Sopenharmony_ci  | ------------------------------------------------------------ | ------------------------------------------------------------ |
70e41f4b71Sopenharmony_ci  | 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) | Opens a camera. |
71e41f4b71Sopenharmony_ci  | int32_t PreLaunch(const PrelaunchConfig& config) | Pre-starts the camera. |
72e41f4b71Sopenharmony_ci
73e41f4b71Sopenharmony_ci- istream_operator.h
74e41f4b71Sopenharmony_ci
75e41f4b71Sopenharmony_ci  | API                                                    | Description                                         |
76e41f4b71Sopenharmony_ci  | ------------------------------------------------------------ | ------------------------------------------------------------ |
77e41f4b71Sopenharmony_ci  | int32_t IsStreamsSupported_V1_1(OperationMode mode,<br>const std::vector<uint8_t>& modeSetting,<br>const std::vector<StreamInfo_V1_1>& infos,<br>StreamSupportType& type) | Checks whether a stream can be added. |
78e41f4b71Sopenharmony_ci  | int32_t CreateStreams_V1_1(const std::vector<StreamInfo_V1_1>& streamInfos) | Creates streams. |
79e41f4b71Sopenharmony_ci
80e41f4b71Sopenharmony_ci
81e41f4b71Sopenharmony_ci### How to Develop
82e41f4b71Sopenharmony_ciThe camera driver development procedure is as follows:
83e41f4b71Sopenharmony_ci
84e41f4b71Sopenharmony_ci1. Register a **CameraHost** instance.
85e41f4b71Sopenharmony_ci
86e41f4b71Sopenharmony_ci    Define the **HdfDriverEntry** structure to define the method for initializing **CameraHost**. For details about the code, see **drivers/peripheral/camera/interfaces/hdi_ipc/camera_host_driver.cpp**.
87e41f4b71Sopenharmony_ci    ```c++
88e41f4b71Sopenharmony_ci   struct HdfDriverEntry g_cameraHostDriverEntry = {
89e41f4b71Sopenharmony_ci       .moduleVersion = 1,
90e41f4b71Sopenharmony_ci       .moduleName = "camera_service",
91e41f4b71Sopenharmony_ci       .Bind = HdfCameraHostDriverBind,
92e41f4b71Sopenharmony_ci       .Init = HdfCameraHostDriverInit,
93e41f4b71Sopenharmony_ci       .Release = HdfCameraHostDriverRelease,
94e41f4b71Sopenharmony_ci   };
95e41f4b71Sopenharmony_ci   HDF_INIT(g_cameraHostDriverEntry); // Register the HdfDriverEntry structure with the HDF.
96e41f4b71Sopenharmony_ci   ```
97e41f4b71Sopenharmony_ci
98e41f4b71Sopenharmony_ci2. Initialize the **CameraHost** service.
99e41f4b71Sopenharmony_ci
100e41f4b71Sopenharmony_ci    The **HdfCameraHostDriverBind()** method defined in the **HdfDriverEntry** structure registers **CameraServiceDispatch()** and **CameraHostStubInstance()**. **CameraServiceDispatch()** is used to remotely call the **CameraHost** methods, such as **OpenCamera()** and **SetFlashlight()**. **CameraHostStubInstance()** is called during the system startup to initialize the camera.
101e41f4b71Sopenharmony_ci
102e41f4b71Sopenharmony_ci   ```c++
103e41f4b71Sopenharmony_ci   static int HdfCameraHostDriverBind(struct HdfDeviceObject *deviceObject)
104e41f4b71Sopenharmony_ci   {
105e41f4b71Sopenharmony_ci       HDF_LOGI("HdfCameraHostDriverBind enter");
106e41f4b71Sopenharmony_ci    
107e41f4b71Sopenharmony_ci       auto *hdfCameraHostHost = new (std::nothrow) HdfCameraHostHost;
108e41f4b71Sopenharmony_ci       if (hdfCameraHostHost == nullptr) {
109e41f4b71Sopenharmony_ci           HDF_LOGE("%{public}s: failed to create HdfCameraHostHost object", __func__);
110e41f4b71Sopenharmony_ci           return HDF_FAILURE;
111e41f4b71Sopenharmony_ci       }
112e41f4b71Sopenharmony_ci    
113e41f4b71Sopenharmony_ci       hdfCameraHostHost->ioService.Dispatch = CameraHostDriverDispatch; // Provide a method to remotely call a CameraHost method.
114e41f4b71Sopenharmony_ci       hdfCameraHostHost->ioService.Open = NULL;
115e41f4b71Sopenharmony_ci       hdfCameraHostHost->ioService.Release = NULL;
116e41f4b71Sopenharmony_ci    
117e41f4b71Sopenharmony_ci       auto serviceImpl = ICameraHost::Get(true);
118e41f4b71Sopenharmony_ci       if (serviceImpl == nullptr) {
119e41f4b71Sopenharmony_ci           HDF_LOGE("%{public}s: failed to get of implement service", __func__);
120e41f4b71Sopenharmony_ci           delete hdfCameraHostHost;
121e41f4b71Sopenharmony_ci           return HDF_FAILURE;
122e41f4b71Sopenharmony_ci       }
123e41f4b71Sopenharmony_ci    
124e41f4b71Sopenharmony_ci       hdfCameraHostHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl,
125e41f4b71Sopenharmony_ci           ICameraHost::GetDescriptor()); // Initialize the camera.
126e41f4b71Sopenharmony_ci       if (hdfCameraHostHost->stub == nullptr) {
127e41f4b71Sopenharmony_ci           HDF_LOGE("%{public}s: failed to get stub object", __func__);
128e41f4b71Sopenharmony_ci           delete hdfCameraHostHost;
129e41f4b71Sopenharmony_ci           return HDF_FAILURE;
130e41f4b71Sopenharmony_ci       }
131e41f4b71Sopenharmony_ci    
132e41f4b71Sopenharmony_ci       deviceObject->service = &hdfCameraHostHost->ioService;
133e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
134e41f4b71Sopenharmony_ci   }
135e41f4b71Sopenharmony_ci   ```
136e41f4b71Sopenharmony_ci
137e41f4b71Sopenharmony_ci   The following functions are the implementation of the methods of the **CameraHost**:
138e41f4b71Sopenharmony_ci
139e41f4b71Sopenharmony_ci   ```c++
140e41f4b71Sopenharmony_ci   int32_t CameraHostStub::CameraHostServiceStubOnRemoteRequest(int cmdId, MessageParcel &data,
141e41f4b71Sopenharmony_ci       MessageParcel &reply, MessageOption &option)
142e41f4b71Sopenharmony_ci   {
143e41f4b71Sopenharmony_ci       switch(cmdId) {
144e41f4b71Sopenharmony_ci           case CMD_CAMERA_HOST_SET_CALLBACK: {
145e41f4b71Sopenharmony_ci               return CameraHostStubSetCallback(data, reply, option);
146e41f4b71Sopenharmony_ci           }
147e41f4b71Sopenharmony_ci           case CMD_CAMERA_HOST_GET_CAMERAID: {
148e41f4b71Sopenharmony_ci               return CameraHostStubGetCameraIds(data, reply, option);
149e41f4b71Sopenharmony_ci           }
150e41f4b71Sopenharmony_ci           case CMD_CAMERA_HOST_GET_CAMERA_ABILITY: {
151e41f4b71Sopenharmony_ci               return CameraHostStubGetCameraAbility(data, reply, option);
152e41f4b71Sopenharmony_ci           }
153e41f4b71Sopenharmony_ci           case CMD_CAMERA_HOST_OPEN_CAMERA: {
154e41f4b71Sopenharmony_ci               return CameraHostStubOpenCamera(data, reply, option);
155e41f4b71Sopenharmony_ci           }
156e41f4b71Sopenharmony_ci           case CMD_CAMERA_HOST_SET_FLASH_LIGHT: {
157e41f4b71Sopenharmony_ci               return CameraHostStubSetFlashlight(data, reply, option);
158e41f4b71Sopenharmony_ci           }
159e41f4b71Sopenharmony_ci           default: {
160e41f4b71Sopenharmony_ci               HDF_LOGE("%s: not support cmd %d", __func__, cmdId);
161e41f4b71Sopenharmony_ci               return HDF_ERR_INVALID_PARAM;
162e41f4b71Sopenharmony_ci           }
163e41f4b71Sopenharmony_ci       }
164e41f4b71Sopenharmony_ci       return HDF_SUCCESS;
165e41f4b71Sopenharmony_ci   }
166e41f4b71Sopenharmony_ci   ```
167e41f4b71Sopenharmony_ci
168e41f4b71Sopenharmony_ci   **CameraHostStubInstance()** finally calls **CameraHostImpl::Init()** to obtain the physical camera and initialize the DeviceManager and PipelineCore modules.
169e41f4b71Sopenharmony_ci
170e41f4b71Sopenharmony_ci3. Obtain the **CameraHost** service.
171e41f4b71Sopenharmony_ci
172e41f4b71Sopenharmony_ci   Use **Get()** to obtain the **CameraHost** from the **CameraService**. The **Get()** method is as follows:
173e41f4b71Sopenharmony_ci
174e41f4b71Sopenharmony_ci   ```c++
175e41f4b71Sopenharmony_ci   sptr<ICameraHost> ICameraHost::Get(const char *serviceName)
176e41f4b71Sopenharmony_ci   {
177e41f4b71Sopenharmony_ci       do {
178e41f4b71Sopenharmony_ci           using namespace OHOS::HDI::ServiceManager::V1_0;
179e41f4b71Sopenharmony_ci           auto servMgr = IServiceManager::Get();
180e41f4b71Sopenharmony_ci           if (servMgr == nullptr) {
181e41f4b71Sopenharmony_ci               HDF_LOGE("%s: IServiceManager failed!", __func__);
182e41f4b71Sopenharmony_ci               break;
183e41f4b71Sopenharmony_ci           }
184e41f4b71Sopenharmony_ci           auto remote = servMgr->GetService(serviceName);  // Obtain the CameraHost based on serviceName.
185e41f4b71Sopenharmony_ci           if (remote != nullptr) {
186e41f4b71Sopenharmony_ci               sptr<CameraHostProxy> hostSptr = iface_cast<CameraHostProxy>(remote); // Return the CameraHostProxy object that contains interfaces such as OpenCamera() to the caller.
187e41f4b71Sopenharmony_ci               return hostSptr;
188e41f4b71Sopenharmony_ci           }
189e41f4b71Sopenharmony_ci           HDF_LOGE("%s: GetService failed! serviceName = %s", __func__, serviceName);
190e41f4b71Sopenharmony_ci       } while(false);
191e41f4b71Sopenharmony_ci       HDF_LOGE("%s: get %s failed!", __func__, serviceName);
192e41f4b71Sopenharmony_ci       return nullptr;
193e41f4b71Sopenharmony_ci   }
194e41f4b71Sopenharmony_ci   ```
195e41f4b71Sopenharmony_ci
196e41f4b71Sopenharmony_ci4. Open a camera device.
197e41f4b71Sopenharmony_ci
198e41f4b71Sopenharmony_ci   The **CameraHostProxy** class provides **SetCallback()**, **GetCameraIds()**, **GetCameraAbility()**, **OpenCamera()**, and **SetFlashlight()**. The following describes **OpenCamera()**.
199e41f4b71Sopenharmony_ci   Use **OpenCamera()** to call the remote **CameraHostStubOpenCamera()** through the **CMD_CAMERA_HOST_OPEN_CAMERA** to obtain an **ICameraDevice** object.
200e41f4b71Sopenharmony_ci
201e41f4b71Sopenharmony_ci   ```c++
202e41f4b71Sopenharmony_ci   int32_t CameraHostProxy::OpenCamera(const std::string& cameraId, const sptr<ICameraDeviceCallback>& callbackObj,
203e41f4b71Sopenharmony_ci       sptr<ICameraDevice>& device)
204e41f4b71Sopenharmony_ci   {
205e41f4b71Sopenharmony_ci       MessageParcel cameraHostData;
206e41f4b71Sopenharmony_ci       MessageParcel cameraHostReply;
207e41f4b71Sopenharmony_ci       MessageOption cameraHostOption(MessageOption::TF_SYNC);
208e41f4b71Sopenharmony_ci    
209e41f4b71Sopenharmony_ci       if (!cameraHostData.WriteInterfaceToken(ICameraHost::GetDescriptor())) {
210e41f4b71Sopenharmony_ci           HDF_LOGE("%{public}s: failed to write interface descriptor!", __func__);
211e41f4b71Sopenharmony_ci           return HDF_ERR_INVALID_PARAM;
212e41f4b71Sopenharmony_ci       }
213e41f4b71Sopenharmony_ci    
214e41f4b71Sopenharmony_ci       if (!cameraHostData.WriteCString(cameraId.c_str())) {
215e41f4b71Sopenharmony_ci           HDF_LOGE("%{public}s: write cameraId failed!", __func__);
216e41f4b71Sopenharmony_ci           return HDF_ERR_INVALID_PARAM;
217e41f4b71Sopenharmony_ci       }
218e41f4b71Sopenharmony_ci    
219e41f4b71Sopenharmony_ci       if (!cameraHostData.WriteRemoteObject(OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(callbackObj, 
220e41f4b71Sopenharmony_ci           ICameraDeviceCallback::GetDescriptor()))) {
221e41f4b71Sopenharmony_ci           HDF_LOGE("%{public}s: write callbackObj failed!", __func__);
222e41f4b71Sopenharmony_ci           return HDF_ERR_INVALID_PARAM;
223e41f4b71Sopenharmony_ci       }
224e41f4b71Sopenharmony_ci    
225e41f4b71Sopenharmony_ci       int32_t cameraHostRet = Remote()->SendRequest(CMD_CAMERA_HOST_OPEN_CAMERA, cameraHostData, cameraHostReply, cameraHostOption);
226e41f4b71Sopenharmony_ci       if (cameraHostRet != HDF_SUCCESS) {
227e41f4b71Sopenharmony_ci           HDF_LOGE("%{public}s failed, error code is %{public}d", __func__, cameraHostRet);
228e41f4b71Sopenharmony_ci           return cameraHostRet;
229e41f4b71Sopenharmony_ci       }
230e41f4b71Sopenharmony_ci    
231e41f4b71Sopenharmony_ci       device = hdi_facecast<ICameraDevice>(cameraHostReply.ReadRemoteObject());
232e41f4b71Sopenharmony_ci    
233e41f4b71Sopenharmony_ci       return cameraHostRet;
234e41f4b71Sopenharmony_ci   }
235e41f4b71Sopenharmony_ci   ```
236e41f4b71Sopenharmony_ci
237e41f4b71Sopenharmony_ci   **Remote()->SendRequest** calls **CameraHostServiceStubOnRemoteRequest()**, locates **CameraHostStubOpenCamera()** based on **cmdId**, and finally calls **CameraHostImpl::OpenCamera()** to obtain a **CameraDevice** and power on the camera hardware.
238e41f4b71Sopenharmony_ci
239e41f4b71Sopenharmony_ci   ```c++
240e41f4b71Sopenharmony_ci   int32_t CameraHostImpl::OpenCamera(const std::string& cameraId, const sptr<ICameraDeviceCallback>& callbackObj,
241e41f4b71Sopenharmony_ci       sptr<ICameraDevice>& device)
242e41f4b71Sopenharmony_ci   {
243e41f4b71Sopenharmony_ci       CAMERA_LOGD("OpenCamera entry");
244e41f4b71Sopenharmony_ci       DFX_LOCAL_HITRACE_BEGIN;
245e41f4b71Sopenharmony_ci       if (CameraIdInvalid(cameraId) != RC_OK || callbackObj == nullptr) {
246e41f4b71Sopenharmony_ci           CAMERA_LOGW("open camera id is empty or callback is null.");
247e41f4b71Sopenharmony_ci           return INVALID_ARGUMENT;
248e41f4b71Sopenharmony_ci       }
249e41f4b71Sopenharmony_ci    
250e41f4b71Sopenharmony_ci       auto itr = cameraDeviceMap_.find(cameraId);
251e41f4b71Sopenharmony_ci       if (itr == cameraDeviceMap_.end()) {
252e41f4b71Sopenharmony_ci           CAMERA_LOGE("camera device not found.");
253e41f4b71Sopenharmony_ci           return INSUFFICIENT_RESOURCES;
254e41f4b71Sopenharmony_ci       }
255e41f4b71Sopenharmony_ci       CAMERA_LOGD("OpenCamera cameraId find success.");
256e41f4b71Sopenharmony_ci    
257e41f4b71Sopenharmony_ci       std::shared_ptr<CameraDeviceImpl> cameraDevice = itr->second;
258e41f4b71Sopenharmony_ci       if (cameraDevice == nullptr) {
259e41f4b71Sopenharmony_ci           CAMERA_LOGE("camera device is null.");
260e41f4b71Sopenharmony_ci           return INSUFFICIENT_RESOURCES;
261e41f4b71Sopenharmony_ci       }
262e41f4b71Sopenharmony_ci    
263e41f4b71Sopenharmony_ci       CamRetCode ret = cameraDevice->SetCallback(callbackObj);
264e41f4b71Sopenharmony_ci       CHECK_IF_NOT_EQUAL_RETURN_VALUE(ret, HDI::Camera::V1_0::NO_ERROR, ret);
265e41f4b71Sopenharmony_ci    
266e41f4b71Sopenharmony_ci       CameraHostConfig *config = CameraHostConfig::GetInstance();
267e41f4b71Sopenharmony_ci       CHECK_IF_PTR_NULL_RETURN_VALUE(config, INVALID_ARGUMENT);
268e41f4b71Sopenharmony_ci    
269e41f4b71Sopenharmony_ci       std::vector<std::string> phyCameraIds;
270e41f4b71Sopenharmony_ci       RetCode rc = config->GetPhysicCameraIds(cameraId, phyCameraIds);
271e41f4b71Sopenharmony_ci       if (rc != RC_OK) {
272e41f4b71Sopenharmony_ci           CAMERA_LOGE("get physic cameraId failed.");
273e41f4b71Sopenharmony_ci           return DEVICE_ERROR;
274e41f4b71Sopenharmony_ci       }
275e41f4b71Sopenharmony_ci       if (CameraPowerUp(cameraId, phyCameraIds) != RC_OK) { // Power on the camera hardware.
276e41f4b71Sopenharmony_ci           CAMERA_LOGE("camera powerup failed.");
277e41f4b71Sopenharmony_ci           CameraPowerDown(phyCameraIds);
278e41f4b71Sopenharmony_ci           return DEVICE_ERROR;
279e41f4b71Sopenharmony_ci       }
280e41f4b71Sopenharmony_ci    
281e41f4b71Sopenharmony_ci       auto sptrDevice = deviceBackup_.find(cameraId);
282e41f4b71Sopenharmony_ci       if (sptrDevice == deviceBackup_.end()) {
283e41f4b71Sopenharmony_ci   #ifdef CAMERA_BUILT_ON_OHOS_LITE
284e41f4b71Sopenharmony_ci           deviceBackup_[cameraId] = cameraDevice;
285e41f4b71Sopenharmony_ci   #else
286e41f4b71Sopenharmony_ci           deviceBackup_[cameraId] = cameraDevice.get();
287e41f4b71Sopenharmony_ci   #endif
288e41f4b71Sopenharmony_ci       }
289e41f4b71Sopenharmony_ci       device = deviceBackup_[cameraId];
290e41f4b71Sopenharmony_ci       cameraDevice->SetStatus(true);
291e41f4b71Sopenharmony_ci       CAMERA_LOGD("open camera success.");
292e41f4b71Sopenharmony_ci       DFX_LOCAL_HITRACE_END;
293e41f4b71Sopenharmony_ci       return HDI::Camera::V1_0::NO_ERROR;
294e41f4b71Sopenharmony_ci   }
295e41f4b71Sopenharmony_ci   ```
296e41f4b71Sopenharmony_ci
297e41f4b71Sopenharmony_ci5. Obtain streams.
298e41f4b71Sopenharmony_ci
299e41f4b71Sopenharmony_ci   **CameraDeviceImpl** defines **GetStreamOperator()**, **UpdateSettings()**, **SetResultMode()**, and **GetEnabledResult()**. Use **GetStreamOperator()** to obtain steams.
300e41f4b71Sopenharmony_ci
301e41f4b71Sopenharmony_ci   ```c++
302e41f4b71Sopenharmony_ci   int32_t CameraDeviceImpl::GetStreamOperator(const sptr<IStreamOperatorCallback>& callbackObj,
303e41f4b71Sopenharmony_ci       sptr<IStreamOperator>& streamOperator)
304e41f4b71Sopenharmony_ci   {
305e41f4b71Sopenharmony_ci       HDI_DEVICE_PLACE_A_WATCHDOG;
306e41f4b71Sopenharmony_ci       DFX_LOCAL_HITRACE_BEGIN;
307e41f4b71Sopenharmony_ci       if (callbackObj == nullptr) {
308e41f4b71Sopenharmony_ci           CAMERA_LOGW("input callback is null.");
309e41f4b71Sopenharmony_ci           return INVALID_ARGUMENT;
310e41f4b71Sopenharmony_ci       }
311e41f4b71Sopenharmony_ci    
312e41f4b71Sopenharmony_ci       spCameraDeciceCallback_ = callbackObj;
313e41f4b71Sopenharmony_ci       if (spStreamOperator_ == nullptr) {
314e41f4b71Sopenharmony_ci   #ifdef CAMERA_BUILT_ON_OHOS_LITE
315e41f4b71Sopenharmony_ci           // Create a spStreamOperator_ object and pass it to the caller for subsequent stream operations.
316e41f4b71Sopenharmony_ci           spStreamOperator_ = std::make_shared<StreamOperator>(spCameraDeciceCallback_, shared_from_this());
317e41f4b71Sopenharmony_ci   #else
318e41f4b71Sopenharmony_ci           spStreamOperator_ = new(std::nothrow) StreamOperator(spCameraDeciceCallback_, shared_from_this());
319e41f4b71Sopenharmony_ci   #endif
320e41f4b71Sopenharmony_ci           if (spStreamOperator_ == nullptr) {
321e41f4b71Sopenharmony_ci               CAMERA_LOGW("create stream operator failed.");
322e41f4b71Sopenharmony_ci               return DEVICE_ERROR;
323e41f4b71Sopenharmony_ci           }
324e41f4b71Sopenharmony_ci           spStreamOperator_->Init();
325e41f4b71Sopenharmony_ci           ismOperator_ = spStreamOperator_;
326e41f4b71Sopenharmony_ci       }
327e41f4b71Sopenharmony_ci       streamOperator = ismOperator_;
328e41f4b71Sopenharmony_ci   #ifndef CAMERA_BUILT_ON_OHOS_LITE
329e41f4b71Sopenharmony_ci       CAMERA_LOGI("CameraDeviceImpl %{public}s: line: %{public}d", __FUNCTION__, __LINE__);
330e41f4b71Sopenharmony_ci       pipelineCore_->GetStreamPipelineCore()->SetCallback(
331e41f4b71Sopenharmony_ci           [this](const std::shared_ptr<CameraMetadata> &metadata) {
332e41f4b71Sopenharmony_ci           OnMetadataChanged(metadata);
333e41f4b71Sopenharmony_ci       });
334e41f4b71Sopenharmony_ci   #endif
335e41f4b71Sopenharmony_ci       DFX_LOCAL_HITRACE_END;
336e41f4b71Sopenharmony_ci       return HDI::Camera::V1_0::NO_ERROR;
337e41f4b71Sopenharmony_ci   }
338e41f4b71Sopenharmony_ci   ```
339e41f4b71Sopenharmony_ci
340e41f4b71Sopenharmony_ci6. Create streams.
341e41f4b71Sopenharmony_ci
342e41f4b71Sopenharmony_ci   Fill in the **StreamInfo** structure before creating streams by calling **CreateStreams()**.
343e41f4b71Sopenharmony_ci
344e41f4b71Sopenharmony_ci   ```c++
345e41f4b71Sopenharmony_ci   using StreamInfo = struct _StreamInfo {
346e41f4b71Sopenharmony_ci       int streamId_; 
347e41f4b71Sopenharmony_ci       int width_; // Stream width
348e41f4b71Sopenharmony_ci       int height_; // Stream height
349e41f4b71Sopenharmony_ci       int format_; // Stream format, for example, PIXEL_FMT_YCRCB_420_SP
350e41f4b71Sopenharmony_ci       int dataSpace_; 
351e41f4b71Sopenharmony_ci       StreamIntent intent_; // StreamIntent, for example, PREVIEW
352e41f4b71Sopenharmony_ci       bool tunneledMode_;
353e41f4b71Sopenharmony_ci       ufferProducerSequenceable bufferQueue_; // Use streamCustomer->CreateProducer() to create a buffer queue for streams.
354e41f4b71Sopenharmony_ci       int minFrameDuration_;
355e41f4b71Sopenharmony_ci       EncodeType encodeType_;
356e41f4b71Sopenharmony_ci   };
357e41f4b71Sopenharmony_ci   ```
358e41f4b71Sopenharmony_ci
359e41f4b71Sopenharmony_ci   **CreateStreams()** is a method in the **StreamOperator** class (**StreamOperatorImpl** is the base class of **StreamOperator**). Use **CreateStreams()** to create a **StreamBase** object, which initializes operations such as **CreateBufferPool** through its **Init()** method.
360e41f4b71Sopenharmony_ci
361e41f4b71Sopenharmony_ci   ```c++
362e41f4b71Sopenharmony_ci   int32_t StreamOperator::CreateStreams(const std::vector<StreamInfo>& streamInfos)
363e41f4b71Sopenharmony_ci   {
364e41f4b71Sopenharmony_ci       PLACE_A_NOKILL_WATCHDOG(requestTimeoutCB_);
365e41f4b71Sopenharmony_ci       DFX_LOCAL_HITRACE_BEGIN;
366e41f4b71Sopenharmony_ci       for (const auto& it : streamInfos) {
367e41f4b71Sopenharmony_ci           CHECK_IF_NOT_EQUAL_RETURN_VALUE(CheckStreamInfo(it), true, INVALID_ARGUMENT);
368e41f4b71Sopenharmony_ci           CAMERA_LOGI("streamId:%{public}d and format:%{public}d and width:%{public}d and height:%{public}d",
369e41f4b71Sopenharmony_ci               it.streamId_, it.format_, it.width_, it.height_);
370e41f4b71Sopenharmony_ci           if (streamMap_.count(it.streamId_) > 0) {
371e41f4b71Sopenharmony_ci               CAMERA_LOGE("stream [id = %{public}d] has already been created.", it.streamId_);
372e41f4b71Sopenharmony_ci               return INVALID_ARGUMENT;
373e41f4b71Sopenharmony_ci           }
374e41f4b71Sopenharmony_ci           std::shared_ptr<IStream> stream = StreamFactory::Instance().CreateShared( // Create a stream instance.
375e41f4b71Sopenharmony_ci               IStream::g_availableStreamType[it.intent_], it.streamId_, it.intent_, pipelineCore_, messenger_);
376e41f4b71Sopenharmony_ci           if (stream == nullptr) {
377e41f4b71Sopenharmony_ci               CAMERA_LOGE("create stream [id = %{public}d] failed.", it.streamId_);
378e41f4b71Sopenharmony_ci               return INSUFFICIENT_RESOURCES;
379e41f4b71Sopenharmony_ci           }
380e41f4b71Sopenharmony_ci           StreamConfiguration scg;
381e41f4b71Sopenharmony_ci           StreamInfoToStreamConfiguration(scg, it);
382e41f4b71Sopenharmony_ci           RetCode rc = stream->ConfigStream(scg);
383e41f4b71Sopenharmony_ci           if (rc != RC_OK) {
384e41f4b71Sopenharmony_ci               CAMERA_LOGE("configure stream %{public}d failed", it.streamId_);
385e41f4b71Sopenharmony_ci               return INVALID_ARGUMENT;
386e41f4b71Sopenharmony_ci           }
387e41f4b71Sopenharmony_ci           if (!scg.tunnelMode && (it.bufferQueue_)->producer_ != nullptr) {
388e41f4b71Sopenharmony_ci               CAMERA_LOGE("stream [id:%{public}d] is not tunnel mode, can't bind a buffer producer", it.streamId_);
389e41f4b71Sopenharmony_ci               return INVALID_ARGUMENT;
390e41f4b71Sopenharmony_ci           }
391e41f4b71Sopenharmony_ci           if ((it.bufferQueue_)->producer_ != nullptr) {
392e41f4b71Sopenharmony_ci               auto tunnel = std::make_shared<StreamTunnel>();
393e41f4b71Sopenharmony_ci               CHECK_IF_PTR_NULL_RETURN_VALUE(tunnel, INSUFFICIENT_RESOURCES);
394e41f4b71Sopenharmony_ci               rc = tunnel->AttachBufferQueue((it.bufferQueue_)->producer_);
395e41f4b71Sopenharmony_ci               CHECK_IF_NOT_EQUAL_RETURN_VALUE(rc, RC_OK, INVALID_ARGUMENT);
396e41f4b71Sopenharmony_ci               if (stream->AttachStreamTunnel(tunnel) != RC_OK) {
397e41f4b71Sopenharmony_ci                   CAMERA_LOGE("attach buffer queue to stream [id = %{public}d] failed", it.streamId_);
398e41f4b71Sopenharmony_ci                   return INVALID_ARGUMENT;
399e41f4b71Sopenharmony_ci               }
400e41f4b71Sopenharmony_ci           }
401e41f4b71Sopenharmony_ci           {
402e41f4b71Sopenharmony_ci               std::lock_guard<std::mutex> l(streamLock_);
403e41f4b71Sopenharmony_ci               streamMap_[stream->GetStreamId()] = stream;
404e41f4b71Sopenharmony_ci           }
405e41f4b71Sopenharmony_ci           CAMERA_LOGI("create stream success [id:%{public}d] [type:%{public}s]", stream->GetStreamId(),
406e41f4b71Sopenharmony_ci                       IStream::g_availableStreamType[it.intent_].c_str());
407e41f4b71Sopenharmony_ci       }
408e41f4b71Sopenharmony_ci       DFX_LOCAL_HITRACE_END;
409e41f4b71Sopenharmony_ci       return HDI::Camera::V1_0::NO_ERROR;
410e41f4b71Sopenharmony_ci    }
411e41f4b71Sopenharmony_ci   ```
412e41f4b71Sopenharmony_ci
413e41f4b71Sopenharmony_ci7. Configure streams.
414e41f4b71Sopenharmony_ci
415e41f4b71Sopenharmony_ci   Use **CommitStreams()** to configure streams, including initializing and creating **PipelineCore**. **CommitStreams()** must be called after the streams are created.
416e41f4b71Sopenharmony_ci
417e41f4b71Sopenharmony_ci   ```c++
418e41f4b71Sopenharmony_ci   int32_t StreamOperator::CommitStreams(OperationMode mode, const std::vector<uint8_t>& modeSetting)
419e41f4b71Sopenharmony_ci   {
420e41f4b71Sopenharmony_ci       CAMERA_LOGV("enter");
421e41f4b71Sopenharmony_ci       CHECK_IF_PTR_NULL_RETURN_VALUE(streamPipeline_, DEVICE_ERROR);
422e41f4b71Sopenharmony_ci       PLACE_A_NOKILL_WATCHDOG(requestTimeoutCB_);
423e41f4b71Sopenharmony_ci       if (modeSetting.empty()) {
424e41f4b71Sopenharmony_ci           CAMERA_LOGE("input vector is empty");
425e41f4b71Sopenharmony_ci           return INVALID_ARGUMENT;
426e41f4b71Sopenharmony_ci       }
427e41f4b71Sopenharmony_ci       DFX_LOCAL_HITRACE_BEGIN;
428e41f4b71Sopenharmony_ci   
429e41f4b71Sopenharmony_ci       std::vector<StreamConfiguration> configs = {};
430e41f4b71Sopenharmony_ci       {
431e41f4b71Sopenharmony_ci           std::lock_guard<std::mutex> l(streamLock_);
432e41f4b71Sopenharmony_ci           std::transform(streamMap_.begin(), streamMap_.end(), std::back_inserter(configs),
433e41f4b71Sopenharmony_ci               [](auto &iter) { return iter.second->GetStreamAttribute(); });
434e41f4b71Sopenharmony_ci       }
435e41f4b71Sopenharmony_ci    
436e41f4b71Sopenharmony_ci       std::shared_ptr<CameraMetadata> setting;
437e41f4b71Sopenharmony_ci       MetadataUtils::ConvertVecToMetadata(modeSetting, setting);
438e41f4b71Sopenharmony_ci       DynamicStreamSwitchMode method = streamPipeline_->CheckStreamsSupported(mode, setting, configs);
439e41f4b71Sopenharmony_ci       if (method == DYNAMIC_STREAM_SWITCH_NOT_SUPPORT) {
440e41f4b71Sopenharmony_ci           return INVALID_ARGUMENT;
441e41f4b71Sopenharmony_ci       }
442e41f4b71Sopenharmony_ci       if (method == DYNAMIC_STREAM_SWITCH_NEED_INNER_RESTART) {
443e41f4b71Sopenharmony_ci           std::lock_guard<std::mutex> l(streamLock_);
444e41f4b71Sopenharmony_ci           for (auto it : streamMap_) {
445e41f4b71Sopenharmony_ci               it.second->StopStream();
446e41f4b71Sopenharmony_ci           }
447e41f4b71Sopenharmony_ci       }
448e41f4b71Sopenharmony_ci       {
449e41f4b71Sopenharmony_ci           std::lock_guard<std::mutex> l(streamLock_);
450e41f4b71Sopenharmony_ci           for (auto it : streamMap_) {
451e41f4b71Sopenharmony_ci               if (it.second->CommitStream() != RC_OK) {
452e41f4b71Sopenharmony_ci                   CAMERA_LOGE("commit stream [id = %{public}d] failed.", it.first);
453e41f4b71Sopenharmony_ci                   return DEVICE_ERROR;
454e41f4b71Sopenharmony_ci               }
455e41f4b71Sopenharmony_ci           }
456e41f4b71Sopenharmony_ci       }
457e41f4b71Sopenharmony_ci       RetCode rc = streamPipeline_->PreConfig(setting); // Configure the device stream.
458e41f4b71Sopenharmony_ci       if (rc != RC_OK) {
459e41f4b71Sopenharmony_ci           CAMERA_LOGE("prepare mode settings failed");
460e41f4b71Sopenharmony_ci           return DEVICE_ERROR;
461e41f4b71Sopenharmony_ci       }
462e41f4b71Sopenharmony_ci       rc = streamPipeline_->CreatePipeline(mode); // Create a pipeline.
463e41f4b71Sopenharmony_ci       if (rc != RC_OK) {
464e41f4b71Sopenharmony_ci           CAMERA_LOGE("create pipeline failed.");
465e41f4b71Sopenharmony_ci           return INVALID_ARGUMENT;
466e41f4b71Sopenharmony_ci       }
467e41f4b71Sopenharmony_ci    
468e41f4b71Sopenharmony_ci       DFX_LOCAL_HITRACE_END;
469e41f4b71Sopenharmony_ci       return HDI::Camera::V1_0::NO_ERROR;
470e41f4b71Sopenharmony_ci   }
471e41f4b71Sopenharmony_ci   ```
472e41f4b71Sopenharmony_ci
473e41f4b71Sopenharmony_ci8. Capture images.
474e41f4b71Sopenharmony_ci
475e41f4b71Sopenharmony_ci   Fill in the **CaptureInfo** structure before calling **Capture()**.
476e41f4b71Sopenharmony_ci
477e41f4b71Sopenharmony_ci   ```c++
478e41f4b71Sopenharmony_ci   using CaptureInfo = struct _CaptureInfo {
479e41f4b71Sopenharmony_ci       int[] streamIds_; // IDs of the streams to capture.
480e41f4b71Sopenharmony_ci       unsigned char[]  captureSetting_; // Use the camera ability obtained by GetCameraAbility() of CameraHost to fill in the settings.
481e41f4b71Sopenharmony_ci       bool enableShutterCallback_;
482e41f4b71Sopenharmony_ci   };
483e41f4b71Sopenharmony_ci   ```
484e41f4b71Sopenharmony_ci
485e41f4b71Sopenharmony_ci   Use the **Capture()** method in **StreamOperator** to capture data streams.
486e41f4b71Sopenharmony_ci
487e41f4b71Sopenharmony_ci   ```c++
488e41f4b71Sopenharmony_ci   int32_t StreamOperator::Capture(int32_t captureId, const CaptureInfo& info, bool isStreaming)
489e41f4b71Sopenharmony_ci   {
490e41f4b71Sopenharmony_ci       CHECK_IF_EQUAL_RETURN_VALUE(captureId < 0, true, INVALID_ARGUMENT);
491e41f4b71Sopenharmony_ci       PLACE_A_NOKILL_WATCHDOG(requestTimeoutCB_);
492e41f4b71Sopenharmony_ci       DFX_LOCAL_HITRACE_BEGIN;
493e41f4b71Sopenharmony_ci    
494e41f4b71Sopenharmony_ci       for (auto id : info.streamIds_) {
495e41f4b71Sopenharmony_ci           std::lock_guard<std::mutex> l(streamLock_);
496e41f4b71Sopenharmony_ci           auto it = streamMap_.find(id);
497e41f4b71Sopenharmony_ci           if (it == streamMap_.end()) {
498e41f4b71Sopenharmony_ci               return INVALID_ARGUMENT;
499e41f4b71Sopenharmony_ci           }
500e41f4b71Sopenharmony_ci       }
501e41f4b71Sopenharmony_ci    
502e41f4b71Sopenharmony_ci       {
503e41f4b71Sopenharmony_ci           std::lock_guard<std::mutex> l(requestLock_);
504e41f4b71Sopenharmony_ci           auto itr = requestMap_.find(captureId);
505e41f4b71Sopenharmony_ci           if (itr != requestMap_.end()) {
506e41f4b71Sopenharmony_ci               return INVALID_ARGUMENT;
507e41f4b71Sopenharmony_ci           }
508e41f4b71Sopenharmony_ci       }
509e41f4b71Sopenharmony_ci    
510e41f4b71Sopenharmony_ci       std::shared_ptr<CameraMetadata> captureSetting;
511e41f4b71Sopenharmony_ci       MetadataUtils::ConvertVecToMetadata(info.captureSetting_, captureSetting);
512e41f4b71Sopenharmony_ci       CaptureSetting setting = captureSetting;
513e41f4b71Sopenharmony_ci       auto request =
514e41f4b71Sopenharmony_ci           std::make_shared<CaptureRequest>(captureId, info.streamIds_.size(), setting,
515e41f4b71Sopenharmony_ci                                             info.enableShutterCallback_, isStreaming);
516e41f4b71Sopenharmony_ci       for (auto id : info.streamIds_) {
517e41f4b71Sopenharmony_ci           RetCode rc = streamMap_[id]->AddRequest(request);
518e41f4b71Sopenharmony_ci           if (rc != RC_OK) {
519e41f4b71Sopenharmony_ci               return DEVICE_ERROR;
520e41f4b71Sopenharmony_ci           }
521e41f4b71Sopenharmony_ci       }
522e41f4b71Sopenharmony_ci    
523e41f4b71Sopenharmony_ci       {
524e41f4b71Sopenharmony_ci           std::lock_guard<std::mutex> l(requestLock_);
525e41f4b71Sopenharmony_ci           requestMap_[captureId] = request;
526e41f4b71Sopenharmony_ci       }
527e41f4b71Sopenharmony_ci       return HDI::Camera::V1_0::NO_ERROR;
528e41f4b71Sopenharmony_ci   }  
529e41f4b71Sopenharmony_ci   ```
530e41f4b71Sopenharmony_ci
531e41f4b71Sopenharmony_ci9. Cancel the capture and release the offline stream.
532e41f4b71Sopenharmony_ci
533e41f4b71Sopenharmony_ci   Use **CancelCapture()** in the **StreamOperatorImpl** class to cancel the stream capture based on **captureId**.
534e41f4b71Sopenharmony_ci
535e41f4b71Sopenharmony_ci   ```c++
536e41f4b71Sopenharmony_ci   int32_t StreamOperator::CancelCapture(int32_t captureId)
537e41f4b71Sopenharmony_ci   {
538e41f4b71Sopenharmony_ci       CHECK_IF_EQUAL_RETURN_VALUE(captureId < 0, true, INVALID_ARGUMENT);
539e41f4b71Sopenharmony_ci       PLACE_A_NOKILL_WATCHDOG(requestTimeoutCB_);
540e41f4b71Sopenharmony_ci       DFX_LOCAL_HITRACE_BEGIN;
541e41f4b71Sopenharmony_ci    
542e41f4b71Sopenharmony_ci       std::lock_guard<std::mutex> l(requestLock_);
543e41f4b71Sopenharmony_ci       auto itr = requestMap_.find(captureId); // Search for the CameraCapture object in the Map based on the captureId.
544e41f4b71Sopenharmony_ci       if (itr == requestMap_.end()) {
545e41f4b71Sopenharmony_ci           CAMERA_LOGE("can't cancel capture [id = %{public}d], this capture doesn't exist", captureId);
546e41f4b71Sopenharmony_ci           return INVALID_ARGUMENT;
547e41f4b71Sopenharmony_ci       }
548e41f4b71Sopenharmony_ci    
549e41f4b71Sopenharmony_ci       RetCode rc = itr->second->Cancel(); // Call Cancel() in CameraCapture to cancel the stream capture.
550e41f4b71Sopenharmony_ci       if (rc != RC_OK) {
551e41f4b71Sopenharmony_ci           return DEVICE_ERROR;
552e41f4b71Sopenharmony_ci       }
553e41f4b71Sopenharmony_ci       requestMap_.erase(itr); // Erase the CameraCapture object.
554e41f4b71Sopenharmony_ci    
555e41f4b71Sopenharmony_ci       DFX_LOCAL_HITRACE_END;
556e41f4b71Sopenharmony_ci       return HDI::Camera::V1_0::NO_ERROR;
557e41f4b71Sopenharmony_ci   }
558e41f4b71Sopenharmony_ci   ```
559e41f4b71Sopenharmony_ci
560e41f4b71Sopenharmony_ci   Use **ReleaseStreams()** in the **StreamOperatorImpl** class to release the streams created by using **CreateStream()** and **CommitStreams()** and destroy the pipeline.
561e41f4b71Sopenharmony_ci
562e41f4b71Sopenharmony_ci   ```c++
563e41f4b71Sopenharmony_ci   int32_t StreamOperator::ReleaseStreams(const std::vector<int32_t>& streamIds)
564e41f4b71Sopenharmony_ci   {
565e41f4b71Sopenharmony_ci       PLACE_A_NOKILL_WATCHDOG(requestTimeoutCB_);
566e41f4b71Sopenharmony_ci       DFX_LOCAL_HITRACE_BEGIN;
567e41f4b71Sopenharmony_ci       for (auto id : streamIds) {
568e41f4b71Sopenharmony_ci           std::lock_guard<std::mutex> l(streamLock_);
569e41f4b71Sopenharmony_ci           auto it = streamMap_.find(id);
570e41f4b71Sopenharmony_ci           if (it == streamMap_.end()) {
571e41f4b71Sopenharmony_ci               continue;
572e41f4b71Sopenharmony_ci           }
573e41f4b71Sopenharmony_ci           if (it->second->IsRunning()) {
574e41f4b71Sopenharmony_ci               it->second->StopStream();
575e41f4b71Sopenharmony_ci           }
576e41f4b71Sopenharmony_ci           it->second->DumpStatsInfo();
577e41f4b71Sopenharmony_ci           streamMap_.erase(it);
578e41f4b71Sopenharmony_ci       }
579e41f4b71Sopenharmony_ci    
580e41f4b71Sopenharmony_ci       for (auto id : streamIds) {
581e41f4b71Sopenharmony_ci           CHECK_IF_EQUAL_RETURN_VALUE(id < 0, true, INVALID_ARGUMENT);
582e41f4b71Sopenharmony_ci       }
583e41f4b71Sopenharmony_ci    
584e41f4b71Sopenharmony_ci       DFX_LOCAL_HITRACE_END;
585e41f4b71Sopenharmony_ci       return HDI::Camera::V1_0::NO_ERROR;
586e41f4b71Sopenharmony_ci   }
587e41f4b71Sopenharmony_ci   ```
588e41f4b71Sopenharmony_ci
589e41f4b71Sopenharmony_ci10. Close the camera device.
590e41f4b71Sopenharmony_ci    
591e41f4b71Sopenharmony_ci    Use **Close()** in the **CameraDeviceImpl** class to close the camera device. The **PowerDown()** in **DeviceManager** is called to power off the device.    
592e41f4b71Sopenharmony_ci
593e41f4b71Sopenharmony_ci### Development Example
594e41f4b71Sopenharmony_ci
595e41f4b71Sopenharmony_ciThere is a [ohos_camera_demo](https://gitee.com/openharmony/drivers_peripheral/tree/master/camera/test/demo) in the **/drivers/peripheral/camera/hal/test/demo** directory. After the system is started, the executable file **ohos_camera_demo** is generated in the **/vendor/bin** directory. This demo implements basic camera capabilities such as preview and photographing. 
596e41f4b71Sopenharmony_ciThe following uses the demo to describe how to use the HDI to implement **PreviewOn()** and **CaptureON()**.
597e41f4b71Sopenharmony_ci
598e41f4b71Sopenharmony_ci1. Construct a **CameraDemo** object in the **main** function. This object contains methods for initializing the camera and starting, stopping, and releasing streams. The **mainDemo->InitSensors()** function is used to initialize the **CameraHost**, and the **mainDemo->InitCameraDevice()** function is used to initialize the **CameraDevice**.
599e41f4b71Sopenharmony_ci
600e41f4b71Sopenharmony_ci   ```c++
601e41f4b71Sopenharmony_ci   int main(int argc, char** argv)
602e41f4b71Sopenharmony_ci   {
603e41f4b71Sopenharmony_ci       RetCode rc = RC_OK;
604e41f4b71Sopenharmony_ci       auto mainDemo = std::make_shared<CameraDemo>();
605e41f4b71Sopenharmony_ci       rc = mainDemo->InitSensors(); // Initialize the CameraHost.
606e41f4b71Sopenharmony_ci       if (rc == RC_ERROR) {
607e41f4b71Sopenharmony_ci           CAMERA_LOGE("main test: mainDemo->InitSensors() error\n");
608e41f4b71Sopenharmony_ci           return -1;
609e41f4b71Sopenharmony_ci       }
610e41f4b71Sopenharmony_ci   
611e41f4b71Sopenharmony_ci       rc = mainDemo->InitCameraDevice(); // Initialize the CameraDevice.
612e41f4b71Sopenharmony_ci       if (rc == RC_ERROR) {
613e41f4b71Sopenharmony_ci           CAMERA_LOGE("main test: mainDemo->InitCameraDevice() error\n");
614e41f4b71Sopenharmony_ci           return -1;
615e41f4b71Sopenharmony_ci       }
616e41f4b71Sopenharmony_ci   
617e41f4b71Sopenharmony_ci       rc = PreviewOn(0, mainDemo); // Configure and enable streams.
618e41f4b71Sopenharmony_ci       if (rc != RC_OK) {
619e41f4b71Sopenharmony_ci           CAMERA_LOGE("main test: PreviewOn() error demo exit");
620e41f4b71Sopenharmony_ci           return -1;
621e41f4b71Sopenharmony_ci       }
622e41f4b71Sopenharmony_ci   
623e41f4b71Sopenharmony_ci       ManuList(mainDemo, argc, argv); // Print the menu to the console.
624e41f4b71Sopenharmony_ci   
625e41f4b71Sopenharmony_ci       return RC_OK;
626e41f4b71Sopenharmony_ci   }
627e41f4b71Sopenharmony_ci   ```
628e41f4b71Sopenharmony_ci
629e41f4b71Sopenharmony_ci   The function used to initialize the **CameraHost** is implemented as follows, where the HDI **ICameraHost::Get()** is called to obtain the **demoCameraHost** and set the callback:
630e41f4b71Sopenharmony_ci
631e41f4b71Sopenharmony_ci   ```c++
632e41f4b71Sopenharmony_ci   RetCode OhosCameraDemo::InitSensors()
633e41f4b71Sopenharmony_ci   {
634e41f4b71Sopenharmony_ci       int rc = 0;
635e41f4b71Sopenharmony_ci   
636e41f4b71Sopenharmony_ci       CAMERA_LOGD("demo test: InitSensors enter");
637e41f4b71Sopenharmony_ci    
638e41f4b71Sopenharmony_ci       if (demoCameraHost_ != nullptr) {
639e41f4b71Sopenharmony_ci           return RC_OK;
640e41f4b71Sopenharmony_ci       }
641e41f4b71Sopenharmony_ci   #ifdef CAMERA_BUILT_ON_OHOS_LITE
642e41f4b71Sopenharmony_ci       demoCameraHost_ = OHOS::Camera::CameraHost::CreateCameraHost();
643e41f4b71Sopenharmony_ci   #else
644e41f4b71Sopenharmony_ci       constexpr const char *DEMO_SERVICE_NAME = "camera_service";
645e41f4b71Sopenharmony_ci       demoCameraHost_ = ICameraHost::Get(DEMO_SERVICE_NAME, false);
646e41f4b71Sopenharmony_ci   #endif
647e41f4b71Sopenharmony_ci       if (demoCameraHost_ == nullptr) {
648e41f4b71Sopenharmony_ci           CAMERA_LOGE("demo test: ICameraHost::Get error");
649e41f4b71Sopenharmony_ci           return RC_ERROR;
650e41f4b71Sopenharmony_ci       }
651e41f4b71Sopenharmony_ci    
652e41f4b71Sopenharmony_ci   #ifdef CAMERA_BUILT_ON_OHOS_LITE
653e41f4b71Sopenharmony_ci       hostCallback_ = std::make_shared<DemoCameraHostCallback>();
654e41f4b71Sopenharmony_ci   #else
655e41f4b71Sopenharmony_ci       hostCallback_ = new DemoCameraHostCallback();
656e41f4b71Sopenharmony_ci   #endif
657e41f4b71Sopenharmony_ci       rc = demoCameraHost_->SetCallback(hostCallback_);
658e41f4b71Sopenharmony_ci       if (rc != HDI::Camera::V1_0::NO_ERROR) {
659e41f4b71Sopenharmony_ci           CAMERA_LOGE("demo test: demoCameraHost_->SetCallback(hostCallback_) error");
660e41f4b71Sopenharmony_ci           return RC_ERROR;
661e41f4b71Sopenharmony_ci       }
662e41f4b71Sopenharmony_ci    
663e41f4b71Sopenharmony_ci       CAMERA_LOGD("demo test: InitSensors exit");
664e41f4b71Sopenharmony_ci    
665e41f4b71Sopenharmony_ci       return RC_OK;
666e41f4b71Sopenharmony_ci   }
667e41f4b71Sopenharmony_ci   ```
668e41f4b71Sopenharmony_ci
669e41f4b71Sopenharmony_ci   The function for initializing the **CameraDevice** is implemented as follows. The **GetCameraIds(cameraIds_)**, **GetCameraAbility(cameraId, ability_)**, and **OpenCamera(cameraIds\_.front(), callback, demoCameraDevice_)** methods are used to obtain the **demoCameraHost**.
670e41f4b71Sopenharmony_ci
671e41f4b71Sopenharmony_ci   ```c++
672e41f4b71Sopenharmony_ci   RetCode OhosCameraDemo::InitCameraDevice()
673e41f4b71Sopenharmony_ci   {
674e41f4b71Sopenharmony_ci       int rc = 0;
675e41f4b71Sopenharmony_ci    
676e41f4b71Sopenharmony_ci       CAMERA_LOGD("demo test: InitCameraDevice enter");
677e41f4b71Sopenharmony_ci    
678e41f4b71Sopenharmony_ci       if (demoCameraHost_ == nullptr) {
679e41f4b71Sopenharmony_ci           CAMERA_LOGE("demo test: InitCameraDevice demoCameraHost_ == nullptr");
680e41f4b71Sopenharmony_ci           return RC_ERROR;
681e41f4b71Sopenharmony_ci       }
682e41f4b71Sopenharmony_ci    
683e41f4b71Sopenharmony_ci       (void)demoCameraHost_->GetCameraIds(cameraIds_);
684e41f4b71Sopenharmony_ci       if (cameraIds_.empty()) {
685e41f4b71Sopenharmony_ci           return RC_ERROR;
686e41f4b71Sopenharmony_ci       }
687e41f4b71Sopenharmony_ci       const std::string cameraId = cameraIds_.front();
688e41f4b71Sopenharmony_ci       demoCameraHost_->GetCameraAbility(cameraId, cameraAbility_);
689e41f4b71Sopenharmony_ci    
690e41f4b71Sopenharmony_ci       MetadataUtils::ConvertVecToMetadata(cameraAbility_, ability_);
691e41f4b71Sopenharmony_ci    
692e41f4b71Sopenharmony_ci       GetFaceDetectMode(ability_);
693e41f4b71Sopenharmony_ci       GetFocalLength(ability_);
694e41f4b71Sopenharmony_ci       GetAvailableFocusModes(ability_);
695e41f4b71Sopenharmony_ci       GetAvailableExposureModes(ability_);
696e41f4b71Sopenharmony_ci       GetExposureCompensationRange(ability_);
697e41f4b71Sopenharmony_ci       GetExposureCompensationSteps(ability_);
698e41f4b71Sopenharmony_ci       GetAvailableMeterModes(ability_);
699e41f4b71Sopenharmony_ci       GetAvailableFlashModes(ability_);
700e41f4b71Sopenharmony_ci       GetMirrorSupported(ability_);
701e41f4b71Sopenharmony_ci       GetStreamBasicConfigurations(ability_);
702e41f4b71Sopenharmony_ci       GetFpsRange(ability_);
703e41f4b71Sopenharmony_ci       GetCameraPosition(ability_);
704e41f4b71Sopenharmony_ci       GetCameraType(ability_);
705e41f4b71Sopenharmony_ci       GetCameraConnectionType(ability_);
706e41f4b71Sopenharmony_ci       GetFaceDetectMaxNum(ability_);
707e41f4b71Sopenharmony_ci    
708e41f4b71Sopenharmony_ci   #ifdef CAMERA_BUILT_ON_OHOS_LITE
709e41f4b71Sopenharmony_ci       std::shared_ptr<CameraDeviceCallback> callback = std::make_shared<CameraDeviceCallback>();
710e41f4b71Sopenharmony_ci   #else
711e41f4b71Sopenharmony_ci       sptr<DemoCameraDeviceCallback> callback = new DemoCameraDeviceCallback();
712e41f4b71Sopenharmony_ci   #endif
713e41f4b71Sopenharmony_ci       rc = demoCameraHost_->OpenCamera(cameraIds_.front(), callback, demoCameraDevice_);
714e41f4b71Sopenharmony_ci       if (rc != HDI::Camera::V1_0::NO_ERROR || demoCameraDevice_ == nullptr) {
715e41f4b71Sopenharmony_ci           CAMERA_LOGE("demo test: InitCameraDevice OpenCamera failed");
716e41f4b71Sopenharmony_ci           return RC_ERROR;
717e41f4b71Sopenharmony_ci       }
718e41f4b71Sopenharmony_ci    
719e41f4b71Sopenharmony_ci       CAMERA_LOGD("demo test: InitCameraDevice exit");
720e41f4b71Sopenharmony_ci    
721e41f4b71Sopenharmony_ci       return RC_OK;
722e41f4b71Sopenharmony_ci   }   
723e41f4b71Sopenharmony_ci   ```
724e41f4b71Sopenharmony_ci
725e41f4b71Sopenharmony_ci2. Implement **PreviewOn()** to configure streams, enable preview streams, and start stream capture. After **PreviewOn()** is called, the camera preview channel starts running. Two streams are enabled: preview stream and capture or video stream. Only the preview stream will be captured.
726e41f4b71Sopenharmony_ci
727e41f4b71Sopenharmony_ci   ```c++
728e41f4b71Sopenharmony_ci   static RetCode PreviewOn(int mode, const std::shared_ptr<OhosCameraDemo>& mainDemo)
729e41f4b71Sopenharmony_ci   {
730e41f4b71Sopenharmony_ci       RetCode rc = RC_OK;
731e41f4b71Sopenharmony_ci       CAMERA_LOGD("main test: PreviewOn enter");
732e41f4b71Sopenharmony_ci    
733e41f4b71Sopenharmony_ci       rc = mainDemo->StartPreviewStream(); // Configure the preview stream.
734e41f4b71Sopenharmony_ci       if (rc != RC_OK) {
735e41f4b71Sopenharmony_ci           CAMERA_LOGE("main test: PreviewOn StartPreviewStream error");
736e41f4b71Sopenharmony_ci           return RC_ERROR;
737e41f4b71Sopenharmony_ci       }
738e41f4b71Sopenharmony_ci    
739e41f4b71Sopenharmony_ci       if (mode == 0) {
740e41f4b71Sopenharmony_ci           rc = mainDemo->StartCaptureStream(); // Configure the capture stream.
741e41f4b71Sopenharmony_ci           if (rc != RC_OK) {
742e41f4b71Sopenharmony_ci               CAMERA_LOGE("main test: PreviewOn StartCaptureStream error");
743e41f4b71Sopenharmony_ci               return RC_ERROR;
744e41f4b71Sopenharmony_ci           }
745e41f4b71Sopenharmony_ci       } else {
746e41f4b71Sopenharmony_ci           rc = mainDemo->StartVideoStream(); // Configure the video stream.
747e41f4b71Sopenharmony_ci           if (rc != RC_OK) {
748e41f4b71Sopenharmony_ci               CAMERA_LOGE("main test: PreviewOn StartVideoStream error");
749e41f4b71Sopenharmony_ci               return RC_ERROR;
750e41f4b71Sopenharmony_ci           }
751e41f4b71Sopenharmony_ci       }
752e41f4b71Sopenharmony_ci    
753e41f4b71Sopenharmony_ci       rc = mainDemo->CaptureON(STREAM_ID_PREVIEW, CAPTURE_ID_PREVIEW, CAPTURE_PREVIEW);
754e41f4b71Sopenharmony_ci       if (rc != RC_OK) {
755e41f4b71Sopenharmony_ci           CAMERA_LOGE("main test: PreviewOn mainDemo->CaptureON() preview error");
756e41f4b71Sopenharmony_ci           return RC_ERROR;
757e41f4b71Sopenharmony_ci       }
758e41f4b71Sopenharmony_ci    
759e41f4b71Sopenharmony_ci       CAMERA_LOGD("main test: PreviewOn exit");
760e41f4b71Sopenharmony_ci       return RC_OK;
761e41f4b71Sopenharmony_ci   }           
762e41f4b71Sopenharmony_ci   ```
763e41f4b71Sopenharmony_ci
764e41f4b71Sopenharmony_ci   The **StartCaptureStream()**, **StartVideoStream()**, and **StartPreviewStream()** methods call **CreateStream()** with different input parameters.
765e41f4b71Sopenharmony_ci
766e41f4b71Sopenharmony_ci   Use **CreateStream()** to call an HDI API to configure and create streams. Specifically, **CreateStream()** calls the HDI to obtain a **StreamOperation** object and then creates a **StreamInfo** object. Call **CreateStreams()** and **CommitStreams()** to create and configure streams.
767e41f4b71Sopenharmony_ci
768e41f4b71Sopenharmony_ci   ```c++
769e41f4b71Sopenharmony_ci   RetCode OhosCameraDemo::CreateStream(const int streamId, std::shared_ptr<StreamCustomer> &streamCustomer,
770e41f4b71Sopenharmony_ci       StreamIntent intent)
771e41f4b71Sopenharmony_ci   {
772e41f4b71Sopenharmony_ci       int rc = 0;
773e41f4b71Sopenharmony_ci       CAMERA_LOGD("demo test: CreateStream enter");
774e41f4b71Sopenharmony_ci    
775e41f4b71Sopenharmony_ci       GetStreamOpt(); // Obtain a StreamOperator object.
776e41f4b71Sopenharmony_ci       if (streamOperator_ == nullptr) {
777e41f4b71Sopenharmony_ci           CAMERA_LOGE("demo test: CreateStream GetStreamOpt() is nullptr\n");
778e41f4b71Sopenharmony_ci           return RC_ERROR;
779e41f4b71Sopenharmony_ci       }
780e41f4b71Sopenharmony_ci    
781e41f4b71Sopenharmony_ci       StreamInfo streamInfo = {0};
782e41f4b71Sopenharmony_ci    
783e41f4b71Sopenharmony_ci       SetStreamInfo(streamInfo, streamCustomer, streamId, intent); // Fills in the StreamInfo stream.
784e41f4b71Sopenharmony_ci       if (streamInfo.bufferQueue_->producer_ == nullptr) {
785e41f4b71Sopenharmony_ci           CAMERA_LOGE("demo test: CreateStream CreateProducer(); is nullptr\n");
786e41f4b71Sopenharmony_ci           return RC_ERROR;
787e41f4b71Sopenharmony_ci       }
788e41f4b71Sopenharmony_ci    
789e41f4b71Sopenharmony_ci       std::vector<StreamInfo> streamInfos;
790e41f4b71Sopenharmony_ci       streamInfos.push_back(streamInfo);
791e41f4b71Sopenharmony_ci    
792e41f4b71Sopenharmony_ci       rc = streamOperator_->CreateStreams(streamInfos); // Create a stream.
793e41f4b71Sopenharmony_ci       if (rc != HDI::Camera::V1_0::NO_ERROR) {
794e41f4b71Sopenharmony_ci           CAMERA_LOGE("demo test: CreateStream CreateStreams error\n");
795e41f4b71Sopenharmony_ci           return RC_ERROR;
796e41f4b71Sopenharmony_ci       }
797e41f4b71Sopenharmony_ci
798e41f4b71Sopenharmony_ci       rc = streamOperator_->CommitStreams(NORMAL, cameraAbility_);
799e41f4b71Sopenharmony_ci       if (rc != HDI::Camera::V1_0::NO_ERROR) {
800e41f4b71Sopenharmony_ci           CAMERA_LOGE("demo test: CreateStream CommitStreams error\n");
801e41f4b71Sopenharmony_ci           std::vector<int> streamIds;
802e41f4b71Sopenharmony_ci           streamIds.push_back(streamId);
803e41f4b71Sopenharmony_ci           streamOperator_->ReleaseStreams(streamIds);
804e41f4b71Sopenharmony_ci           return RC_ERROR;
805e41f4b71Sopenharmony_ci       }
806e41f4b71Sopenharmony_ci
807e41f4b71Sopenharmony_ci       CAMERA_LOGD("demo test: CreateStream exit");
808e41f4b71Sopenharmony_ci    
809e41f4b71Sopenharmony_ci       return RC_OK;
810e41f4b71Sopenharmony_ci   }
811e41f4b71Sopenharmony_ci   ```
812e41f4b71Sopenharmony_ci
813e41f4b71Sopenharmony_ci   Use **CaptureON()** to call the **Capture()** method of **StreamOperator** to obtain camera data, flip the buffer, and start a thread to receive data of the corresponding type.
814e41f4b71Sopenharmony_ci
815e41f4b71Sopenharmony_ci   ```c++
816e41f4b71Sopenharmony_ci   RetCode OhosCameraDemo::CaptureON(const int streamId,
817e41f4b71Sopenharmony_ci       const int captureId, CaptureMode mode)
818e41f4b71Sopenharmony_ci   {
819e41f4b71Sopenharmony_ci       CAMERA_LOGI("demo test: CaptureON enter streamId == %{public}d and captureId == %{public}d and mode == %{public}d",
820e41f4b71Sopenharmony_ci           streamId, captureId, mode);
821e41f4b71Sopenharmony_ci       std::lock_guard<std::mutex> l(metaDatalock_);
822e41f4b71Sopenharmony_ci       if (mode == CAPTURE_SNAPSHOT) {
823e41f4b71Sopenharmony_ci           constexpr double latitude = 27.987500; // dummy data: Qomolangma latitde
824e41f4b71Sopenharmony_ci           constexpr double longitude = 86.927500; // dummy data: Qomolangma longituude
825e41f4b71Sopenharmony_ci           constexpr double altitude = 8848.86; // dummy data: Qomolangma altitude
826e41f4b71Sopenharmony_ci           constexpr size_t entryCapacity = 100;
827e41f4b71Sopenharmony_ci           constexpr size_t dataCapacity = 2000;
828e41f4b71Sopenharmony_ci           captureSetting_ = std::make_shared<CameraSetting>(entryCapacity, dataCapacity);
829e41f4b71Sopenharmony_ci           captureQuality_ = OHOS_CAMERA_JPEG_LEVEL_HIGH;
830e41f4b71Sopenharmony_ci           captureOrientation_ = OHOS_CAMERA_JPEG_ROTATION_270;
831e41f4b71Sopenharmony_ci           mirrorSwitch_ = OHOS_CAMERA_MIRROR_ON;
832e41f4b71Sopenharmony_ci           gps_.push_back(latitude);
833e41f4b71Sopenharmony_ci           gps_.push_back(longitude);
834e41f4b71Sopenharmony_ci           gps_.push_back(altitude);
835e41f4b71Sopenharmony_ci           captureSetting_->addEntry(OHOS_JPEG_QUALITY, static_cast<void*>(&captureQuality_),
836e41f4b71Sopenharmony_ci               sizeof(captureQuality_));
837e41f4b71Sopenharmony_ci           captureSetting_->addEntry(OHOS_JPEG_ORIENTATION, static_cast<void*>(&captureOrientation_),
838e41f4b71Sopenharmony_ci               sizeof(captureOrientation_));
839e41f4b71Sopenharmony_ci           captureSetting_->addEntry(OHOS_CONTROL_CAPTURE_MIRROR, static_cast<void*>(&mirrorSwitch_),
840e41f4b71Sopenharmony_ci               sizeof(mirrorSwitch_));
841e41f4b71Sopenharmony_ci           captureSetting_->addEntry(OHOS_JPEG_GPS_COORDINATES, gps_.data(), gps_.size());
842e41f4b71Sopenharmony_ci       }
843e41f4b71Sopenharmony_ci    
844e41f4b71Sopenharmony_ci       std::vector<uint8_t> setting;
845e41f4b71Sopenharmony_ci       MetadataUtils::ConvertMetadataToVec(captureSetting_, setting);
846e41f4b71Sopenharmony_ci       captureInfo_.streamIds_ = {streamId};
847e41f4b71Sopenharmony_ci       if (mode == CAPTURE_SNAPSHOT) {
848e41f4b71Sopenharmony_ci           captureInfo_.captureSetting_ = setting;
849e41f4b71Sopenharmony_ci       } else {
850e41f4b71Sopenharmony_ci           captureInfo_.captureSetting_ = cameraAbility_;
851e41f4b71Sopenharmony_ci       }
852e41f4b71Sopenharmony_ci       captureInfo_.enableShutterCallback_ = false;
853e41f4b71Sopenharmony_ci    
854e41f4b71Sopenharmony_ci       int rc = streamOperator_->Capture(captureId, captureInfo_, true); // The capture starts, and buffer starts to flip.
855e41f4b71Sopenharmony_ci       if (rc != HDI::Camera::V1_0::NO_ERROR) {
856e41f4b71Sopenharmony_ci           CAMERA_LOGE("demo test: CaptureStart Capture error\n");
857e41f4b71Sopenharmony_ci           streamOperator_->ReleaseStreams(captureInfo_.streamIds_);
858e41f4b71Sopenharmony_ci           return RC_ERROR;
859e41f4b71Sopenharmony_ci       }
860e41f4b71Sopenharmony_ci    
861e41f4b71Sopenharmony_ci       if (mode == CAPTURE_PREVIEW) {
862e41f4b71Sopenharmony_ci           streamCustomerPreview_->ReceiveFrameOn(nullptr); // Create a preview thread to receive the passed buffer.
863e41f4b71Sopenharmony_ci       } else if (mode == CAPTURE_SNAPSHOT) {
864e41f4b71Sopenharmony_ci           streamCustomerCapture_->ReceiveFrameOn([this](void* addr, const uint32_t size) { // Create a capture thread to receive the passed buffer through the StoreImage callback.
865e41f4b71Sopenharmony_ci               StoreImage(addr, size);
866e41f4b71Sopenharmony_ci           });
867e41f4b71Sopenharmony_ci       } else if (mode == CAPTURE_VIDEO) {
868e41f4b71Sopenharmony_ci           OpenVideoFile();
869e41f4b71Sopenharmony_ci    
870e41f4b71Sopenharmony_ci           streamCustomerVideo_->ReceiveFrameOn([this](void* addr, const uint32_t size) { // Create a video thread to receive the passed buffer through the StoreImage callback.
871e41f4b71Sopenharmony_ci               StoreVideo(addr, size);
872e41f4b71Sopenharmony_ci           });
873e41f4b71Sopenharmony_ci       }
874e41f4b71Sopenharmony_ci       CAMERA_LOGD("demo test: CaptureON exit");
875e41f4b71Sopenharmony_ci    
876e41f4b71Sopenharmony_ci       return RC_OK;
877e41f4b71Sopenharmony_ci   }
878e41f4b71Sopenharmony_ci   ```
879e41f4b71Sopenharmony_ci
880e41f4b71Sopenharmony_ci3. Implement **ManuList()** to obtain characters from the console through **fgets()**. Different characters correspond to different capabilities provided by the demo, and the functionality menu is printed.
881e41f4b71Sopenharmony_ci
882e41f4b71Sopenharmony_ci   ```c++
883e41f4b71Sopenharmony_ci   static void ManuList(const std::shared_ptr<OhosCameraDemo>& mainDemo,
884e41f4b71Sopenharmony_ci       const int argc, char** argv)
885e41f4b71Sopenharmony_ci   {
886e41f4b71Sopenharmony_ci       int idx, c;
887e41f4b71Sopenharmony_ci       bool isAwb = true;
888e41f4b71Sopenharmony_ci       const char *shortOptions = "h:cwvaeqof:";
889e41f4b71Sopenharmony_ci       c = getopt_long(argc, argv, shortOptions, LONG_OPTIONS, &idx);
890e41f4b71Sopenharmony_ci       while (1) {
891e41f4b71Sopenharmony_ci           switch (c) {
892e41f4b71Sopenharmony_ci               case 'h':
893e41f4b71Sopenharmony_ci                   c = PutMenuAndGetChr(); // Print the menu.
894e41f4b71Sopenharmony_ci                   break;
895e41f4b71Sopenharmony_ci               case 'f':
896e41f4b71Sopenharmony_ci                   FlashLightTest(mainDemo); // Verify the flashlight capability.
897e41f4b71Sopenharmony_ci                   c = PutMenuAndGetChr();
898e41f4b71Sopenharmony_ci                   break;
899e41f4b71Sopenharmony_ci               case 'o':
900e41f4b71Sopenharmony_ci                   OfflineTest(mainDemo);    // Verify the offline capability.
901e41f4b71Sopenharmony_ci                   c = PutMenuAndGetChr();
902e41f4b71Sopenharmony_ci                   break;
903e41f4b71Sopenharmony_ci               case 'c':
904e41f4b71Sopenharmony_ci                   CaptureTest(mainDemo);    // Verify the capture capability.
905e41f4b71Sopenharmony_ci                   c = PutMenuAndGetChr();
906e41f4b71Sopenharmony_ci                   break;
907e41f4b71Sopenharmony_ci               case 'w':                     // Verify the AWB capability.
908e41f4b71Sopenharmony_ci                   if (isAwb) {
909e41f4b71Sopenharmony_ci                       mainDemo->SetAwbMode(OHOS_CAMERA_AWB_MODE_INCANDESCENT);
910e41f4b71Sopenharmony_ci                   } else {
911e41f4b71Sopenharmony_ci                       mainDemo->SetAwbMode(OHOS_CAMERA_AWB_MODE_OFF);
912e41f4b71Sopenharmony_ci                   }
913e41f4b71Sopenharmony_ci                   isAwb = !isAwb;
914e41f4b71Sopenharmony_ci                   c = PutMenuAndGetChr();
915e41f4b71Sopenharmony_ci                   break;
916e41f4b71Sopenharmony_ci               case 'a':                    // Verify the AE capability.
917e41f4b71Sopenharmony_ci                   mainDemo->SetAeExpo();
918e41f4b71Sopenharmony_ci                   c = PutMenuAndGetChr();
919e41f4b71Sopenharmony_ci                   break;
920e41f4b71Sopenharmony_ci               case'e':                     // Verify the metadata operations.
921e41f4b71Sopenharmony_ci                   mainDemo->SetMetadata();
922e41f4b71Sopenharmony_ci                   c = PutMenuAndGetChr();
923e41f4b71Sopenharmony_ci                   break;
924e41f4b71Sopenharmony_ci               case'v':                     // Verify the video function.
925e41f4b71Sopenharmony_ci                   VideoTest(mainDemo);
926e41f4b71Sopenharmony_ci                   c = PutMenuAndGetChr();
927e41f4b71Sopenharmony_ci                   break;
928e41f4b71Sopenharmony_ci               case 'q': // Exit the demo.
929e41f4b71Sopenharmony_ci                   PreviewOff(mainDemo);
930e41f4b71Sopenharmony_ci                   mainDemo->QuitDemo();
931e41f4b71Sopenharmony_ci                   return;
932e41f4b71Sopenharmony_ci               default:
933e41f4b71Sopenharmony_ci                   CAMERA_LOGE("main test: command error please retry input command");
934e41f4b71Sopenharmony_ci                   c = PutMenuAndGetChr();
935e41f4b71Sopenharmony_ci                   break;
936e41f4b71Sopenharmony_ci           }
937e41f4b71Sopenharmony_ci       }
938e41f4b71Sopenharmony_ci   }
939e41f4b71Sopenharmony_ci   ```
940e41f4b71Sopenharmony_ci
941e41f4b71Sopenharmony_ci   Use **PutMenuAndGetChr()** to print the menu of the demo and call **fgets()** to wait for commands from the console.
942e41f4b71Sopenharmony_ci
943e41f4b71Sopenharmony_ci   ```c++
944e41f4b71Sopenharmony_ci   static int PutMenuAndGetChr(void)
945e41f4b71Sopenharmony_ci   {
946e41f4b71Sopenharmony_ci       constexpr uint32_t inputCount = 50;
947e41f4b71Sopenharmony_ci       int c = 0;
948e41f4b71Sopenharmony_ci       char strs[inputCount];
949e41f4b71Sopenharmony_ci       Usage(stdout);
950e41f4b71Sopenharmony_ci       CAMERA_LOGD("pls input command(input -q exit this app)\n");
951e41f4b71Sopenharmony_ci       fgets(strs, inputCount, stdin);
952e41f4b71Sopenharmony_ci   
953e41f4b71Sopenharmony_ci       for (int i = 0; i < inputCount; i++) {
954e41f4b71Sopenharmony_ci           if (strs[i] != '-') {
955e41f4b71Sopenharmony_ci               c = strs[i];
956e41f4b71Sopenharmony_ci               break;
957e41f4b71Sopenharmony_ci           }
958e41f4b71Sopenharmony_ci       }
959e41f4b71Sopenharmony_ci       return c;
960e41f4b71Sopenharmony_ci   }
961e41f4b71Sopenharmony_ci   ```
962e41f4b71Sopenharmony_ci
963e41f4b71Sopenharmony_ci   The console outputs the menu details as follows:
964e41f4b71Sopenharmony_ci
965e41f4b71Sopenharmony_ci   ```c++
966e41f4b71Sopenharmony_ci   "Options:\n"
967e41f4b71Sopenharmony_ci   "-h | --help          Print this message\n"
968e41f4b71Sopenharmony_ci   "-o | --offline       stream offline test\n"
969e41f4b71Sopenharmony_ci   "-c | --capture       capture one picture\n"
970e41f4b71Sopenharmony_ci   "-w | --set WB        Set white balance Cloudy\n"
971e41f4b71Sopenharmony_ci   "-v | --video         capture Video of 10s\n"
972e41f4b71Sopenharmony_ci   "-a | --Set AE        Set Auto exposure\n"
973e41f4b71Sopenharmony_ci   "-e | --Set Metadeta  Set Metadata\n"
974e41f4b71Sopenharmony_ci   "-f | --Set Flashlight        Set flashlight ON 5s OFF\n"
975e41f4b71Sopenharmony_ci   "-q | --quit          stop preview and quit this app\n");
976e41f4b71Sopenharmony_ci   ```
977e41f4b71Sopenharmony_ci
978e41f4b71Sopenharmony_ci4. Compile and build the **ohos_camera_demo**.        
979e41f4b71Sopenharmony_ci   Add **init:ohos_camera_demo** to **deps** in the **drivers/peripheral/camera/BUILD.gn** file. The sample code is as follows:
980e41f4b71Sopenharmony_ci   ```
981e41f4b71Sopenharmony_ci   deps = [
982e41f4b71Sopenharmony_ci       "vdi_base/common/buffer_manager:camera_buffer_manager",
983e41f4b71Sopenharmony_ci       "vdi_base/common/device_manager:camera_device_manager",
984e41f4b71Sopenharmony_ci       "vdi_base/common/hdi_impl:camera_host_service_1.0",
985e41f4b71Sopenharmony_ci       "vdi_base/common/pipeline_core:camera_pipeline_core",
986e41f4b71Sopenharmony_ci       "vdi_base/common/utils:camera_utils",
987e41f4b71Sopenharmony_ci       "test/common:ohos_camera_demo",
988e41f4b71Sopenharmony_ci       ]
989e41f4b71Sopenharmony_ci   ```
990e41f4b71Sopenharmony_ci
991e41f4b71Sopenharmony_ci   The following uses RK3568 development board as an example.       
992e41f4b71Sopenharmony_ci   1. Run the **./build.sh --product-name rk3568 --ccache** command to generate the executable binary file **ohos_camera_demo** in **out/rk3568/packages/phone/vendor/bin/**.       
993e41f4b71Sopenharmony_ci   2. Import the executable file **ohos_camera_demo** to the development board, modify the permission, and run the file.
994e41f4b71Sopenharmony_ci
995e41f4b71Sopenharmony_ci## Reference
996e41f4b71Sopenharmony_ci
997e41f4b71Sopenharmony_ci### HCS Configuration
998e41f4b71Sopenharmony_ci
999e41f4b71Sopenharmony_ciThe system provides default HCS configuration for the camera module. You can modify the HCS files as required. The HCS files of the camera module are located in **/vendor/hihope/rk3568/hdf_config/uhdf/camera**.
1000e41f4b71Sopenharmony_ci
1001e41f4b71Sopenharmony_ci-  **./hdi_impl/camera_host_config.hcs**: defines the camera static capabilities, including the type and position of the lens, connection type, and supported exposure mode. Configure the camera static capabilities based on the specifications of your camera.
1002e41f4b71Sopenharmony_ci-  **./pipeline_core/config.hcs**: defines the pipeline connection mode. The pipeline configuration includes the supported pipeline types, nodes in each pipeline, and connections between the nodes.
1003e41f4b71Sopenharmony_ci
1004e41f4b71Sopenharmony_ci    After compilation, the **congfig.c** and **congfig.h** files are generated in the **/drivers/periphera/camra/vdi_base/common/pipeline_core/pipeline_impl/src/strategy/config** directory.
1005e41f4b71Sopenharmony_ci-  **./pipeline_core/ipp_algo_config.hcs**: provides algorithm configuration.
1006e41f4b71Sopenharmony_ci-  **./pipeline_core/params.hcs**: defines the scenarios, stream types, and stream IDs. The pipeline uses the stream ID to identify the stream type. Therefore, you need to configure the stream information here.
1007e41f4b71Sopenharmony_ci
1008e41f4b71Sopenharmony_ci    After compilation, the **params.c** and **params.h** files are generated in the **/drivers/periphera/camra/vdi_base/common/pipeline_core/pipeline_impl/src/strategy/config** directory.
1009e41f4b71Sopenharmony_ci
1010e41f4b71Sopenharmony_ci### Camera Dump
1011e41f4b71Sopenharmony_ci
1012e41f4b71Sopenharmony_ci#### Function Overview
1013e41f4b71Sopenharmony_ciCamera dump can be used to test camera-related functions. You can enable this feature in the configuration file. Camera dump provides the following functionalities:
1014e41f4b71Sopenharmony_ci* Provides buffer dump in different phases to help quickly locate image problems and the related data.
1015e41f4b71Sopenharmony_ci* Dumps metadata to determine whether metadata parameters are correctly set and determine the impact of different parameters on image quality.
1016e41f4b71Sopenharmony_ci
1017e41f4b71Sopenharmony_ci#### Directory Structure
1018e41f4b71Sopenharmony_ci
1019e41f4b71Sopenharmony_ci
1020e41f4b71Sopenharmony_ci```
1021e41f4b71Sopenharmony_ci/drivers/peripheral/camera/vdi_base/common/dump
1022e41f4b71Sopenharmony_ci├── include
1023e41f4b71Sopenharmony_ci│   └── camera_dump.h    # Dump head file
1024e41f4b71Sopenharmony_ci└── src
1025e41f4b71Sopenharmony_ci    └── camera_dump.cpp  # Dump core code
1026e41f4b71Sopenharmony_ci```
1027e41f4b71Sopenharmony_ci
1028e41f4b71Sopenharmony_ci
1029e41f4b71Sopenharmony_ci#### Dump Configuration File
1030e41f4b71Sopenharmony_ci
1031e41f4b71Sopenharmony_ciYou can find the dump configuration **dump.config** in the **/data/local/tmp** directory of the device.
1032e41f4b71Sopenharmony_ci
1033e41f4b71Sopenharmony_ci  **Table 1** Dump switch settings
1034e41f4b71Sopenharmony_ci
1035e41f4b71Sopenharmony_ci| **Switch**| **Value**| **Description**| **Application Scenarios**| **Output Data Format**|
1036e41f4b71Sopenharmony_ci| -------- | -------- | -------- | -------- | -------- |
1037e41f4b71Sopenharmony_ci| enableDQBufDump | true/false | The value **true** means to dump the data in the **DequeueBuffer** method defined in the **v4l2_buffer.cpp** file.| Preview, photo taking, and video recording| Onboard camera: YUV420<br>USB camera: YUV422|
1038e41f4b71Sopenharmony_ci| enableUVCNodeBufferDump | true/false | The value **true** means to dump the data to be converted by the **YUV422To420** method defined in the **uvc_node.cpp** file.| Preview, photo taking, and video recording| USB camera: YUV422|
1039e41f4b71Sopenharmony_ci| enableUVCNodeConvertedBufferDump | true/false | The value **true** means to dump the converted data returned by the **YUV422To420** method defined in the **uvc_node.cpp** file.| Preview, photo taking, and video recording| USB camera: YUV420|
1040e41f4b71Sopenharmony_ci| enableExifNodeConvertedBufferDump | true/false | The value **true** means to dump the data in the **DeliverBuffer** method defined in the **exif_node.cpp** file.| Photo taking| JPEG |
1041e41f4b71Sopenharmony_ci| enableFaceNodeConvertedBufferDump | true/false | The value **true** means to dump the data in the **DeliverBuffer** method defined in the **face_node.cpp** file.| Reserved for future use| NA|
1042e41f4b71Sopenharmony_ci| enableForkNodeConvertedBufferDump | true/false | The value **true** means to dump the data in the **DeliverBuffer** method defined in the **fork_node.cpp** file.| Preview, photo taking, and video recording| YUV422 |
1043e41f4b71Sopenharmony_ci| enableRKFaceNodeConvertedBufferDump | true/false | The value **true** means to dump the data in the **DeliverBuffer** method defined in the **rk_face_node.cpp** file.| Reserved for future use| NA|
1044e41f4b71Sopenharmony_ci| enableRKExifNodeConvertedBufferDump | true/false | The value **true** means to dump the data in the **DeliverBuffer** method defined in the **rk_exif_node.cpp** file.| Photo taking| JPEG |
1045e41f4b71Sopenharmony_ci| enableCodecNodeConvertedBufferDump | true/false | The value **true** means to dump the data in the **DeliverBuffer** method defined in the **codec_node.cpp** file.| Preview, photo taking, and video recording| JPEG, YUV420, RGBA8888|
1046e41f4b71Sopenharmony_ci| enableRKCodecNodeConvertedBufferDump | true/false | The value **true** means to dump the data in the **DeliverBuffer** method defined in the **rk_codec_node.cpp** file.| Preview, photo taking, and video recording| JPEG, H264, RGBA8888|
1047e41f4b71Sopenharmony_ci| enableSreamTunnelBufferDump | true/false | The value **true** means to dump the data in the **PutBuffer** method defined in the **stream_tunnel.cpp** file.| Preview, photo taking, and video recording| JPEG, H264, YUV420, RGBA8888|
1048e41f4b71Sopenharmony_ci| enableMetadataDump | true/false | The value **true** means to enable the dump metadata feature.| Preview, photo taking, and video recording| .meta |
1049e41f4b71Sopenharmony_ci
1050e41f4b71Sopenharmony_ci
1051e41f4b71Sopenharmony_ciYou can also set the dump sampling interval, as described in the following table.
1052e41f4b71Sopenharmony_ci
1053e41f4b71Sopenharmony_ci  **Table 2** Dump sampling interval
1054e41f4b71Sopenharmony_ci
1055e41f4b71Sopenharmony_ci| Dump sampling interval| **Value**| **Description**|
1056e41f4b71Sopenharmony_ci| -------- | -------- | -------- |
1057e41f4b71Sopenharmony_ci| previewInterval | Integer greater than or equal to 1| Interval for dumping preview. The default value is **1**, which means to dump every frame.|
1058e41f4b71Sopenharmony_ci| videoInterval | Integer greater than or equal to 1| Interval for dumping video recording. The default value is **1**, which means to dump every frame.|
1059e41f4b71Sopenharmony_ci
1060e41f4b71Sopenharmony_ci#### Configuration Example
1061e41f4b71Sopenharmony_ci
1062e41f4b71Sopenharmony_ciCreate a file named **dump.config** in any location on your PC and configure the related parameters.
1063e41f4b71Sopenharmony_ci
1064e41f4b71Sopenharmony_ciComplete configuration:
1065e41f4b71Sopenharmony_ci
1066e41f4b71Sopenharmony_ci>__enableDQBufDump=true__<br>
1067e41f4b71Sopenharmony_ci>enableUVCNodeBufferDump=false<br>
1068e41f4b71Sopenharmony_ci>enableUVCNodeConvertedBufferDump=false<br>
1069e41f4b71Sopenharmony_ci>enableExifNodeConvertedBufferDump=false<br>
1070e41f4b71Sopenharmony_ci>enableFaceNodeConvertedBufferDump=false<br>
1071e41f4b71Sopenharmony_ci>enableForkNodeConvertedBufferDump=false<br>
1072e41f4b71Sopenharmony_ci>enableRKFaceNodeConvertedBufferDump=false<br>
1073e41f4b71Sopenharmony_ci>enableRKExifNodeConvertedBufferDump=false<br>
1074e41f4b71Sopenharmony_ci>enableCodecNodeConvertedBufferDump=false<br>
1075e41f4b71Sopenharmony_ci>enableRKCodecNodeConvertedBufferDump=false<br>
1076e41f4b71Sopenharmony_ci>enableSreamTunnelBufferDump=false<br>
1077e41f4b71Sopenharmony_ci>**enableMetadataDump=true**<br>
1078e41f4b71Sopenharmony_ci>**previewInterval=3**<br>
1079e41f4b71Sopenharmony_ci>videoInterval=1<br>
1080e41f4b71Sopenharmony_ci
1081e41f4b71Sopenharmony_ci
1082e41f4b71Sopenharmony_ciExample:
1083e41f4b71Sopenharmony_ci
1084e41f4b71Sopenharmony_ciDump **DequeueBuffer** data and metadata with a dump sampling interval of 3.
1085e41f4b71Sopenharmony_ci
1086e41f4b71Sopenharmony_ci#### Enabling Dump
1087e41f4b71Sopenharmony_ci1. Transfer the configuration file to the **/data/local/tmp** directory of the target device.
1088e41f4b71Sopenharmony_ci
1089e41f4b71Sopenharmony_ci   ```
1090e41f4b71Sopenharmony_ci   hdc file send dump.config /data/local/tmp
1091e41f4b71Sopenharmony_ci   ```
1092e41f4b71Sopenharmony_ci
1093e41f4b71Sopenharmony_ci2. Modify the permission on the dump directory.
1094e41f4b71Sopenharmony_ci
1095e41f4b71Sopenharmony_ci   ```
1096e41f4b71Sopenharmony_ci   hdc shell mount -o rw,remount /data
1097e41f4b71Sopenharmony_ci   hdc shell chmod 777 /data/ -R
1098e41f4b71Sopenharmony_ci   ```
1099e41f4b71Sopenharmony_ci
1100e41f4b71Sopenharmony_ci3. Enable the dump feature.
1101e41f4b71Sopenharmony_ci
1102e41f4b71Sopenharmony_ci   ```
1103e41f4b71Sopenharmony_ci   hdc shell "hidumper -s 5100 -a '-host camera_host -o'"
1104e41f4b71Sopenharmony_ci   ```
1105e41f4b71Sopenharmony_ci
1106e41f4b71Sopenharmony_ci   * **-s 5100**: obtains all information about the ability whose ID is 5100. In this example, ability 5100 is camera.
1107e41f4b71Sopenharmony_ci   * **-a '-host camera_host -o'**: exports the specified ability information.
1108e41f4b71Sopenharmony_ci   * For details about how to use HiDumper, see [HiDumper](../../device-dev/subsystems/subsys-dfx-hidumper.md).
1109e41f4b71Sopenharmony_ci
1110e41f4b71Sopenharmony_ci
1111e41f4b71Sopenharmony_ci4. Start the camera and perform operations, such as taking photos and videos, and previewing the photos and videos.
1112e41f4b71Sopenharmony_ci
1113e41f4b71Sopenharmony_ci#### Dumping Data
1114e41f4b71Sopenharmony_ciAfter the dump feature is enabled, a file containing the data dumped will be generated in the **/data/local/tmp** directory of the device. You can view the file after sending it to a PC.
1115e41f4b71Sopenharmony_ci```
1116e41f4b71Sopenharmony_cihdc file recv /data/local/tmp/xxxx.yuv ~/
1117e41f4b71Sopenharmony_ci```
1118