1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef CPP_EVS_MANAGER_AIDL_STATS_INCLUDE_CAMERAUSAGESTATS_H 18 #define CPP_EVS_MANAGER_AIDL_STATS_INCLUDE_CAMERAUSAGESTATS_H 19 20 #include <aidl/android/hardware/automotive/evs/BufferDesc.h> 21 #include <android-base/stringprintf.h> 22 #include <utils/Mutex.h> 23 #include <utils/RefBase.h> 24 #include <utils/SystemClock.h> 25 26 #include <cinttypes> 27 #include <queue> 28 #include <unordered_map> 29 30 namespace aidl::android::automotive::evs::implementation { 31 32 namespace aidlevs = ::aidl::android::hardware::automotive::evs; 33 34 struct CameraUsageStatsRecord { 35 public: 36 // Time a snapshot is generated 37 nsecs_t timestamp; 38 39 // Total number of frames received 40 int64_t framesReceived; 41 42 // Total number of frames returned to EVS HAL 43 int64_t framesReturned; 44 45 // Number of frames ignored because no clients are listening 46 int64_t framesIgnored; 47 48 // Number of frames skipped to synchronize camera frames 49 int64_t framesSkippedToSync; 50 51 // Roundtrip latency of the very first frame after the stream started. 52 int64_t framesFirstRoundtripLatency; 53 54 // Peak mFrame roundtrip latency 55 int64_t framesPeakRoundtripLatency; 56 57 // Average mFrame roundtrip latency 58 double framesAvgRoundtripLatency; 59 60 // Number of the erroneous streaming events 61 int32_t erroneousEventsCount; 62 63 // Peak number of active clients 64 int32_t peakClientsCount; 65 66 // Calculates a delta between two records 67 CameraUsageStatsRecord& operator-=(const CameraUsageStatsRecord& rhs) { 68 // Only calculates differences in the frame statistics 69 framesReceived = framesReceived - rhs.framesReceived; 70 framesReturned = framesReturned - rhs.framesReturned; 71 framesIgnored = framesIgnored - rhs.framesIgnored; 72 framesSkippedToSync = framesSkippedToSync - rhs.framesSkippedToSync; 73 erroneousEventsCount = erroneousEventsCount - rhs.erroneousEventsCount; 74 75 return *this; 76 } 77 78 friend CameraUsageStatsRecord operator-(CameraUsageStatsRecord lhs, 79 const CameraUsageStatsRecord& rhs) noexcept { 80 lhs -= rhs; // reuse compound assignment 81 return lhs; 82 } 83 84 // Constructs a string that shows collected statistics 85 std::string toString(const char* indent = "") const { 86 std::string buffer; 87 ::android::base::StringAppendF(&buffer, 88 "%sTime Collected: @%" PRId64 "ms\n" 89 "%sFrames Received: %" PRId64 "\n" 90 "%sFrames Returned: %" PRId64 "\n" 91 "%sFrames Ignored : %" PRId64 "\n" 92 "%sFrames Skipped To Sync: %" PRId64 "\n" 93 "%sFrames First Roundtrip: %" PRId64 "\n" 94 "%sFrames Peak Roundtrip: %" PRId64 "\n" 95 "%sFrames Average Roundtrip: %f\n" 96 "%sPeak Number of Clients: %" PRId32 "\n\n", 97 indent, ns2ms(timestamp), indent, framesReceived, indent, 98 framesReturned, indent, framesIgnored, indent, 99 framesSkippedToSync, indent, framesFirstRoundtripLatency, 100 indent, framesPeakRoundtripLatency, indent, 101 framesAvgRoundtripLatency, indent, peakClientsCount); 102 103 return buffer; 104 } 105 }; 106 107 struct BufferRecord { BufferRecordBufferRecord108 BufferRecord(int64_t timestamp) : timestamp(timestamp), sum(0), peak(0) {} 109 110 // Recent processing time 111 std::queue<int32_t> history; 112 113 // Timestamp on the buffer arrival 114 int64_t timestamp; 115 116 // Sum of processing times 117 int64_t sum; 118 119 // Peak processing time 120 int64_t peak; 121 }; 122 123 class CameraUsageStats : public ::android::RefBase { 124 public: CameraUsageStats(int32_t id)125 CameraUsageStats(int32_t id) : 126 mMutex(::android::Mutex()), 127 mId(id), 128 mTimeCreatedMs(::android::uptimeMillis()), 129 mStats({}) {} 130 131 void framesReceived(int32_t n = 1) EXCLUDES(mMutex); 132 void framesReturned(int32_t n = 1) EXCLUDES(mMutex); 133 void framesReceived(const std::vector<aidlevs::BufferDesc>& bufs) EXCLUDES(mMutex); 134 void framesReturned(const std::vector<aidlevs::BufferDesc>& bufs) EXCLUDES(mMutex); 135 void framesIgnored(int32_t n = 1) EXCLUDES(mMutex); 136 void framesSkippedToSync(int32_t n = 1) EXCLUDES(mMutex); 137 void eventsReceived() EXCLUDES(mMutex); 138 int64_t getTimeCreated() const EXCLUDES(mMutex); 139 int64_t getFramesReceived() const EXCLUDES(mMutex); 140 int64_t getFramesReturned() const EXCLUDES(mMutex); 141 void updateNumClients(size_t n) EXCLUDES(mMutex); 142 void updateFrameStatsOnArrivalLocked(const std::vector<aidlevs::BufferDesc>& bufs) 143 REQUIRES(mMutex); 144 void updateFrameStatsOnReturnLocked(const std::vector<aidlevs::BufferDesc>& bufs) 145 REQUIRES(mMutex); 146 147 // Returns the statistics collected so far 148 CameraUsageStatsRecord snapshot() EXCLUDES(mMutex); 149 150 // Reports the usage statistics 151 void writeStats() const EXCLUDES(mMutex); 152 153 // Generates a string with current statistics 154 static std::string toString(const CameraUsageStatsRecord& record, const char* indent = ""); 155 156 private: 157 // Mutex to protect a collection record 158 mutable ::android::Mutex mMutex; 159 160 // Unique identifier 161 int32_t mId; 162 163 // Time this object was created 164 int64_t mTimeCreatedMs; 165 166 // Usage statistics to collect 167 CameraUsageStatsRecord mStats GUARDED_BY(mMutex); 168 169 // Frame buffer histories 170 std::unordered_map<int, BufferRecord> mBufferHistory GUARDED_BY(mMutex); 171 }; 172 173 } // namespace aidl::android::automotive::evs::implementation 174 175 #endif // CPP_EVS_MANAGER_AIDL_STATS_INCLUDE_CAMERAUSAGESTATS_H 176