diff options
author | Chong Zhang <chz@google.com> | 2018-04-17 14:14:31 -0700 |
---|---|---|
committer | Chong Zhang <chz@google.com> | 2018-04-18 13:46:03 -0700 |
commit | 79d2b28f3a04d7914bb932a65d87117c0c7c11cf (patch) | |
tree | 386c0e23123c52191f3c098351898cd6a0bdb4bf | |
parent | 1cdd674121096020f7f17c216940a14aa58ff31e (diff) | |
download | frameworks_av-79d2b28f3a04d7914bb932a65d87117c0c7c11cf.tar.gz frameworks_av-79d2b28f3a04d7914bb932a65d87117c0c7c11cf.tar.bz2 frameworks_av-79d2b28f3a04d7914bb932a65d87117c0c7c11cf.zip |
Request cpuset change for 1080p HDR using soft decoder
Keep track of cpuset change requests in ResourceManagerService,
and request changing of cpuset via SchedulingPolicyService.
Bug: 72841545
Test:
1)Using modified Youtube/Exoplayer (that uses softMediaCodec
to decode VP9 profile2), manually verify the following:
- media.codec is put into top-app cpuset playing VP9 1080p HDR
- media.codec is put back into foreground after done
- media.codec stays in foreground cpuset playing other content
- kill the app process, verify media.codec is put back to
foreground until new instances request top-app
- kill mediaserver process, verify media.codec is put back to
foreground until new instances request top-app
- kill media.codec process, starting playback again, verify new
media.codec's cpuset can be changed correctly
- kill system_server process (using 'adb shell stop &&
adb shell start'), verify media.codec is put back to
foreground. Restart playback and verify the cpuset can be
changed correctly.
2) CTS post submit tests
Change-Id: Iba50ede1c08b695821fe4f56dbfc5694eab54e7b
-rw-r--r-- | media/libmedia/include/media/MediaResource.h | 3 | ||||
-rw-r--r-- | media/libstagefright/MediaCodec.cpp | 28 | ||||
-rw-r--r-- | media/libstagefright/include/media/stagefright/MediaCodec.h | 2 | ||||
-rw-r--r-- | media/utils/ISchedulingPolicyService.cpp | 19 | ||||
-rw-r--r-- | media/utils/ISchedulingPolicyService.h | 1 | ||||
-rw-r--r-- | media/utils/SchedulingPolicyService.cpp | 27 | ||||
-rw-r--r-- | media/utils/include/mediautils/SchedulingPolicyService.h | 11 | ||||
-rw-r--r-- | services/mediaresourcemanager/ResourceManagerService.cpp | 25 | ||||
-rw-r--r-- | services/mediaresourcemanager/ResourceManagerService.h | 2 |
9 files changed, 115 insertions, 3 deletions
diff --git a/media/libmedia/include/media/MediaResource.h b/media/libmedia/include/media/MediaResource.h index 1957a45da1..e1fdb9be3f 100644 --- a/media/libmedia/include/media/MediaResource.h +++ b/media/libmedia/include/media/MediaResource.h @@ -29,7 +29,8 @@ public: kUnspecified = 0, kSecureCodec, kNonSecureCodec, - kGraphicMemory + kGraphicMemory, + kCpuBoost, }; enum SubType { diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index f25d1f1ae4..23bee497ac 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -523,6 +523,7 @@ MediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid) mDequeueOutputReplyID(0), mHaveInputSurface(false), mHavePendingInputBuffers(false), + mCpuBoostRequested(false), mLatencyUnknown(0) { if (uid == kNoUid) { mUid = IPCThreadState::self()->getCallingUid(); @@ -1638,6 +1639,31 @@ void MediaCodec::requestActivityNotification(const sp<AMessage> ¬ify) { msg->post(); } +void MediaCodec::requestCpuBoostIfNeeded() { + if (mCpuBoostRequested) { + return; + } + int32_t colorFormat; + if (mSoftRenderer != NULL + && mOutputFormat->contains("hdr-static-info") + && mOutputFormat->findInt32("color-format", &colorFormat) + && (colorFormat == OMX_COLOR_FormatYUV420Planar16)) { + int32_t left, top, right, bottom, width, height; + int64_t totalPixel = 0; + if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) { + totalPixel = (right - left + 1) * (bottom - top + 1); + } else if (mOutputFormat->findInt32("width", &width) + && mOutputFormat->findInt32("height", &height)) { + totalPixel = width * height; + } + if (totalPixel >= 1920 * 1080) { + addResource(MediaResource::kCpuBoost, + MediaResource::kUnspecifiedSubType, 1); + mCpuBoostRequested = true; + } + } +} + //////////////////////////////////////////////////////////////////////////////// void MediaCodec::cancelPendingDequeueOperations() { @@ -2160,6 +2186,8 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { } } + requestCpuBoostIfNeeded(); + if (mFlags & kFlagIsEncoder) { // Before we announce the format change we should // collect codec specific data and amend the output diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h index 48a1224bfa..67808f1c1f 100644 --- a/media/libstagefright/include/media/stagefright/MediaCodec.h +++ b/media/libstagefright/include/media/stagefright/MediaCodec.h @@ -369,6 +369,7 @@ private: bool mHaveInputSurface; bool mHavePendingInputBuffers; + bool mCpuBoostRequested; std::shared_ptr<BufferChannelBase> mBufferChannel; @@ -425,6 +426,7 @@ private: uint64_t getGraphicBufferSize(); void addResource(MediaResource::Type type, MediaResource::SubType subtype, uint64_t value); + void requestCpuBoostIfNeeded(); bool hasPendingBuffer(int portIndex); bool hasPendingBuffer(); diff --git a/media/utils/ISchedulingPolicyService.cpp b/media/utils/ISchedulingPolicyService.cpp index 22fbc97cb1..b210404639 100644 --- a/media/utils/ISchedulingPolicyService.cpp +++ b/media/utils/ISchedulingPolicyService.cpp @@ -25,6 +25,7 @@ namespace android { // Keep in sync with frameworks/base/core/java/android/os/ISchedulingPolicyService.aidl enum { REQUEST_PRIORITY_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, + REQUEST_CPUSET_BOOST, }; // ---------------------------------------------------------------------- @@ -60,6 +61,23 @@ public: } return reply.readInt32(); } + + virtual int requestCpusetBoost(bool enable, const sp<IInterface>& client) + { + Parcel data, reply; + data.writeInterfaceToken(ISchedulingPolicyService::getInterfaceDescriptor()); + data.writeInt32(enable); + data.writeStrongBinder(IInterface::asBinder(client)); + status_t status = remote()->transact(REQUEST_CPUSET_BOOST, data, &reply, 0); + if (status != NO_ERROR) { + return status; + } + // fail on exception: force binder reconnection + if (reply.readExceptionCode() != 0) { + return DEAD_OBJECT; + } + return reply.readInt32(); + } }; IMPLEMENT_META_INTERFACE(SchedulingPolicyService, "android.os.ISchedulingPolicyService"); @@ -71,6 +89,7 @@ status_t BnSchedulingPolicyService::onTransact( { switch (code) { case REQUEST_PRIORITY_TRANSACTION: + case REQUEST_CPUSET_BOOST: // Not reached return NO_ERROR; break; diff --git a/media/utils/ISchedulingPolicyService.h b/media/utils/ISchedulingPolicyService.h index 101567726a..e4f7c0daa5 100644 --- a/media/utils/ISchedulingPolicyService.h +++ b/media/utils/ISchedulingPolicyService.h @@ -29,6 +29,7 @@ public: virtual int requestPriority(/*pid_t*/int32_t pid, /*pid_t*/int32_t tid, int32_t prio, bool isForApp, bool asynchronous) = 0; + virtual int requestCpusetBoost(bool enable, const sp<IInterface>& client) = 0; }; class BnSchedulingPolicyService : public BnInterface<ISchedulingPolicyService> diff --git a/media/utils/SchedulingPolicyService.cpp b/media/utils/SchedulingPolicyService.cpp index d7055ef9a1..4e9792fc7b 100644 --- a/media/utils/SchedulingPolicyService.cpp +++ b/media/utils/SchedulingPolicyService.cpp @@ -59,4 +59,31 @@ int requestPriority(pid_t pid, pid_t tid, int32_t prio, bool isForApp, bool asyn return ret; } +int requestCpusetBoost(bool enable, const sp<IInterface> &client) +{ + int ret; + sMutex.lock(); + sp<ISchedulingPolicyService> sps = sSchedulingPolicyService; + sMutex.unlock(); + if (sps == 0) { + sp<IBinder> binder = defaultServiceManager()->checkService(_scheduling_policy); + if (binder == 0) { + return DEAD_OBJECT; + } + sps = interface_cast<ISchedulingPolicyService>(binder); + sMutex.lock(); + sSchedulingPolicyService = sps; + sMutex.unlock(); + } + ret = sps->requestCpusetBoost(enable, client); + if (ret != DEAD_OBJECT) { + return ret; + } + ALOGW("SchedulingPolicyService died"); + sMutex.lock(); + sSchedulingPolicyService.clear(); + sMutex.unlock(); + return ret; +} + } // namespace android diff --git a/media/utils/include/mediautils/SchedulingPolicyService.h b/media/utils/include/mediautils/SchedulingPolicyService.h index 47d873475f..a33539fce1 100644 --- a/media/utils/include/mediautils/SchedulingPolicyService.h +++ b/media/utils/include/mediautils/SchedulingPolicyService.h @@ -17,8 +17,11 @@ #ifndef _ANDROID_SCHEDULING_POLICY_SERVICE_H #define _ANDROID_SCHEDULING_POLICY_SERVICE_H +#include <utils/RefBase.h> + namespace android { +class IInterface; // Request elevated priority for thread tid, whose thread group leader must be pid. // The priority parameter is currently restricted to either 1 or 2. // The asynchronous parameter should be 'true' to return immediately, @@ -26,6 +29,14 @@ namespace android { // The default value 'false' means to return after request has been enqueued and executed. int requestPriority(pid_t pid, pid_t tid, int32_t prio, bool isForApp, bool asynchronous = false); +// Request to move media.codec process between SP_FOREGROUND and SP_TOP_APP. +// When 'enable' is 'true', server will attempt to move media.codec process +// from SP_FOREGROUND into SP_TOP_APP cpuset. A valid 'client' must be provided +// for the server to receive death notifications. When 'enable' is 'false', server +// will attempt to move media.codec process back to the original cpuset, and +// 'client' is ignored in this case. +int requestCpusetBoost(bool enable, const sp<IInterface> &client); + } // namespace android #endif // _ANDROID_SCHEDULING_POLICY_SERVICE_H diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp index 78bb58765c..28bfd3ff51 100644 --- a/services/mediaresourcemanager/ResourceManagerService.cpp +++ b/services/mediaresourcemanager/ResourceManagerService.cpp @@ -31,7 +31,8 @@ #include "ResourceManagerService.h" #include "ServiceLog.h" - +#include "mediautils/SchedulingPolicyService.h" +#include <cutils/sched_policy.h> namespace android { namespace { @@ -111,6 +112,7 @@ static ResourceInfo& getResourceInfoForEdit( ResourceInfo info; info.clientId = clientId; info.client = client; + info.cpuBoost = false; infos.push_back(info); return infos.editItemAt(infos.size() - 1); } @@ -201,7 +203,8 @@ ResourceManagerService::ResourceManagerService(sp<ProcessInfoInterface> processI : mProcessInfo(processInfo), mServiceLog(new ServiceLog()), mSupportsMultipleSecureCodecs(true), - mSupportsSecureWithNonSecureCodec(true) {} + mSupportsSecureWithNonSecureCodec(true), + mCpuBoostCount(0) {} ResourceManagerService::~ResourceManagerService() {} @@ -239,6 +242,19 @@ void ResourceManagerService::addResource( ResourceInfo& info = getResourceInfoForEdit(clientId, client, infos); // TODO: do the merge instead of append. info.resources.appendVector(resources); + + for (size_t i = 0; i < resources.size(); ++i) { + if (resources[i].mType == MediaResource::kCpuBoost && !info.cpuBoost) { + info.cpuBoost = true; + // Request it on every new instance of kCpuBoost, as the media.codec + // could have died, if we only do it the first time subsequent instances + // never gets the boost. + if (requestCpusetBoost(true, this) != OK) { + ALOGW("couldn't request cpuset boost"); + } + mCpuBoostCount++; + } + } if (info.deathNotifier == nullptr) { info.deathNotifier = new DeathNotifier(this, pid, clientId); IInterface::asBinder(client)->linkToDeath(info.deathNotifier); @@ -270,6 +286,11 @@ void ResourceManagerService::removeResource(int pid, int64_t clientId, bool chec ResourceInfos &infos = mMap.editValueAt(index); for (size_t j = 0; j < infos.size(); ++j) { if (infos[j].clientId == clientId) { + if (infos[j].cpuBoost && mCpuBoostCount > 0) { + if (--mCpuBoostCount == 0) { + requestCpusetBoost(false, this); + } + } IInterface::asBinder(infos[j].client)->unlinkToDeath(infos[j].deathNotifier); j = infos.removeAt(j); found = true; diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h index 9e97ac0cfd..82d2a0b369 100644 --- a/services/mediaresourcemanager/ResourceManagerService.h +++ b/services/mediaresourcemanager/ResourceManagerService.h @@ -38,6 +38,7 @@ struct ResourceInfo { sp<IResourceManagerClient> client; sp<IBinder::DeathRecipient> deathNotifier; Vector<MediaResource> resources; + bool cpuBoost; }; typedef Vector<ResourceInfo> ResourceInfos; @@ -112,6 +113,7 @@ private: PidResourceInfosMap mMap; bool mSupportsMultipleSecureCodecs; bool mSupportsSecureWithNonSecureCodec; + int32_t mCpuBoostCount; }; // ---------------------------------------------------------------------------- |