IResourceManagerClient – 回调应用提供的接口
ResourceManagerService 调用 Client 的接口.
主要是 reclaimResource(), 通知 Client 回收资源.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// frameworks/av/media/libmedia/aidl/android/media/IResourceManagerClient.aidl interface IResourceManagerClient { /** * Instruct the client to reclaim its resources. * * @return true if the reclaim was successful and false otherwise. */ boolean reclaimResource(); /** * Retrieve the name of the client. * * @return name of the client. */ @utf8InCpp String getName(); } |
MediaCodec 中 Client 的创建 添加 移除
Client 对象创建
MediaCodec 内部有个内部类 ResourceManagerClient, 是 IResourceManagerClient 的子类.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
// frameworks/av/media/libstagefright/MediaCodec.cpp struct ResourceManagerClient : public BnResourceManagerClient { explicit ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {} Status reclaimResource(bool* _aidl_return) override { sp<MediaCodec> codec = mMediaCodec.promote(); if (codec == NULL) { // codec is already gone. *_aidl_return = true; return Status::ok(); } status_t err = codec->reclaim();// 回调 MediaCodec::reclaim 函数 if (err == WOULD_BLOCK) { ALOGD("Wait for the client to release codec."); usleep(kMaxReclaimWaitTimeInUs); ALOGD("Try to reclaim again."); err = codec->reclaim(true /* force */); } if (err != OK) { ALOGW("ResourceManagerClient failed to release codec with err %d", err); } *_aidl_return = (err == OK); return Status::ok(); } Status getName(::std::string* _aidl_return) override { _aidl_return->clear(); sp<MediaCodec> codec = mMediaCodec.promote(); if (codec == NULL) { // codec is already gone. return Status::ok(); } AString name; if (codec->getName(&name) == OK) { *_aidl_return = name.c_str(); } return Status::ok(); } virtual ~ResourceManagerClient() {} private: wp<MediaCodec> mMediaCodec; DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient); }; |
将 Client 对象被添加到 ResourceManagerService
MediaCodec 中使用 ResourceManagerServiceProxy 与 ResourceManagerService 通信.
调用 ResourceManagerService::addResource 将对象加入 Service.
这里的 Resource 指的是 MediaResource
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
// frameworks/av/media/libstagefright/MediaCodec.cpp // 这里只有当是视频时才处理 void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { ... case kWhatComponentAllocated:// 编码器创建完成 { ... if (mIsVideo) { // audio codec is currently ignored. mResourceManagerProxy->addResource( MediaResource::CodecResource(mFlags & kFlagIsSecure, mIsVideo)); } ... } ... case kWhatStartCompleted:// start 之后 { ... if (mIsVideo) { mResourceManagerProxy->addResource( MediaResource::GraphicMemoryResource(getGraphicBufferSize())); } ... break; } ... } } void MediaCodec::ResourceManagerServiceProxy::addResource( const MediaResourceParcel &resource) { std::vector<MediaResourceParcel> resources; resources.push_back(resource); Mutex::Autolock _l(mLock); if (mService == nullptr) { return; } mService->addResource(mPid, mUid, getId(mClient), mClient, resources); } // 获取 client 对象的地址 static int64_t getId(const std::shared_ptr<IResourceManagerClient> &client) { return (int64_t) client.get(); } |
还有其它几处, 不了解触发时机
移除 Client
同样需要从 MediaCodec 发起, 或者 Service 端监听到死亡自动移除
MediaCodec 析构时, 会调用 removeClient()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// frameworks/av/media/libstagefright/MediaCodec.cpp MediaCodec::~MediaCodec() { CHECK_EQ(mState, UNINITIALIZED); mResourceManagerProxy->removeClient(); flushMediametrics(); } void MediaCodec::ResourceManagerServiceProxy::removeClient() { Mutex::Autolock _l(mLock); if (mService == nullptr) { return; } mService->removeClient(mPid, getId(mClient)); } |
0 Comments