MediaPlayer调用过程

framework 架构:

 

 

MediaServer是整个android中media部分的核心。frameworks\base\media\mediaserver\main_mediaserver.cpp 中main 函数是程序的入口

 

简单的调用过程:

frameworks/base/media/java/android/media/MediaPlayer.java -----》 /frameworks/base/media/jni/android_media_MediaPlayer.cpp ------》

/frameworks/av/media/libmedia/mediaplayer.cpp------》

/frameworks/av/media/libmedia/IMediaPlayer.cpp

 

MediaPlayer调用流程:

 

framework提供了MediaPlayer类供上层应用使用,java层的MediaPlayer对象对应一个native层的MediaPlayer对象,同时对应一个mediaserver进程中的Client对象,native层的MediaPlayer对象通过IMediaPlayer binder接口调用到mediaserver进程中的Client对象。MediaPlayer的核心功能都是在mediaserver进程中完成的,在应用程序这一端,只是提供接口,逻辑比较简单,就不细说了,IMediaPlayer接口定义如下,主要就是提供设置数据源、设置输出Surface和启停等控制接口。

 

frameworks/base/media/mediaserver/main_mediaserver.cpp

int main(int argc, char*argv[])

{

sp<ProcessState> proc(ProcessState)::self(); // 获得ProcessState在构造函数中打开binder驱动

sp<IServiceManager> sm = defaultServiceManager();

MediaPlayService::instantiate();

ProcessState::self()->startThreadPool();

IPCThreadState::self()->joinThreadPool();

}

1)获得ServiceManager的代理BpServiceManager

 

sp<IServiceManager> sm = defaultServiceManager();

sp<IServiceManager> defaultServiceManager()

{

if(gDefaultServiceManager != NULL) return gDefaultServiceManager;

{

AutoMutex -l(gDefaultServiceManagerLock);

if(gDefaultServiceManager == NULL)

gDefaultServiceManager = interface_cast<IServiceManager>(

ProcessState::self()->getContextObject(NULL));

}

return gDefaultServiceManager;

}

这里又是一个单例模式,每个进程只需要一个BpServiceManager代理,通过interface_cast获得。

首先看看ProcessState::self()->getContextObject(NULL)

 

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)

{

return getStrongProxyForHandle(0);

}

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)

{

sp<IBinder> result;

AutoMutex _l(mLock);

handle_entry *e = lookupHandleLocked(handle);

if( e != NULL) {

IBinder* b = e->binder;

if(b == NULL || !e->refs->attemptIncWeak(this)) {

b = new BpBinder(handle);

e->binder = b;

if(b) e->refs = b->getWeakRefs();

result = b;

}else{

result.force_set(b);

e->refs->decWeak(this);

}

}

return result;

}

struct handle_entry{

IBinder* binder;

RefBase::weakref_type* refs;

}

ProcessState::handle_entry* ProcessState::lookupHandleLocked()从数组mHandleToObject里面根据handle索引,查找

一个handle_entry结构体。然后根据传入的句柄handle这里为0,表示ServiceManager,new一个BpBinder

所以现在相当于:

gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));

 

现在我们看看interface_cast是什么?

 

frameworks/base/include/binder/IInterface.h

template<typename INTERFACE>

inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)

{

return INTERFACE::asInterface(obj);

}

等价于:

inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj)

{

return IServiceManager::asInterface(obj);

}

继续我们跟到IServiceManager里面去:

frameworks/base/include/binder/IServiceManager.h

class IServiceManager:public IInterface

{

public:

DECLARE_META_INTERFACE(ServiceManager);// MLGB的又是宏!!!

virtual status_t addService(const String16& name, const sp<IBinder>& service) = 0;

virtual sp<IBinder> getService(const String16& name) const = 0;

}

#define DECLARE_META_INTERFACE(INTERFACE) \

static const android::String16 descriptor; \

static android::sp<I##INTERFACE> asInterface( \

const android::sp<android::IBinder>& obj); \

virtual const android::String16& getInterfaceDescriptor() const;\

I##INTERFACE(); \

virtual !I##INTERFACE();

替换之后就是:

static const android::String16 descriptor;

static android::sp<IServiceManager> asInterface(

const android::sp<android::IBinder>& obj);

virtual const android::String16& getInterfaceDescriptor() const;

IServiceManager();

virtual !IServiceManager();

都是一些函数声明,既然有声明的地方,肯定有实现的地方了。

#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \

const android::String16 I##INTERFACE::descriptor(NAME); \

const android::String16& \

I##INTERFACE::getInterfaceDescriptor() const { \

return I##INTERFACE::descriptor; \

} \

android::sp<I##INTERFACE> I##INTERFACE::asInterface( \

const android::sp<android::IBinder>& obj) \

{ \

android::sp<I##INTERFACE> intr; \

if (obj != NULL) { \

intr = static_cast<I##INTERFACE*>( \

obj->queryLocalInterface( \

I##INTERFACE::descriptor).get()); \

if (intr == NULL) { \

intr = new Bp##INTERFACE(obj); \

} \

} \

return intr; \

} \

I##INTERFACE::I##INTERFACE() { } \

I##INTERFACE::~I##INTERFACE() { }

继续替换:

{

const android::String16 IServiceManager::descriptor(NAME);

const android::String16&

IServiceManager::getInterfaceDescriptor() const {

return IServiceManager::descriptor;

}

android::sp<IServiceManager> IServiceManager::asInterface(

const android::sp<android::IBinder>& obj) // 参数为new BpBinder(0)

{

android::sp<IServiceManager> intr;

if (obj != NULL) {

intr = static_cast<IServiceManager*>(

obj->queryLocalInterface(

IServiceManager::descriptor).get());

if (intr == NULL) {

intr = new BpServiceManager(obj); // 原来在这里new 了一个BpServiceManager对象

}

}

return intr;

}

IServiceManager::IServiceManager() { }

IServiceManager::~IServiceManager() { }

}

总结:根据句柄handle 0 创建一个new BpBinder(0),根据这个BpBinder创建了一个BpServiceManager代理。

 

下面来看看BpServiceManager代理:

 

class BpServiceManager : public BpInterface<IServiceManager>

{

public:

BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(iml)

{}

}

这里BpInterface是一个模板类,表示这里BpServiceManager同时继承与BpInterface和IServiceManager类

 

template<typename INTERFACE>

class BpInterface : public INTERFACE, public BpRefBase

{

public: BpInterface(const sp<IBinder>& remote);

...

}

调用了基类BpInterface构造函数:

BpInterface<IServiceManager>::BpInterace(const sp<IBinder>& remote) : BpRefBase(remote)

{}

//这里的remote就是刚刚的new BpBinder(0)

BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()),mRefs(NULL), mState(0)

{

}

 

 

2)添加服务 MediaPlayerService::instantiate();

 

frameworks/base/media/libmediaplayerservice/ibMediaPlayerService.cpp

void MediaPlayerService::instantiate()

{

defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService);

}

defaultServiceManager()返回的是刚创建的BpServiceManager,调用add函数。

BpMediaPlayService作为服务代理端,那么BnMediaPlayerService一定是实现端,MediaPlayerService继承于

BnMediaPlayerService,实现了真正的业务函数。

 

来看看BpServiceManager的addService()函数:

 

virtual status_t addService(const String16& name, const sp<IBinder>& service)

{

Parcel data, reply;

data.writeInterfaceToken(IServiceManager.getInterfaceDescriptor()); // android.os.IServiceManager

data.writeString16(name); // media.player

data.writeStrongBinder(service); // 也就是MediaPlayerService

status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);

return err == NO_ERROR ? reply.readInt32() : err;

}

这里remote()就是前面创建的BpBinder(0)对象。

 

status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)

{

IPCThreadState::self()->transact(mHandle, code, data, reply, flags);

}

status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)

{

// 发送ADD_SERVICE_TRANSACTION请求

writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);

if(reply) // 等待响应

waitForResponse(NULL, reply);

}

status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle,

uint32_t code, const Parcel& data, status_t *statusBuffer)

{

// cmd BC_TRANSACTION 应用程序向BINDER发送的命令

binder_transaction_data tr;

tr.target.handle = handle; // 0

tr.code = code; // ADD_SERVICE_TRANSACTION

tr.flags = binderFlags;

// 把命令和数据一起发送到 Parcel mOut中

mOut.writeInt32(cmd);

mOut.write(&tr, sizeof(tr));

}

status_t IPCThreadState::waitForResponse(Parcel* reply, status_t *acquireResult)

{

int32_t cmd;

while(1)

talkWithDriver();

cmd = mIn.readInt32();

switch(cmd) {

case BR_TRANSACTION_COMPLETE:

...

break;

}

{

return err;

}

status_t IPCThreadState::talkWithDriver(bool doReceive)

{

binder_write_read bwr;

bwr.write_size = outAvail;

bwr.write_buf = (long unsigned int)mOut.data(); // 写入mOut的数据

bwr.read_size = mIn.dataCapacity;

bwr.read_buffer = (long unsigned int)mIn.data();

ioctl(mProcess->mDriverFD, BINDER_WRITE_READm &bwr); // 把mOut写到Binder,并读取mIn数据

}

 

 

 

3)IPCThreadState::joinThreadPool(), ProcessState::self()->startThreadPool()

进入线程循环talkWithDriver 等待客户端Client请求,从Binder读取命令请求进行处理。

 

 

 

到现在为止MediaPlayerService的服务端已经向服务总管ServiceManager注册了,下面我们看看客户端是如何获得服务的代理并和服务端通信的。

我们以MediaPlayer的业务函数decode解析播放一个URL为例

 

sp<IMemory> MediaPlayer::decode(const char*url, uint32_t *pSampleRate, ...)

{

sp<IMemory> p;

const sp<IMediaPlayerService>& service = getMediaPlayerService(); // 获得BpMediaPlayerSerivce代理

if(service != 0)

p = service->decode(url, ....);

return p;

}

这里我们主要分析getMediaPlayerService,客户端是如何向ServiceManager总管查询服务并获得代理的。

 

sp<IMediaPlayerService>& IMediaDeathNotifier::getMediaPlayerService()

{

sp<IServiceManager> sm = defaultServiceManager(); // 生成一个BpServiceManager代理对象

sp<IBinder> binder;

do {

binder = sm->getService(String16("media.player"));

if(binder != 0)

break;

usleep(500000)

} while(true);

sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);

return sMediaPlayerService;

}

 

 

1)首先获得BpServiceManager的代理,然后调用getService()函数向服务总管ServiceManager查询服务。

frameworks/base/libs/binder/IServiceManager.cpp

 

class BpServiceManager : public BpInterface<IServiceManager>

{

public:

virtual sp<IBinder> getService(const String16& name) const

{

for(n = 0; n < 5; n++) {

sp<IBinder> svc = checkService(name); // 调用checkService函数

if(svc != NULL) return svc;

sleep(1);

}

return NULL;

}

virtual sp<IBinder> checkService(const String16& name) const

{

Parcel data, reply;

data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());

// 首先调用data.writeInt32(IPCThreadState::self()->getStrictModePolicy())

// 然后再写入android.os.IServiceManager

data.writeString16(name); // 写入 media.player

remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);

return reply.readStrongBinder();

}

}

这里首先将请求打包成Parcel各式,然后调用remote()->transact()函数,前面我们分析过BpServiceManager::remote()返回

的就是前面new BpBinder(0)对应句柄为ServiceManager。继续去BpBinder中寻找实现代码:

frameworks/base/libs/binder/BpBinder.cpp

 

status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)

{

IPCThreadState::self()->transact(mHandle, code, data, reply, flags);

}

最后调用的IPCThreadState的transact()函数,IPCThreadState是专门提供通过Binder进程间通信的接口的。

 

status_t IPCTheadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)

{

// 填充binder_transaction_data 结构体,写入到mOut中去

writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);

// 调用talkWithDriver() 将mOut写到Binder驱动,并从Binder驱动读取mIn数据

waitForResponse(reply);

}

首先通过writeTransactionData函数来填充mOut结构体,mOut里面内容为:

 mOut.writeInt32(BC_TRANSACTION);

 mOut.write(&tr, sizeof(tr));

这里binder_transaction_data tr内容为:

 tr.target.handle = 0; // 表面是发往ServiceManager的

 tr.code = CHECK_SERVICE_TRANSACTION;

 tr.flags = 0;

tr.data内容为:

 data.writeInt32(IPCThreadState::self()->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);

 data.writeString16("android.os.IServiceManager");

 data.writeString16("media.player");

根据前面Android开发之ServiceManager一章中我们分析,svcmgr_handler处理从句柄为0的Binder的请求:

strict_policy = bio_get_string32();

s = bio_get_string16(); // 就是上面的android.os.IServiceManager

s = bio_get_string16(); // 就是上面的 media.player

根据media.player遍历全局链表svclist找到相应的服务,调用bio_put_ref(reply, ptr) 返回目标Binder实体。

 

 

这个waitForResponse()函数是关键:

 

status_t IPCThreadState::waitForResponse(Parcel* reply)

{

while(1) {

talkWithDriver(); // 输入mOut 输出mIn

cmd = mIn.readInt32();

switch(cmd) {

case BR_REPLY:

{

binder_transaction_data tr;

mIn.read(&tr, sizeof(tr));

if(reply) {

reply->ipcSetDataReference(reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),

tr.data.size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets),

tr.offsets_size/sizeof(sizt_t), freeBuffer, this);

} else {

err = *static_cast<const status_t*>(tr.data.ptr.buffer);

freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),

tr.data.size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets),

tr.offsets_size/sizeof(sizt_t), freeBuffer, this)

}

}

}

}

}

最后返回的是:return reply.readStrongBinder();进入到Parcel的readStrongBinder()函数

sp<IBinder> Parcel::readStrongBinder() const

{

sp<IBinder> val;

unflatten_binder(ProcessState::self(), *this, &val);

return val;

}

status_t unflatten_binder(const sp<ProcessState>& proc, const Parcel& in, sp<IBinder>* out)

{

const flat_binder_object* flat = in.readObject(false);

if(flat) {

switch(flat->type) {

case BINDER_TYPE_BINDER:

*out = static_cast<IBinder*>(flat->cookie);

return finish_unflatten_binder(NULL, *flat, in);

case BINDER_TYPE_HANDLE:

*out = proc->getStrongProxyForHandle(flat->handle);

return finish_unflatten_binder(static_cast<BpBinder*>(out->get()), *flat, in);

}

}

}

这里flat->type是BINDER_TYPE_HANDLE,所以调用ProcessState::getStrongProxyForHandle()函数

 

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)

{

sp<IBinder> result;

handle_entry* e = lookupHandleLocked(handle);

if(e != NULL) {

IBinder* b = e->binder;

if(b == NULL || !e->refs->attemptIncWeak(this)) {

b = new BpBinder(handle);

e->binder = b;

if( b ) e->refs = e->getWeakRefs();

result = b;

} else {

result.force_set(b);

e->refs->decWeak(this);

}

}

return result;

}

这里的handle就是ServiceManager内维护的MediaPlayerService对应的Binder句柄,这个ProcessState根据这个句柄

new 了一个BpBinder,并将其保存起来,这样下次需要从ServiceManager请求获取到相同句柄的时候就可以直接返回了。

最后根据这个返回的BpBinder获得MediaPlayerService的代理:

sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);

根据前面ServiceManager一样,最后调用的是IMediaPlayerService的asInterface()宏函数

 

android::sp<IMediaPlayerService> IMediaPlayerService::asInterface(const android::sp<android::IBinder>& obj)

{

android::sp<IMediaPlayerService> intr;

if(obj != NULL ) {

intr = static_cast<IMediaPlayerService>(

obj->queryLocalInterface(IMediaPlayerService::descriptor).get);

if (intr == NULL) {

intr = new BpMediaPlayerService(obj);

}

}

return intr;

}

 

 

这样我就获得了一个代理BpMediaPlayerService对象,它的remote()为BpBinder(handle),这个handle就是向服务总共ServiceManager

查询到的MediaPlayerService对应的Binder句柄。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值