• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Performance Optimization Practices (for System Applications Only) (ArkTS)
2<!--Kit: Camera Kit-->
3<!--Subsystem: Multimedia-->
4<!--Owner: @qano-->
5<!--SE: @leo_ysl-->
6<!--TSE: @xchaosioda-->
7
8Before developing a camera application, request permissions by following the instructions provided in [Requesting Camera Development Permissions](camera-preparation.md).
9
10The 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.
11
12​These features are involved in the processes of starting the camera device, configuring streams, and taking photos. This topic describes the three scenarios.
13
14## Deferred Stream Configuration
15
16A 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**.
17
18The 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.
19
20![deferred-surface-scene](figures/deferred-surface-scene.png)
21
22Before 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.
23
24After 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.
25
26### Available APIs
27
28Read [Module Description](../../reference/apis-camera-kit/arkts-apis-camera.md) for the API reference.
29
30| API| Description|
31| ---- | ---- |
32| 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.|
33| addDeferredSurface(surfaceId: string): Promise\<void> | Adds a surface for delayed preview. This API can run after [session.commitConfig](../../reference/apis-camera-kit/arkts-apis-camera-Session.md#commitconfig11) or [session.start](../../reference/apis-camera-kit/arkts-apis-camera-Session.md#start11) is called.|
34
35### Development Example
36
37The figure below shows the recommended API call process.
38
39![](figures/deferred-surface-sequence-diagram.png)
40
41For details about how to obtain the context, see [Obtaining the Context of UIAbility](../../application-models/uiability-usage.md#obtaining-the-context-of-uiability).
42
43```ts
44import { camera } from '@kit.CameraKit';
45import { common } from '@kit.AbilityKit';
46
47async function preview(baseContext: common.BaseContext, cameraInfo: camera.CameraDevice, previewProfile: camera.Profile, photoProfile: camera.Profile, previewSurfaceId: string): Promise<void> {
48  const cameraManager: camera.CameraManager = camera.getCameraManager(baseContext);
49  const cameraInput: camera.CameraInput = cameraManager.createCameraInput(cameraInfo);
50  const previewOutput: camera.PreviewOutput = cameraManager.createDeferredPreviewOutput(previewProfile);
51  const photoOutput: camera.PhotoOutput = cameraManager.createPhotoOutput(photoProfile);
52  const session: camera.PhotoSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO) as camera.PhotoSession;
53  session.beginConfig();
54  session.addInput(cameraInput);
55  session.addOutput(previewOutput);
56  session.addOutput(photoOutput);
57  await session.commitConfig();
58  await session.start();
59  previewOutput.addDeferredSurface(previewSurfaceId);
60}
61```
62
63## Quick Thumbnail
64
65The photo capture performance depends on the algorithm processing speed. A complex algorithm chain provides better image effect while requiring longer processing time.
66
67To 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.
68
69In 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.
70
71### Available APIs
72
73Read [Module Description](../../reference/apis-camera-kit/arkts-apis-camera.md) for the API reference.
74
75| API| Description|
76| ---- | ---- |
77| isQuickThumbnailSupported() : boolean | Checks whether the quick thumbnail feature is supported. The value **true** means that the feature is supported, and **false** means the opposite.|
78| enableQuickThumbnail(enabled:bool): void | Enables or disables the quick thumbnail feature.|
79| on(type: 'quickThumbnail', callback: AsyncCallback\<image.PixelMap>): void | Listens for camera thumbnails.|
80
81> **NOTE**
82>
83> - [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).
84> - The **on** API takes effect after [enableQuickThumbnail(true)](../../reference/apis-camera-kit/js-apis-camera-sys.md#enablequickthumbnail) is called.
85
86### Development Example
87
88The figure below shows the recommended API call process.
89
90![](figures/quick-thumbnail-sequence-diagram.png)
91
92For details about how to obtain the context, see [Obtaining the Context of UIAbility](../../application-models/uiability-usage.md#obtaining-the-context-of-uiability).
93```ts
94import { camera } from '@kit.CameraKit';
95import { BusinessError } from '@kit.BasicServicesKit';
96import { image } from '@kit.ImageKit';
97import { common } from '@kit.AbilityKit';
98
99async function enableQuickThumbnail(baseContext: common.BaseContext, photoProfile: camera.Profile): Promise<void> {
100  let cameraManager: camera.CameraManager = camera.getCameraManager(baseContext);
101  let cameras: Array<camera.CameraDevice> = cameraManager.getSupportedCameras();
102  // Create a PhotoSession instance.
103  let photoSession: camera.PhotoSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO) as camera.PhotoSession;
104  // Start configuration for the session.
105  photoSession.beginConfig();
106  // Add a CameraInput instance to the session.
107  let cameraInput: camera.CameraInput = cameraManager.createCameraInput(cameras[0]);
108  cameraInput.open();
109  photoSession.addInput(cameraInput);
110  // Add a PhotoOutput instance to the session.
111  let photoOutPut: camera.PhotoOutput = cameraManager.createPhotoOutput(photoProfile);
112  photoSession.addOutput(photoOutPut);
113  let isSupported: boolean = photoOutPut.isQuickThumbnailSupported();
114  if (isSupported) {
115    // Enable the quick thumbnail feature.
116    photoOutPut.enableQuickThumbnail(true);
117    photoOutPut.on('quickThumbnail', (err: BusinessError, pixelMap: image.PixelMap) => {
118      if (err || pixelMap === undefined) {
119        console.error('photoOutPut on thumbnail failed');
120        return;
121      }
122      // Display or save the PixelMap instance.
123      showOrSavePicture(pixelMap);
124    });
125  }
126}
127
128function showOrSavePicture(pixelMap: image.PixelMap): void {
129  // Do something.
130}
131```
132
133## Prelaunch
134
135Generally, 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.
136
137
138​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.
139
140![prelaunch-scene](figures/prelaunch-scene.png)
141
142### Available APIs
143
144Read [Module Description](../../reference/apis-camera-kit/arkts-apis-camera.md) for the API reference.
145
146| API| Description|
147| ---- | ---- |
148| isPrelaunchSupported(camera: CameraDevice) : boolean |  Checks whether the camera supports prelaunch. The value **true** means that the camera supports prelaunch, and **false** means the opposite.|
149| setPrelaunchConfig(prelaunchConfig: PrelaunchConfig) : void | Sets the prelaunch parameters.|
150| prelaunch() : void | Prelaunches the camera. This API is called when a user touches the system camera icon to start the camera application.|
151
152### Development Example
153
154The figure below shows the recommended API call process.
155
156![](figures/prelaunch-sequence-diagram.png)
157
158For details about how to obtain the context, see [Obtaining the Context of UIAbility](../../application-models/uiability-usage.md#obtaining-the-context-of-uiability).
159
160- **Home screen**
161
162  ```ts
163  import { camera } from '@kit.CameraKit';
164  import { BusinessError } from '@kit.BasicServicesKit';
165  import { common } from '@kit.AbilityKit';
166
167  function preLaunch(baseContext: common.BaseContext): void {
168    let cameraManager: camera.CameraManager = camera.getCameraManager(baseContext);
169    try {
170      cameraManager.prelaunch();
171    } catch (error) {
172      let err = error as BusinessError;
173      console.error(`catch error: Code: ${err.code}, message: ${err.message}`);
174    }
175  }
176  ```
177
178- **Camera application**
179
180  To use the prelaunch feature, the camera application must configure the ohos.permission.CAMERA permission.
181
182  For details about how to request and verify the permissions, see [Requesting User Authorization](../../security/AccessToken/request-user-authorization.md).
183
184  ```ts
185  import { camera } from '@kit.CameraKit';
186  import { BusinessError } from '@kit.BasicServicesKit';
187  import { common } from '@kit.AbilityKit';
188
189  function setPreLaunchConfig(baseContext: common.BaseContext): void {
190    let cameraManager: camera.CameraManager = camera.getCameraManager(baseContext);
191    let cameras: Array<camera.CameraDevice> = [];
192    try {
193      cameras = cameraManager.getSupportedCameras();
194    } catch (error) {
195      let err = error as BusinessError;
196      console.error(`getSupportedCameras catch error: Code: ${err.code}, message: ${err.message}`);
197    }
198    if (cameras.length <= 0) {
199      return;
200    }
201    if(cameraManager.isPrelaunchSupported(cameras[0])) {
202      try {
203        cameraManager.setPrelaunchConfig({cameraDevice: cameras[0]});
204      } catch (error) {
205        let err = error as BusinessError;
206        console.error(`setPrelaunchConfig catch error: Code: ${err.code}, message: ${err.message}`);
207      }
208    }
209  }
210  ```
211