Loading camera/CameraSessionStats.cpp +36 −0 Original line number Original line Diff line number Diff line Loading @@ -94,6 +94,24 @@ status_t CameraStreamStats::readFromParcel(const android::Parcel* parcel) { return err; return err; } } int histogramType = HISTOGRAM_TYPE_UNKNOWN; if ((err = parcel->readInt32(&histogramType)) != OK) { ALOGE("%s: Failed to read histogram type from parcel", __FUNCTION__); return err; } std::vector<float> histogramBins; if ((err = parcel->readFloatVector(&histogramBins)) != OK) { ALOGE("%s: Failed to read histogram bins from parcel", __FUNCTION__); return err; } std::vector<int64_t> histogramCounts; if ((err = parcel->readInt64Vector(&histogramCounts)) != OK) { ALOGE("%s: Failed to read histogram counts from parcel", __FUNCTION__); return err; } mWidth = width; mWidth = width; mHeight = height; mHeight = height; mFormat = format; mFormat = format; Loading @@ -104,6 +122,9 @@ status_t CameraStreamStats::readFromParcel(const android::Parcel* parcel) { mStartLatencyMs = startLatencyMs; mStartLatencyMs = startLatencyMs; mMaxHalBuffers = maxHalBuffers; mMaxHalBuffers = maxHalBuffers; mMaxAppBuffers = maxAppBuffers; mMaxAppBuffers = maxAppBuffers; mHistogramType = histogramType; mHistogramBins = std::move(histogramBins); mHistogramCounts = std::move(histogramCounts); return OK; return OK; } } Loading Loading @@ -166,6 +187,21 @@ status_t CameraStreamStats::writeToParcel(android::Parcel* parcel) const { return err; return err; } } if ((err = parcel->writeInt32(mHistogramType)) != OK) { ALOGE("%s: Failed to write histogram type", __FUNCTION__); return err; } if ((err = parcel->writeFloatVector(mHistogramBins)) != OK) { ALOGE("%s: Failed to write histogram bins!", __FUNCTION__); return err; } if ((err = parcel->writeInt64Vector(mHistogramCounts)) != OK) { ALOGE("%s: Failed to write histogram counts!", __FUNCTION__); return err; } return OK; return OK; } } Loading camera/include/camera/CameraSessionStats.h +18 −2 Original line number Original line Diff line number Diff line Loading @@ -27,6 +27,11 @@ namespace hardware { */ */ class CameraStreamStats : public android::Parcelable { class CameraStreamStats : public android::Parcelable { public: public: enum HistogramType { HISTOGRAM_TYPE_UNKNOWN = 0, HISTOGRAM_TYPE_CAPTURE_LATENCY = 1, }; int mWidth; int mWidth; int mHeight; int mHeight; int mFormat; int mFormat; Loading @@ -45,15 +50,26 @@ public: int mMaxHalBuffers; int mMaxHalBuffers; int mMaxAppBuffers; int mMaxAppBuffers; // Histogram type. So far only capture latency histogram is supported. int mHistogramType; // The bounary values separating adjacent histogram bins. // A vector of {h1, h2, h3} represents bins of [0, h1), [h1, h2), [h2, h3), // and [h3, infinity) std::vector<float> mHistogramBins; // The counts for all histogram bins. // size(mHistogramBins) + 1 = size(mHistogramCounts) std::vector<int64_t> mHistogramCounts; CameraStreamStats() : CameraStreamStats() : mWidth(0), mHeight(0), mFormat(0), mDataSpace(0), mUsage(0), mWidth(0), mHeight(0), mFormat(0), mDataSpace(0), mUsage(0), mRequestCount(0), mErrorCount(0), mStartLatencyMs(0), mRequestCount(0), mErrorCount(0), mStartLatencyMs(0), mMaxHalBuffers(0), mMaxAppBuffers(0) {} mMaxHalBuffers(0), mMaxAppBuffers(0), mHistogramType(HISTOGRAM_TYPE_UNKNOWN) {} CameraStreamStats(int width, int height, int format, int dataSpace, int64_t usage, CameraStreamStats(int width, int height, int format, int dataSpace, int64_t usage, int maxHalBuffers, int maxAppBuffers) int maxHalBuffers, int maxAppBuffers) : mWidth(width), mHeight(height), mFormat(format), mDataSpace(dataSpace), : mWidth(width), mHeight(height), mFormat(format), mDataSpace(dataSpace), mUsage(usage), mRequestCount(0), mErrorCount(0), mStartLatencyMs(0), mUsage(usage), mRequestCount(0), mErrorCount(0), mStartLatencyMs(0), mMaxHalBuffers(maxHalBuffers), mMaxAppBuffers(maxAppBuffers) {} mMaxHalBuffers(maxHalBuffers), mMaxAppBuffers(maxAppBuffers), mHistogramType(HISTOGRAM_TYPE_UNKNOWN) {} virtual status_t readFromParcel(const android::Parcel* parcel) override; virtual status_t readFromParcel(const android::Parcel* parcel) override; virtual status_t writeToParcel(android::Parcel* parcel) const override; virtual status_t writeToParcel(android::Parcel* parcel) const override; Loading services/camera/libcameraservice/device3/Camera3Device.cpp +8 −0 Original line number Original line Diff line number Diff line Loading @@ -2161,6 +2161,14 @@ void Camera3Device::notifyStatus(bool idle) { streamStats[i].mRequestCount = stats->second.mRequestedFrameCount; streamStats[i].mRequestCount = stats->second.mRequestedFrameCount; streamStats[i].mErrorCount = stats->second.mDroppedFrameCount; streamStats[i].mErrorCount = stats->second.mDroppedFrameCount; streamStats[i].mStartLatencyMs = stats->second.mStartLatencyMs; streamStats[i].mStartLatencyMs = stats->second.mStartLatencyMs; streamStats[i].mHistogramType = hardware::CameraStreamStats::HISTOGRAM_TYPE_CAPTURE_LATENCY; streamStats[i].mHistogramBins.assign( stats->second.mCaptureLatencyBins.begin(), stats->second.mCaptureLatencyBins.end()); streamStats[i].mHistogramCounts.assign( stats->second.mCaptureLatencyHistogram.begin(), stats->second.mCaptureLatencyHistogram.end()); } } } } listener->notifyIdle(requestCount, resultErrorCount, deviceError, streamStats); listener->notifyIdle(requestCount, resultErrorCount, deviceError, streamStats); Loading services/camera/libcameraservice/utils/SessionStatsBuilder.cpp +51 −19 Original line number Original line Diff line number Diff line Loading @@ -18,12 +18,21 @@ #define ATRACE_TAG ATRACE_TAG_CAMERA #define ATRACE_TAG ATRACE_TAG_CAMERA //#define LOG_NDEBUG 0 //#define LOG_NDEBUG 0 #include <numeric> #include <inttypes.h> #include <utils/Log.h> #include <utils/Log.h> #include "SessionStatsBuilder.h" #include "SessionStatsBuilder.h" namespace android { namespace android { // Bins for capture latency: [0, 100], [100, 200], [200, 300], ... // [1300, 2100], [2100, inf]. // Capture latency is in the unit of millisecond. const std::array<int32_t, StreamStats::LATENCY_BIN_COUNT-1> StreamStats::mCaptureLatencyBins { { 100, 200, 300, 400, 500, 700, 900, 1300, 2100 } }; status_t SessionStatsBuilder::addStream(int id) { status_t SessionStatsBuilder::addStream(int id) { std::lock_guard<std::mutex> l(mLock); std::lock_guard<std::mutex> l(mLock); StreamStats stats; StreamStats stats; Loading Loading @@ -52,10 +61,14 @@ void SessionStatsBuilder::buildAndReset(int64_t* requestCount, mCounterStopped = false; mCounterStopped = false; mDeviceError = false; mDeviceError = false; for (auto& streamStats : mStatsMap) { for (auto& streamStats : mStatsMap) { streamStats.second.mRequestedFrameCount = 0; StreamStats& streamStat = streamStats.second; streamStats.second.mDroppedFrameCount = 0; streamStat.mRequestedFrameCount = 0; streamStats.second.mCounterStopped = false; streamStat.mDroppedFrameCount = 0; streamStats.second.mStartLatencyMs = 0; streamStat.mCounterStopped = false; streamStat.mStartLatencyMs = 0; std::fill(streamStat.mCaptureLatencyHistogram.begin(), streamStat.mCaptureLatencyHistogram.end(), 0); } } } } Loading @@ -66,23 +79,28 @@ void SessionStatsBuilder::startCounter(int id) { void SessionStatsBuilder::stopCounter(int id) { void SessionStatsBuilder::stopCounter(int id) { std::lock_guard<std::mutex> l(mLock); std::lock_guard<std::mutex> l(mLock); mStatsMap[id].mCounterStopped = true; StreamStats& streamStat = mStatsMap[id]; streamStat.mCounterStopped = true; } } void SessionStatsBuilder::incCounter(int id, bool dropped, int32_t captureLatencyMs) { void SessionStatsBuilder::incCounter(int id, bool dropped, int32_t captureLatencyMs) { std::lock_guard<std::mutex> l(mLock); std::lock_guard<std::mutex> l(mLock); auto it = mStatsMap.find(id); auto it = mStatsMap.find(id); if (it != mStatsMap.end()) { if (it == mStatsMap.end()) return; if (!it->second.mCounterStopped) { it->second.mRequestedFrameCount++; StreamStats& streamStat = it->second; if (streamStat.mCounterStopped) return; streamStat.mRequestedFrameCount++; if (dropped) { if (dropped) { it->second.mDroppedFrameCount++; streamStat.mDroppedFrameCount++; } else if (it->second.mRequestedFrameCount == 1) { } else if (streamStat.mRequestedFrameCount - streamStat.mDroppedFrameCount == 1) { // The capture latency for the first request. // The capture latency for the first request. it->second.mStartLatencyMs = captureLatencyMs; streamStat.mStartLatencyMs = captureLatencyMs; } } } } streamStat.updateLatencyHistogram(captureLatencyMs); } } void SessionStatsBuilder::stopCounter() { void SessionStatsBuilder::stopCounter() { Loading @@ -95,15 +113,29 @@ void SessionStatsBuilder::stopCounter() { void SessionStatsBuilder::incResultCounter(bool dropped) { void SessionStatsBuilder::incResultCounter(bool dropped) { std::lock_guard<std::mutex> l(mLock); std::lock_guard<std::mutex> l(mLock); if (!mCounterStopped) { if (mCounterStopped) return; mRequestCount++; mRequestCount++; if (dropped) mErrorResultCount++; if (dropped) mErrorResultCount++; } } } void SessionStatsBuilder::onDeviceError() { void SessionStatsBuilder::onDeviceError() { std::lock_guard<std::mutex> l(mLock); std::lock_guard<std::mutex> l(mLock); mDeviceError = true; mDeviceError = true; } } void StreamStats::updateLatencyHistogram(int32_t latencyMs) { size_t i; for (i = 0; i < mCaptureLatencyBins.size(); i++) { if (latencyMs < mCaptureLatencyBins[i]) { mCaptureLatencyHistogram[i] ++; break; } } if (i == mCaptureLatencyBins.size()) { mCaptureLatencyHistogram[i]++; } } }; // namespace android }; // namespace android services/camera/libcameraservice/utils/SessionStatsBuilder.h +18 −2 Original line number Original line Diff line number Diff line Loading @@ -19,22 +19,38 @@ #include <utils/Errors.h> #include <utils/Errors.h> #include <mutex> #include <array> #include <map> #include <map> #include <mutex> namespace android { namespace android { // Helper class to build stream stats // Helper class to build stream stats struct StreamStats { struct StreamStats { // Fields for buffer drop int64_t mRequestedFrameCount; int64_t mRequestedFrameCount; int64_t mDroppedFrameCount; int64_t mDroppedFrameCount; bool mCounterStopped; bool mCounterStopped; // Fields for stream startup latency int32_t mStartLatencyMs; int32_t mStartLatencyMs; // Fields for capture latency measurement const static int LATENCY_BIN_COUNT = 10; // Boundary values separating between adjacent bins, excluding 0 and // infinity. const static std::array<int32_t, LATENCY_BIN_COUNT-1> mCaptureLatencyBins; // Counter values for all histogram bins. One more entry than mCaptureLatencyBins. std::array<int64_t, LATENCY_BIN_COUNT> mCaptureLatencyHistogram; StreamStats() : mRequestedFrameCount(0), StreamStats() : mRequestedFrameCount(0), mDroppedFrameCount(0), mDroppedFrameCount(0), mCounterStopped(false), mCounterStopped(false), mStartLatencyMs(0) {} mStartLatencyMs(0), mCaptureLatencyHistogram{} {} void updateLatencyHistogram(int32_t latencyMs); }; }; // Helper class to build session stats // Helper class to build session stats Loading Loading
camera/CameraSessionStats.cpp +36 −0 Original line number Original line Diff line number Diff line Loading @@ -94,6 +94,24 @@ status_t CameraStreamStats::readFromParcel(const android::Parcel* parcel) { return err; return err; } } int histogramType = HISTOGRAM_TYPE_UNKNOWN; if ((err = parcel->readInt32(&histogramType)) != OK) { ALOGE("%s: Failed to read histogram type from parcel", __FUNCTION__); return err; } std::vector<float> histogramBins; if ((err = parcel->readFloatVector(&histogramBins)) != OK) { ALOGE("%s: Failed to read histogram bins from parcel", __FUNCTION__); return err; } std::vector<int64_t> histogramCounts; if ((err = parcel->readInt64Vector(&histogramCounts)) != OK) { ALOGE("%s: Failed to read histogram counts from parcel", __FUNCTION__); return err; } mWidth = width; mWidth = width; mHeight = height; mHeight = height; mFormat = format; mFormat = format; Loading @@ -104,6 +122,9 @@ status_t CameraStreamStats::readFromParcel(const android::Parcel* parcel) { mStartLatencyMs = startLatencyMs; mStartLatencyMs = startLatencyMs; mMaxHalBuffers = maxHalBuffers; mMaxHalBuffers = maxHalBuffers; mMaxAppBuffers = maxAppBuffers; mMaxAppBuffers = maxAppBuffers; mHistogramType = histogramType; mHistogramBins = std::move(histogramBins); mHistogramCounts = std::move(histogramCounts); return OK; return OK; } } Loading Loading @@ -166,6 +187,21 @@ status_t CameraStreamStats::writeToParcel(android::Parcel* parcel) const { return err; return err; } } if ((err = parcel->writeInt32(mHistogramType)) != OK) { ALOGE("%s: Failed to write histogram type", __FUNCTION__); return err; } if ((err = parcel->writeFloatVector(mHistogramBins)) != OK) { ALOGE("%s: Failed to write histogram bins!", __FUNCTION__); return err; } if ((err = parcel->writeInt64Vector(mHistogramCounts)) != OK) { ALOGE("%s: Failed to write histogram counts!", __FUNCTION__); return err; } return OK; return OK; } } Loading
camera/include/camera/CameraSessionStats.h +18 −2 Original line number Original line Diff line number Diff line Loading @@ -27,6 +27,11 @@ namespace hardware { */ */ class CameraStreamStats : public android::Parcelable { class CameraStreamStats : public android::Parcelable { public: public: enum HistogramType { HISTOGRAM_TYPE_UNKNOWN = 0, HISTOGRAM_TYPE_CAPTURE_LATENCY = 1, }; int mWidth; int mWidth; int mHeight; int mHeight; int mFormat; int mFormat; Loading @@ -45,15 +50,26 @@ public: int mMaxHalBuffers; int mMaxHalBuffers; int mMaxAppBuffers; int mMaxAppBuffers; // Histogram type. So far only capture latency histogram is supported. int mHistogramType; // The bounary values separating adjacent histogram bins. // A vector of {h1, h2, h3} represents bins of [0, h1), [h1, h2), [h2, h3), // and [h3, infinity) std::vector<float> mHistogramBins; // The counts for all histogram bins. // size(mHistogramBins) + 1 = size(mHistogramCounts) std::vector<int64_t> mHistogramCounts; CameraStreamStats() : CameraStreamStats() : mWidth(0), mHeight(0), mFormat(0), mDataSpace(0), mUsage(0), mWidth(0), mHeight(0), mFormat(0), mDataSpace(0), mUsage(0), mRequestCount(0), mErrorCount(0), mStartLatencyMs(0), mRequestCount(0), mErrorCount(0), mStartLatencyMs(0), mMaxHalBuffers(0), mMaxAppBuffers(0) {} mMaxHalBuffers(0), mMaxAppBuffers(0), mHistogramType(HISTOGRAM_TYPE_UNKNOWN) {} CameraStreamStats(int width, int height, int format, int dataSpace, int64_t usage, CameraStreamStats(int width, int height, int format, int dataSpace, int64_t usage, int maxHalBuffers, int maxAppBuffers) int maxHalBuffers, int maxAppBuffers) : mWidth(width), mHeight(height), mFormat(format), mDataSpace(dataSpace), : mWidth(width), mHeight(height), mFormat(format), mDataSpace(dataSpace), mUsage(usage), mRequestCount(0), mErrorCount(0), mStartLatencyMs(0), mUsage(usage), mRequestCount(0), mErrorCount(0), mStartLatencyMs(0), mMaxHalBuffers(maxHalBuffers), mMaxAppBuffers(maxAppBuffers) {} mMaxHalBuffers(maxHalBuffers), mMaxAppBuffers(maxAppBuffers), mHistogramType(HISTOGRAM_TYPE_UNKNOWN) {} virtual status_t readFromParcel(const android::Parcel* parcel) override; virtual status_t readFromParcel(const android::Parcel* parcel) override; virtual status_t writeToParcel(android::Parcel* parcel) const override; virtual status_t writeToParcel(android::Parcel* parcel) const override; Loading
services/camera/libcameraservice/device3/Camera3Device.cpp +8 −0 Original line number Original line Diff line number Diff line Loading @@ -2161,6 +2161,14 @@ void Camera3Device::notifyStatus(bool idle) { streamStats[i].mRequestCount = stats->second.mRequestedFrameCount; streamStats[i].mRequestCount = stats->second.mRequestedFrameCount; streamStats[i].mErrorCount = stats->second.mDroppedFrameCount; streamStats[i].mErrorCount = stats->second.mDroppedFrameCount; streamStats[i].mStartLatencyMs = stats->second.mStartLatencyMs; streamStats[i].mStartLatencyMs = stats->second.mStartLatencyMs; streamStats[i].mHistogramType = hardware::CameraStreamStats::HISTOGRAM_TYPE_CAPTURE_LATENCY; streamStats[i].mHistogramBins.assign( stats->second.mCaptureLatencyBins.begin(), stats->second.mCaptureLatencyBins.end()); streamStats[i].mHistogramCounts.assign( stats->second.mCaptureLatencyHistogram.begin(), stats->second.mCaptureLatencyHistogram.end()); } } } } listener->notifyIdle(requestCount, resultErrorCount, deviceError, streamStats); listener->notifyIdle(requestCount, resultErrorCount, deviceError, streamStats); Loading
services/camera/libcameraservice/utils/SessionStatsBuilder.cpp +51 −19 Original line number Original line Diff line number Diff line Loading @@ -18,12 +18,21 @@ #define ATRACE_TAG ATRACE_TAG_CAMERA #define ATRACE_TAG ATRACE_TAG_CAMERA //#define LOG_NDEBUG 0 //#define LOG_NDEBUG 0 #include <numeric> #include <inttypes.h> #include <utils/Log.h> #include <utils/Log.h> #include "SessionStatsBuilder.h" #include "SessionStatsBuilder.h" namespace android { namespace android { // Bins for capture latency: [0, 100], [100, 200], [200, 300], ... // [1300, 2100], [2100, inf]. // Capture latency is in the unit of millisecond. const std::array<int32_t, StreamStats::LATENCY_BIN_COUNT-1> StreamStats::mCaptureLatencyBins { { 100, 200, 300, 400, 500, 700, 900, 1300, 2100 } }; status_t SessionStatsBuilder::addStream(int id) { status_t SessionStatsBuilder::addStream(int id) { std::lock_guard<std::mutex> l(mLock); std::lock_guard<std::mutex> l(mLock); StreamStats stats; StreamStats stats; Loading Loading @@ -52,10 +61,14 @@ void SessionStatsBuilder::buildAndReset(int64_t* requestCount, mCounterStopped = false; mCounterStopped = false; mDeviceError = false; mDeviceError = false; for (auto& streamStats : mStatsMap) { for (auto& streamStats : mStatsMap) { streamStats.second.mRequestedFrameCount = 0; StreamStats& streamStat = streamStats.second; streamStats.second.mDroppedFrameCount = 0; streamStat.mRequestedFrameCount = 0; streamStats.second.mCounterStopped = false; streamStat.mDroppedFrameCount = 0; streamStats.second.mStartLatencyMs = 0; streamStat.mCounterStopped = false; streamStat.mStartLatencyMs = 0; std::fill(streamStat.mCaptureLatencyHistogram.begin(), streamStat.mCaptureLatencyHistogram.end(), 0); } } } } Loading @@ -66,23 +79,28 @@ void SessionStatsBuilder::startCounter(int id) { void SessionStatsBuilder::stopCounter(int id) { void SessionStatsBuilder::stopCounter(int id) { std::lock_guard<std::mutex> l(mLock); std::lock_guard<std::mutex> l(mLock); mStatsMap[id].mCounterStopped = true; StreamStats& streamStat = mStatsMap[id]; streamStat.mCounterStopped = true; } } void SessionStatsBuilder::incCounter(int id, bool dropped, int32_t captureLatencyMs) { void SessionStatsBuilder::incCounter(int id, bool dropped, int32_t captureLatencyMs) { std::lock_guard<std::mutex> l(mLock); std::lock_guard<std::mutex> l(mLock); auto it = mStatsMap.find(id); auto it = mStatsMap.find(id); if (it != mStatsMap.end()) { if (it == mStatsMap.end()) return; if (!it->second.mCounterStopped) { it->second.mRequestedFrameCount++; StreamStats& streamStat = it->second; if (streamStat.mCounterStopped) return; streamStat.mRequestedFrameCount++; if (dropped) { if (dropped) { it->second.mDroppedFrameCount++; streamStat.mDroppedFrameCount++; } else if (it->second.mRequestedFrameCount == 1) { } else if (streamStat.mRequestedFrameCount - streamStat.mDroppedFrameCount == 1) { // The capture latency for the first request. // The capture latency for the first request. it->second.mStartLatencyMs = captureLatencyMs; streamStat.mStartLatencyMs = captureLatencyMs; } } } } streamStat.updateLatencyHistogram(captureLatencyMs); } } void SessionStatsBuilder::stopCounter() { void SessionStatsBuilder::stopCounter() { Loading @@ -95,15 +113,29 @@ void SessionStatsBuilder::stopCounter() { void SessionStatsBuilder::incResultCounter(bool dropped) { void SessionStatsBuilder::incResultCounter(bool dropped) { std::lock_guard<std::mutex> l(mLock); std::lock_guard<std::mutex> l(mLock); if (!mCounterStopped) { if (mCounterStopped) return; mRequestCount++; mRequestCount++; if (dropped) mErrorResultCount++; if (dropped) mErrorResultCount++; } } } void SessionStatsBuilder::onDeviceError() { void SessionStatsBuilder::onDeviceError() { std::lock_guard<std::mutex> l(mLock); std::lock_guard<std::mutex> l(mLock); mDeviceError = true; mDeviceError = true; } } void StreamStats::updateLatencyHistogram(int32_t latencyMs) { size_t i; for (i = 0; i < mCaptureLatencyBins.size(); i++) { if (latencyMs < mCaptureLatencyBins[i]) { mCaptureLatencyHistogram[i] ++; break; } } if (i == mCaptureLatencyBins.size()) { mCaptureLatencyHistogram[i]++; } } }; // namespace android }; // namespace android
services/camera/libcameraservice/utils/SessionStatsBuilder.h +18 −2 Original line number Original line Diff line number Diff line Loading @@ -19,22 +19,38 @@ #include <utils/Errors.h> #include <utils/Errors.h> #include <mutex> #include <array> #include <map> #include <map> #include <mutex> namespace android { namespace android { // Helper class to build stream stats // Helper class to build stream stats struct StreamStats { struct StreamStats { // Fields for buffer drop int64_t mRequestedFrameCount; int64_t mRequestedFrameCount; int64_t mDroppedFrameCount; int64_t mDroppedFrameCount; bool mCounterStopped; bool mCounterStopped; // Fields for stream startup latency int32_t mStartLatencyMs; int32_t mStartLatencyMs; // Fields for capture latency measurement const static int LATENCY_BIN_COUNT = 10; // Boundary values separating between adjacent bins, excluding 0 and // infinity. const static std::array<int32_t, LATENCY_BIN_COUNT-1> mCaptureLatencyBins; // Counter values for all histogram bins. One more entry than mCaptureLatencyBins. std::array<int64_t, LATENCY_BIN_COUNT> mCaptureLatencyHistogram; StreamStats() : mRequestedFrameCount(0), StreamStats() : mRequestedFrameCount(0), mDroppedFrameCount(0), mDroppedFrameCount(0), mCounterStopped(false), mCounterStopped(false), mStartLatencyMs(0) {} mStartLatencyMs(0), mCaptureLatencyHistogram{} {} void updateLatencyHistogram(int32_t latencyMs); }; }; // Helper class to build session stats // Helper class to build session stats Loading