本讲是Android Camera性能分析专题的第31讲,我们介绍添加Stream FPS统计图和Trace,包括如下内容:
- 添加Stream FPS Histogram
 - 添加Stream FPS Trace
 
| 资源 | 描述 | 
|---|---|
| 在线课程 | 极客笔记在线课程 | 
| 知识星球 | 星球名称:深入浅出Android Camera  星球ID: 17296815  | 
| 极客笔记圈 | 
添加Stream FPS Histogram
代码见视频讲解,运行效果如下:

添加Stream FPS Trace
代码见视频讲解,运行效果如下:

代码修改点
diff --git a/Android13/libcameraservice/device3/Camera3OutputStream.cpp b/Android13/libcameraservice/device3/Camera3OutputStream.cpp
index 204947c..d7ab76c 100644
--- a/Android13/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/Android13/libcameraservice/device3/Camera3OutputStream.cpp
@@ -73,6 +73,7 @@ Camera3OutputStream::Camera3OutputStream(int id,
         mDequeueBufferLatency(kDequeueLatencyBinSize),
 #ifdef Deepinout
         mQueueBufferIntervalHistogram(kQueueBufferIntervalBinSize),
+        mStreamFpsHistogram(kFpsBinSize),
 #endif
         mIPCTransport(transport) {
@@ -109,6 +110,7 @@ Camera3OutputStream::Camera3OutputStream(int id,
         mDequeueBufferLatency(kDequeueLatencyBinSize),
 #ifdef Deepinout
         mQueueBufferIntervalHistogram(kQueueBufferIntervalBinSize),
+        mStreamFpsHistogram(kFpsBinSize),
 #endif
         mIPCTransport(transport) {
@@ -152,6 +154,7 @@ Camera3OutputStream::Camera3OutputStream(int id,
         mDequeueBufferLatency(kDequeueLatencyBinSize),
 #ifdef Deepinout
         mQueueBufferIntervalHistogram(kQueueBufferIntervalBinSize),
+        mStreamFpsHistogram(kFpsBinSize),
 #endif
         mIPCTransport(transport) {
     // Deferred consumer only support preview surface format now.
@@ -203,6 +206,7 @@ Camera3OutputStream::Camera3OutputStream(int id, camera_stream_type_t type,
         mDequeueBufferLatency(kDequeueLatencyBinSize),
 #ifdef Deepinout
         mQueueBufferIntervalHistogram(kQueueBufferIntervalBinSize),
+        mStreamFpsHistogram(kFpsBinSize),
 #endif
         mIPCTransport(transport) {
@@ -334,6 +338,23 @@ status_t Camera3OutputStream::returnBufferLocked(
         ATRACE_ASYNC_END(traceLog, mId);
     }
     mLastQueueBufferTime = currentQueueBufferTime;
+
+    // Add for stream FPS
+    if (mLastSecTimestamp == 0) {
+        mLastSecTimestamp = timestamp;
+        mLastFrameCount = mFrameCount;
+    }
+    if ((timestamp - mLastSecTimestamp) >= 1000 * 1000000) {
+        int32_t curFrameCount = (int32_t) (mFrameCount - mLastFrameCount);
+        nsecs_t timestampInterval = timestamp - mLastSecTimestamp;
+        char fpsTraceTag[48];
+        snprintf(fpsTraceTag, sizeof(fpsTraceTag), "Stream %d: FPS\n", mId);
+        float streamFps = 1000 / ((timestampInterval / 1000000) / curFrameCount);
+        ATRACE_INT(fpsTraceTag, (int32_t)streamFps);
+        mLastSecTimestamp = timestamp;
+        mLastFrameCount = mFrameCount;
+        mStreamFpsHistogram.addFps(streamFps);
+    }
 #endif
     return OK;
@@ -547,6 +568,8 @@ void Camera3OutputStream::dump(int fd, const Vector &args) const {
 #ifdef Deepinout
     mQueueBufferIntervalHistogram.dump(fd,
         "      QueueBufferInterval histogram:");
+    mStreamFpsHistogram.dump(fd,
+        "      Stream FPS histogram:");
 #endif
 }
@@ -1060,6 +1083,15 @@ status_t Camera3OutputStream::disconnectLocked() {
     camera_stream::width,
     camera_stream::height);
     mQueueBufferIntervalHistogram.reset();
+
+    mStreamFpsHistogram.logFps("CamId(L:P):(%s:%s) Stream %d-%s-%dx%d FPS histogram",
+    mLogicalCameraId.string(),
+    getPhysicalCameraId().string(),
+    mId,
+    mConsumerName.string(),
+    camera_stream::width,
+    camera_stream::height);
+    mStreamFpsHistogram.reset();
 #endif
     mDequeueBufferLatency.reset();
     return OK;
diff --git a/Android13/libcameraservice/device3/Camera3OutputStream.h b/Android13/libcameraservice/device3/Camera3OutputStream.h
index 05831ec..65d8292 100644
--- a/Android13/libcameraservice/device3/Camera3OutputStream.h
+++ b/Android13/libcameraservice/device3/Camera3OutputStream.h
@@ -412,6 +412,12 @@ class Camera3OutputStream :
     nsecs_t mLastQueueBufferTime = 0;
     static const int32_t kQueueBufferIntervalBinSize = 35; // in ms
     CameraLatencyHistogram mQueueBufferIntervalHistogram;
+
+    // Add for stream FPS
+    nsecs_t mLastSecTimestamp = 0;
+    uint32_t mLastFrameCount;
+    static const int32_t kFpsBinSize = 5; // in fps
+    CameraLatencyHistogram mStreamFpsHistogram;
 #endif
     IPCTransport mIPCTransport = IPCTransport::INVALID;
diff --git a/Android13/libcameraservice/utils/LatencyHistogram.cpp b/Android13/libcameraservice/utils/LatencyHistogram.cpp
index a48ada7..f289ce6 100644
--- a/Android13/libcameraservice/utils/LatencyHistogram.cpp
+++ b/Android13/libcameraservice/utils/LatencyHistogram.cpp
@@ -137,4 +137,53 @@ void CameraLatencyHistogram::formatHistogramText(
     lineBinCounts.append(" (%)");
 }
+#ifdef Deepinout
+void CameraLatencyHistogram::addFps(float fps) {
+    int32_t binIndex = floor(fps / mBinSizeMs) - 1;
+
+    if (binIndex < 0) {
+        binIndex = 0;
+    } else if (binIndex >= mBinCount) {
+        binIndex = mBinCount-1;
+    }
+
+    mBins[binIndex]++;
+    mTotalCount++;
+#ifdef Deepinout
+    mTotalFps += fps;
+    if (mMaxFps == 0 || mMaxFps < fps) {
+        mMaxFps = fps;
+    }
+    if (mMinFps ==0 || mMinFps > fps) {
+        mMinFps = fps;
+    }
+#endif
+}
+
+void CameraLatencyHistogram::logFps(const char* fmt, ...) {
+    if (mTotalCount == 0) {
+        return;
+    }
+
+    va_list args;
+    va_start(args, fmt);
+    String8 histogramName = String8::formatV(fmt, args);
+
+    ALOGI("%s (%" PRId64 ") samples, avg:max:min(%.2f fps:%.2f fps:%.2f fps):",
+    histogramName.string(),
+    mTotalCount,
+    mTotalFps / mTotalCount,
+    mMaxFps,
+    mMinFps);
+
+    va_end(args);
+
+    String8 lineBins, lineBinCounts;
+    formatHistogramText(lineBins, lineBinCounts);
+
+    ALOGI("%s", lineBins.c_str());
+    ALOGI("%s", lineBinCounts.c_str());
+}
+#endif
+
 }; //namespace android
diff --git a/Android13/libcameraservice/utils/LatencyHistogram.h b/Android13/libcameraservice/utils/LatencyHistogram.h
index d0dcbf7..9ae7706 100644
--- a/Android13/libcameraservice/utils/LatencyHistogram.h
+++ b/Android13/libcameraservice/utils/LatencyHistogram.h
@@ -21,6 +21,9 @@
 #include 
 #include 
+#ifdef Deepinout
+#include 
+#endif
 namespace android {
@@ -34,6 +37,10 @@ public:
     void dump(int fd, const char* name) const;
     void log(const char* format, ...);
+#ifdef Deepinout
+    void addFps(float fps);
+    void logFps(const char* format, ...);
+#endif
 private:
     int32_t mBinSizeMs;
     int32_t mBinCount;
@@ -42,6 +49,9 @@ private:
     nsecs_t mTotoalDuration;
     nsecs_t mMaxDuration;
     nsecs_t mMinDuration;
+    float mTotalFps;
+    float mMaxFps;
+    float mMinFps;
 #endif
     uint64_t mTotalCount;    
极客笔记