Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9bf2a191 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Camera: Collect capture latency histograms"

parents 94365445 db8f2785
Loading
Loading
Loading
Loading
+36 −0
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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;
}
}
@@ -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;
}
}


+18 −2
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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;
+8 −0
Original line number Original line Diff line number Diff line
@@ -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);
+51 −19
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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);
    }
    }
}
}


@@ -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() {
@@ -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
+18 −2
Original line number Original line Diff line number Diff line
@@ -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