blob: f8cdb80ab0e9f75ce93e39c6f2d33ccd0b965d35 [file] [log] [blame]
Girish1f002cf2023-02-17 00:36:29 +00001/*
2**
3** Copyright 2023, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18//#define LOG_NDEBUG 0
19#define LOG_TAG "ResourceManagerMetrics"
20#include <utils/Log.h>
21#include <mediautils/ProcessInfo.h>
22
23#include <stats_media_metrics.h>
24
25#include "UidObserver.h"
26#include "ResourceManagerMetrics.h"
27
28#include <cmath>
29#include <sstream>
30
31namespace android {
32
33using stats::media_metrics::stats_write;
34using stats::media_metrics::MEDIA_CODEC_STARTED;
35using stats::media_metrics::MEDIA_CODEC_STOPPED;
36// Disabling this for now.
37#ifdef ENABLE_MEDIA_CODEC_CONCURRENT_USAGE_REPORTED
38using stats::media_metrics::MEDIA_CODEC_CONCURRENT_USAGE_REPORTED;
39#endif
40using stats::media_metrics::MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED;
41using stats::media_metrics::MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_SUCCESS;
42using stats::media_metrics::\
43 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_NO_CLIENTS;
44using stats::media_metrics::\
45 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_RECLAIM_RESOURCES;
46
47inline const char* getCodecType(MediaResourceSubType codecType) {
48 switch (codecType) {
49 case MediaResourceSubType::kAudioCodec: return "Audio";
50 case MediaResourceSubType::kVideoCodec: return "Video";
51 case MediaResourceSubType::kImageCodec: return "Image";
52 case MediaResourceSubType::kUnspecifiedSubType:
53 default:
54 return "Unspecified";
55 }
56 return "Unspecified";
57}
58
59static CodecBucket getCodecBucket(bool isHardware,
60 bool isEncoder,
61 MediaResourceSubType codecType) {
62 if (isHardware) {
63 switch (codecType) {
64 case MediaResourceSubType::kAudioCodec:
65 if (isEncoder) return HwAudioEncoder;
66 return HwAudioDecoder;
67 case MediaResourceSubType::kVideoCodec:
68 if (isEncoder) return HwVideoEncoder;
69 return HwVideoDecoder;
70 case MediaResourceSubType::kImageCodec:
71 if (isEncoder) return HwImageEncoder;
72 return HwImageDecoder;
73 case MediaResourceSubType::kUnspecifiedSubType:
74 default:
75 return CodecBucketUnspecified;
76 }
77 } else {
78 switch (codecType) {
79 case MediaResourceSubType::kAudioCodec:
80 if (isEncoder) return SwAudioEncoder;
81 return SwAudioDecoder;
82 case MediaResourceSubType::kVideoCodec:
83 if (isEncoder) return SwVideoEncoder;
84 return SwVideoDecoder;
85 case MediaResourceSubType::kImageCodec:
86 if (isEncoder) return SwImageEncoder;
87 return SwImageDecoder;
88 case MediaResourceSubType::kUnspecifiedSubType:
89 default:
90 return CodecBucketUnspecified;
91 }
92 }
93
94 return CodecBucketUnspecified;
95}
96
97static bool getLogMessage(int hwCount, int swCount, std::stringstream& logMsg) {
98 bool update = false;
99 logMsg.clear();
100
101 if (hwCount > 0) {
102 logMsg << " HW: " << hwCount;
103 update = true;
104 }
105 if (swCount > 0) {
106 logMsg << " SW: " << swCount;
107 update = true;
108 }
109
110 if (update) {
111 logMsg << " ] ";
112 }
113 return update;
114}
115
116ResourceManagerMetrics::ResourceManagerMetrics(const sp<ProcessInfoInterface>& processInfo) {
117 // Create a process termination watcher, with 5seconds of polling frequency.
118 mUidObserver = sp<UidObserver>::make(processInfo,
119 [this] (int32_t pid, uid_t uid) {
120 onProcessTerminated(pid, uid);
121 });
122 mUidObserver->start();
123}
124
125ResourceManagerMetrics::~ResourceManagerMetrics() {
126 mUidObserver->stop();
127}
128
129void ResourceManagerMetrics::addPid(int pid, uid_t uid) {
130 if (uid != 0) {
131 std::scoped_lock lock(mLock);
132 mUidObserver->add(pid, uid);
133 }
134}
135
136void ResourceManagerMetrics::notifyClientCreated(const ClientInfoParcel& clientInfo) {
137 std::scoped_lock lock(mLock);
138 // Update the resource instance count.
139 std::map<std::string, int>::iterator found = mConcurrentResourceCountMap.find(clientInfo.name);
140 if (found == mConcurrentResourceCountMap.end()) {
141 mConcurrentResourceCountMap[clientInfo.name] = 1;
142 } else {
143 found->second++;
144 }
145}
146
147void ResourceManagerMetrics::notifyClientReleased(const ClientInfoParcel& clientInfo) {
148 bool stopCalled = true;
Girishc9637682023-03-23 23:33:32 +0000149 ClientConfigParcel clientConfig;
Girish1f002cf2023-02-17 00:36:29 +0000150 {
151 std::scoped_lock lock(mLock);
Girishc9637682023-03-23 23:33:32 +0000152 ClientConfigMap::iterator found = mClientConfigMap.find(clientInfo.id);
Girish1f002cf2023-02-17 00:36:29 +0000153 if (found != mClientConfigMap.end()) {
154 // Release is called without Stop!
155 stopCalled = false;
Girishc9637682023-03-23 23:33:32 +0000156 clientConfig = found->second;
157 // Update the timestamp for stopping the codec.
158 clientConfig.timeStamp = systemTime(SYSTEM_TIME_MONOTONIC) / 1000LL;
Girish1f002cf2023-02-17 00:36:29 +0000159 }
160 }
161 if (!stopCalled) {
162 // call Stop to update the metrics.
Girishc9637682023-03-23 23:33:32 +0000163 notifyClientStopped(clientConfig);
Girish1f002cf2023-02-17 00:36:29 +0000164 }
165 {
166 std::scoped_lock lock(mLock);
167 // Update the resource instance count also.
168 std::map<std::string, int>::iterator found =
169 mConcurrentResourceCountMap.find(clientInfo.name);
170 if (found != mConcurrentResourceCountMap.end()) {
171 if (found->second > 0) {
172 found->second--;
173 }
174 }
175 }
176}
177
Girishde8eb592023-04-13 18:49:17 +0000178void ResourceManagerMetrics::notifyClientConfigChanged(const ClientConfigParcel& clientConfig) {
179 std::scoped_lock lock(mLock);
180 ClientConfigMap::iterator entry = mClientConfigMap.find(clientConfig.clientInfo.id);
181 if (entry != mClientConfigMap.end() &&
182 (clientConfig.codecType == MediaResourceSubType::kVideoCodec ||
183 clientConfig.codecType == MediaResourceSubType::kImageCodec)) {
184 int pid = clientConfig.clientInfo.pid;
185 // Update the pixel count for this process
186 updatePixelCount(pid, clientConfig.width * (long)clientConfig.height,
187 entry->second.width * (long)entry->second.height);
188 // Update the resolution in the record.
189 entry->second.width = clientConfig.width;
190 entry->second.height = clientConfig.height;
191 }
192}
193
Girish1f002cf2023-02-17 00:36:29 +0000194void ResourceManagerMetrics::notifyClientStarted(const ClientConfigParcel& clientConfig) {
195 std::scoped_lock lock(mLock);
196 int pid = clientConfig.clientInfo.pid;
197 // We need to observer this process.
198 mUidObserver->add(pid, clientConfig.clientInfo.uid);
199
200 // Update the client config for thic client.
201 mClientConfigMap[clientConfig.clientInfo.id] = clientConfig;
202
203 // Update the concurrent codec count for this process.
204 CodecBucket codecBucket = getCodecBucket(clientConfig.isHardware,
205 clientConfig.isEncoder,
206 clientConfig.codecType);
207 increaseConcurrentCodecs(pid, codecBucket);
208
209 if (clientConfig.codecType == MediaResourceSubType::kVideoCodec ||
210 clientConfig.codecType == MediaResourceSubType::kImageCodec) {
211 // Update the pixel count for this process
212 increasePixelCount(pid, clientConfig.width * (long)clientConfig.height);
213 }
214
215 // System concurrent codec usage
Girishde8eb592023-04-13 18:49:17 +0000216 int systemConcurrentCodecs = mConcurrentCodecsMap[codecBucket];
Girish1f002cf2023-02-17 00:36:29 +0000217 // Process/Application concurrent codec usage for this type of codec
Girishde8eb592023-04-13 18:49:17 +0000218 const ConcurrentCodecs& concurrentCodecs = mProcessConcurrentCodecsMap[pid];
219 int appConcurrentCodecs = concurrentCodecs.mCurrent[codecBucket];
220 int hwVideoCodecs = concurrentCodecs.mHWVideoCodecs;
221 int swVideoCodecs = concurrentCodecs.mSWVideoCodecs;
222 int videoCodecs = concurrentCodecs.mVideoCodecs;
223 int audioCodecs = concurrentCodecs.mAudioCodecs;
224 int imageCodecs = concurrentCodecs.mImageCodecs;
Girish1f002cf2023-02-17 00:36:29 +0000225 // Process/Application's current pixel count.
226 long pixelCount = 0;
227 std::map<int32_t, PixelCount>::iterator it = mProcessPixelsMap.find(pid);
228 if (it != mProcessPixelsMap.end()) {
229 pixelCount = it->second.mCurrent;
230 }
231
232 int result = stats_write(
233 MEDIA_CODEC_STARTED,
234 clientConfig.clientInfo.uid,
235 clientConfig.id,
236 clientConfig.clientInfo.name.c_str(),
237 static_cast<int32_t>(clientConfig.codecType),
238 clientConfig.isEncoder,
239 clientConfig.isHardware,
240 clientConfig.width, clientConfig.height,
Girishde8eb592023-04-13 18:49:17 +0000241 systemConcurrentCodecs,
242 appConcurrentCodecs,
243 pixelCount,
244 hwVideoCodecs,
245 swVideoCodecs,
246 videoCodecs,
247 audioCodecs,
248 imageCodecs);
Girish1f002cf2023-02-17 00:36:29 +0000249
250 ALOGV("%s: Pushed MEDIA_CODEC_STARTED atom: "
251 "Process[pid(%d): uid(%d)] "
252 "Codec: [%s: %ju] is %s %s %s "
253 "Timestamp: %jd "
254 "Resolution: %d x %d "
255 "ConcurrentCodec[%d]={System: %d App: %d} "
Girishde8eb592023-04-13 18:49:17 +0000256 "AppConcurrentCodecs{Video: %d(HW[%d] SW[%d]) Audio: %d Image: %d} "
Girish1f002cf2023-02-17 00:36:29 +0000257 "result: %d",
258 __func__,
259 pid, clientConfig.clientInfo.uid,
260 clientConfig.clientInfo.name.c_str(),
261 clientConfig.id,
262 clientConfig.isHardware? "hardware" : "software",
263 getCodecType(clientConfig.codecType),
264 clientConfig.isEncoder? "encoder" : "decoder",
265 clientConfig.timeStamp,
266 clientConfig.width, clientConfig.height,
Girishde8eb592023-04-13 18:49:17 +0000267 codecBucket, systemConcurrentCodecs, appConcurrentCodecs,
268 videoCodecs, hwVideoCodecs, swVideoCodecs, audioCodecs, imageCodecs,
Girish1f002cf2023-02-17 00:36:29 +0000269 result);
270}
271
272void ResourceManagerMetrics::notifyClientStopped(const ClientConfigParcel& clientConfig) {
273 std::scoped_lock lock(mLock);
274 int pid = clientConfig.clientInfo.pid;
275 // Update the concurrent codec count for this process.
276 CodecBucket codecBucket = getCodecBucket(clientConfig.isHardware,
277 clientConfig.isEncoder,
278 clientConfig.codecType);
279 decreaseConcurrentCodecs(pid, codecBucket);
280
281 if (clientConfig.codecType == MediaResourceSubType::kVideoCodec ||
282 clientConfig.codecType == MediaResourceSubType::kImageCodec) {
283 // Update the pixel count for this process
284 decreasePixelCount(pid, clientConfig.width * (long)clientConfig.height);
285 }
286
287 // System concurrent codec usage
Girishde8eb592023-04-13 18:49:17 +0000288 int systemConcurrentCodecs = mConcurrentCodecsMap[codecBucket];
Girish1f002cf2023-02-17 00:36:29 +0000289 // Process/Application concurrent codec usage for this type of codec
Girishde8eb592023-04-13 18:49:17 +0000290 int appConcurrentCodecs = 0;
Girish1f002cf2023-02-17 00:36:29 +0000291 std::map<int32_t, ConcurrentCodecs>::iterator found = mProcessConcurrentCodecsMap.find(pid);
292 if (found != mProcessConcurrentCodecsMap.end()) {
Girishde8eb592023-04-13 18:49:17 +0000293 appConcurrentCodecs = found->second.mCurrent[codecBucket];
Girish1f002cf2023-02-17 00:36:29 +0000294 }
295 // Process/Application's current pixel count.
296 long pixelCount = 0;
297 std::map<int32_t, PixelCount>::iterator it = mProcessPixelsMap.find(pid);
298 if (it != mProcessPixelsMap.end()) {
299 pixelCount = it->second.mCurrent;
300 }
301
302 // calculate the usageTime as:
303 // MediaCodecStopped.clientConfig.timeStamp -
304 // MediaCodecStarted.clientConfig.timeStamp
305 int64_t usageTime = 0;
306 ClientConfigMap::iterator entry = mClientConfigMap.find(clientConfig.clientInfo.id);
307 if (entry != mClientConfigMap.end()) {
308 usageTime = clientConfig.timeStamp - entry->second.timeStamp;
309 // And we can erase this config now.
310 mClientConfigMap.erase(entry);
311 } else {
312 ALOGW("%s: Start Config is missing!", __func__);
313 }
314
315 int result = stats_write(
316 MEDIA_CODEC_STOPPED,
317 clientConfig.clientInfo.uid,
318 clientConfig.id,
319 clientConfig.clientInfo.name.c_str(),
320 static_cast<int32_t>(clientConfig.codecType),
321 clientConfig.isEncoder,
322 clientConfig.isHardware,
323 clientConfig.width, clientConfig.height,
Girishde8eb592023-04-13 18:49:17 +0000324 systemConcurrentCodecs,
325 appConcurrentCodecs,
Girish1f002cf2023-02-17 00:36:29 +0000326 pixelCount,
327 usageTime);
328 ALOGV("%s: Pushed MEDIA_CODEC_STOPPED atom: "
329 "Process[pid(%d): uid(%d)] "
330 "Codec: [%s: %ju] is %s %s %s "
331 "Timestamp: %jd Usage time: %jd "
332 "Resolution: %d x %d "
333 "ConcurrentCodec[%d]={System: %d App: %d} "
334 "result: %d",
335 __func__,
336 pid, clientConfig.clientInfo.uid,
337 clientConfig.clientInfo.name.c_str(),
338 clientConfig.id,
339 clientConfig.isHardware? "hardware" : "software",
340 getCodecType(clientConfig.codecType),
341 clientConfig.isEncoder? "encoder" : "decoder",
342 clientConfig.timeStamp, usageTime,
343 clientConfig.width, clientConfig.height,
Girishde8eb592023-04-13 18:49:17 +0000344 codecBucket, systemConcurrentCodecs, appConcurrentCodecs,
Girish1f002cf2023-02-17 00:36:29 +0000345 result);
346}
347
348void ResourceManagerMetrics::onProcessTerminated(int32_t pid, uid_t uid) {
349 std::scoped_lock lock(mLock);
350 // post MediaCodecConcurrentUsageReported for this terminated pid.
351 pushConcurrentUsageReport(pid, uid);
352}
353
354void ResourceManagerMetrics::pushConcurrentUsageReport(int32_t pid, uid_t uid) {
355 // Process/Application peak concurrent codec usage
356 std::map<int32_t, ConcurrentCodecs>::iterator found = mProcessConcurrentCodecsMap.find(pid);
357 if (found == mProcessConcurrentCodecsMap.end()) {
358 ALOGI("%s: No MEDIA_CODEC_CONCURRENT_USAGE_REPORTED atom Entry for: "
359 "Application[pid(%d): uid(%d)]", __func__, pid, uid);
360 return;
361 }
362 const ConcurrentCodecsMap& codecsMap = found->second.mPeak;
363 int peakHwAudioEncoderCount = codecsMap[HwAudioEncoder];
364 int peakHwAudioDecoderCount = codecsMap[HwAudioDecoder];
365 int peakHwVideoEncoderCount = codecsMap[HwVideoEncoder];
366 int peakHwVideoDecoderCount = codecsMap[HwVideoDecoder];
367 int peakHwImageEncoderCount = codecsMap[HwImageEncoder];
368 int peakHwImageDecoderCount = codecsMap[HwImageDecoder];
369 int peakSwAudioEncoderCount = codecsMap[SwAudioEncoder];
370 int peakSwAudioDecoderCount = codecsMap[SwAudioDecoder];
371 int peakSwVideoEncoderCount = codecsMap[SwVideoEncoder];
372 int peakSwVideoDecoderCount = codecsMap[SwVideoDecoder];
373 int peakSwImageEncoderCount = codecsMap[SwImageEncoder];
374 int peakSwImageDecoderCount = codecsMap[SwImageDecoder];
375
376 long peakPixels = 0;
377 std::map<int32_t, PixelCount>::iterator it = mProcessPixelsMap.find(pid);
378 if (it == mProcessPixelsMap.end()) {
379 ALOGI("%s: No Video Codec Entry for Application[pid(%d): uid(%d)]",
380 __func__, pid, uid);
381 } else {
382 peakPixels = it->second.mPeak;
383 }
384 std::string peakPixelsLog("Peak Pixels: " + std::to_string(peakPixels));
385
386 std::stringstream peakCodecLog;
387 peakCodecLog << "Peak { ";
388 std::stringstream logMsg;
389 if (getLogMessage(peakHwAudioEncoderCount, peakSwAudioEncoderCount, logMsg)) {
390 peakCodecLog << "AudioEnc[" << logMsg.str();
391 }
392 if (getLogMessage(peakHwAudioDecoderCount, peakSwAudioDecoderCount, logMsg)) {
393 peakCodecLog << "AudioDec[" << logMsg.str();
394 }
395 if (getLogMessage(peakHwVideoEncoderCount, peakSwVideoEncoderCount, logMsg)) {
396 peakCodecLog << "VideoEnc[" << logMsg.str();
397 }
398 if (getLogMessage(peakHwVideoDecoderCount, peakSwVideoDecoderCount, logMsg)) {
399 peakCodecLog << "VideoDec[" << logMsg.str();
400 }
401 if (getLogMessage(peakHwImageEncoderCount, peakSwImageEncoderCount, logMsg)) {
402 peakCodecLog << "ImageEnc[" << logMsg.str();
403 }
404 if (getLogMessage(peakHwImageDecoderCount, peakSwImageDecoderCount, logMsg)) {
405 peakCodecLog << "ImageDec[" << logMsg.str();
406 }
407 peakCodecLog << "}";
408
409#ifdef ENABLE_MEDIA_CODEC_CONCURRENT_USAGE_REPORTED
410 int result = stats_write(
411 MEDIA_CODEC_CONCURRENT_USAGE_REPORTED,
412 uid,
413 peakHwVideoDecoderCount,
414 peakHwVideoEncoderCount,
415 peakSwVideoDecoderCount,
416 peakSwVideoEncoderCount,
417 peakHwAudioDecoderCount,
418 peakHwAudioEncoderCount,
419 peakSwAudioDecoderCount,
420 peakSwAudioEncoderCount,
421 peakHwImageDecoderCount,
422 peakHwImageEncoderCount,
423 peakSwImageDecoderCount,
424 peakSwImageEncoderCount,
425 peakPixels);
426 ALOGI("%s: Pushed MEDIA_CODEC_CONCURRENT_USAGE_REPORTED atom: "
427 "Process[pid(%d): uid(%d)] %s %s result: %d",
428 __func__, pid, uid, peakCodecLog.str().c_str(), peakPixelsLog.c_str(), result);
429#else
430 ALOGI("%s: Concurrent Codec Usage Report for the Process[pid(%d): uid(%d)] is %s %s",
431 __func__, pid, uid, peakCodecLog.str().c_str(), peakPixelsLog.c_str());
432#endif
433}
434
435void ResourceManagerMetrics::pushReclaimAtom(const ClientInfoParcel& clientInfo,
436 const std::vector<int>& priorities,
437 const Vector<std::shared_ptr<IResourceManagerClient>>& clients,
438 const PidUidVector& idList, bool reclaimed) {
439 // Construct the metrics for codec reclaim as a pushed atom.
440 // 1. Information about the requester.
441 // - UID and the priority (oom score)
442 int32_t callingPid = clientInfo.pid;
443 int32_t requesterUid = clientInfo.uid;
444 std::string clientName = clientInfo.name;
445 int requesterPriority = priorities[0];
446
447 // 2. Information about the codec.
448 // - Name of the codec requested
449 // - Number of concurrent codecs running.
450 int32_t noOfConcurrentCodecs = 0;
451 std::map<std::string, int>::iterator found = mConcurrentResourceCountMap.find(clientName);
452 if (found != mConcurrentResourceCountMap.end()) {
453 noOfConcurrentCodecs = found->second;
454 }
455
456 // 3. Information about the Reclaim:
457 // - Status of reclaim request
458 // - How many codecs are reclaimed
459 // - For each codecs reclaimed, information of the process that it belonged to:
460 // - UID and the Priority (oom score)
461 int32_t reclaimStatus = MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_SUCCESS;
462 if (!reclaimed) {
463 if (clients.size() == 0) {
464 // No clients to reclaim from
465 reclaimStatus =
466 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_NO_CLIENTS;
467 } else {
468 // Couldn't reclaim resources from the clients
469 reclaimStatus =
470 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_RECLAIM_RESOURCES;
471 }
472 }
473 int32_t noOfCodecsReclaimed = clients.size();
474 int32_t targetIndex = 1;
475 for (PidUidVector::const_reference id : idList) {
476 int32_t targetUid = id.second;
477 int targetPriority = priorities[targetIndex];
478 // Post the pushed atom
479 int result = stats_write(
480 MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED,
481 requesterUid,
482 requesterPriority,
483 clientName.c_str(),
484 noOfConcurrentCodecs,
485 reclaimStatus,
486 noOfCodecsReclaimed,
487 targetIndex,
488 targetUid,
489 targetPriority);
490 ALOGI("%s: Pushed MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED atom: "
491 "Requester[pid(%d): uid(%d): priority(%d)] "
492 "Codec: [%s] "
493 "No of concurrent codecs: %d "
494 "Reclaim Status: %d "
495 "No of codecs reclaimed: %d "
496 "Target[%d][pid(%d): uid(%d): priority(%d)] result: %d",
497 __func__, callingPid, requesterUid, requesterPriority,
498 clientName.c_str(), noOfConcurrentCodecs,
499 reclaimStatus, noOfCodecsReclaimed,
500 targetIndex, id.first, targetUid, targetPriority, result);
501 targetIndex++;
502 }
503}
504
505void ResourceManagerMetrics::increaseConcurrentCodecs(int32_t pid,
506 CodecBucket codecBucket) {
507 // Increase the codec usage across the system.
508 mConcurrentCodecsMap[codecBucket]++;
509
510 // Now update the codec usage for this (pid) process.
511 std::map<int32_t, ConcurrentCodecs>::iterator found = mProcessConcurrentCodecsMap.find(pid);
512 if (found == mProcessConcurrentCodecsMap.end()) {
513 ConcurrentCodecs codecs;
514 codecs.mCurrent[codecBucket] = 1;
515 codecs.mPeak[codecBucket] = 1;
Girishde8eb592023-04-13 18:49:17 +0000516 auto added = mProcessConcurrentCodecsMap.emplace(pid, codecs);
517 found = added.first;
Girish1f002cf2023-02-17 00:36:29 +0000518 } else {
519 found->second.mCurrent[codecBucket]++;
520 // Check if it's the peak count for this slot.
521 if (found->second.mPeak[codecBucket] < found->second.mCurrent[codecBucket]) {
522 found->second.mPeak[codecBucket] = found->second.mCurrent[codecBucket];
523 }
524 }
Girishde8eb592023-04-13 18:49:17 +0000525
526 switch (codecBucket) {
527 case HwVideoEncoder:
528 case HwVideoDecoder:
529 case SwVideoEncoder:
530 case SwVideoDecoder:
531 if (codecBucket == HwVideoEncoder || codecBucket == HwVideoDecoder) {
532 found->second.mHWVideoCodecs++;
533 } else {
534 found->second.mSWVideoCodecs++;
535 }
536 found->second.mVideoCodecs++;
537 break;
538 case HwAudioEncoder:
539 case HwAudioDecoder:
540 case SwAudioEncoder:
541 case SwAudioDecoder:
542 found->second.mAudioCodecs++;
543 break;
544 case HwImageEncoder:
545 case HwImageDecoder:
546 case SwImageEncoder:
547 case SwImageDecoder:
548 found->second.mImageCodecs++;
549 break;
550 default:
551 break;
552 }
Girish1f002cf2023-02-17 00:36:29 +0000553}
554
555void ResourceManagerMetrics::decreaseConcurrentCodecs(int32_t pid,
556 CodecBucket codecBucket) {
557 // Decrease the codec usage across the system.
558 if (mConcurrentCodecsMap[codecBucket] > 0) {
559 mConcurrentCodecsMap[codecBucket]--;
560 }
561
562 // Now update the codec usage for this (pid) process.
563 std::map<int32_t, ConcurrentCodecs>::iterator found = mProcessConcurrentCodecsMap.find(pid);
564 if (found != mProcessConcurrentCodecsMap.end()) {
565 if (found->second.mCurrent[codecBucket] > 0) {
566 found->second.mCurrent[codecBucket]--;
567 }
Girishde8eb592023-04-13 18:49:17 +0000568
569 switch (codecBucket) {
570 case HwVideoEncoder:
571 case HwVideoDecoder:
572 case SwVideoEncoder:
573 case SwVideoDecoder:
574 if (codecBucket == HwVideoEncoder || codecBucket == HwVideoDecoder) {
575 found->second.mHWVideoCodecs--;
576 } else {
577 found->second.mSWVideoCodecs--;
578 }
579 found->second.mVideoCodecs--;
580 break;
581 case HwAudioEncoder:
582 case HwAudioDecoder:
583 case SwAudioEncoder:
584 case SwAudioDecoder:
585 found->second.mAudioCodecs--;
586 break;
587 case HwImageEncoder:
588 case HwImageDecoder:
589 case SwImageEncoder:
590 case SwImageDecoder:
591 found->second.mImageCodecs--;
592 break;
593 default:
594 break;
595 }
Girish1f002cf2023-02-17 00:36:29 +0000596 }
597}
598
599void ResourceManagerMetrics::increasePixelCount(int32_t pid, long pixels) {
600 // Now update the current pixel usage for this (pid) process.
601 std::map<int32_t, PixelCount>::iterator found = mProcessPixelsMap.find(pid);
602 if (found == mProcessPixelsMap.end()) {
603 PixelCount pixelCount {pixels, pixels};
604 mProcessPixelsMap.emplace(pid, pixelCount);
605 } else {
606 if (__builtin_add_overflow(found->second.mCurrent, pixels, &found->second.mCurrent)) {
607 ALOGI("Pixel Count overflow");
608 return;
609 }
610 // Check if it's the peak count for this slot.
611 if (found->second.mPeak < found->second.mCurrent) {
612 found->second.mPeak = found->second.mCurrent;
613 }
614 }
615}
616
Girishde8eb592023-04-13 18:49:17 +0000617void ResourceManagerMetrics::updatePixelCount(int32_t pid, long newPixels, long lastPixels) {
618 // Since there is change in resolution, decrease it by last pixels and
619 // increase it by new pixels.
620 decreasePixelCount(pid, lastPixels);
621 increasePixelCount(pid, newPixels);
622}
623
Girish1f002cf2023-02-17 00:36:29 +0000624void ResourceManagerMetrics::decreasePixelCount(int32_t pid, long pixels) {
625 // Now update the current pixel usage for this (pid) process.
626 std::map<int32_t, PixelCount>::iterator found = mProcessPixelsMap.find(pid);
627 if (found != mProcessPixelsMap.end()) {
628 if (found->second.mCurrent < pixels) {
629 found->second.mCurrent = 0;
630 } else {
631 if (__builtin_sub_overflow(found->second.mCurrent, pixels, &found->second.mCurrent)) {
632 ALOGI("Pixel Count overflow");
633 return;
634 }
635 }
636 }
637}
638
639long ResourceManagerMetrics::getPeakConcurrentPixelCount(int pid) const {
640 std::map<int32_t, PixelCount>::const_iterator found = mProcessPixelsMap.find(pid);
641 if (found != mProcessPixelsMap.end()) {
642 return found->second.mPeak;
643 }
644
645 return 0;
646}
647
648long ResourceManagerMetrics::getCurrentConcurrentPixelCount(int pid) const {
649 std::map<int32_t, PixelCount>::const_iterator found = mProcessPixelsMap.find(pid);
650 if (found != mProcessPixelsMap.end()) {
651 return found->second.mCurrent;
652 }
653
654 return 0;
655}
656
657} // namespace android