[Android P] CameraAPI1 转 HAL3 预览流程(一) — 背景概述

系列文章

  • [Android P] CameraAPI1 转 HAL3 预览流程(一) — 背景概述
  • [Android P] CameraAPI1 转 HAL3 预览流程(二) — startPreview
  • [Android P] CameraAPI1 转 HAL3 预览流程(三) — setPreviewCallbackFlag
  • [Android P] CameraAPI1 转 HAL3 预览流程(四) — Preview Data

正文

HAL3 强制升级已经有一年左右了,和 HAL3 搭配的 Camera API2 目前已经改用的三方相机应用还并不算多,所以为了更好地 debug 三方相机相关的卡顿问题,我近期花时间专门研究了 Android Framework 层提供的 API1 转 API2 连接 HAL3 的逻辑(以启动预览、预览数据流为例),以便对转换过程有一个总体认识,并且对经常遇到的两个由于 API 逻辑转换导致的卡顿问题进行更细致的分析。

先说说目前几个项目经常碰到的两种卡顿现象:

  1. 启动预览后出现短暂预览卡顿现象,然后恢复正常;
  2. 预览过程中偶现卡顿(但应用自身、GPU 都没有很长耗时的情况);

第一种卡顿的原理,以及示意图如下:

  1. APP 启动预览采用的是 startPreview + setPreviewCallbackWithBuffer 的方式;
  2. 后发调用 setPreviewCallbackWithBuffer 相当于增加一路 stream,会触发 HAL3 逻辑下的 re-config 机制,相当于再启动一次预览;
  3. startPreview 调用成功后会先有一些预览数据出来
  4. setPreviewCallbackWithBuffer 最终调用到的 setPreviewCallbackFlag 触发 re-config,取消了前面出来的预览帧,导致无数据而卡顿一小段时间;
  5. 后续的预览过程不会受到影响。
    [Android P] CameraAPI1 转 HAL3 预览流程(一) — 背景概述_第1张图片

第二种卡顿的原理,以及示意图如下:

  1. APP 使用 preview callback 这路数据去做预览(因为应用本身想要对数据进行一些客制化操作);
  2. 每一次数据帧上传后,JNI 部分 copyAndPost 调用时若 CallbackBuffer 被取空了,则会把 callbackEnabled 这个标记设置为 false(APP 接着调用 addCallbackBuffer 的时候才会设置回 true);
  3. 此时 streamList size 为 1
  4. 如果刚好在这时 RequestThread 执行到 prepareHalRequests,就会只准备 preview stream 的 buffer,而 callback 的 buffer 就没有准备
  5. 这一次 Request 对应的 Result 里没有 callback 这一路的数据(会有 preview 的数据,但 APP 并不是用这一路数据做预览,或者取 preview 的时机取决于 callback 数据处理完的时间点),最终出现预览卡顿现象。
    [Android P] CameraAPI1 转 HAL3 预览流程(一) — 背景概述_第2张图片

这两种卡顿实际上都与 Framework 层中 API1 转 API2 的逻辑有关,如果三方应用都按照 Google 标准转用 API2 的话,就不会有这两种问题。

当然,现在对于整个 Android 生态来说 API2 还是新东西,升级适配需要一些过渡。而且有些应用设计得比较简单,只需要考虑打开预览、拿预览数据做处理就完了,改换 API2 要花费不少精力重新设计,其实用 API1 对他们来说也是合情合理的。

可以预见的是,在今后相当一段时间内,我们每个项目都要对一些 API1 的三方相机进行 debug,所以还是有必要对 API1 转 HAL3 的流程进行一些细致的了解的。

而这两类问题的解法(在保持 API1 的情况下)通常是:

  1. 对于第一种卡顿问题,需要 APP 把 setPreviewCallbackWithBuffer 放在 startPreview 前面(实际上 Google 也没有规定这两个方法谁要在前),这样一次就 config 了两路 stream,就不会触发 re-config 的情况了;
  2. 对于第二种卡顿问题,可以让 APP 多调用一次 addCallbackBuffer,这样保证 APP 自己带下来的 Buffer 足够,在 copyAndPost 时就不会触发到 setPreviewCallbackFlags(0x00)
  3. 对于第二种卡顿问题,还可以想办法把 callbackEnabled 控制为 true,这样也可以实现 prepareHalRequests 时不会缺 Callback 这一路的 request。

为了更清晰地了解这些解决方案的原理,我花了点时间探索了一下 API1 转 HAL3 在 Framework 层中的整体运作机制,接下来几篇文章将要分别详细介绍这几个内容:

  1. startPreview 流程;
  2. setPreviewCallbackFlag 流程;
  3. 持续预览时 Request 和 Result 对应的流程。

你可能感兴趣的:(Android,Android,Camera)