1# Using Performance Improvement Features (for System Applications Only) (ArkTS)
2
3Before developing a camera application, request permissions by following the instructions provided in [Camera Development Preparations](camera-preparation.md).
4
5The camera startup performance is affected by time-consuming operations such as power-on of underlying components and initialization of the process pipeline. To improve the camera startup speed and thumbnail display speed, OpenHarmony introduces some features. The capabilities of these features are related to underlying components. You need to check whether your underlying components support these capabilities before using the capabilities.
6
7​These features are involved in the processes of starting the camera device, configuring streams, and taking photos. This topic describes the three scenarios.
8
9## Deferred Stream Configuration
10
11A typical camera startup process includes starting the camera device, configuring a data stream, and starting the data stream. Before configuring the data stream, you need to obtain the surface ID of the **XComponent**.
12
13The deferred stream configuration feature decouples stream configuration and start from the surface. Before the **XComponent** provides the surface for the camera application, the system configures and starts the stream. This way, the surface only needs to be available before the stream is started. This improves the startup speed and prevents the implementation of other startup optimization schemas from being affected.
14
15![deferred-surface-scene](figures/deferred-surface-scene.png)
16
17Before optimization: Stream configuration depends on a **Surface** object, which is available after UI loading is complete. In other words, you can create a session, configure input and output streams, and start the session only after the UI is loaded. The camera HDI is responsible for stream configuration.
18
19After optimization: Stream configuration does not depend on the **Surface** object. UI loading and stream configuration are executed concurrently. After the parameters are prepared, you can create a session.
20
21### Available APIs
22
23Read [Camera](../../reference/apis-camera-kit/js-apis-camera.md) for the API reference.
24
25| API| Description|
26| ---- | ---- |
27| createDeferredPreviewOutput(profile: Profile): Promise\<PreviewOutput> | Creates a deferred **PreviewOutput** instance and adds it, instead of a common **PreviewOutput** instance, to the data stream during stream configuration.|
28| addDeferredSurface(surfaceId: string): Promise\<void> | Adds a surface for delayed preview. This API can run after [session.commitConfig](../../reference/apis-camera-kit/js-apis-camera.md#commitconfig11) or [session.start](../../reference/apis-camera-kit/js-apis-camera.md#start11) is called.|
29
30### Development Example
31
32The figure below shows the recommended API call process.
33
34![](figures/deferred-surface-sequence-diagram.png)
35
36For details about how to obtain the context, see [Obtaining the Context of UIAbility](../../application-models/uiability-usage.md#obtaining-the-context-of-uiability).
37
38```ts
39import { camera } from '@kit.CameraKit';
40import { common } from '@kit.AbilityKit';
41
42async function preview(baseContext: common.BaseContext, cameraInfo: camera.CameraDevice, previewProfile: camera.Profile, photoProfile: camera.Profile, previewSurfaceId: string): Promise<void> {
43  const cameraManager: camera.CameraManager = camera.getCameraManager(baseContext);
44  const cameraInput: camera.CameraInput = cameraManager.createCameraInput(cameraInfo);
45  const previewOutput: camera.PreviewOutput = cameraManager.createDeferredPreviewOutput(previewProfile);
46  const photoOutput: camera.PhotoOutput = cameraManager.createPhotoOutput(photoProfile);
47  const session: camera.PhotoSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO) as camera.PhotoSession;
48  session.beginConfig();
49  session.addInput(cameraInput);
50  session.addOutput(previewOutput);
51  session.addOutput(photoOutput);
52  await session.commitConfig();
53  await session.start();
54  previewOutput.addDeferredSurface(previewSurfaceId);
55}
56```
57
58## Quick Thumbnail
59
60The photo capture performance depends on the algorithm processing speed. A complex algorithm chain provides better image effect while requiring longer processing time.
61
62To improve the photo capture speed perceived by end users, the quick thumbnail feature is introduced. When the user takes a photo, a thumbnail is output and reported to the camera application for display before a real image is reported.
63
64In this way, the photo capture process is optimized, which fulfills the processing requirements of the post-processing algorithm without blocking the photo capture speed of the foreground.
65
66### Available APIs
67
68Read [Camera](../../reference/apis-camera-kit/js-apis-camera.md) for the API reference.
69
70| API| Description|
71| ---- | ---- |
72| isQuickThumbnailSupported() : boolean | Checks whether the quick thumbnail feature is supported.|
73| enableQuickThumbnail(enabled:bool): void | Enables or disables the quick thumbnail feature.|
74| on(type: 'quickThumbnail', callback: AsyncCallback\<image.PixelMap>): void | Listens for camera thumbnails.|
75
76> **NOTE**
77>
78> - [isQuickThumbnailSupported](../../reference/apis-camera-kit/js-apis-camera-sys.md#isquickthumbnailsupported) and [enableQuickThumbnail](../../reference/apis-camera-kit/js-apis-camera-sys.md#enablequickthumbnail) must be called after [addOutput](../../reference/apis-camera-kit/js-apis-camera.md#addoutput11) and [addInput](../../reference/apis-camera-kit/js-apis-camera.md#addinput11) but before [commitConfig](../../reference/apis-camera-kit/js-apis-camera.md#commitconfig11).
79> - The **on** API takes effect after [enableQuickThumbnail(true)](../../reference/apis-camera-kit/js-apis-camera-sys.md#enablequickthumbnail) is called.
80
81### Development Example
82
83The figure below shows the recommended API call process.
84
85![](figures/quick-thumbnail-sequence-diagram.png)
86
87For details about how to obtain the context, see [Obtaining the Context of UIAbility](../../application-models/uiability-usage.md#obtaining-the-context-of-uiability).
88```ts
89import { camera } from '@kit.CameraKit';
90import { BusinessError } from '@kit.BasicServicesKit';
91import { image } from '@kit.ImageKit';
92import { common } from '@kit.AbilityKit';
93
94async function enableQuickThumbnail(baseContext: common.BaseContext, photoProfile: camera.Profile): Promise<void> {
95  let cameraManager: camera.CameraManager = camera.getCameraManager(baseContext);
96  let cameras: Array<camera.CameraDevice> = cameraManager.getSupportedCameras();
97  // Create a PhotoSession instance.
98  let photoSession: camera.PhotoSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO) as camera.PhotoSession;
99  // Start configuration for the session.
100  photoSession.beginConfig();
101  // Add a CameraInput instance to the session.
102  let cameraInput: camera.CameraInput = cameraManager.createCameraInput(cameras[0]);
103  cameraInput.open();
104  photoSession.addInput(cameraInput);
105  // Add a PhotoOutput instance to the session.
106  let photoOutPut: camera.PhotoOutput = cameraManager.createPhotoOutput(photoProfile);
107  photoSession.addOutput(photoOutPut);
108  let isSupported: boolean = photoOutPut.isQuickThumbnailSupported();
109  if (isSupported) {
110    // Enable the quick thumbnail feature.
111    photoOutPut.enableQuickThumbnail(true);
112    photoOutPut.on('quickThumbnail', (err: BusinessError, pixelMap: image.PixelMap) => {
113      if (err || pixelMap === undefined) {
114        console.error('photoOutPut on thumbnail failed');
115        return;
116      }
117      // Display or save the PixelMap instance.
118      showOrSavePicture(pixelMap);
119    });
120  }
121}
122
123function showOrSavePicture(pixelMap: image.PixelMap): void {
124  //do something
125}
126```
127
128## Prelaunch
129
130Generally, the startup of the camera application is triggered when the user touches the camera icon on the home screen. The home screen senses the touch event and instructs the application manager to start the camera application. This takes a relatively long time. After the camera application is started, the camera startup process starts. A typical camera startup process includes starting the camera device, configuring a data stream, and starting the data stream, which is also time-consuming.
131
132​The prelaunch feature triggers the action of starting the camera device before the camera application is started. In other words, when the user touches the camera icon on the home screen, the system starts the camera device. At this time, the camera application is not started yet. The figure below shows the camera application process before and after the prelaunch feature is introduced.
133
134![prelaunch-scene](figures/prelaunch-scene.png)
135
136### Available APIs
137
138Read [Camera](../../reference/apis-camera-kit/js-apis-camera.md) for the API reference.
139
140| API| Description|
141| ---- | ---- |
142| isPrelaunchSupported(camera: CameraDevice) : boolean |  Checks whether the camera supports prelaunch.|
143| setPrelaunchConfig(prelaunchConfig: PrelaunchConfig) : void | Sets the prelaunch parameters.|
144| prelaunch() : void | Prelaunches the camera. This API is called when a user touches the system camera icon to start the camera application.|
145
146### Development Example
147
148The figure below shows the recommended API call process.
149
150![](figures/prelaunch-sequence-diagram.png)
151
152For details about how to obtain the context, see [Obtaining the Context of UIAbility](../../application-models/uiability-usage.md#obtaining-the-context-of-uiability).
153
154- **Home screen**
155
156  ```ts
157  import { camera } from '@kit.CameraKit';
158  import { BusinessError } from '@kit.BasicServicesKit';
159  import { common } from '@kit.AbilityKit';
160
161  function preLaunch(baseContext: common.BaseContext): void {
162    let cameraManager: camera.CameraManager = camera.getCameraManager(baseContext);
163    try {
164      cameraManager.prelaunch();
165    } catch (error) {
166      let err = error as BusinessError;
167      console.error(`catch error: Code: ${err.code}, message: ${err.message}`);
168    }
169  }
170  ```
171
172- **Camera application**
173
174  To use the prelaunch feature, the camera application must configure the **ohos.permission.CAMERA** permission.
175
176  For details about how to request and verify the permissions, see [Requesting User Authorization](../../security/AccessToken/request-user-authorization.md).
177
178  ```ts
179  import { camera } from '@kit.CameraKit';
180  import { BusinessError } from '@kit.BasicServicesKit';
181  import { common } from '@kit.AbilityKit';
182
183  function setPreLaunchConfig(baseContext: common.BaseContext): void {
184    let cameraManager: camera.CameraManager = camera.getCameraManager(baseContext);
185    let cameras: Array<camera.CameraDevice> = [];
186    try {
187      cameras = cameraManager.getSupportedCameras();
188    } catch (error) {
189      let err = error as BusinessError;
190      console.error(`getSupportedCameras catch error: Code: ${err.code}, message: ${err.message}`);
191    }
192    if (cameras.length <= 0) {
193      return;
194    }
195    if(cameraManager.isPrelaunchSupported(cameras[0])) {
196      try {
197        cameraManager.setPrelaunchConfig({cameraDevice: cameras[0]});
198      } catch (error) {
199        let err = error as BusinessError;
200        console.error(`setPrelaunchConfig catch error: Code: ${err.code}, message: ${err.message}`);
201      }
202    }
203  }
204  ```
205