| /* |
| * 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. |
| */ |
| |
| #ifndef ANDROID_AUTOMOTIVE_EVS_V1_1_CAMERAUSAGESTATS_H |
| #define ANDROID_AUTOMOTIVE_EVS_V1_1_CAMERAUSAGESTATS_H |
| |
| #include <android-base/result.h> |
| #include <android-base/stringprintf.h> |
| #include <android/hardware/automotive/evs/1.1/types.h> |
| #include <utils/Mutex.h> |
| #include <utils/RefBase.h> |
| #include <utils/SystemClock.h> |
| |
| #include <inttypes.h> |
| |
| #include <queue> |
| #include <unordered_map> |
| |
| namespace android { |
| namespace automotive { |
| namespace evs { |
| namespace V1_1 { |
| namespace implementation { |
| |
| struct CameraUsageStatsRecord { |
| public: |
| // Time a snapshot is generated |
| nsecs_t timestamp; |
| |
| // Total number of frames received |
| int64_t framesReceived; |
| |
| // Total number of frames returned to EVS HAL |
| int64_t framesReturned; |
| |
| // Number of frames ignored because no clients are listening |
| int64_t framesIgnored; |
| |
| // Number of frames skipped to synchronize camera frames |
| int64_t framesSkippedToSync; |
| |
| // Roundtrip latency of the very first frame after the stream started. |
| int64_t framesFirstRoundtripLatency; |
| |
| // Peak mFrame roundtrip latency |
| int64_t framesPeakRoundtripLatency; |
| |
| // Average mFrame roundtrip latency |
| double framesAvgRoundtripLatency; |
| |
| // Number of the erroneous streaming events |
| int32_t erroneousEventsCount; |
| |
| // Peak number of active clients |
| int32_t peakClientsCount; |
| |
| // Calculates a delta between two records |
| CameraUsageStatsRecord& operator-=(const CameraUsageStatsRecord& rhs) { |
| // Only calculates differences in the frame statistics |
| framesReceived = framesReceived - rhs.framesReceived; |
| framesReturned = framesReturned - rhs.framesReturned; |
| framesIgnored = framesIgnored - rhs.framesIgnored; |
| framesSkippedToSync = framesSkippedToSync - rhs.framesSkippedToSync; |
| erroneousEventsCount = erroneousEventsCount - rhs.erroneousEventsCount; |
| |
| return *this; |
| } |
| |
| friend CameraUsageStatsRecord operator-(CameraUsageStatsRecord lhs, |
| const CameraUsageStatsRecord& rhs) noexcept { |
| lhs -= rhs; // reuse compound assignment |
| return lhs; |
| } |
| |
| // Constructs a string that shows collected statistics |
| std::string toString(const char* indent = "") const { |
| std::string buffer; |
| android::base::StringAppendF(&buffer, |
| "%sTime Collected: @%" PRId64 "ms\n" |
| "%sFrames Received: %" PRId64 "\n" |
| "%sFrames Returned: %" PRId64 "\n" |
| "%sFrames Ignored : %" PRId64 "\n" |
| "%sFrames Skipped To Sync: %" PRId64 "\n" |
| "%sFrames First Roundtrip: %" PRId64 "\n" |
| "%sFrames Peak Roundtrip: %" PRId64 "\n" |
| "%sFrames Average Roundtrip: %f\n" |
| "%sPeak Number of Clients: %" PRId32 "\n\n", |
| indent, ns2ms(timestamp), indent, framesReceived, indent, |
| framesReturned, indent, framesIgnored, indent, |
| framesSkippedToSync, indent, framesFirstRoundtripLatency, |
| indent, framesPeakRoundtripLatency, indent, |
| framesAvgRoundtripLatency, indent, peakClientsCount); |
| |
| return buffer; |
| } |
| }; |
| |
| struct BufferRecord { |
| BufferRecord(int64_t timestamp) : timestamp(timestamp), sum(0), peak(0) {} |
| |
| // Recent processing time |
| std::queue<int32_t> history; |
| |
| // Timestamp on the buffer arrival |
| int64_t timestamp; |
| |
| // Sum of processing times |
| int64_t sum; |
| |
| // Peak processing time |
| int64_t peak; |
| }; |
| |
| class CameraUsageStats : public RefBase { |
| public: |
| CameraUsageStats(int32_t id) : |
| mMutex(Mutex()), mId(id), mTimeCreatedMs(android::uptimeMillis()), mStats({}) {} |
| |
| private: |
| // Mutex to protect a collection record |
| mutable Mutex mMutex; |
| |
| // Unique identifier |
| int32_t mId; |
| |
| // Time this object was created |
| int64_t mTimeCreatedMs; |
| |
| // Usage statistics to collect |
| CameraUsageStatsRecord mStats GUARDED_BY(mMutex); |
| |
| // Frame buffer histories |
| std::unordered_map<int, BufferRecord> mBufferHistory GUARDED_BY(mMutex); |
| |
| public: |
| void framesReceived(int n = 1) EXCLUDES(mMutex); |
| void framesReturned(int n = 1) EXCLUDES(mMutex); |
| void framesReceived( |
| const hardware::hidl_vec<::android::hardware::automotive::evs::V1_1::BufferDesc>& bufs) |
| EXCLUDES(mMutex); |
| void framesReturned( |
| const hardware::hidl_vec<::android::hardware::automotive::evs::V1_1::BufferDesc>& bufs) |
| EXCLUDES(mMutex); |
| void framesIgnored(int n = 1) EXCLUDES(mMutex); |
| void framesSkippedToSync(int n = 1) EXCLUDES(mMutex); |
| void eventsReceived() EXCLUDES(mMutex); |
| int64_t getTimeCreated() const EXCLUDES(mMutex); |
| int64_t getFramesReceived() const EXCLUDES(mMutex); |
| int64_t getFramesReturned() const EXCLUDES(mMutex); |
| void updateNumClients(size_t n) EXCLUDES(mMutex); |
| void updateFrameStatsOnArrival( |
| const hardware::hidl_vec<::android::hardware::automotive::evs::V1_1::BufferDesc>& bufs) |
| REQUIRES(mMutex); |
| void updateFrameStatsOnReturn( |
| const hardware::hidl_vec<::android::hardware::automotive::evs::V1_1::BufferDesc>& bufs) |
| REQUIRES(mMutex); |
| |
| // Returns the statistics collected so far |
| CameraUsageStatsRecord snapshot() EXCLUDES(mMutex); |
| |
| // Reports the usage statistics |
| android::base::Result<void> writeStats() const EXCLUDES(mMutex); |
| |
| // Generates a string with current statistics |
| static std::string toString(const CameraUsageStatsRecord& record, const char* indent = ""); |
| }; |
| |
| } // namespace implementation |
| } // namespace V1_1 |
| } // namespace evs |
| } // namespace automotive |
| } // namespace android |
| |
| #endif // ANDROID_AUTOMOTIVE_EVS_V1_1_CAMERAUSAGESTATS_H |