206 lines
5.3 KiB
C++
206 lines
5.3 KiB
C++
/*
|
|
* Copyright 2020 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "CameraUsageStats.h"
|
|
|
|
#include <android-base/logging.h>
|
|
#include <statslog_evs.h>
|
|
|
|
namespace {
|
|
|
|
// Length of frame roundtrip history
|
|
const int kMaxHistoryLength = 100;
|
|
|
|
}
|
|
|
|
namespace android {
|
|
namespace automotive {
|
|
namespace evs {
|
|
namespace V1_1 {
|
|
namespace implementation {
|
|
|
|
using ::android::base::Result;
|
|
using ::android::base::StringAppendF;
|
|
using ::android::hardware::hidl_vec;
|
|
using ::android::hardware::automotive::evs::V1_1::BufferDesc;
|
|
|
|
void CameraUsageStats::updateFrameStatsOnArrival(
|
|
const hidl_vec<BufferDesc>& bufs) {
|
|
const auto now = android::uptimeMillis();
|
|
for (const auto& b : bufs) {
|
|
auto it = mBufferHistory.find(b.bufferId);
|
|
if (it == mBufferHistory.end()) {
|
|
mBufferHistory.emplace(b.bufferId, now);
|
|
} else {
|
|
it->second.timestamp = now;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CameraUsageStats::updateFrameStatsOnReturn(
|
|
const hidl_vec<BufferDesc>& bufs) {
|
|
const auto now = android::uptimeMillis();
|
|
for (auto& b : bufs) {
|
|
auto it = mBufferHistory.find(b.bufferId);
|
|
if (it == mBufferHistory.end()) {
|
|
LOG(WARNING) << "Buffer " << b.bufferId << " from "
|
|
<< b.deviceId << " is unknown.";
|
|
} else {
|
|
const auto roundtrip = now - it->second.timestamp;
|
|
it->second.history.emplace(roundtrip);
|
|
it->second.sum += roundtrip;
|
|
if (it->second.history.size() > kMaxHistoryLength) {
|
|
it->second.sum -= it->second.history.front();
|
|
it->second.history.pop();
|
|
}
|
|
|
|
if (roundtrip > it->second.peak) {
|
|
it->second.peak = roundtrip;
|
|
}
|
|
|
|
if (mStats.framesFirstRoundtripLatency == 0) {
|
|
mStats.framesFirstRoundtripLatency = roundtrip;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CameraUsageStats::framesReceived(int n) {
|
|
AutoMutex lock(mMutex);
|
|
mStats.framesReceived += n;
|
|
}
|
|
|
|
|
|
void CameraUsageStats::framesReceived(
|
|
const hidl_vec<BufferDesc>& bufs) {
|
|
AutoMutex lock(mMutex);
|
|
mStats.framesReceived += bufs.size();
|
|
|
|
updateFrameStatsOnArrival(bufs);
|
|
}
|
|
|
|
|
|
void CameraUsageStats::framesReturned(int n) {
|
|
AutoMutex lock(mMutex);
|
|
mStats.framesReturned += n;
|
|
}
|
|
|
|
|
|
void CameraUsageStats::framesReturned(
|
|
const hidl_vec<BufferDesc>& bufs) {
|
|
AutoMutex lock(mMutex);
|
|
mStats.framesReturned += bufs.size();
|
|
|
|
updateFrameStatsOnReturn(bufs);
|
|
}
|
|
|
|
|
|
void CameraUsageStats::framesIgnored(int n) {
|
|
AutoMutex lock(mMutex);
|
|
mStats.framesIgnored += n;
|
|
}
|
|
|
|
|
|
void CameraUsageStats::framesSkippedToSync(int n) {
|
|
AutoMutex lock(mMutex);
|
|
mStats.framesSkippedToSync += n;
|
|
}
|
|
|
|
|
|
void CameraUsageStats::eventsReceived() {
|
|
AutoMutex lock(mMutex);
|
|
++mStats.erroneousEventsCount;
|
|
}
|
|
|
|
|
|
void CameraUsageStats::updateNumClients(size_t n) {
|
|
AutoMutex lock(mMutex);
|
|
if (n > mStats.peakClientsCount) {
|
|
mStats.peakClientsCount = n;
|
|
}
|
|
}
|
|
|
|
|
|
int64_t CameraUsageStats::getTimeCreated() const {
|
|
AutoMutex lock(mMutex);
|
|
return mTimeCreatedMs;
|
|
}
|
|
|
|
|
|
int64_t CameraUsageStats::getFramesReceived() const {
|
|
AutoMutex lock(mMutex);
|
|
return mStats.framesReceived;
|
|
}
|
|
|
|
|
|
int64_t CameraUsageStats::getFramesReturned() const {
|
|
AutoMutex lock(mMutex);
|
|
return mStats.framesReturned;
|
|
}
|
|
|
|
|
|
CameraUsageStatsRecord CameraUsageStats::snapshot() {
|
|
AutoMutex lock(mMutex);
|
|
|
|
int32_t sum = 0;
|
|
int32_t peak = 0;
|
|
int32_t len = 0;
|
|
for (auto& [id, rec] : mBufferHistory) {
|
|
sum += rec.sum;
|
|
len += rec.history.size();
|
|
if (peak < rec.peak) {
|
|
peak = rec.peak;
|
|
}
|
|
}
|
|
|
|
mStats.framesPeakRoundtripLatency = peak;
|
|
mStats.framesAvgRoundtripLatency = (double)sum / len;
|
|
return mStats;
|
|
}
|
|
|
|
|
|
Result<void> CameraUsageStats::writeStats() const {
|
|
AutoMutex lock(mMutex);
|
|
|
|
// EvsUsageStatsReported atom is defined in
|
|
// frameworks/base/cmds/statsd/src/atoms.proto
|
|
const auto duration = android::uptimeMillis() - mTimeCreatedMs;
|
|
auto result =
|
|
stats::stats_write(stats::EVS_USAGE_STATS_REPORTED, mId, mStats.peakClientsCount,
|
|
mStats.erroneousEventsCount, mStats.framesFirstRoundtripLatency,
|
|
mStats.framesAvgRoundtripLatency, mStats.framesPeakRoundtripLatency,
|
|
mStats.framesReceived, mStats.framesIgnored,
|
|
mStats.framesSkippedToSync, duration);
|
|
if (result < 0) {
|
|
LOG(WARNING) << "Failed to report usage stats";
|
|
}
|
|
return {};
|
|
}
|
|
|
|
|
|
std::string CameraUsageStats::toString(const CameraUsageStatsRecord& record, const char* indent) {
|
|
return record.toString(indent);
|
|
}
|
|
|
|
} // namespace implementation
|
|
} // namespace V1_1
|
|
} // namespace evs
|
|
} // namespace automotive
|
|
} // namespace android
|
|
|