blob: 7a5a89fa5e999fc050bbcf3cd79150bc316ed9fc [file] [log] [blame]
/*
**
** Copyright 2023, 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_MEDIA_RESOURCEMANAGERMETRICS_H_
#define ANDROID_MEDIA_RESOURCEMANAGERMETRICS_H_
#include "ResourceManagerService.h"
namespace android {
using ::aidl::android::media::ClientInfoParcel;
using ::aidl::android::media::ClientConfigParcel;
using ::aidl::android::media::IResourceManagerClient;
struct ProcessInfoInterface;
class UidObserver;
//
// Enumeration for Codec bucket based on:
// - Encoder or Decoder
// - hardware implementation or not
// - Audio/Video/Image codec
//
enum CodecBucket {
CodecBucketUnspecified = 0,
HwAudioEncoder = 1,
HwAudioDecoder = 2,
HwVideoEncoder = 3,
HwVideoDecoder = 4,
HwImageEncoder = 5,
HwImageDecoder = 6,
SwAudioEncoder = 7,
SwAudioDecoder = 8,
SwVideoEncoder = 9,
SwVideoDecoder = 10,
SwImageEncoder = 11,
SwImageDecoder = 12,
CodecBucketMaxSize = 13,
};
// Map of client id and client configuration, when it was started last.
typedef std::map<int64_t, ClientConfigParcel> ClientConfigMap;
// Map of pid and the uid.
typedef std::map<int32_t, uid_t> PidUidMap;
// Map of concurrent codes by Codec type bucket.
struct ConcurrentCodecsMap {
int& operator[](CodecBucket index) {
return mCodec[index];
}
const int& operator[](CodecBucket index) const {
return mCodec[index];
}
private:
int mCodec[CodecBucketMaxSize] = {0};
};
// Current and Peak ConcurrentCodecMap for a process.
struct ConcurrentCodecs {
ConcurrentCodecsMap mCurrent;
ConcurrentCodecsMap mPeak;
// concurrent HW Video codecs.
int mHWVideoCodecs;
// concurrent SW Video codecs.
int mSWVideoCodecs;
// concurrent Video codecs.
int mVideoCodecs;
// concurrent Audio codecs.
int mAudioCodecs;
// concurrent Image codecs.
int mImageCodecs;
};
// Current and Peak pixel count for a process.
struct PixelCount {
long mCurrent = 0;
long mPeak = 0;
};
//
// Resource Manager Metrics is designed to answer some of the questions like:
// - What apps are causing reclaim and what apps are targeted (reclaimed from) in the process?
// - which apps use the most codecs and the most codec memory?
// - What is the % of total successful reclaims?
//
// Though, it's not in the context of this class, metrics should also answer:
// - what % of codec errors are due to codec being reclaimed?
// - What % of successful codec creation(start) requires codec reclaims?
// - How often codec start fails even after successful reclaim?
//
// The metrics are collected to analyze and understand the codec resource usage
// and use that information to help with:
// - minimize the no of reclaims
// - reduce the codec start delays by minimizing no of times we try to reclaim
// - minimize the reclaim errors in codec records
//
// Success metrics for Resource Manager Service could be defined as:
// - increase in sucecssful codec creation for the foreground apps
// - reduce the number of reclaims for codecs
// - reduce the time to create codec
//
// We would like to use this data to come up with a better resource management that would:
// - increase the successful codec creation (for all kind of apps)
// - decrease the codec errors due to resources
//
// This class that maintains concurrent codec counts based on:
//
// 1. # of concurrent active codecs (initialized, but aren't released yet) of given
// implementation (by codec name) across the system.
//
// 2. # of concurrent codec usage (started, but not stopped yet), which is
// measured using codec type bucket (CodecBucket) for:
// - each process/application.
// - across the system.
// Also the peak count of the same for each process/application is maintained.
//
// 3. # of Peak Concurrent Pixels for each process/application.
// This should help with understanding the (video) memory usage per
// application.
//
class ResourceManagerMetrics {
public:
ResourceManagerMetrics(const sp<ProcessInfoInterface>& processInfo);
~ResourceManagerMetrics();
// To be called when a client is created.
void notifyClientCreated(const ClientInfoParcel& clientInfo);
// To be called when a client is released.
void notifyClientReleased(const ClientInfoParcel& clientInfo);
// To be called when a client is started.
void notifyClientStarted(const ClientConfigParcel& clientConfig);
// To be called when a client is stopped.
void notifyClientStopped(const ClientConfigParcel& clientConfig);
// To be called when a client's configuration has changed.
void notifyClientConfigChanged(const ClientConfigParcel& clientConfig);
// To be called when after a reclaim event.
void pushReclaimAtom(const ClientInfoParcel& clientInfo,
const std::vector<int>& priorities,
const std::vector<ClientInfo>& targetClients,
bool reclaimed);
// Add this pid/uid set to monitor for the process termination state.
void addPid(int pid, uid_t uid = 0);
// Get the peak concurrent pixel count (associated with the video codecs) for the process.
long getPeakConcurrentPixelCount(int pid) const;
// Get the current concurrent pixel count (associated with the video codecs) for the process.
long getCurrentConcurrentPixelCount(int pid) const;
private:
ResourceManagerMetrics(const ResourceManagerMetrics&) = delete;
ResourceManagerMetrics(ResourceManagerMetrics&&) = delete;
ResourceManagerMetrics& operator=(const ResourceManagerMetrics&) = delete;
ResourceManagerMetrics& operator=(ResourceManagerMetrics&&) = delete;
// To increase/decrease the concurrent codec usage for a given CodecBucket.
void increaseConcurrentCodecs(int32_t pid, CodecBucket codecBucket);
void decreaseConcurrentCodecs(int32_t pid, CodecBucket codecBucket);
// To increase/update/decrease the concurrent pixels usage for a process.
void increasePixelCount(int32_t pid, long pixels);
void updatePixelCount(int32_t pid, long newPixels, long lastPixels);
void decreasePixelCount(int32_t pid, long pixels);
// Issued when the process/application with given pid/uid is terminated.
void onProcessTerminated(int32_t pid, uid_t uid);
// To push conccuret codec usage of a process/application.
void pushConcurrentUsageReport(int32_t pid, uid_t uid);
private:
std::mutex mLock;
// Map of client id and the configuration.
ClientConfigMap mClientConfigMap;
// Concurrent and Peak Pixel count for each process/application.
std::map<int32_t, PixelCount> mProcessPixelsMap;
// Map of resources (name) and number of concurrent instances
std::map<std::string, int> mConcurrentResourceCountMap;
// Map of concurrent codes by CodecBucket across the system.
ConcurrentCodecsMap mConcurrentCodecsMap;
// Map of concurrent and peak codes by CodecBucket for each process/application.
std::map<int32_t, ConcurrentCodecs> mProcessConcurrentCodecsMap;
// Uid Observer to monitor the application termination.
sp<UidObserver> mUidObserver;
};
} // namespace android
#endif // ANDROID_MEDIA_RESOURCEMANAGERMETRICS_H_