1# Camera Recording Sample (C/C++)
2
3This topic provides sample code that covers the complete recording process and the API calling sequence. For details about a single process (such as device input, session management, and recording), see the corresponding C/C++ development guide links provided in [Camera Development Preparations](camera-preparation.md).
4
5## Development Process
6
7After obtaining the output stream capabilities supported by the camera, create a video stream. The development process is as follows:
8
9![Recording Development Process](figures/recording-ndk-development-process.png)
10
11## Sample Code
12
131. Link the dynamic library in the CMake script.
14    ```txt
15        target_link_libraries(entry PUBLIC libohcamera.so libhilog_ndk.z.so)
16    ```
17
182. Import the NDK APIs on the C++ side, and perform recording based on the surface ID passed in.
19    ```c++
20    #include "hilog/log.h"
21    #include "ohcamera/camera.h"
22    #include "ohcamera/camera_input.h"
23    #include "ohcamera/capture_session.h"
24    #include "ohcamera/photo_output.h"
25    #include "ohcamera/preview_output.h"
26    #include "ohcamera/video_output.h"
27    #include "ohcamera/camera_manager.h"
28
29    void OnCameraInputError(const Camera_Input* cameraInput, Camera_ErrorCode errorCode)
30    {
31        OH_LOG_INFO(LOG_APP, "OnCameraInput errorCode = %{public}d", errorCode);
32    }
33
34    CameraInput_Callbacks* GetCameraInputListener(void)
35    {
36        static CameraInput_Callbacks cameraInputCallbacks = {
37            .onError = OnCameraInputError
38        };
39        return &cameraInputCallbacks;
40    }
41
42    void CaptureSessionOnFocusStateChange(Camera_CaptureSession* session, Camera_FocusState focusState)
43    {
44        OH_LOG_INFO(LOG_APP, "CaptureSessionOnFocusStateChange");
45    }
46
47    void CaptureSessionOnError(Camera_CaptureSession* session, Camera_ErrorCode errorCode)
48    {
49        OH_LOG_INFO(LOG_APP, "CaptureSessionOnError = %{public}d", errorCode);
50    }
51
52    CaptureSession_Callbacks* GetCaptureSessionRegister(void)
53    {
54        static CaptureSession_Callbacks captureSessionCallbacks = {
55            .onFocusStateChange = CaptureSessionOnFocusStateChange,
56            .onError = CaptureSessionOnError
57        };
58        return &captureSessionCallbacks;
59    }
60
61    void VideoOutputOnFrameStart(Camera_VideoOutput* videoOutput)
62    {
63        OH_LOG_INFO(LOG_APP, "VideoOutputOnFrameStart");
64    }
65
66    void VideoOutputOnFrameEnd(Camera_VideoOutput* videoOutput, int32_t frameCount)
67    {
68        OH_LOG_INFO(LOG_APP, "VideoOutput frameCount = %{public}d", frameCount);
69    }
70
71    void VideoOutputOnError(Camera_VideoOutput* videoOutput, Camera_ErrorCode errorCode)
72    {
73        OH_LOG_INFO(LOG_APP, "VideoOutput errorCode = %{public}d", errorCode);
74    }
75
76    VideoOutput_Callbacks* GetVideoOutputListener(void)
77    {
78        static VideoOutput_Callbacks videoOutputListener = {
79            .onFrameStart = VideoOutputOnFrameStart,
80            .onFrameEnd = VideoOutputOnFrameEnd,
81            .onError = VideoOutputOnError
82        };
83        return &videoOutputListener;
84    }
85
86    void CameraManagerStatusCallback(Camera_Manager* cameraManager, Camera_StatusInfo* status)
87    {
88        OH_LOG_INFO(LOG_APP, "CameraManagerStatusCallback is called");
89    }
90
91    CameraManager_Callbacks* GetCameraManagerListener()
92    {
93        static CameraManager_Callbacks cameraManagerListener = {
94            .onCameraStatus = CameraManagerStatusCallback
95        };
96        return &cameraManagerListener;
97    }
98
99    NDKCamera::NDKCamera(char *previewId, char *videoId)
100    {
101        Camera_Manager* cameraManager = nullptr;
102        Camera_Device* cameras = nullptr;
103        Camera_CaptureSession* captureSession = nullptr;
104        Camera_OutputCapability* cameraOutputCapability = nullptr;
105        Camera_VideoOutput* videoOutput = nullptr;
106        const Camera_Profile* previewProfile = nullptr;
107        const Camera_Profile* photoProfile = nullptr;
108        const Camera_VideoProfile* videoProfile = nullptr;
109        Camera_PreviewOutput* previewOutput = nullptr;
110        Camera_PhotoOutput* photoOutput = nullptr;
111        Camera_Input* cameraInput = nullptr;
112        uint32_t size = 0;
113        uint32_t cameraDeviceIndex = 0;
114        char* videoSurfaceId = videoId;
115        char* previewSurfaceId = previewId;
116        // Create a CameraManager object.
117        Camera_ErrorCode ret = OH_Camera_GetCameraManager(&cameraManager);
118        if (cameraManager == nullptr || ret != CAMERA_OK) {
119            OH_LOG_ERROR(LOG_APP, "OH_Camera_GetCameraMananger failed.");
120        }
121        // Listen for camera status changes.
122        ret = OH_CameraManager_RegisterCallback(cameraManager, GetCameraManagerListener());
123        if (ret != CAMERA_OK) {
124            OH_LOG_ERROR(LOG_APP, "OH_CameraManager_RegisterCallback failed.");
125        }
126
127        // Obtain the camera list.
128        ret = OH_CameraManager_GetSupportedCameras(cameraManager, &cameras, &size);
129        if (cameras == nullptr || size < 0 || ret != CAMERA_OK) {
130            OH_LOG_ERROR(LOG_APP, "OH_CameraManager_GetSupportedCameras failed.");
131        }
132
133        for (int index = 0; index < size; index++) {
134            OH_LOG_ERROR(LOG_APP, "cameraId  =  %{public}s ", cameras[index].cameraId);              // Obtain the camera ID.
135            OH_LOG_ERROR(LOG_APP, "cameraPosition  =  %{public}d ", cameras[index].cameraPosition);  // Obtain the camera position.
136            OH_LOG_ERROR(LOG_APP, "cameraType  =  %{public}d ", cameras[index].cameraType);          // Obtain the camera type.
137            OH_LOG_ERROR(LOG_APP, "connectionType  =  %{public}d ", cameras[index].connectionType);  // Obtain the camera connection type.
138        }
139
140        // Obtain the output streams supported by the camera.
141        ret = OH_CameraManager_GetSupportedCameraOutputCapability(cameraManager, &cameras[cameraDeviceIndex],
142                                                                &cameraOutputCapability);
143        if (cameraOutputCapability == nullptr || ret != CAMERA_OK) {
144            OH_LOG_ERROR(LOG_APP, "OH_CameraManager_GetSupportedCameraOutputCapability failed.");
145        }
146
147        if (cameraOutputCapability->previewProfilesSize < 0) {
148            OH_LOG_ERROR(LOG_APP, "previewProfilesSize == null");
149        }
150        previewProfile = cameraOutputCapability->previewProfiles[0];
151
152        if (cameraOutputCapability->photoProfilesSize < 0) {
153            OH_LOG_ERROR(LOG_APP, "photoProfilesSize == null");
154        }
155        photoProfile = cameraOutputCapability->photoProfiles[0];
156
157        if (cameraOutputCapability->videoProfilesSize < 0) {
158            OH_LOG_ERROR(LOG_APP, "videorofilesSize == null");
159        }
160        videoProfile = cameraOutputCapability->videoProfiles[0];
161
162        // Create a VideoOutput instance.
163        ret = OH_CameraManager_CreateVideoOutput(cameraManager, videoProfile, videoSurfaceId, &videoOutput);
164        if (videoProfile == nullptr || videoOutput == nullptr || ret != CAMERA_OK) {
165            OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreateVideoOutput failed.");
166        }
167
168        // Listen for video output errors.
169        ret = OH_VideoOutput_RegisterCallback(videoOutput, GetVideoOutputListener());
170        if (ret != CAMERA_OK) {
171            OH_LOG_ERROR(LOG_APP, "OH_VideoOutput_RegisterCallback failed.");
172        }
173
174        // Create a session.
175        ret = OH_CameraManager_CreateCaptureSession(cameraManager, &captureSession);
176        if (captureSession == nullptr || ret != CAMERA_OK) {
177            OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreateCaptureSession failed.");
178        }
179        // Listen for session errors.
180        ret = OH_CaptureSession_RegisterCallback(captureSession, GetCaptureSessionRegister());
181        if (ret != CAMERA_OK) {
182            OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_RegisterCallback failed.");
183        }
184
185        // Start configuration for the session.
186        ret = OH_CaptureSession_BeginConfig(captureSession);
187        if (ret != CAMERA_OK) {
188            OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_BeginConfig failed.");
189        }
190
191        // Create a camera input stream.
192        ret = OH_CameraManager_CreateCameraInput(cameraManager, &cameras[cameraDeviceIndex], &cameraInput);
193        if (cameraInput == nullptr || ret != CAMERA_OK) {
194            OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreateCameraInput failed.");
195        }
196
197        // Listen for camera input errors.
198        ret = OH_CameraInput_RegisterCallback(cameraInput, GetCameraInputListener());
199        if (ret != CAMERA_OK) {
200            OH_LOG_ERROR(LOG_APP, "OH_CameraInput_RegisterCallback failed.");
201        }
202
203        // Open the camera.
204        ret = OH_CameraInput_Open(cameraInput);
205        if (ret != CAMERA_OK) {
206            OH_LOG_ERROR(LOG_APP, "OH_CameraInput_Open failed.");
207        }
208
209        // Add the camera input stream to the session.
210        ret = OH_CaptureSession_AddInput(captureSession, cameraInput);
211        if (ret != CAMERA_OK) {
212            OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddInput failed.");
213        }
214
215        // Create a preview output stream. For details about the surfaceId parameter, see the <XComponent>. The preview stream is the surface provided by the <XComponent>.
216        ret = OH_CameraManager_CreatePreviewOutput(cameraManager, previewProfile, 0, &previewOutput);
217        if (previewProfile == nullptr || previewOutput == nullptr || ret != CAMERA_OK) {
218            OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreatePreviewOutput failed.");
219        }
220
221        // Add the preview output stream to the session.
222        ret = OH_CaptureSession_AddPreviewOutput(captureSession, previewOutput);
223        if (ret != CAMERA_OK) {
224            OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddPreviewOutput failed.");
225        }
226
227        // Add the video output stream to the session.
228        ret = OH_CaptureSession_AddVideoOutput(captureSession, videoOutput);
229        if (ret != CAMERA_OK) {
230            OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddVideoOutput failed.");
231        }
232
233        // Commit the session configuration.
234        ret = OH_CaptureSession_CommitConfig(captureSession);
235        if (ret != CAMERA_OK) {
236            OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_CommitConfig failed.");
237        }
238
239        // Start the session.
240        ret = OH_CaptureSession_Start(captureSession);
241        if (ret != CAMERA_OK) {
242            OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Start failed.");
243        }
244
245        // Start the video output stream.
246        ret = OH_VideoOutput_Start(videoOutput);
247        if (ret != CAMERA_OK) {
248            OH_LOG_ERROR(LOG_APP, "OH_VideoOutput_Start failed.");
249        }
250
251        // Call avRecorder.start() on the TS side to start video recording.
252
253        // Stop the video output stream.
254        ret = OH_VideoOutput_Stop(videoOutput);
255        if (ret != CAMERA_OK) {
256            OH_LOG_ERROR(LOG_APP, "OH_VideoOutput_Stop failed.");
257        }
258
259        // Call avRecorder.stop() on the TS side to stop video recording.
260
261        // Stop the session.
262        ret = OH_CaptureSession_Stop(captureSession);
263        if (ret == CAMERA_OK) {
264            OH_LOG_INFO(LOG_APP, "OH_CaptureSession_Stop success ");
265        } else {
266            OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Stop failed. %d ", ret);
267        }
268
269        // Release the camera input stream.
270        ret = OH_CameraInput_Close(cameraInput);
271        if (ret == CAMERA_OK) {
272            OH_LOG_INFO(LOG_APP, "OH_CameraInput_Close success ");
273        } else {
274            OH_LOG_ERROR(LOG_APP, "OH_CameraInput_Close failed. %d ", ret);
275        }
276
277        // Release the preview output stream.
278        ret = OH_PreviewOutput_Release(previewOutput);
279        if (ret == CAMERA_OK) {
280            OH_LOG_INFO(LOG_APP, "OH_PreviewOutput_Release success ");
281        } else {
282            OH_LOG_ERROR(LOG_APP, "OH_PreviewOutput_Release failed. %d ", ret);
283        }
284
285        // Release the video output stream.
286        ret = OH_VideoOutput_Release(videoOutput);
287        if (ret == CAMERA_OK) {
288            OH_LOG_INFO(LOG_APP, "OH_VideoOutput_Release success ");
289        } else {
290            OH_LOG_ERROR(LOG_APP, "OH_VideoOutput_Release failed. %d ", ret);
291        }
292
293        // Release the session.
294        ret = OH_CaptureSession_Release(captureSession);
295        if (ret == CAMERA_OK) {
296            OH_LOG_INFO(LOG_APP, "OH_CaptureSession_Release success ");
297        } else {
298            OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Release failed. %d ", ret);
299        }
300    }
301    ```
302