Loading media/libmedia/aidl/android/media/IResourceManagerService.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -94,4 +94,12 @@ interface IResourceManagerService { * remove existing override on originalPid if newPid is -1. */ void overridePid(int originalPid, int newPid); /** * Mark a client for pending removal * * @param pid pid from which the client's resources will be removed. * @param clientId clientId within the pid that will be removed. */ void markClientForPendingRemoval(int pid, long clientId); } media/libstagefright/MediaCodec.cpp +71 −1 Original line number Diff line number Diff line Loading @@ -199,6 +199,7 @@ struct MediaCodec::ResourceManagerServiceProxy : public RefBase { void addResource(const MediaResourceParcel &resource); void removeResource(const MediaResourceParcel &resource); void removeClient(); void markClientForPendingRemoval(); bool reclaimResource(const std::vector<MediaResourceParcel> &resources); private: Loading Loading @@ -280,6 +281,14 @@ void MediaCodec::ResourceManagerServiceProxy::removeClient() { mService->removeClient(mPid, getId(mClient)); } void MediaCodec::ResourceManagerServiceProxy::markClientForPendingRemoval() { Mutex::Autolock _l(mLock); if (mService == nullptr) { return; } mService->markClientForPendingRemoval(mPid, getId(mClient)); } bool MediaCodec::ResourceManagerServiceProxy::reclaimResource( const std::vector<MediaResourceParcel> &resources) { Mutex::Autolock _l(mLock); Loading @@ -297,6 +306,33 @@ MediaCodec::BufferInfo::BufferInfo() : mOwnedByClient(false) {} //////////////////////////////////////////////////////////////////////////////// class MediaCodec::ReleaseSurface { public: ReleaseSurface() { BufferQueue::createBufferQueue(&mProducer, &mConsumer); mSurface = new Surface(mProducer, false /* controlledByApp */); struct ConsumerListener : public BnConsumerListener { void onFrameAvailable(const BufferItem&) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} }; sp<ConsumerListener> listener{new ConsumerListener}; mConsumer->consumerConnect(listener, false); mConsumer->setConsumerName(String8{"MediaCodec.release"}); } const sp<Surface> &getSurface() { return mSurface; } private: sp<IGraphicBufferProducer> mProducer; sp<IGraphicBufferConsumer> mConsumer; sp<Surface> mSurface; }; //////////////////////////////////////////////////////////////////////////////// namespace { enum { Loading Loading @@ -1432,7 +1468,13 @@ status_t MediaCodec::reclaim(bool force) { status_t MediaCodec::release() { sp<AMessage> msg = new AMessage(kWhatRelease, this); sp<AMessage> response; return PostAndAwaitResponse(msg, &response); } status_t MediaCodec::releaseAsync() { sp<AMessage> msg = new AMessage(kWhatRelease, this); msg->setInt32("async", 1); sp<AMessage> response; return PostAndAwaitResponse(msg, &response); } Loading Loading @@ -2600,7 +2642,9 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mResourceManagerProxy->removeClient(); if (mReplyID != nullptr) { (new AMessage)->postReply(mReplyID); } break; } Loading Loading @@ -2987,6 +3031,26 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { break; } int32_t async = 0; if (msg->findInt32("async", &async) && async) { if ((mState == CONFIGURED || mState == STARTED || mState == FLUSHED) && mSurface != NULL) { if (!mReleaseSurface) { mReleaseSurface.reset(new ReleaseSurface); } status_t err = connectToSurface(mReleaseSurface->getSurface()); ALOGW_IF(err != OK, "error connecting to release surface: err = %d", err); if (err == OK && !(mFlags & kFlagUsesSoftwareRenderer)) { err = mCodec->setSurface(mReleaseSurface->getSurface()); ALOGW_IF(err != OK, "error setting release surface: err = %d", err); } if (err == OK) { (void)disconnectFromSurface(); mSurface = mReleaseSurface->getSurface(); } } } mReplyID = replyID; setState(msg->what() == kWhatStop ? STOPPING : RELEASING); Loading @@ -2999,6 +3063,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { pushBlankBuffersToNativeWindow(mSurface.get()); } if (async) { mResourceManagerProxy->markClientForPendingRemoval(); (new AMessage)->postReply(mReplyID); mReplyID = 0; } break; } Loading media/libstagefright/include/media/stagefright/MediaCodec.h +5 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,8 @@ struct MediaCodec : public AHandler { // object. status_t release(); status_t releaseAsync(); status_t flush(); status_t queueInputBuffer( Loading Loading @@ -509,6 +511,9 @@ private: // when low latency is on int64_t mInputBufferCounter; // number of input buffers queued since last reset/flush class ReleaseSurface; std::unique_ptr<ReleaseSurface> mReleaseSurface; sp<BatteryChecker> mBatteryChecker; void statsBufferSent(int64_t presentationUs); Loading services/mediaresourcemanager/ResourceManagerService.cpp +42 −1 Original line number Diff line number Diff line Loading @@ -114,6 +114,7 @@ static ResourceInfo& getResourceInfoForEdit( info.uid = uid; info.clientId = clientId; info.client = client; info.pendingRemoval = false; index = infos.add(clientId, info); } Loading Loading @@ -648,6 +649,36 @@ Status ResourceManagerService::overridePid( return Status::ok(); } Status ResourceManagerService::markClientForPendingRemoval(int32_t pid, int64_t clientId) { String8 log = String8::format( "markClientForPendingRemoval(pid %d, clientId %lld)", pid, (long long) clientId); mServiceLog->add(log); Mutex::Autolock lock(mLock); if (!mProcessInfo->isValidPid(pid)) { ALOGE("Rejected markClientForPendingRemoval call with invalid pid."); return Status::fromServiceSpecificError(BAD_VALUE); } ssize_t index = mMap.indexOfKey(pid); if (index < 0) { ALOGV("markClientForPendingRemoval: didn't find pid %d for clientId %lld", pid, (long long)clientId); return Status::ok(); } ResourceInfos &infos = mMap.editValueAt(index); index = infos.indexOfKey(clientId); if (index < 0) { ALOGV("markClientForPendingRemoval: didn't find clientId %lld", (long long) clientId); return Status::ok(); } ResourceInfo &info = infos.editValueAt(index); info.pendingRemoval = true; return Status::ok(); } bool ResourceManagerService::getPriority_l(int pid, int* priority) { int newPid = pid; Loading Loading @@ -693,6 +724,12 @@ bool ResourceManagerService::getLowestPriorityBiggestClient_l( int lowestPriorityPid; int lowestPriority; int callingPriority; // Before looking into other processes, check if we have clients marked for // pending removal in the same process. if (getBiggestClient_l(callingPid, type, client, true /* pendingRemovalOnly */)) { return true; } if (!getPriority_l(callingPid, &callingPriority)) { ALOGE("getLowestPriorityBiggestClient_l: can't get process priority for pid %d", callingPid); Loading Loading @@ -761,7 +798,8 @@ bool ResourceManagerService::isCallingPriorityHigher_l(int callingPid, int pid) } bool ResourceManagerService::getBiggestClient_l( int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client) { int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client, bool pendingRemovalOnly) { ssize_t index = mMap.indexOfKey(pid); if (index < 0) { ALOGE("getBiggestClient_l: can't find resource info for pid %d", pid); Loading @@ -773,6 +811,9 @@ bool ResourceManagerService::getBiggestClient_l( const ResourceInfos &infos = mMap.valueAt(index); for (size_t i = 0; i < infos.size(); ++i) { const ResourceList &resources = infos[i].resources; if (pendingRemovalOnly && !infos[i].pendingRemoval) { continue; } for (auto it = resources.begin(); it != resources.end(); it++) { const MediaResourceParcel &resource = it->second; if (resource.type == type) { Loading services/mediaresourcemanager/ResourceManagerService.h +7 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ #ifndef ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H #define ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H #include <map> #include <aidl/android/media/BnResourceManagerService.h> #include <arpa/inet.h> #include <media/MediaResource.h> Loading Loading @@ -50,6 +52,7 @@ struct ResourceInfo { std::shared_ptr<IResourceManagerClient> client; sp<DeathNotifier> deathNotifier; ResourceList resources; bool pendingRemoval{false}; }; // TODO: convert these to std::map Loading Loading @@ -122,6 +125,8 @@ public: int originalPid, int newPid) override; Status markClientForPendingRemoval(int32_t pid, int64_t clientId) override; Status removeResource(int pid, int64_t clientId, bool checkValid); private: Loading @@ -146,7 +151,8 @@ private: // Gets the client who owns biggest piece of specified resource type from pid. // Returns false if failed. The client will remain unchanged if failed. bool getBiggestClient_l(int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client); std::shared_ptr<IResourceManagerClient> *client, bool pendingRemovalOnly = false); bool isCallingPriorityHigher_l(int callingPid, int pid); Loading Loading
media/libmedia/aidl/android/media/IResourceManagerService.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -94,4 +94,12 @@ interface IResourceManagerService { * remove existing override on originalPid if newPid is -1. */ void overridePid(int originalPid, int newPid); /** * Mark a client for pending removal * * @param pid pid from which the client's resources will be removed. * @param clientId clientId within the pid that will be removed. */ void markClientForPendingRemoval(int pid, long clientId); }
media/libstagefright/MediaCodec.cpp +71 −1 Original line number Diff line number Diff line Loading @@ -199,6 +199,7 @@ struct MediaCodec::ResourceManagerServiceProxy : public RefBase { void addResource(const MediaResourceParcel &resource); void removeResource(const MediaResourceParcel &resource); void removeClient(); void markClientForPendingRemoval(); bool reclaimResource(const std::vector<MediaResourceParcel> &resources); private: Loading Loading @@ -280,6 +281,14 @@ void MediaCodec::ResourceManagerServiceProxy::removeClient() { mService->removeClient(mPid, getId(mClient)); } void MediaCodec::ResourceManagerServiceProxy::markClientForPendingRemoval() { Mutex::Autolock _l(mLock); if (mService == nullptr) { return; } mService->markClientForPendingRemoval(mPid, getId(mClient)); } bool MediaCodec::ResourceManagerServiceProxy::reclaimResource( const std::vector<MediaResourceParcel> &resources) { Mutex::Autolock _l(mLock); Loading @@ -297,6 +306,33 @@ MediaCodec::BufferInfo::BufferInfo() : mOwnedByClient(false) {} //////////////////////////////////////////////////////////////////////////////// class MediaCodec::ReleaseSurface { public: ReleaseSurface() { BufferQueue::createBufferQueue(&mProducer, &mConsumer); mSurface = new Surface(mProducer, false /* controlledByApp */); struct ConsumerListener : public BnConsumerListener { void onFrameAvailable(const BufferItem&) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} }; sp<ConsumerListener> listener{new ConsumerListener}; mConsumer->consumerConnect(listener, false); mConsumer->setConsumerName(String8{"MediaCodec.release"}); } const sp<Surface> &getSurface() { return mSurface; } private: sp<IGraphicBufferProducer> mProducer; sp<IGraphicBufferConsumer> mConsumer; sp<Surface> mSurface; }; //////////////////////////////////////////////////////////////////////////////// namespace { enum { Loading Loading @@ -1432,7 +1468,13 @@ status_t MediaCodec::reclaim(bool force) { status_t MediaCodec::release() { sp<AMessage> msg = new AMessage(kWhatRelease, this); sp<AMessage> response; return PostAndAwaitResponse(msg, &response); } status_t MediaCodec::releaseAsync() { sp<AMessage> msg = new AMessage(kWhatRelease, this); msg->setInt32("async", 1); sp<AMessage> response; return PostAndAwaitResponse(msg, &response); } Loading Loading @@ -2600,7 +2642,9 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mResourceManagerProxy->removeClient(); if (mReplyID != nullptr) { (new AMessage)->postReply(mReplyID); } break; } Loading Loading @@ -2987,6 +3031,26 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { break; } int32_t async = 0; if (msg->findInt32("async", &async) && async) { if ((mState == CONFIGURED || mState == STARTED || mState == FLUSHED) && mSurface != NULL) { if (!mReleaseSurface) { mReleaseSurface.reset(new ReleaseSurface); } status_t err = connectToSurface(mReleaseSurface->getSurface()); ALOGW_IF(err != OK, "error connecting to release surface: err = %d", err); if (err == OK && !(mFlags & kFlagUsesSoftwareRenderer)) { err = mCodec->setSurface(mReleaseSurface->getSurface()); ALOGW_IF(err != OK, "error setting release surface: err = %d", err); } if (err == OK) { (void)disconnectFromSurface(); mSurface = mReleaseSurface->getSurface(); } } } mReplyID = replyID; setState(msg->what() == kWhatStop ? STOPPING : RELEASING); Loading @@ -2999,6 +3063,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { pushBlankBuffersToNativeWindow(mSurface.get()); } if (async) { mResourceManagerProxy->markClientForPendingRemoval(); (new AMessage)->postReply(mReplyID); mReplyID = 0; } break; } Loading
media/libstagefright/include/media/stagefright/MediaCodec.h +5 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,8 @@ struct MediaCodec : public AHandler { // object. status_t release(); status_t releaseAsync(); status_t flush(); status_t queueInputBuffer( Loading Loading @@ -509,6 +511,9 @@ private: // when low latency is on int64_t mInputBufferCounter; // number of input buffers queued since last reset/flush class ReleaseSurface; std::unique_ptr<ReleaseSurface> mReleaseSurface; sp<BatteryChecker> mBatteryChecker; void statsBufferSent(int64_t presentationUs); Loading
services/mediaresourcemanager/ResourceManagerService.cpp +42 −1 Original line number Diff line number Diff line Loading @@ -114,6 +114,7 @@ static ResourceInfo& getResourceInfoForEdit( info.uid = uid; info.clientId = clientId; info.client = client; info.pendingRemoval = false; index = infos.add(clientId, info); } Loading Loading @@ -648,6 +649,36 @@ Status ResourceManagerService::overridePid( return Status::ok(); } Status ResourceManagerService::markClientForPendingRemoval(int32_t pid, int64_t clientId) { String8 log = String8::format( "markClientForPendingRemoval(pid %d, clientId %lld)", pid, (long long) clientId); mServiceLog->add(log); Mutex::Autolock lock(mLock); if (!mProcessInfo->isValidPid(pid)) { ALOGE("Rejected markClientForPendingRemoval call with invalid pid."); return Status::fromServiceSpecificError(BAD_VALUE); } ssize_t index = mMap.indexOfKey(pid); if (index < 0) { ALOGV("markClientForPendingRemoval: didn't find pid %d for clientId %lld", pid, (long long)clientId); return Status::ok(); } ResourceInfos &infos = mMap.editValueAt(index); index = infos.indexOfKey(clientId); if (index < 0) { ALOGV("markClientForPendingRemoval: didn't find clientId %lld", (long long) clientId); return Status::ok(); } ResourceInfo &info = infos.editValueAt(index); info.pendingRemoval = true; return Status::ok(); } bool ResourceManagerService::getPriority_l(int pid, int* priority) { int newPid = pid; Loading Loading @@ -693,6 +724,12 @@ bool ResourceManagerService::getLowestPriorityBiggestClient_l( int lowestPriorityPid; int lowestPriority; int callingPriority; // Before looking into other processes, check if we have clients marked for // pending removal in the same process. if (getBiggestClient_l(callingPid, type, client, true /* pendingRemovalOnly */)) { return true; } if (!getPriority_l(callingPid, &callingPriority)) { ALOGE("getLowestPriorityBiggestClient_l: can't get process priority for pid %d", callingPid); Loading Loading @@ -761,7 +798,8 @@ bool ResourceManagerService::isCallingPriorityHigher_l(int callingPid, int pid) } bool ResourceManagerService::getBiggestClient_l( int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client) { int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client, bool pendingRemovalOnly) { ssize_t index = mMap.indexOfKey(pid); if (index < 0) { ALOGE("getBiggestClient_l: can't find resource info for pid %d", pid); Loading @@ -773,6 +811,9 @@ bool ResourceManagerService::getBiggestClient_l( const ResourceInfos &infos = mMap.valueAt(index); for (size_t i = 0; i < infos.size(); ++i) { const ResourceList &resources = infos[i].resources; if (pendingRemovalOnly && !infos[i].pendingRemoval) { continue; } for (auto it = resources.begin(); it != resources.end(); it++) { const MediaResourceParcel &resource = it->second; if (resource.type == type) { Loading
services/mediaresourcemanager/ResourceManagerService.h +7 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ #ifndef ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H #define ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H #include <map> #include <aidl/android/media/BnResourceManagerService.h> #include <arpa/inet.h> #include <media/MediaResource.h> Loading Loading @@ -50,6 +52,7 @@ struct ResourceInfo { std::shared_ptr<IResourceManagerClient> client; sp<DeathNotifier> deathNotifier; ResourceList resources; bool pendingRemoval{false}; }; // TODO: convert these to std::map Loading Loading @@ -122,6 +125,8 @@ public: int originalPid, int newPid) override; Status markClientForPendingRemoval(int32_t pid, int64_t clientId) override; Status removeResource(int pid, int64_t clientId, bool checkValid); private: Loading @@ -146,7 +151,8 @@ private: // Gets the client who owns biggest piece of specified resource type from pid. // Returns false if failed. The client will remain unchanged if failed. bool getBiggestClient_l(int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client); std::shared_ptr<IResourceManagerClient> *client, bool pendingRemovalOnly = false); bool isCallingPriorityHigher_l(int callingPid, int pid); Loading