本讲是Android Camera性能分析专题的第26讲 ,我们介绍DequeueBuffer Latency,包括如下内容:
- DequeueBuffer Latency是什么
- DequeueBuffer Latency配置
- DequeeuBuffer Latency实战
视频在线观看:
- 极客笔记:
极客笔记在线课程
加入知识星球与更多Camera同学交流
– 星球名称:深入浅出Android Camera
– 星球ID: 17296815
– Wechat: 极客笔记圈
DequeueBuffer Latency是什么
DequeueBuffer Latency 用于衡量/记录从BufferQueue里面获取Buffer的耗时。
影响:
- 如果该耗时太长,会拉低CaptureRequest的帧率,具体体现在送给HAL的CaptureRequest速度变慢。
每一个Camera3OutputStream都会统计DequeueBuffer Latency。
- 这里的Output/Input Stream是相对HAL而言,HAL输出的流是Output Stream,输入给HAL的流是Input Stream
DequeueBuffer:
- 通过GraphicBufferProducer从BufferQueue里面获取一张未使用的Buffer
DequeueBuffer Latency配置
DequeueBuffer Latency直方图配置
-
分成10份(默认值),间隔为5ms
-
static const int32_t kDequeueLatencyBinSize = 5; // in ms
添加Sample的时机
-
在每个CaptureRequest的prepareHalRequests中会调用getBuffer,进而触发到对BufferQueue的DequeueBuffer操作。
-
Camera3OutputStream会对每次dequeueBuffer操作耗时做记录,然后作为一个Sample添加到CameraLatencyHistogram。
DequeeuBuffer Latency实战
-
代码讲解
nsecs_t dequeueStart = systemTime(SYSTEM_TIME_MONOTONIC); size_t batchSize = mBatchSize.load(); if (batchSize == 1) { sp anw = consumer; res = anw->dequeueBuffer(anw.get(), anb, fenceFd); } else { std::unique_lock batchLock(mBatchLock); res = OK; if (mBatchedBuffers.size() == 0) { if (remainingBuffers == 0) { ALOGE("%s: cannot get buffer while all buffers are handed out", __FUNCTION__); return INVALID_OPERATION; } if (batchSize > remainingBuffers) { batchSize = remainingBuffers; } batchLock.unlock(); // Refill batched buffers std::vector batchedBuffers; batchedBuffers.resize(batchSize); res = consumer->dequeueBuffers(&batchedBuffers); batchLock.lock(); if (res != OK) { ALOGE("%s: batch dequeueBuffers call failed! %s (%d)", __FUNCTION__, strerror(-res), res); } else { mBatchedBuffers = std::move(batchedBuffers); } } if (res == OK) { // Dispatch batch buffers *anb = mBatchedBuffers.back().buffer; *fenceFd = mBatchedBuffers.back().fenceFd; mBatchedBuffers.pop_back(); } } nsecs_t dequeueEnd = systemTime(SYSTEM_TIME_MONOTONIC); mDequeueBufferLatency.add(dequeueStart, dequeueEnd);
-
实战演示,请参阅视频