Camera: Add metrics collection for FPS range
- Add new misc analytics flag for 24q3
- Add collection of most common FPS range requested by client
- Add tests for FPS histogram
- Clean up unit test build files so that a source file doesn't have to be
listed twice
Bug: 324485285
Test: New unit tests pass, camera CTS, manual checking of new metrics logging
Change-Id: I0e76b0f7c4a2e41e2a160051bba12d54e6fd480b
diff --git a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
index 65e93a9..4afae9b 100644
--- a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
+++ b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
@@ -95,7 +95,8 @@
sp<hardware::ICameraServiceProxy>& proxyBinder,
int64_t requestCount, int64_t resultErrorCount, bool deviceError,
const std::string& userTag, int32_t videoStabilizationMode, bool usedUltraWide,
- bool usedZoomOverride, const std::vector<hardware::CameraStreamStats>& streamStats) {
+ bool usedZoomOverride, std::pair<int32_t, int32_t> mostRequestedFpsRange,
+ const std::vector<hardware::CameraStreamStats>& streamStats) {
Mutex::Autolock l(mLock);
mSessionStats.mNewCameraState = CameraSessionStats::CAMERA_STATE_IDLE;
@@ -106,6 +107,7 @@
mSessionStats.mVideoStabilizationMode = videoStabilizationMode;
mSessionStats.mUsedUltraWide = usedUltraWide;
mSessionStats.mUsedZoomOverride = usedZoomOverride;
+ mSessionStats.mMostRequestedFpsRange = mostRequestedFpsRange;
mSessionStats.mStreamStats = streamStats;
updateProxyDeviceState(proxyBinder);
@@ -281,7 +283,8 @@
void CameraServiceProxyWrapper::logIdle(const std::string& id,
int64_t requestCount, int64_t resultErrorCount, bool deviceError,
const std::string& userTag, int32_t videoStabilizationMode, bool usedUltraWide,
- bool usedZoomOverride, const std::vector<hardware::CameraStreamStats>& streamStats) {
+ bool usedZoomOverride, std::pair<int32_t, int32_t> mostRequestedFpsRange,
+ const std::vector<hardware::CameraStreamStats>& streamStats) {
std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
{
Mutex::Autolock l(mLock);
@@ -294,8 +297,9 @@
}
ALOGV("%s: id %s, requestCount %" PRId64 ", resultErrorCount %" PRId64 ", deviceError %d"
- ", userTag %s, videoStabilizationMode %d", __FUNCTION__, id.c_str(), requestCount,
- resultErrorCount, deviceError, userTag.c_str(), videoStabilizationMode);
+ ", userTag %s, videoStabilizationMode %d, most common FPS [%d,%d]",
+ __FUNCTION__, id.c_str(), requestCount, resultErrorCount, deviceError, userTag.c_str(),
+ videoStabilizationMode, mostRequestedFpsRange.first, mostRequestedFpsRange.second);
for (size_t i = 0; i < streamStats.size(); i++) {
ALOGV("%s: streamStats[%zu]: w %d h %d, requestedCount %" PRId64 ", dropCount %"
PRId64 ", startTimeMs %d" ,
@@ -306,7 +310,8 @@
sp<hardware::ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
sessionStats->onIdle(proxyBinder, requestCount, resultErrorCount, deviceError, userTag,
- videoStabilizationMode, usedUltraWide, usedZoomOverride, streamStats);
+ videoStabilizationMode, usedUltraWide, usedZoomOverride,
+ mostRequestedFpsRange, streamStats);
}
void CameraServiceProxyWrapper::logOpen(const std::string& id, int facing,
diff --git a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
index 49b7a8c..b6a967f 100644
--- a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
+++ b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
@@ -62,7 +62,8 @@
void onIdle(sp<hardware::ICameraServiceProxy>& proxyBinder,
int64_t requestCount, int64_t resultErrorCount, bool deviceError,
const std::string& userTag, int32_t videoStabilizationMode, bool usedUltraWide,
- bool usedZoomOverride, const std::vector<hardware::CameraStreamStats>& streamStats);
+ bool usedZoomOverride, std::pair<int32_t, int32_t> mostRequestedFpsRange,
+ const std::vector<hardware::CameraStreamStats>& streamStats);
std::string updateExtensionSessionStats(
const hardware::CameraExtensionSessionStats& extStats);
@@ -111,7 +112,8 @@
void logIdle(const std::string& id,
int64_t requestCount, int64_t resultErrorCount, bool deviceError,
const std::string& userTag, int32_t videoStabilizationMode, bool usedUltraWide,
- bool usedZoomOverride, const std::vector<hardware::CameraStreamStats>& streamStats);
+ bool usedZoomOverride, std::pair<int32_t, int32_t> mostRequestedFpsRange,
+ const std::vector<hardware::CameraStreamStats>& streamStats);
// Ping camera service proxy for user update
void pingCameraServiceProxy();
diff --git a/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp b/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp
index c3aac72..2bca4cb 100644
--- a/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp
+++ b/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp
@@ -48,19 +48,35 @@
void SessionStatsBuilder::buildAndReset(int64_t* requestCount,
int64_t* errorResultCount, bool* deviceError,
- std::map<int, StreamStats> *statsMap) {
+ std::pair<int32_t, int32_t>* mostRequestedFpsRange,
+ std::map<int, StreamStats>* statsMap) {
std::lock_guard<std::mutex> l(mLock);
*requestCount = mRequestCount;
*errorResultCount = mErrorResultCount;
*deviceError = mDeviceError;
*statsMap = mStatsMap;
+ int32_t minFps = 0, maxFps = 0;
+ if (mRequestedFpsRangeHistogram.size() > 0) {
+ auto mostCommonIt = mRequestedFpsRangeHistogram.begin();
+ for (auto it = mostCommonIt; it != mRequestedFpsRangeHistogram.end(); it++) {
+ if (it->second.first > mostCommonIt->second.first) {
+ mostCommonIt = it;
+ }
+ }
+ minFps = mostCommonIt->first >> 32;
+ maxFps = mostCommonIt->first & 0xFFFF'FFFFU;
+ }
+ *mostRequestedFpsRange = std::make_pair(minFps, maxFps);
+
// Reset internal states
mRequestCount = 0;
mErrorResultCount = 0;
mCounterStopped = false;
mDeviceError = false;
mUserTag.clear();
+ mRequestedFpsRangeHistogram.clear();
+
for (auto& streamStats : mStatsMap) {
StreamStats& streamStat = streamStats.second;
streamStat.mRequestedFrameCount = 0;
@@ -125,6 +141,31 @@
mDeviceError = true;
}
+void SessionStatsBuilder::incFpsRequestedCount(int32_t minFps, int32_t maxFps,
+ int64_t frameNumber) {
+ std::lock_guard<std::mutex> l(mLock);
+
+ // Stuff range into a 64-bit value to make hashing simple
+ uint64_t currentFpsTarget = minFps;
+ currentFpsTarget = currentFpsTarget << 32 | maxFps;
+
+ auto &stats = mRequestedFpsRangeHistogram[currentFpsTarget];
+ stats.first++;
+ stats.second = frameNumber;
+
+ // Ensure weird app input of target FPS ranges doesn't cause unbounded memory growth
+ if (mRequestedFpsRangeHistogram.size() > FPS_HISTOGRAM_MAX_SIZE) {
+ // Find oldest used fps to drop by last seen frame number
+ auto deleteIt = mRequestedFpsRangeHistogram.begin();
+ for (auto it = deleteIt; it != mRequestedFpsRangeHistogram.end(); it++) {
+ if (it->second.second < deleteIt->second.second) {
+ deleteIt = it;
+ }
+ }
+ mRequestedFpsRangeHistogram.erase(deleteIt);
+ }
+}
+
void StreamStats::updateLatencyHistogram(int32_t latencyMs) {
size_t i;
for (i = 0; i < mCaptureLatencyBins.size(); i++) {
diff --git a/services/camera/libcameraservice/utils/SessionStatsBuilder.h b/services/camera/libcameraservice/utils/SessionStatsBuilder.h
index 2936531..914c09e 100644
--- a/services/camera/libcameraservice/utils/SessionStatsBuilder.h
+++ b/services/camera/libcameraservice/utils/SessionStatsBuilder.h
@@ -22,6 +22,8 @@
#include <array>
#include <map>
#include <mutex>
+#include <unordered_map>
+#include <utility>
namespace android {
@@ -64,7 +66,8 @@
void buildAndReset(/*out*/int64_t* requestCount,
/*out*/int64_t* errorResultCount,
/*out*/bool* deviceError,
- /*out*/std::map<int, StreamStats> *statsMap);
+ /*out*/std::pair<int32_t, int32_t>* mostRequestedFpsRange,
+ /*out*/std::map<int, StreamStats>* statsMap);
// Stream specific counter
void startCounter(int streamId);
@@ -76,6 +79,13 @@
void incResultCounter(bool dropped);
void onDeviceError();
+ // Session specific statistics
+
+ // Limit on size of FPS range histogram
+ static const size_t FPS_HISTOGRAM_MAX_SIZE = 10;
+
+ void incFpsRequestedCount(int32_t minFps, int32_t maxFps, int64_t frameNumber);
+
SessionStatsBuilder() : mRequestCount(0), mErrorResultCount(0),
mCounterStopped(false), mDeviceError(false) {}
private:
@@ -85,6 +95,11 @@
bool mCounterStopped;
bool mDeviceError;
std::string mUserTag;
+
+ // Histogram of frame counts of requested target FPS ranges
+ // (min_fps << 32 | max_fps) -> (# of frames with this fps, last seen framenumber)
+ std::unordered_map<uint64_t, std::pair<int64_t, int64_t>> mRequestedFpsRangeHistogram;
+
// Map from stream id to stream statistics
std::map<int, StreamStats> mStatsMap;
};