media: update on concurrent codec usage
This change includes:
- Calculating and passing application concurrent codec
usage for Video (Hw, SW), Audio and Image codecs to
stats.
- Updating the resource manager with change in resolution
for the video codecs
Bug: 265488359
Test: atest cts/tests/media/misc/src/android/media/misc/cts/ResourceManagerTest.java
/data/nativetest64/ResourceManagerService_test/ResourceManagerService_test
/data/nativetest64/ResourceObserverService_test/ResourceObserverService_test
Merged-In: I69536f10e01f66556536812dbbe3af7831a3c722
Change-Id: I69536f10e01f66556536812dbbe3af7831a3c722
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index c5da2fd..681f7a6 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -295,6 +295,7 @@
void notifyClientCreated();
void notifyClientStarted(ClientConfigParcel& clientConfig);
void notifyClientStopped(ClientConfigParcel& clientConfig);
+ void notifyClientConfigChanged(ClientConfigParcel& clientConfig);
inline void setCodecName(const char* name) {
mCodecName = name;
@@ -482,7 +483,7 @@
}
void MediaCodec::ResourceManagerServiceProxy::notifyClientStarted(
- ClientConfigParcel& clientConfig) {
+ ClientConfigParcel& clientConfig) {
clientConfig.clientInfo.pid = static_cast<int32_t>(mPid);
clientConfig.clientInfo.uid = static_cast<int32_t>(mUid);
clientConfig.clientInfo.id = getId(mClient);
@@ -491,7 +492,7 @@
}
void MediaCodec::ResourceManagerServiceProxy::notifyClientStopped(
- ClientConfigParcel& clientConfig) {
+ ClientConfigParcel& clientConfig) {
clientConfig.clientInfo.pid = static_cast<int32_t>(mPid);
clientConfig.clientInfo.uid = static_cast<int32_t>(mUid);
clientConfig.clientInfo.id = getId(mClient);
@@ -499,6 +500,15 @@
mService->notifyClientStopped(clientConfig);
}
+void MediaCodec::ResourceManagerServiceProxy::notifyClientConfigChanged(
+ ClientConfigParcel& clientConfig) {
+ clientConfig.clientInfo.pid = static_cast<int32_t>(mPid);
+ clientConfig.clientInfo.uid = static_cast<int32_t>(mUid);
+ clientConfig.clientInfo.id = getId(mClient);
+ clientConfig.clientInfo.name = mCodecName;
+ mService->notifyClientConfigChanged(clientConfig);
+}
+
////////////////////////////////////////////////////////////////////////////////
MediaCodec::BufferInfo::BufferInfo() : mOwnedByClient(false) {}
@@ -5097,15 +5107,28 @@
postActivityNotificationIfPossible();
}
- // Notify mCrypto of video resolution changes
- if (mCrypto != NULL) {
- int32_t left, top, right, bottom, width, height;
- if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
- mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
- } else if (mOutputFormat->findInt32("width", &width)
- && mOutputFormat->findInt32("height", &height)) {
- mCrypto->notifyResolution(width, height);
+ // Update the width and the height.
+ int32_t left = 0, top = 0, right = 0, bottom = 0, width = 0, height = 0;
+ bool resolutionChanged = false;
+ if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
+ mWidth = right - left + 1;
+ mHeight = bottom - top + 1;
+ resolutionChanged = true;
+ } else if (mOutputFormat->findInt32("width", &width) &&
+ mOutputFormat->findInt32("height", &height)) {
+ mWidth = width;
+ mHeight = height;
+ resolutionChanged = true;
+ }
+
+ // Notify mCrypto and the RM of video resolution changes
+ if (resolutionChanged) {
+ if (mCrypto != NULL) {
+ mCrypto->notifyResolution(mWidth, mHeight);
}
+ ClientConfigParcel clientConfig;
+ initClientConfigParcel(clientConfig);
+ mResourceManagerProxy->notifyClientConfigChanged(clientConfig);
}
updateHdrMetrics(false /* isConfig */);
diff --git a/services/mediaresourcemanager/ResourceManagerMetrics.cpp b/services/mediaresourcemanager/ResourceManagerMetrics.cpp
index 8d591df..f8cdb80 100644
--- a/services/mediaresourcemanager/ResourceManagerMetrics.cpp
+++ b/services/mediaresourcemanager/ResourceManagerMetrics.cpp
@@ -175,6 +175,22 @@
}
}
+void ResourceManagerMetrics::notifyClientConfigChanged(const ClientConfigParcel& clientConfig) {
+ std::scoped_lock lock(mLock);
+ ClientConfigMap::iterator entry = mClientConfigMap.find(clientConfig.clientInfo.id);
+ if (entry != mClientConfigMap.end() &&
+ (clientConfig.codecType == MediaResourceSubType::kVideoCodec ||
+ clientConfig.codecType == MediaResourceSubType::kImageCodec)) {
+ int pid = clientConfig.clientInfo.pid;
+ // Update the pixel count for this process
+ updatePixelCount(pid, clientConfig.width * (long)clientConfig.height,
+ entry->second.width * (long)entry->second.height);
+ // Update the resolution in the record.
+ entry->second.width = clientConfig.width;
+ entry->second.height = clientConfig.height;
+ }
+}
+
void ResourceManagerMetrics::notifyClientStarted(const ClientConfigParcel& clientConfig) {
std::scoped_lock lock(mLock);
int pid = clientConfig.clientInfo.pid;
@@ -197,9 +213,15 @@
}
// System concurrent codec usage
- int systemConcurrentCodecCount = mConcurrentCodecsMap[codecBucket];
+ int systemConcurrentCodecs = mConcurrentCodecsMap[codecBucket];
// Process/Application concurrent codec usage for this type of codec
- int appConcurrentCodecCount = mProcessConcurrentCodecsMap[pid].mCurrent[codecBucket];
+ const ConcurrentCodecs& concurrentCodecs = mProcessConcurrentCodecsMap[pid];
+ int appConcurrentCodecs = concurrentCodecs.mCurrent[codecBucket];
+ int hwVideoCodecs = concurrentCodecs.mHWVideoCodecs;
+ int swVideoCodecs = concurrentCodecs.mSWVideoCodecs;
+ int videoCodecs = concurrentCodecs.mVideoCodecs;
+ int audioCodecs = concurrentCodecs.mAudioCodecs;
+ int imageCodecs = concurrentCodecs.mImageCodecs;
// Process/Application's current pixel count.
long pixelCount = 0;
std::map<int32_t, PixelCount>::iterator it = mProcessPixelsMap.find(pid);
@@ -216,9 +238,14 @@
clientConfig.isEncoder,
clientConfig.isHardware,
clientConfig.width, clientConfig.height,
- systemConcurrentCodecCount,
- appConcurrentCodecCount,
- pixelCount);
+ systemConcurrentCodecs,
+ appConcurrentCodecs,
+ pixelCount,
+ hwVideoCodecs,
+ swVideoCodecs,
+ videoCodecs,
+ audioCodecs,
+ imageCodecs);
ALOGV("%s: Pushed MEDIA_CODEC_STARTED atom: "
"Process[pid(%d): uid(%d)] "
@@ -226,6 +253,7 @@
"Timestamp: %jd "
"Resolution: %d x %d "
"ConcurrentCodec[%d]={System: %d App: %d} "
+ "AppConcurrentCodecs{Video: %d(HW[%d] SW[%d]) Audio: %d Image: %d} "
"result: %d",
__func__,
pid, clientConfig.clientInfo.uid,
@@ -236,7 +264,8 @@
clientConfig.isEncoder? "encoder" : "decoder",
clientConfig.timeStamp,
clientConfig.width, clientConfig.height,
- codecBucket, systemConcurrentCodecCount, appConcurrentCodecCount,
+ codecBucket, systemConcurrentCodecs, appConcurrentCodecs,
+ videoCodecs, hwVideoCodecs, swVideoCodecs, audioCodecs, imageCodecs,
result);
}
@@ -256,12 +285,12 @@
}
// System concurrent codec usage
- int systemConcurrentCodecCount = mConcurrentCodecsMap[codecBucket];
+ int systemConcurrentCodecs = mConcurrentCodecsMap[codecBucket];
// Process/Application concurrent codec usage for this type of codec
- int appConcurrentCodecCount = 0;
+ int appConcurrentCodecs = 0;
std::map<int32_t, ConcurrentCodecs>::iterator found = mProcessConcurrentCodecsMap.find(pid);
if (found != mProcessConcurrentCodecsMap.end()) {
- appConcurrentCodecCount = found->second.mCurrent[codecBucket];
+ appConcurrentCodecs = found->second.mCurrent[codecBucket];
}
// Process/Application's current pixel count.
long pixelCount = 0;
@@ -292,8 +321,8 @@
clientConfig.isEncoder,
clientConfig.isHardware,
clientConfig.width, clientConfig.height,
- systemConcurrentCodecCount,
- appConcurrentCodecCount,
+ systemConcurrentCodecs,
+ appConcurrentCodecs,
pixelCount,
usageTime);
ALOGV("%s: Pushed MEDIA_CODEC_STOPPED atom: "
@@ -312,7 +341,7 @@
clientConfig.isEncoder? "encoder" : "decoder",
clientConfig.timeStamp, usageTime,
clientConfig.width, clientConfig.height,
- codecBucket, systemConcurrentCodecCount, appConcurrentCodecCount,
+ codecBucket, systemConcurrentCodecs, appConcurrentCodecs,
result);
}
@@ -484,7 +513,8 @@
ConcurrentCodecs codecs;
codecs.mCurrent[codecBucket] = 1;
codecs.mPeak[codecBucket] = 1;
- mProcessConcurrentCodecsMap.emplace(pid, codecs);
+ auto added = mProcessConcurrentCodecsMap.emplace(pid, codecs);
+ found = added.first;
} else {
found->second.mCurrent[codecBucket]++;
// Check if it's the peak count for this slot.
@@ -492,6 +522,34 @@
found->second.mPeak[codecBucket] = found->second.mCurrent[codecBucket];
}
}
+
+ switch (codecBucket) {
+ case HwVideoEncoder:
+ case HwVideoDecoder:
+ case SwVideoEncoder:
+ case SwVideoDecoder:
+ if (codecBucket == HwVideoEncoder || codecBucket == HwVideoDecoder) {
+ found->second.mHWVideoCodecs++;
+ } else {
+ found->second.mSWVideoCodecs++;
+ }
+ found->second.mVideoCodecs++;
+ break;
+ case HwAudioEncoder:
+ case HwAudioDecoder:
+ case SwAudioEncoder:
+ case SwAudioDecoder:
+ found->second.mAudioCodecs++;
+ break;
+ case HwImageEncoder:
+ case HwImageDecoder:
+ case SwImageEncoder:
+ case SwImageDecoder:
+ found->second.mImageCodecs++;
+ break;
+ default:
+ break;
+ }
}
void ResourceManagerMetrics::decreaseConcurrentCodecs(int32_t pid,
@@ -507,6 +565,34 @@
if (found->second.mCurrent[codecBucket] > 0) {
found->second.mCurrent[codecBucket]--;
}
+
+ switch (codecBucket) {
+ case HwVideoEncoder:
+ case HwVideoDecoder:
+ case SwVideoEncoder:
+ case SwVideoDecoder:
+ if (codecBucket == HwVideoEncoder || codecBucket == HwVideoDecoder) {
+ found->second.mHWVideoCodecs--;
+ } else {
+ found->second.mSWVideoCodecs--;
+ }
+ found->second.mVideoCodecs--;
+ break;
+ case HwAudioEncoder:
+ case HwAudioDecoder:
+ case SwAudioEncoder:
+ case SwAudioDecoder:
+ found->second.mAudioCodecs--;
+ break;
+ case HwImageEncoder:
+ case HwImageDecoder:
+ case SwImageEncoder:
+ case SwImageDecoder:
+ found->second.mImageCodecs--;
+ break;
+ default:
+ break;
+ }
}
}
@@ -528,6 +614,13 @@
}
}
+void ResourceManagerMetrics::updatePixelCount(int32_t pid, long newPixels, long lastPixels) {
+ // Since there is change in resolution, decrease it by last pixels and
+ // increase it by new pixels.
+ decreasePixelCount(pid, lastPixels);
+ increasePixelCount(pid, newPixels);
+}
+
void ResourceManagerMetrics::decreasePixelCount(int32_t pid, long pixels) {
// Now update the current pixel usage for this (pid) process.
std::map<int32_t, PixelCount>::iterator found = mProcessPixelsMap.find(pid);
diff --git a/services/mediaresourcemanager/ResourceManagerMetrics.h b/services/mediaresourcemanager/ResourceManagerMetrics.h
index b7810e5..3124aa2 100644
--- a/services/mediaresourcemanager/ResourceManagerMetrics.h
+++ b/services/mediaresourcemanager/ResourceManagerMetrics.h
@@ -77,6 +77,16 @@
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.
@@ -119,6 +129,9 @@
// 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,
@@ -143,8 +156,9 @@
void increaseConcurrentCodecs(int32_t pid, CodecBucket codecBucket);
void decreaseConcurrentCodecs(int32_t pid, CodecBucket codecBucket);
- // To increase/decrease the concurrent pixels usage for a process.
+ // 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.
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 803bfec..7446e0e 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -1208,6 +1208,11 @@
return Status::ok();
}
+Status ResourceManagerService::notifyClientConfigChanged(const ClientConfigParcel& clientConfig) {
+ mResourceManagerMetrics->notifyClientConfigChanged(clientConfig);
+ return Status::ok();
+}
+
long ResourceManagerService::getPeakConcurrentPixelCount(int pid) const {
return mResourceManagerMetrics->getPeakConcurrentPixelCount(pid);
}
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index b9756ae..1519e0e 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -127,6 +127,8 @@
Status notifyClientStopped(const ClientConfigParcel& clientConfig) override;
+ Status notifyClientConfigChanged(const ClientConfigParcel& clientConfig) override;
+
private:
friend class ResourceManagerServiceTest;
friend class DeathNotifier;
diff --git a/services/mediaresourcemanager/aidl/android/media/IResourceManagerService.aidl b/services/mediaresourcemanager/aidl/android/media/IResourceManagerService.aidl
index fcade38..5071fa3 100644
--- a/services/mediaresourcemanager/aidl/android/media/IResourceManagerService.aidl
+++ b/services/mediaresourcemanager/aidl/android/media/IResourceManagerService.aidl
@@ -156,4 +156,16 @@
* @param clientConfig Configuration information of the client.
*/
void notifyClientStopped(in ClientConfigParcel clientConfig);
+
+ /**
+ * Notify that the client's configuration has changed.
+ *
+ * This call is made to collect the (concurrent) metrics about the
+ * resources associated with the Codec (and also DRM sessions).
+ * This is called after notifyClientStarted (and before notifyClientStopped)
+ * to make changes to some of the configurations associated with the client.
+ *
+ * @param clientConfig Configuration information of the client.
+ */
+ void notifyClientConfigChanged(in ClientConfigParcel clientConfig);
}