camera-preformance-imporvement.md 6.3 KB
Newer Older
Z
zengyawen 已提交
1 2 3 4 5 6 7 8 9 10 11 12
# 性能提升方案(仅对系统应用开放)

相机启动性能受限于底层器件上点、流程Pipeline初始化等耗时操作影响,本文档将开发者提供更进一步的指导,提升相机启动速度以及拍照返回缩略图速度。相关能力与底层器件相关,开发者在使用前需确认是否支持相关特性。

​相关特性分别在打开相机设备过程、配流过程以及拍照过程中。本文档针对三个场景分别进行介绍。

## 延时配流

经典的相机启动过程经过“相机设备打开”、“配置数据流”、“启动数据流”等流程,而配流启流之前需要得到图形组件的surfaceId。

延时配流方案是把配流启流与surface解耦,在组件尚未给应用surface之前,可以先进行配流启流,只需要在启流结束之前提供surface,可以提升启动速度,防止影响其他启动优化方案的落地。

Z
zengyawen 已提交
13 14 15 16 17
![deferred-surface-scene](figures/deferred-surface-scene.png)

优化前:配流动作依赖surface对象,surface对象依赖于UI加载完成。

优化后:配流动作不依赖surface对象,界面加载和配流并行执行。
Z
zengyawen 已提交
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56

### 接口说明

详细的API参考说明,请参考[Camera API文档](../reference/apis/js-apis-camera.md)

| 接口 | 说明 |
| ---- | ---- |
| createDeferredPreviewOutput(profile: Profile): Promise\<PreviewOutput> | 创建延迟预览输出对象,在配流时替代普通的预览输出对象加入数据流。 |
| addDeferredSurface(surfaceId: string): Promise\<void> | 配置延迟预览的Surface,可以在session.commitConfig()配流和session.start()启流之后运行。 |

### 开发示例

```js
import camera from '@ohos.multimedia.camera';

function async preview(context: Context, cameraInfo: camera.Device, previewProfile: camera.Profile, photoProfile: camera.Profile, surfaceId: string): Promise<void> {
  const cameraManager: camera.CameraManager = camera.getCameraManager(context);
  const cameraInput camera.CameraInput = await cameraManager.createCameraInput(cameraInfo)
  const previewOutput: camera.PreviewOutput = await cameraManager.createDeferredPreviewOutput(previewProfile);
  const photoOutput: camera.PhotoOutput = await cameraManager.createPhotoOutput(photoProfile);
  const session: camera.CaptureSession  = await this.mCameraManager.createCaptureSession();
  await session.beginConfig();
  await session.addInput(cameraInput);
  await session.addOutput(previewOutput);
  await session.addOutput(photoOutput);
  await session.commitConfig();
  await session.start();
  await previewOutput.addDeferredSurface(surfaceId);
}
```

## 快速缩略图

相机拍照性能依赖算法处理的速度,算法链越复杂、效果就越好,但同时处理时间就越长。要能够从拍照流程上进行优化,既满足后处理算法处理的要求,又不要阻塞前台的拍照速度。

通过相机快速缩略图技术,相机拍照可单独输出拇指缩略图,在真图没有上来前,提前上报一张缩略图给应用去显示,提升shot2see用户感知拍照速度。

### 接口说明

Z
zengyawen 已提交
57 58 59 60 61 62 63 64 65 66 67 68 69
详细的API参考说明,请参考[Camera API文档](../reference/apis/js-apis-camera.md)

| 接口 | 说明 |
| ---- | ---- |
| isQuickThumbnailSupported() : boolean | 是否支持快速缩略图。 |
| enableQuickThumbnail(enabled:bool): void | 使能/去使能快速缩略图。 |
| on(type: 'quickThumbnail', callback: AsyncCallback\<image.PixelMap>): void | 相机缩略图监听回调。 |

> **说明:**
>
> - isQuickThumbnailSupported及enableQuickThumbnail接口的调用需要在CaptureSession.addOutput、CaptureSession.addInput后,CaptureSession.commitConfig()之前。
> - on接口需要在enableQuickThumbnail(true)之后生效。

Z
zengyawen 已提交
70 71
### 开发示例

Z
zengyawen 已提交
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
```js
import camera from '@ohos.multimedia.camera'

this.cameraManager = camera.getCameraManager(globalThis.abilityContext);
let cameras = this.cameraManager.getSupportedCameras()
// 创建CaptureSession实例
this.captureSession = await this.cameraManager.createCaptureSession()
// 开始配置会话
await this.captureSession.beginConfig()
// 把CameraInput加入到会话
this.cameraInput = await this.cameraManager.createCameraInput(cameras[0])
await this.cameraInput.open()
await this.captureSession.addInput(this.cameraInput)
// 把PhotoOutPut加入到会话
this.photoOutPut = await this.cameraManager.createPhotoOutput(photoProfile, surfaceId)
await this.captureSession.addOutput(this.photoOutPut)
boolean isSupported = this.photoOutPut.isQuickThumbnailSupported()
if (isSupported) {
    // 使能快速缩略图
    this.photoOutPut.enableQuickThumbnail(true)
}
this.photoOutPut.on('quickThumbnail', (err, pixelmap) => {
    if (err || pixelmap === undefined) {
        Logger.error(this.tag, 'photoOutPut on thumbnail failed ')
        return
    }
    // 显示或保存pixelmap
    this.showOrSavePicture(pixelmap)
})
```
Z
zengyawen 已提交
102

Z
zengyawen 已提交
103 104 105 106 107 108 109
## 预热启动

普通情况下相机应用的启动是用户通过点击桌面相机图标触发的。桌面应用感知用户点击相机图标,然后通知应用管理器启动对应的相机应用(进程),这个过程是耗时较长。进入相机应用后,开始进入相机启动流程。经典的相机启动过程会经过,“相机设备打开”,“配置数据流”,“启动数据流等”,这个过程也较为耗时。

​相机启动方案是把“相机设备打开”这个动作提前到相机应用启动之前,即在用户点击相机图标,
还没等相机应用启动的时候,触发相机设备打开的动作,从而缩短相机应用内启动相机的流程,加速相机启动。使用预热启动前后的相机应用流程对比如下:

Z
zengyawen 已提交
110
![prelaunch-scene](figures/prelaunch-scene.png)
Z
zengyawen 已提交
111 112 113

### 接口说明

Z
zengyawen 已提交
114 115 116 117 118 119 120 121 122 123 124
详细的API参考说明,请参考[Camera API文档](../reference/apis/js-apis-camera.md)

| 接口 | 说明 |
| ---- | ---- |
| isPreLaunchSupported(camera: CameraDevice) : boolean |  判断指定cameraDevice是否支持预热启动。 |
| setPreLaunchConfig(camera: CameraDevice) : void | 配置相机预热参数。 |
| preLaunch() : void | 用户点击系统相机图标,拉起相机应用的同时调用,下发预热请求,使能相机预热启动。 |

### 调用流程


Z
zengyawen 已提交
125
### 开发示例
Z
zengyawen 已提交
126 127 128 129

使用该功能前需要申请权限:ohos.permission.CAMERA

具体申请方式及校验方式,请参考[访问控制授权申请指导](../security/accesstoken-guidelines.md)