1 /* 2 * Copyright (C) 2020 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 ANDROID_SERVICE_UTILS_SESSION_STATS_BUILDER_H 18 #define ANDROID_SERVICE_UTILS_SESSION_STATS_BUILDER_H 19 20 #include <utils/Errors.h> 21 22 #include <array> 23 #include <map> 24 #include <mutex> 25 #include <unordered_map> 26 #include <utility> 27 28 namespace android { 29 30 // Helper class to build stream stats 31 struct StreamStats { 32 // Fields for buffer drop 33 int64_t mRequestedFrameCount; 34 int64_t mDroppedFrameCount; 35 bool mCounterStopped; 36 37 // Fields for stream startup latency 38 int32_t mStartLatencyMs; 39 40 // Fields for capture latency measurement 41 const static int LATENCY_BIN_COUNT = 10; 42 // Boundary values separating between adjacent bins, excluding 0 and 43 // infinity. 44 const static std::array<int32_t, LATENCY_BIN_COUNT-1> mCaptureLatencyBins; 45 // Counter values for all histogram bins. One more entry than mCaptureLatencyBins. 46 std::array<int64_t, LATENCY_BIN_COUNT> mCaptureLatencyHistogram; 47 StreamStatsStreamStats48 StreamStats() : mRequestedFrameCount(0), 49 mDroppedFrameCount(0), 50 mCounterStopped(false), 51 mStartLatencyMs(0), 52 mCaptureLatencyHistogram{} 53 {} 54 55 void updateLatencyHistogram(int32_t latencyMs); 56 }; 57 58 // Helper class to build session stats 59 class SessionStatsBuilder { 60 public: 61 62 status_t addStream(int streamId); 63 status_t removeStream(int streamId); 64 65 // Return the session statistics and reset the internal states. 66 void buildAndReset(/*out*/int64_t* requestCount, 67 /*out*/int64_t* errorResultCount, 68 /*out*/bool* deviceError, 69 /*out*/std::pair<int32_t, int32_t>* mostRequestedFpsRange, 70 /*out*/std::map<int, StreamStats>* statsMap); 71 72 // Stream specific counter 73 void startCounter(int streamId); 74 void stopCounter(int streamId); 75 void incCounter(int streamId, bool dropped, int32_t captureLatencyMs); 76 77 // Session specific counter 78 void stopCounter(); 79 void incResultCounter(bool dropped); 80 void onDeviceError(); 81 82 // Session specific statistics 83 84 // Limit on size of FPS range histogram 85 static const size_t FPS_HISTOGRAM_MAX_SIZE = 10; 86 87 void incFpsRequestedCount(int32_t minFps, int32_t maxFps, int64_t frameNumber); 88 SessionStatsBuilder()89 SessionStatsBuilder() : mRequestCount(0), mErrorResultCount(0), 90 mCounterStopped(false), mDeviceError(false) {} 91 private: 92 std::mutex mLock; 93 int64_t mRequestCount; 94 int64_t mErrorResultCount; 95 bool mCounterStopped; 96 bool mDeviceError; 97 std::string mUserTag; 98 99 // Histogram of frame counts of requested target FPS ranges 100 // (min_fps << 32 | max_fps) -> (# of frames with this fps, last seen framenumber) 101 std::unordered_map<uint64_t, std::pair<int64_t, int64_t>> mRequestedFpsRangeHistogram; 102 103 // Map from stream id to stream statistics 104 std::map<int, StreamStats> mStatsMap; 105 }; 106 107 }; // namespace android 108 109 #endif // ANDROID_SERVICE_UTILS_SESSION_STATS_BUILDER_H 110