写点什么

AOSP CameraLatencyHistogram 的原理与使用

作者:桑榆
  • 2022 年 8 月 03 日
  • 本文字数:1917 字

    阅读完需:约 6 分钟

AOSP 代码引用参考:www.aospxref.com/

可以搜索到 android 各个版本的代码,比较方便,不必下载 AOSP 代码。

CameraLatencyHistogram 是什么

CameraLatencyHistogram 是 AOSP Camera 模块的一个工具类,主要作用是进行直方图统计,针对一些有时延的操作,比如 request 执行的时间,dequeue buffer 的时间等,做直方图统计,最后用于性能相关问题的 debug。

核心源代码位置:/frameworks/av/services/camera/libcameraservice/utils/LatencyHistogram.cpp

源码解析

头文件定义

其中,

  • mBinSizeMs 记录的是当前记录表的标准时间,比如预设一次 request 的标准时长为 40ms

  • mBinCount 记录的是直方图的等级划分数量,通常默认是 10 个等级

  • mBins 记录的是直方图各个等级的数量

  • mTotalCount 记录的是直方图的统计数量总数

类初始化

初始化上述的变量,注意,这里对 vector 进行的初始化,实际上是设定 vector 的 size 大小,不是将第一个元素设定为 binCount。

增加一个数据/清空所有数据

add 一个数据时:先计算时间差,注意,这里是 ns,然后转换为 ms,再与标准时间做除法(计算机的整数除法只取整数部分,比如标准时间是 40ms,本次耗时 30ms,则除法得到 0,耗时 70ms,则除法得到 1),这样就能保证 0<=t<mBinSizeMs 的时长 index 为 0,然后依次类推到 9mbinSizeMs<=t<10mBinSizeMs 的 index 为 9;

然后针对小于 0 和大于等于 10 的做归一化操作;

然后对应存储位置加一,总数加一。

dump/log 以及内部处理函数 formatHistogramText

dump 的逻辑:

  • 先 dump 数据的行头,标识 dump 时的记录数据量;

  • 然后将直方图数据构造成字符串;

  • 将直方图数据写入到对应的 fd 文件中。

log 函数的操作与 dump 基本一致,只是这时是调用 Android log 打印出来。

这个函数的作用就是将统计结果表示成字符串:

  • 先打印耗时的时间段,如 33ms/66ms/99ms,最大值打印为 inf (max ms)

  • 然后打印每一个段数据占总数据量的百分比100.0*mBins[i]/mTotalCount

  • 最后打印一个 %号。

使用该工具的位置

mDequeueBufferLatency:dequeue buffer 的时延,5ms

///frameworks/av/services/camera/libcameraservice/device3/Camera3OutputStream.h//dequebuffer默认耗时5ms,进行记录 static const int32_t kDequeueLatencyBinSize = 5; // in ms CameraLatencyHistogram mDequeueBufferLatency; 
status_t Camera3OutputStream::getBuffersLocked(std::vector<OutstandingBuffer>* outBuffers) { ... nsecs_t dequeueStart = systemTime(SYSTEM_TIME_MONOTONIC); res = consumer->dequeueBuffers(&buffers); nsecs_t dequeueEnd = systemTime(SYSTEM_TIME_MONOTONIC); mDequeueBufferLatency.add(dequeueStart, dequeueEnd); ... }
复制代码

mBufferLimitLatency:buffer signal 时延,33ms

///frameworks/av/services/camera/libcameraservice/device3/Camera3Stream.h// Latency histogram of the wait time for handout buffer count to drop below // max_buffers. static const int32_t kBufferLimitLatencyBinSize = 33; //in ms CameraLatencyHistogram mBufferLimitLatency; status_t Camera3Stream::getBuffer(camera_stream_buffer *buffer, nsecs_t waitBufferTimeout, const std::vector<size_t>& surface_ids) {     ...     nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC);     if (waitBufferTimeout < kWaitForBufferDuration) {         waitBufferTimeout = kWaitForBufferDuration;     }     res = mOutputBufferReturnedSignal.waitRelative(mLock, waitBufferTimeout);     nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC);    mBufferLimitLatency.add(waitStart, waitEnd);     ... }
复制代码

mRequestLatency:request 执行的时延,40ms

///frameworks/av/services/camera/libcameraservice/device3/Camera3Device.h//记录request的时延,默认一帧request时长40ms static const int32_t kRequestLatencyBinSize = 40; // in ms CameraLatencyHistogram mRequestLatency; bool Camera3Device::RequestThread::threadLoop() {     ...     bool submitRequestSuccess = false;     nsecs_t tRequestStart = systemTime(SYSTEM_TIME_MONOTONIC);     submitRequestSuccess = sendRequestsBatch();     nsecs_t tRequestEnd = systemTime(SYSTEM_TIME_MONOTONIC);    mRequestLatency.add(tRequestStart, tRequestEnd);     ... }
复制代码

具体使用

ADBlog 搜索关键字:CameraLatencyHistogram

由此可见,采样 41 个 request,40ms 内执行成功的有 95.12%;采样 36 个 dequeue buffer,全部都在 5ms 内执行成功。

该模块主要用于查看 framework 的一些耗时流程的时延直方图分布,check 性能时可以进行参考

发布于: 刚刚阅读数: 5
用户头像

桑榆

关注

北海虽赊,扶摇可接;东隅已逝,桑榆非晚! 2020.02.29 加入

Android手机厂商-相机软件系统工程师 爬山/徒步/Coding

评论

发布
暂无评论
AOSP CameraLatencyHistogram的原理与使用_Android;_桑榆_InfoQ写作社区