• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define LOG_TAG "CameraSessionStatsBuilder"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20 
21 #include <numeric>
22 
23 #include <inttypes.h>
24 #include <utils/Log.h>
25 
26 #include "SessionStatsBuilder.h"
27 
28 namespace android {
29 
30 // Bins for capture latency: [0, 100], [100, 200], [200, 300], ...
31 // [1300, 2100], [2100, inf].
32 // Capture latency is in the unit of millisecond.
33 const std::array<int32_t, StreamStats::LATENCY_BIN_COUNT-1> StreamStats::mCaptureLatencyBins {
34         { 100, 200, 300, 400, 500, 700, 900, 1300, 2100 } };
35 
addStream(int id)36 status_t SessionStatsBuilder::addStream(int id) {
37     std::lock_guard<std::mutex> l(mLock);
38     StreamStats stats;
39     mStatsMap.emplace(id, stats);
40     return OK;
41 }
42 
removeStream(int id)43 status_t SessionStatsBuilder::removeStream(int id) {
44     std::lock_guard<std::mutex> l(mLock);
45     mStatsMap.erase(id);
46     return OK;
47 }
48 
buildAndReset(int64_t * requestCount,int64_t * errorResultCount,bool * deviceError,std::map<int,StreamStats> * statsMap)49 void SessionStatsBuilder::buildAndReset(int64_t* requestCount,
50         int64_t* errorResultCount, bool* deviceError,
51         std::map<int, StreamStats> *statsMap) {
52     std::lock_guard<std::mutex> l(mLock);
53     *requestCount = mRequestCount;
54     *errorResultCount = mErrorResultCount;
55     *deviceError = mDeviceError;
56     *statsMap = mStatsMap;
57 
58     // Reset internal states
59     mRequestCount = 0;
60     mErrorResultCount = 0;
61     mCounterStopped = false;
62     mDeviceError = false;
63     for (auto& streamStats : mStatsMap) {
64         StreamStats& streamStat = streamStats.second;
65         streamStat.mRequestedFrameCount = 0;
66         streamStat.mDroppedFrameCount = 0;
67         streamStat.mCounterStopped = false;
68         streamStat.mStartLatencyMs = 0;
69 
70         std::fill(streamStat.mCaptureLatencyHistogram.begin(),
71                 streamStat.mCaptureLatencyHistogram.end(), 0);
72     }
73 }
74 
startCounter(int id)75 void SessionStatsBuilder::startCounter(int id) {
76     std::lock_guard<std::mutex> l(mLock);
77     mStatsMap[id].mCounterStopped = false;
78 }
79 
stopCounter(int id)80 void SessionStatsBuilder::stopCounter(int id) {
81     std::lock_guard<std::mutex> l(mLock);
82     StreamStats& streamStat = mStatsMap[id];
83     streamStat.mCounterStopped = true;
84 }
85 
incCounter(int id,bool dropped,int32_t captureLatencyMs)86 void SessionStatsBuilder::incCounter(int id, bool dropped, int32_t captureLatencyMs) {
87     std::lock_guard<std::mutex> l(mLock);
88 
89     auto it = mStatsMap.find(id);
90     if (it == mStatsMap.end()) return;
91 
92     StreamStats& streamStat = it->second;
93     if (streamStat.mCounterStopped) return;
94 
95     streamStat.mRequestedFrameCount++;
96     if (dropped) {
97         streamStat.mDroppedFrameCount++;
98     } else if (streamStat.mRequestedFrameCount - streamStat.mDroppedFrameCount == 1) {
99         // The capture latency for the first request.
100         streamStat.mStartLatencyMs = captureLatencyMs;
101     }
102 
103     streamStat.updateLatencyHistogram(captureLatencyMs);
104 }
105 
stopCounter()106 void SessionStatsBuilder::stopCounter() {
107     std::lock_guard<std::mutex> l(mLock);
108     mCounterStopped = true;
109     for (auto& streamStats : mStatsMap) {
110         streamStats.second.mCounterStopped = true;
111     }
112 }
113 
incResultCounter(bool dropped)114 void SessionStatsBuilder::incResultCounter(bool dropped) {
115     std::lock_guard<std::mutex> l(mLock);
116     if (mCounterStopped) return;
117 
118     mRequestCount++;
119     if (dropped) mErrorResultCount++;
120 }
121 
onDeviceError()122 void SessionStatsBuilder::onDeviceError() {
123     std::lock_guard<std::mutex> l(mLock);
124     mDeviceError = true;
125 }
126 
updateLatencyHistogram(int32_t latencyMs)127 void StreamStats::updateLatencyHistogram(int32_t latencyMs) {
128     size_t i;
129     for (i = 0; i < mCaptureLatencyBins.size(); i++) {
130         if (latencyMs < mCaptureLatencyBins[i]) {
131             mCaptureLatencyHistogram[i] ++;
132             break;
133         }
134     }
135 
136     if (i == mCaptureLatencyBins.size()) {
137         mCaptureLatencyHistogram[i]++;
138     }
139 }
140 
141 }; // namespace android
142