Android开发之MediaPlayerService服务详解(一)

前面一节我们分析了Binder通信相关的两个重要类:ProcessState 和 IPCThreadState。ProcessState负责打开Binder
驱动,每个进程只有一个。而 IPCThreadState负责提供与Binder通信相关的接口,每个线程有一个。下面我们通过具体
示例MediaPlayerService来分析我们应用程序中怎么通过Binder通信的。


frameworks/base/media/mediaserver/main_mediaserver.cpp

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:14px;">int main(int argc, char*argv[])  
  2. {  
  3.     sp<ProcessState> proc(ProcessState)::self();  // 获得ProcessState在构造函数中打开binder驱动  
  4.     sp<IServiceManager> sm = defaultServiceManager();  
  5.     MediaPlayService::instantiate();  
  6.     ProcessState::self()->startThreadPool();  
  7.     IPCThreadState::self()->joinThreadPool();  
  8. }</span>  

1)获得ServiceManager的代理BpServiceManager

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. sp<IServiceManager> sm = defaultServiceManager();  
  2. sp<IServiceManager> defaultServiceManager()  
  3. {  
  4.     if(gDefaultServiceManager != NULL) return gDefaultServiceManager;  
  5.     {  
  6.         AutoMutex -l(gDefaultServiceManagerLock);  
  7.         if(gDefaultServiceManager == NULL)  
  8.             gDefaultServiceManager = interface_cast<IServiceManager>(  
  9.                 ProcessState::self()->getContextObject(NULL));  
  10.     }  
  11.     return gDefaultServiceManager;  
  12. }  

这里又是一个单例模式,每个进程只需要一个BpServiceManager代理,通过interface_cast获得。
首先看看ProcessState::self()->getContextObject(NULL)

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)  
  2. {  
  3.     return getStrongProxyForHandle(0);  
  4. }  
  5.   
  6. sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)   
  7. {  
  8.     sp<IBinder> result;  
  9.     AutoMutex _l(mLock);  
  10.     handle_entry *e = lookupHandleLocked(handle);  
  11.     if( e != NULL) {  
  12.         IBinder* b = e->binder;  
  13.         if(b == NULL || !e->refs->attemptIncWeak(this)) {  
  14.             b = new BpBinder(handle);  
  15.             e->binder = b;  
  16.             if(b) e->refs = b->getWeakRefs();  
  17.             result = b;  
  18.         }else{  
  19.             result.force_set(b);  
  20.             e->refs->decWeak(this);  
  21.         }  
  22.     }  
  23.     return result;  
  24. }  
  25. struct handle_entry{  
  26.     IBinder* binder;  
  27.     RefBase::weakref_type* refs;  
  28. }  

ProcessState::handle_entry* ProcessState::lookupHandleLocked()从数组mHandleToObject里面根据handle索引,查找
一个handle_entry结构体。然后根据传入的句柄handle这里为0,表示ServiceManager,new一个BpBinder
所以现在相当于:
gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));

现在我们看看interface_cast是什么?

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. frameworks/base/include/binder/IInterface.h  
  2. template<typename INTERFACE>  
  3. inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)  
  4. {  
  5.     return INTERFACE::asInterface(obj);  
  6. }  
  7. 等价于:  
  8. inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj)  
  9. {  
  10.     return IServiceManager::asInterface(obj);  
  11. }  
  12. 继续我们跟到IServiceManager里面去:  
  13. frameworks/base/include/binder/IServiceManager.h  
  14. class IServiceManager:public IInterface  
  15. {  
  16. public:  
  17.     DECLARE_META_INTERFACE(ServiceManager);// MLGB的又是宏!!!  
  18.     virtual status_t addService(const String16& name, const sp<IBinder>& service) = 0;  
  19.     virtual sp<IBinder> getService(const String16& name) const = 0;  
  20. }  
  21. #define DECLARE_META_INTERFACE(INTERFACE)               \  
  22.     static const android::String16 descriptor;          \  
  23.     static android::sp<I##INTERFACE> asInterface(         \  
  24.             const android::sp<android::IBinder>& obj);    \  
  25.     virtual const android::String16& getInterfaceDescriptor() const;\  
  26.     I##INTERFACE();                         \  
  27.     virtual !I##INTERFACE();  
  28. 替换之后就是:  
  29.     static const android::String16 descriptor;            
  30.     static android::sp<IServiceManager> asInterface(            
  31.             const android::sp<android::IBinder>& obj);      
  32.     virtual const android::String16& getInterfaceDescriptor() const;  
  33.     IServiceManager();                            
  34.     virtual !IServiceManager();  
  35. 都是一些函数声明,既然有声明的地方,肯定有实现的地方了。  
  36. #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \  
  37.     const android::String16 I##INTERFACE::descriptor(NAME);             \  
  38.     const android::String16&                                            \  
  39.             I##INTERFACE::getInterfaceDescriptor() const {              \  
  40.         return I##INTERFACE::descriptor;                                \  
  41.     }                                                                   \  
  42.     android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \  
  43.             const android::sp<android::IBinder>& obj)                   \  
  44.     {                                                                   \  
  45.         android::sp<I##INTERFACE> intr;                                 \  
  46.         if (obj != NULL) {                                              \  
  47.             intr = static_cast<I##INTERFACE*>(                          \  
  48.                 obj->queryLocalInterface(                               \  
  49.                         I##INTERFACE::descriptor).get());               \  
  50.             if (intr == NULL) {                                         \  
  51.                 intr = new Bp##INTERFACE(obj);                          \  
  52.             }                                                           \  
  53.         }                                                               \  
  54.         return intr;                                                    \  
  55.     }                                                                   \  
  56.     I##INTERFACE::I##INTERFACE() { }                                    \  
  57.     I##INTERFACE::~I##INTERFACE() { }                                     
  58. 继续替换:  
  59. {  
  60.     const android::String16 IServiceManager::descriptor(NAME);               
  61.     const android::String16&                                              
  62.            IServiceManager::getInterfaceDescriptor() const {                
  63.         return IServiceManager::descriptor;                                  
  64.     }                                                                     
  65.     android::sp<IServiceManager> IServiceManager::asInterface(                  
  66.             const android::sp<android::IBinder>& obj)   // 参数为new BpBinder(0)                  
  67.     {                                                                     
  68.         android::sp<IServiceManager> intr;                                   
  69.         if (obj != NULL) {                                                
  70.             intr = static_cast<IServiceManager*>(                            
  71.                 obj->queryLocalInterface(                                 
  72.                         IServiceManager::descriptor).get());                 
  73.             if (intr == NULL) {                                           
  74.                 intr = new BpServiceManager(obj);     // 原来在这里new 了一个BpServiceManager对象                       
  75.             }                                                             
  76.         }                                                                 
  77.         return intr;                                                      
  78.     }                                                                     
  79.     IServiceManager::IServiceManager() { }                                      
  80.     IServiceManager::~IServiceManager() { }                                     
  81. }  

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

下面来看看BpServiceManager代理:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class BpServiceManager : public BpInterface<IServiceManager>  
  2. {  
  3. public:  
  4.     BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(iml)  
  5.     {}  
  6. }   

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

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. template<typename INTERFACE>  
  2. class BpInterface : public INTERFACE, public BpRefBase  
  3. {  
  4. public: BpInterface(const sp<IBinder>& remote);  
  5. ...  
  6. }  
  7. 调用了基类BpInterface构造函数:  
  8. BpInterface<IServiceManager>::BpInterace(const sp<IBinder>& remote) : BpRefBase(remote)  
  9. {}  
  10. //这里的remote就是刚刚的new BpBinder(0)  
  11. BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()),mRefs(NULL), mState(0)  
  12. {  
  13. }  

 

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

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. frameworks/base/media/libmediaplayerservice/ibMediaPlayerService.cpp  
  2. void <strong style="color:black;background-color:#A0FFFF">MediaPlayerService</strong>::instantiate()  
  3. {  
  4.     defaultServiceManager()->addService(String16("media.player"), new <strong style="color:black;background-color:#A0FFFF">MediaPlayerService</strong>);  
  5. }  

defaultServiceManager()返回的是刚创建的BpServiceManager,调用add函数。
BpMediaPlayService作为服务代理端,那么BnMediaPlayerService一定是实现端,MediaPlayerService继承于
BnMediaPlayerService,实现了真正的业务函数。

来看看BpServiceManager的addService()函数:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. virtual status_t addService(const String16& name, const sp<IBinder>& service)  
  2. {  
  3.     Parcel data, reply;  
  4.     data.writeInterfaceToken(IServiceManager.getInterfaceDescriptor()); // android.os.IServiceManager  
  5.     data.writeString16(name);   // media.player  
  6.     data.writeStrongBinder(service);    // 也就是<strong style="color:black;background-color:#A0FFFF">MediaPlayerService</strong>  
  7.     status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);  
  8.     return err == NO_ERROR ? reply.readInt32() : err;  
  9. }  

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

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  2. {  
  3.     IPCThreadState::self()->transact(mHandle, code, data, reply, flags);  
  4. }  
  5. status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  6. {  
  7.     // 发送ADD_SERVICE_TRANSACTION请求  
  8.     writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);  
  9.     if(reply)   // 等待响应  
  10.         waitForResponse(NULL, reply);  
  11. }  
  12.   
  13. status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle,   
  14.         uint32_t code, const Parcel& data, status_t *statusBuffer)  
  15. {  
  16.     // cmd  BC_TRANSACTION  应用程序向BINDER发送的命令  
  17.     binder_transaction_data tr;  
  18.     tr.target.handle = handle;  // 0  
  19.     tr.code = code;         // ADD_SERVICE_TRANSACTION  
  20.     tr.flags = binderFlags;  
  21.     // 把命令和数据一起发送到 Parcel mOut中  
  22.     mOut.writeInt32(cmd);  
  23.     mOut.write(&tr, sizeof(tr));  
  24. }  
  25. status_t IPCThreadState::waitForResponse(Parcel* reply, status_t *acquireResult)  
  26. {  
  27.     int32_t cmd;  
  28.       
  29.     while(1)   
  30.         talkWithDriver();  
  31.         cmd = mIn.readInt32();  
  32.         switch(cmd) {  
  33.             case BR_TRANSACTION_COMPLETE:  
  34.                 ...  
  35.                 break;  
  36.         }  
  37.     {  
  38.     return err;  
  39. }  
  40. status_t IPCThreadState::talkWithDriver(bool doReceive)  
  41. {  
  42.     binder_write_read bwr;  
  43.       
  44.     bwr.write_size = outAvail;  
  45.     bwr.write_buf = (long unsigned int)mOut.data(); // 写入mOut的数据  
  46.     bwr.read_size = mIn.dataCapacity;  
  47.     bwr.read_buffer = (long unsigned int)mIn.data();  
  48.     ioctl(mProcess->mDriverFD, BINDER_WRITE_READm &bwr); // 把mOut写到Binder,并读取mIn数据  
  49. }  


 

3)IPCThreadState::joinThreadPool(), ProcessState::self()->startThreadPool()
进入线程循环talkWithDriver 等待客户端Client请求,从Binder读取命令请求进行处理。

 

到现在为止MediaPlayerService的服务端已经向服务总管ServiceManager注册了,下面我们看看客户端是如何获得服务的代理并和服务端通信的。
我们以MediaPlayer的业务函数decode解析播放一个URL为例

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. sp<IMemory> MediaPlayer::decode(const char*url, uint32_t *pSampleRate, ...)  
  2. {  
  3.     sp<IMemory> p;  
  4.     const sp<IMediaPlayerService>service = getMediaPlayerService(); // 获得BpMediaPlayerSerivce代理  
  5.     if(service != 0)  
  6.         p = service->decode(url, ....);  
  7.     return p;  
  8. }  

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

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. sp<IMediaPlayerService>& IMediaDeathNotifier::getMediaPlayerService()  
  2. {  
  3.     sp<IServiceManager> sm = defaultServiceManager(); // 生成一个BpServiceManager代理对象  
  4.     sp<IBinder> binder;  
  5.     do {  
  6.         binder = sm->getService(String16("media.player"));  
  7.         if(binder != 0)  
  8.             break;  
  9.         usleep(500000)  
  10.     } while(true);  
  11.     sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);  
  12.     return sMediaPlayerService;  
  13. }  

 

1)首先获得BpServiceManager的代理,然后调用getService()函数向服务总管ServiceManager查询服务。
frameworks/base/libs/binder/IServiceManager.cpp

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class BpServiceManager : public BpInterface<IServiceManager>  
  2. {  
  3. public:  
  4.     virtual sp<IBinder> getService(const String16& name) const  
  5.     {  
  6.         for(n = 0; n < 5; n++) {  
  7.             sp<IBinder> svc = checkService(name); // 调用checkService函数  
  8.             if(svc != NULL) return svc;  
  9.             sleep(1);  
  10.         }  
  11.         return NULL;  
  12.     }  
  13.     virtual sp<IBinder> checkService(const String16& name) const   
  14.     {  
  15.         Parcel data, reply;  
  16.         data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());  
  17.         // 首先调用data.writeInt32(IPCThreadState::self()->getStrictModePolicy())  
  18.         // 然后再写入android.os.IServiceManager  
  19.         data.writeString16(name);   // 写入 media.player  
  20.         remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);  
  21.         return reply.readStrongBinder();  
  22.     }  
  23. }  

这里首先将请求打包成Parcel各式,然后调用remote()->transact()函数,前面我们分析过BpServiceManager::remote()返回
的就是前面new BpBinder(0)对应句柄为ServiceManager。继续去BpBinder中寻找实现代码:
frameworks/base/libs/binder/BpBinder.cpp

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  2. {  
  3.     IPCThreadState::self()->transact(mHandle, code, data, reply, flags);  
  4. }  

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

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. status_t IPCTheadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  2. {  
  3.     // 填充binder_transaction_data 结构体,写入到mOut中去  
  4.     writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);  
  5.       
  6.     // 调用talkWithDriver() 将mOut写到Binder驱动,并从Binder驱动读取mIn数据  
  7.     waitForResponse(reply);  
  8. }  

首先通过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()函数是关键:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. status_t IPCThreadState::waitForResponse(Parcel* reply)  
  2. {  
  3.     while(1) {  
  4.         talkWithDriver();   // 输入mOut 输出mIn  
  5.         cmd = mIn.readInt32();  
  6.         switch(cmd) {  
  7.         case BR_REPLY:    
  8.         {  
  9.             binder_transaction_data tr;  
  10.             mIn.read(&tr, sizeof(tr));  
  11.             if(reply) {  
  12.             reply->ipcSetDataReference(reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),  
  13.             tr.data.size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets),   
  14.             tr.offsets_size/sizeof(sizt_t), freeBuffer, this);  
  15.             } else {  
  16.             err = *static_cast<const status_t*>(tr.data.ptr.buffer);  
  17.             freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),  
  18.             tr.data.size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets),   
  19.             tr.offsets_size/sizeof(sizt_t), freeBuffer, this)  
  20.             }  
  21.         }  
  22.         }  
  23.     }  
  24. }  
  25. 最后返回的是:return reply.readStrongBinder();进入到Parcel的readStrongBinder()函数  
  26. sp<IBinder> Parcel::readStrongBinder() const  
  27. {  
  28.     sp<IBinder> val;  
  29.     unflatten_binder(ProcessState::self(), *this, &val);  
  30.     return val;  
  31. }  
  32. status_t unflatten_binder(const sp<ProcessState>& proc, const Parcel& in, sp<IBinder>* out)  
  33. {  
  34.     const flat_binder_object* flat = in.readObject(false);  
  35.     if(flat) {  
  36.         switch(flat->type) {  
  37.             case BINDER_TYPE_BINDER:  
  38.                 *out = static_cast<IBinder*>(flat->cookie);  
  39.                 return finish_unflatten_binder(NULL, *flat, in);  
  40.             case BINDER_TYPE_HANDLE:  
  41.                 *out = proc->getStrongProxyForHandle(flat->handle);  
  42.                 return finish_unflatten_binder(static_cast<BpBinder*>(out->get()), *flat, in);  
  43.         }  
  44.     }  
  45. }  

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

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)  
  2. {  
  3.     sp<IBinder> result;  
  4.       
  5.     handle_entry* e = lookupHandleLocked(handle);  
  6.     if(e != NULL) {  
  7.         IBinder* b = e->binder;  
  8.         if(b == NULL || !e->refs->attemptIncWeak(this)) {  
  9.             b = new BpBinder(handle);  
  10.             e->binder = b;  
  11.             if( b ) e->refs = e->getWeakRefs();  
  12.             result = b;  
  13.         } else {  
  14.             result.force_set(b);  
  15.             e->refs->decWeak(this);  
  16.         }  
  17.     }  
  18.     return result;  
  19. }  

这里的handle就是ServiceManager内维护的MediaPlayerService对应的Binder句柄,这个ProcessState根据这个句柄
new 了一个BpBinder,并将其保存起来,这样下次需要从ServiceManager请求获取到相同句柄的时候就可以直接返回了。
最后根据这个返回的BpBinder获得MediaPlayerService的代理:
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
根据前面ServiceManager一样,最后调用的是IMediaPlayerService的asInterface()宏函数

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. android::sp<IMediaPlayerService> IMediaPlayerService::asInterface(const android::sp<android::IBinder>& obj)  
  2. {  
  3.     android::sp<IMediaPlayerService> intr;  
  4.     if(obj != NULL ) {  
  5.         intr = static_cast<IMediaPlayerService>(  
  6.             obj->queryLocalInterface(IMediaPlayerService::descriptor).get);  
  7.             if (intr == NULL) {  
  8.                 intr = new BpMediaPlayerService(obj);  
  9.             }  
  10.     }  
  11.     return intr;  
  12. }  

 

这样我就获得了一个代理BpMediaPlayerService对象,它的remote()为BpBinder(handle),这个handle就是向服务总共ServiceManager
查询到的MediaPlayerService对应的Binder句柄。

   下一章我们分析,客户端如何通过这个BpServiceManager代理对象调用服务端MediaPlayerService的业务函数的?



原文二:Android的MediaPlayer分析

链接:http://www.byywee.com/page/M0/S846/846697.html

前段时候接到任务,商量一下MediaPlayer在Android体系中是如何实现的。到如今为止终于有些端倪了,在查询拜访代码时辰固然有些吃力,然则还算是有所得的。今天把本身对MediaPlayer的粗浅懂得拿出来,一来作为笔记备份;一来和大师分享。以下代码都是以Android4.2代码为根蒂根基的,迎接大师斧正,共同窗习。

  为了有一个完全的浏览代码的脉络和思路,我是以一个很是简单的Java应用法度开端。法度很是简单,代码如下:



1 MediaPlayer mediaPlayer = new MediaPlayer();

2 mediaPlayer.setDataSource("/sdcard/test.mp3");

3 mediaPlayer.prepare();

4 mediaPlayer.start();

5 mediaPlayer.stop();


 创建MediaPlayer对象


从第一行代码开端看:


MediaPlayer mediaPlayer = new MediaPlayer();
这行代码是在Java应用法度中,功能是新建一个对象。既然如此,我们就看看MediaPlayer这个类在Java层的机关函数,如下:


[/frameworks/base/media/java/android/media/MediaPlayer.java]



 1     public MediaPlayer() {

 2 

 3         Looper looper;

 4         if ((looper = Looper.myLooper()) != null) {

 5             mEventHandler = new EventHandler(this, looper);

 6         } else if ((looper = Looper.getMainLooper()) != null) {

 7             mEventHandler = new EventHandler(this, looper);

 8         } else {

 9             mEventHandler = null;

10         }

11 

12         /* Native setup requires a weak reference to our object.

13          * It""s easier to create it here than in C++.

14          */

15         native_setup(new WeakReference<MediaPlayer>(this));

16     }


在这个机关函数中,较为首要的就是native_setup(). 这个函数在之前的声明中包含native,申明这是一个native函数。也就是说native_setup()函数其实native层实现的。接下来我们要做的就是按照JNI找到这个函数是如何实现的。native函数实现地点的文件的文件名都是如下定名的,把包名中的"."调换为"_"+类名。所以我们要找文件就是android_media_MediaPlayer.cpp.在这个文件中我们有个首要的数组,如下:


【/frameworks/base/media/jni/android_media_MediaPlayer.cpp】



 1 static JNINativeMethod gMethods[] = {

 2     {

 3         "_setDataSource",

 4         "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",

 5         (void *)android_media_MediaPlayer_setDataSourceAndHeaders

 6     },

 7 

 8     {"setDataSource",       "(Ljava/io/FileDescriptor;JJ)V",    (void *)android_media_MediaPlayer_setDataSourceFD},

 9     {"_setVideoSurface",    "(Landroid/view/Surface;)V",        (void *)android_media_MediaPlayer_setVideoSurface},

10     {"prepare",             "()V",                              (void *)android_media_MediaPlayer_prepare},

11     {"prepareAsync",        "()V",                              (void *)android_media_MediaPlayer_prepareAsync},

12     {"_start",              "()V",                              (void *)android_media_MediaPlayer_start},

13     {"_stop",               "()V",                              (void *)android_media_MediaPlayer_stop},

14     {"getVideoWidth",       "()I",                              (void *)android_media_MediaPlayer_getVideoWidth},

15     {"getVideoHeight",      "()I",                              (void *)android_media_MediaPlayer_getVideoHeight},

16     {"seekTo",              "(I)V",                             (void *)android_media_MediaPlayer_seekTo},

17     {"_pause",              "()V",                              (void *)android_media_MediaPlayer_pause},

18     {"isPlaying",           "()Z",                              (void *)android_media_MediaPlayer_isPlaying},

19     {"getCurrentPosition",  "()I",                              (void *)android_media_MediaPlayer_getCurrentPosition},

20     {"getDuration",         "()I",                              (void *)android_media_MediaPlayer_getDuration},

21     {"_release",            "()V",                              (void *)android_media_MediaPlayer_release},

22     {"_reset",              "()V",                              (void *)android_media_MediaPlayer_reset},

23     {"setAudioStreamType",  "(I)V",                             (void *)android_media_MediaPlayer_setAudioStreamType},

24     {"setLooping",          "(Z)V",                             (void *)android_media_MediaPlayer_setLooping},

25     {"isLooping",           "()Z",                              (void *)android_media_MediaPlayer_isLooping},

26     {"setVolume",           "(FF)V",                            (void *)android_media_MediaPlayer_setVolume},

27     {"getFrameAt",          "(I)Landroid/graphics/Bitmap;",     (void *)android_media_MediaPlayer_getFrameAt},

28     {"native_invoke",       "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},

29     {"native_setMetadataFilter", "(Landroid/os/Parcel;)I",      (void *)android_media_MediaPlayer_setMetadataFilter},

30     {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer_getMetadata},

31     {"native_init",         "()V",                              (void *)android_media_MediaPlayer_native_init},

32     {"native_setup",        "(Ljava/lang/Object;)V",            (void *)android_media_MediaPlayer_native_setup},

33     {"native_finalize",     "()V",                              (void *)android_media_MediaPlayer_native_finalize},

34     {"getAudioSessionId",   "()I",                              (void *)android_media_MediaPlayer_get_audio_session_id},

35     {"setAudioSessionId",   "(I)V",                             (void *)android_media_MediaPlayer_set_audio_session_id},

36     {"setAuxEffectSendLevel", "(F)V",                           (void *)android_media_MediaPlayer_setAuxEffectSendLevel},

37     {"attachAuxEffect",     "(I)V",                             (void *)android_media_MediaPlayer_attachAuxEffect},

38     {"native_pullBatteryData", "(Landroid/os/Parcel;)I",        (void *)android_media_MediaPlayer_pullBatteryData},

39     {"setParameter",        "(ILandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer_setParameter},

40     {"getParameter",        "(ILandroid/os/Parcel;)V",          (void *)android_media_MediaPlayer_getParameter},

41     {"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I",  (void *)android_media_MediaPlayer_setRetransmitEndpoint},

42     {"setNextMediaPlayer",  "(Landroid/media/MediaPlayer;)V",   (void *)android_media_MediaPlayer_setNextMediaPlayer},

43 };


在这个数组中,第一列默示的是Java层中函数名,第二列是Java层函数对应的参数以及返回值类型,第三列就是对应在Native层的函数名。从这个数组中,我们可以找到native_setup(),对应的函数名是android_media_MediaPlayer_native_setup,接下来我们就看看这个函数的实现:


【/frameworks/base/media/jni/android_media_MediaPlayer.cpp】



 1 static void

 2 android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)

 3 {

 4     ALOGV("native_setup");

 5     sp<MediaPlayer> mp = new MediaPlayer();

 6     if (mp == NULL) {

 7         jniThrowException(env, "java/lang/RuntimeException", "Out of memory");

 8         return;

 9     }

10 

11     // create new listener and give it to MediaPlayer

12     sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);

13     mp->setListener(listener);

14 

15     // Stow our new C++ MediaPlayer in an opaque field in the Java object.

16     setMediaPlayer(env, thiz, mp);

17 }


 在本文中,对于解析MediaPlayer流程较为首要的函数,我都邑用红色字体标识出来。这不是说没有标红的就不首要,在法度里没有无用的代码,只是对于我们此次的流程解析不太首要罢了。先看第5行 



sp<MediaPlayer> mp = new MediaPlayer();


这行代码的功能就是创建一个MediaPlayer类的对象,不过这个对象是Native层的对象,也就是说这个Native层的MediaPlayer类是应用C++代码实现的。我们先往下看下面一句较为首要的代码,然后在后头解析Native层MediaPlayer对象的机关函数。



16     setMediaPlayer(env, thiz, mp);


这行代码的功能就是把我们新创建的Native层的MediaPlayer对象保存到Java层。也就是说将来我们经由过程getMediaplayer()的时辰获取到的就是这个对象。接下来,我就开端解析Native层的MediaPlayer的机关函数,代码如下:



 1 MediaPlayer::MediaPlayer()

 2 {

 3     ALOGV("constructor");

 4     mListener = NULL;

 5     mCookie = NULL;

 6     mStreamType = AUDIO_STREAM_MUSIC;

 7     mCurrentPosition = -1;

 8     mSeekPosition = -1;

 9     mCurrentState = MEDIA_PLAYER_IDLE;

10     mPrepareSync = false;

11     mPrepareStatus = NO_ERROR;

12     mLoop = false;

13     mLeftVolume = mRightVolume = 1.0;

14     mVideoWidth = mVideoHeight = 0;

15     mLockThreadId = 0;

16     mAudioSessionId = AudioSystem::newAudioSessionId();

17     AudioSystem::acquireAudioSessionId(mAudioSessionId);

18     mSendLevel = 0;

19     mRetransmitEndpointValid = false;

20 }


在机关Native层的MediaPlayer对象的时辰,也会机关父类的对象。只不过在这些对象机关过程中,对于我们解析MediaPlayer流程并没有希罕首要的器材。然则我们要懂得的一点就是在MediaPlayer的父类IMediaDeathNotifier中有个很首要的办法getMediaPlayerService(),对于这个办法我们在之后的解析过程中还会用到,到时辰在具体介绍。


到这里为止,这一末节根蒂根基停止。总结一下,在MediaPlayer的初始化过程中,就是创建了MediaPlayer的对象。


首要的函数setDataSource()


 在写这篇blog之前,已经对MediaPlayer的流程有了可能的懂得。如今回头再看,发明这个函数真的很是首要。在这个函数中,MediaPlayer和MediaPlayerService建树了接洽,MediaPlayerService和Stagefright或者OpenCore也建树了接洽。 我们持续RFCD,在Java层,我们应用的办法如下: 



mediaPlayer.setDataSource("/sdcard/test.mp3");


在Java层这个函数代码如下:


【/frameworks/base/media/java/android/media/MediaPlayer.java】



 1     public void setDataSource(String path)

 2             throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {

 3         setDataSource(path, null, null);

 4     }

 5 调用setDataSource()的重载办法,之后的重载调用过程我们就略过,终极会调用到如下办法:

 6     public void setDataSource(FileDescriptor fd)

 7             throws IOException, IllegalArgumentException, IllegalStateException {

 8         // intentionally less than LONG_MAX

 9         setDataSource(fd, 0, 0 x7ffffffffffffffL);

10     }

11     public native void setDataSource(FileDescriptor fd, long offset, long length)

12             throws IOException, IllegalArgumentException, IllegalStateException;


 所以这个函数终极还是调用到类Native层。在之后的过程中,我们都邑跳过对于JNI层的寻找过程,直接进入Native层的MediaPlayer对象寻找响应的办法。在Native层中setDataSource()对应的代码如下:


【/frameworks/av/media/libmedia/mediaplayer.cpp】



 1 status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)

 2 {

 3     ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);

 4     status_t err = UNKNOWN_ERROR;

 5     const sp<IMediaPlayerService>& service(getMediaPlayerService());

 6     if (service != 0) {

 7         sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));

 8         if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||

 9             (NO_ERROR != player->setDataSource(fd, offset, length))) {

10             player.clear();

11         }

12         err = attachNewPlayer(player);

13     }

14     return err;

15 }


 上方这段代码重点处所有三个,都已经标示出来。先看第一个,getMediaPlayerService(),这个函数从其名字上看是获取MediaPlayerService。是以


 5     const sp<IMediaPlayerService>& service(getMediaPlayerService());

的功能就是获取MediaPlayerService并且把返回值赋值给service。关于getMediaPlayerService函数,我们在前面说过一次,这个办法是MediaPlayer的父类IMediaDeathNotifier的一个办法,关系到MediaPlayer和MediaPlayerService之间的通信。下面我们就看看这个办法的代码:
[/frameworks/av/media/libmedia/IMediaDeathNotifier.cpp]


 1 // establish binder interface to MediaPlayerService

 2 /*static*/const sp<IMediaPlayerService>&

 3 IMediaDeathNotifier::getMediaPlayerService()

 4 {

 5     ALOGV("getMediaPlayerService");

 6     Mutex::Autolock _l(sServiceLock);

 7     if (sMediaPlayerService == 0) {

 8         sp<IServiceManager> sm = defaultServiceManager();

 9         sp<IBinder> binder;

10         do {

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

12             if (binder != 0) {

13                 break;

14             }

15             ALOGW("Media player service not published, waiting...");

16             usleep(500000); // 0.5 s

17         } while (true);

18 

19         if (sDeathNotifier == NULL) {

20         sDeathNotifier = new DeathNotifier();

21     }

22     binder->linkToDeath(sDeathNotifier);

23     sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);

24     }

25     ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");

26     return sMediaPlayerService;

27 }


在getMediaPlayerService()函数中,重点内容有三处,不过都是为了最后获取MediaPlayerService办事的。第8行是获取ServiceManager;第11行是从ServiceManager中获取到我们所须要的一个对象,这个对象是BpBinder类型,为我们最后取得MediaPlayerService作筹办。第23行是获取MediaPlayerService,不过终极获得这个对象是BpMediaPlayerService类型。我们获取到得这个BpMediaPlayerService,这个对象的所有操纵终极都邑由真正的MediaPlayerService对象来完成,是以完全可以看做是MediaPlayerService。这个过程和Binder通信相干,不是我们此次商量的重点,这里不再赘述。


  到这里,我们解析完成了getMediaPlayerService办法,获得了返回值,并把它赋值给了service。接下来我们就要看看MediaPlayer应用这个service都做了些什么工作。从代码中看,统共有两件工作,分别是:


    1)按照过程ID,对象本身,AudioSessionId这三个参数,在server端创建了一个Player对象并返回给MediaPlayer端的player。这个Player也是具有过程间通信才能的。



 7         sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));


    2)为server端的Player设置播放资料



player->setDataSource(fd, offset, length)


我们开端看看第一件工作时如何完成的,以及在Server段创建player的时辰都做了那些工作。这个Create操纵终极会在Server端履行,所以我们就去MediaPlayerService段在这个过程中都做了些什么,代码如下:


[/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp]



 1 sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client,

 2         int audioSessionId)

 3 {

 4     int32_t connId = android_atomic_inc(&mNextConnId);

 5 

 6     sp<Client> c = new Client(

 7             this, pid, connId, client, audioSessionId,

 8             IPCThreadState::self()->getCallingUid());

 9 

10     ALOGV("Create new client(%d)  pid %d, uid %d, ", connId, pid,

11          IPCThreadState::self()->getCallingUid());

12 

13     wp<Client> w = c;

14     {

15         Mutex::Autolock lock(mLock);

16         mClients.add(w);

17     }

18     return c;

19 }


从代码中,我们可以看出,在Server端,我们新建的对象是Client,是MediaPlayerService的内部类。然则这个Client履行了MediaPlayerService的绝大项目组操纵。同样我们将来传输过来的数据也都是会交给内部类Client进行处理惩罚的。到这里,在Server端的对象就创建完成了。


接下来就是要做第二件工作了,就是在MediaPlayer中调用player->setDataSource();,这件事还是要在Server完成的,代码如下:


[/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp]



 1 status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)

 2 {

 3     ALOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length);

 4     struct stat sb;

 5     int ret = fstat(fd, &sb);

 6     if (ret != 0) {

 7         ALOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));

 8         return UNKNOWN_ERROR;

 9     }

10 

11     ALOGV("st_dev  = %llu", sb.st_dev);

12     ALOGV("st_mode = %u", sb.st_mode);

13     ALOGV("st_uid  = %lu", sb.st_uid);

14     ALOGV("st_gid  = %lu", sb.st_gid);

15     ALOGV("st_size = %llu", sb.st_size);

16 

17     if (offset >= sb.st_size) {

18         ALOGE("offset error");

19         ::close(fd);

20         return UNKNOWN_ERROR;

21     }

22     if (offset + length > sb.st_size) {

23         length = sb.st_size - offset;

24         ALOGV("calculated length = %lld", length);

25     }

26 

27     player_type playerType = MediaPlayerFactory::getPlayerType(this,

28                                                                fd,

29                                                                offset,

30                                                                length);

31     sp<MediaPlayerBase> p = setDataSource_pre(playerType);

32     if (p == NULL) {

33         return NO_INIT;

34     }

35 

36     // now set data source

37     setDataSource_post(p, p->setDataSource(fd, offset, length));

38     return mStatus;

39 }


 上方这段代码感化就是获取一个PlayerType,然后一这个PlayerType作为参数传递到setDataSource _pre(),在这个办法中按照playerType做一些工作。关于PlayerType是如何获取的,以及我们传入的文件test.mp3,对应什么类型的playerType,我就不再介绍了。之所以不介绍是因为牵扯到资料的一些特有的参数和属性断定的,我不太懂得。不过我们可以从代码中找到在Android中一共又几种如许的Type,如下:


/frameworks/av/include/media/MediaPlayerInterface.h



 1 enum player_type {

 2     PV_PLAYER = 1,

 3     SONIVOX_PLAYER = 2,

 4     STAGEFRIGHT_PLAYER = 3,

 5     NU_PLAYER = 4,

 6     // Test players are available only in the ""test"" and ""eng"" builds.

 7     // The shared library with the test player is passed passed as an

 8     // argument to the ""test:"" url in the setDataSource call.

 9     TEST_PLAYER = 5,

10 };


一种有五种type,然则PV_PLAYER如同是从Android2.3之后就作废了,因为PVPlayer是和Opencore相干的,自从OpenCore从Android2.3中移出之后,这个type对应的Player就没有了。所以在Android4.2中只剩下


四种type了。这些type和他们对应的player都邑以键值对的情势放入一个数据布局中,以备后用。在后面我们在应用这些type的时辰,就会发明这些键值对是存放在sFactoryMap中的,而sFactoryMap 是tFactoryMap型的,


也就是就是KeyVector。貌似KeyVector是android定义的数据布局吧,类似Hashmap。而把这些type和player键值对添参加sFactorymap中过程如下:


[/frameworks/av/media/libmediaplayerservice/MediaPlayerFactory.cpp]



 1 void MediaPlayerFactory::registerBuiltinFactories() {

 2     Mutex::Autolock lock_(&sLock);

 3 

 4     if (sInitComplete)

 5         return;

 6 

 7     registerFactory_l(new StagefrightPlayerFactory(), STAGEFRIGHT_PLAYER);

 8     registerFactory_l(new NuPlayerFactory(), NU_PLAYER);

 9     registerFactory_l(new SonivoxPlayerFactory(), SONIVOX_PLAYER);

10     registerFactory_l(new TestPlayerFactory(), TEST_PLAYER);

11 

12     sInitComplete = true;

13 }


看看上方这两段代码还是有益处的,最起码让我们熟悉打听工作的来龙去脉。若是我们想要在Android中扩大,应用新的解码对象,可以直接持续MediaPlayerFactory类,然后在这里注册所须要的type就行了。


接着上方的说,假设我们mp3对应的时defaultType,也就是STAGEFRIGHT_PLAYER,那么这个数据就会作为setDataSource_pre()的参数应用。我们就看看这个函数是如何哄骗Type参数创建新的对象的,代码如下:


【/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp】



 1 sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(

 2         player_type playerType)

 3 {

 4     ALOGV("player type = %d", playerType);

 5 

 6     // create the right type of player

 7     sp<MediaPlayerBase> p = createPlayer(playerType);

 8     if (p == NULL) {

 9         return p;

10     }

11 

12     if (!p->hardwareOutput()) {

13         mAudioOutput = new AudioOutput(mAudioSessionId);

14         static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);

15     }

16 

17     return p;

18 }


先申明一下,上方的红色代码都是很首要的,不过13和14行代码在setDataSource()临时还是用不上,要比及start()的时辰,和AudioFlinger建树接洽的时辰才干用到。如今先标识表记标帜下,有个印象。我们持续我们的工作,解析createPlayer()办法,代码如下:


/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp



 1 sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)

 2 {

 3     // determine if we have the right player type

 4     sp<MediaPlayerBase> p = mPlayer;

 5     if ((p != NULL) && (p->playerType() != playerType)) {

 6         ALOGV(" player");

 7         p.clear();

 8     }

 9     if (p == NULL) {

10         p = MediaPlayerFactory::createPlayer(playerType, this, notify);

11     }

12 

13     if (p != NULL) {

14         p->setUID(mUID);

15     }

16 

17     return p;

18 }


看红色代码标识的第10行代码,这里应用的设计模式中的--Factory模式,大师可以参考进修下。Android体系时一个如此重大错杂的体系,为了杰出的扩大性应用了很多设计模式。无论是进修策画机哪方面内容,Android源码都是一份不错的教材。还是持续看我们的任务,接着看代码,在MediaPlayerFactory::createPlayer()的代码如下:


[/frameworks/av/media/libmediaplayerservice/MediaPlayerFactory.cpp]



 1 sp<MediaPlayerBase> MediaPlayerFactory::createPlayer(

 2         player_type playerType,

 3         void* cookie,

 4         notify_callback_f notifyFunc) {

 5     sp<MediaPlayerBase> p;

 6     IFactory* factory;

 7     status_t init_result;

 8     Mutex::Autolock lock_(&sLock);

 9 

10     if (sFactoryMap.indexOfKey(playerType) < 0) {

11         ALOGE("Failed to create player object of type %d, no registered"

12               " factory", playerType);

13         return p;

14     }

15 

16     factory = sFactoryMap.valueFor(playerType);

17     CHECK(NULL != factory);

18     p = factory->createPlayer();

19 

20     if (p == NULL) {

21         ALOGE("Failed to create player object of type %d, create failed",

22                playerType);

23         return p;

24     }

25 

26     init_result = p->initCheck();

27     if (init_result == NO_ERROR) {

28         p->setNotifyCallback(cookie, notifyFunc);

29     } else {

30         ALOGE("Failed to create player object of type %d, initCheck failed"

31               " (res = %d)", playerType, init_result);

32         p.clear();

33     }

34 

35     return p;

36 }


 
我们经由过程playerType获取到得是IFactory对象,然后应用这个对象进行createPlayer。对于这一点的懂得和Factory模式有关,若是不熟悉打听的话,抽出一点点时候看看Factory模式必然是会有益处的。按照

playerType,我们这里的factory应当是StageFrightPlayerFactory的对象,然后调用它的的createPlayer函数。createPlayer()的实现如下:
[/frameworks/av/media/libmediaplayerservice/MediaPlayerFactory.cpp]


1     virtual sp<MediaPlayerBase> createPlayer() {

2         ALOGV(" create StagefrightPlayer");

3         return new StagefrightPlayer();

4     }


从这里StageFrightPlayerFactory的createPlayer中我们获得的返回值是一个新的对象--StagefrightPlayer的实例。到这里,我们就算是进入stagefright了,我们代码查询拜访到这儿也根蒂根基将近停止了。
我们还是接着看看这个新的对象的机关办法,代码如下:
[/frameworks/av/media/libmediaplayerservice/StagefrightPlayer.cpp]


1 StagefrightPlayer::StagefrightPlayer()

2     : mPlayer(new AwesomePlayer) {

3     ALOGV("StagefrightPlayer");

4 

5     mPlayer->setListener(this);

6 }


在这个机关函数中,有个很轻易忽视的处所,就是机关函数的属性赋值的体式格式,在C++中经常应用,叫做机关函数的初始化列表。乍一看,这个机关函数什么也没有,其实重点内容就在机关函数的初始化列表中,在这里我们又
创建了一个对象AwesomPlayer. 我感觉我们进行到这儿,也可以告一段落了,因为我们已经接触到了Stagefright,再向下查询拜访代码的话就应当是零丁研究stagefright的工作了。今后,在查询拜访过stagefrigh后,我会
再补上一篇博客说说stagefright的。
  好了,骚年们,让我们像函数调用停止时一样,一步一步return吧,直到可以或许持续向下履行的处所。我们一向查询拜访到这儿,是在解析MediaPlayerService中要做的两件事中的第二件工作:setDataSource()。我们方才停止
解析的处所是:sp<MediaPlayerBase> p = setDataSource_pre(playerType);让我们先总结一下我们方才都做了哪些工作,其实挺简单的就是创建了一个对象StagefrightPlayer,并把这个对象保存到p中。StagefrightPlayer
对象在创建的过程中,我们也设置了一些参数,比如p->setAudioSink(),还创建了AwesomePlayer对象,保存在StagefrightPlayer对象中的mPlayer属性中。既然setDataSource_pre()已经查询拜访停止,那么我们就要开端下一步
操纵了,就是下面已经用红色代码标示出来的项目组:
[/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp]


 1 status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)

 2 {

 3 ...

 4     player_type playerType = MediaPlayerFactory::getPlayerType(this,

 5                                                                fd,

 6                                                                offset,

 7                                                                length);

 8     sp<MediaPlayerBase> p = setDataSource_pre(playerType);

 9 ...

10     // now set data source

11     setDataSource_post(p, p->setDataSource(fd, offset, length));

12     return mStatus;

13 }


 


 其实函数setDataSource_post()对于我们解析MediaPlayer流程的感化不太大,可能是要设置MediaPlayer的一些功能
的属,我们此次重点存眷的是这个办法中的第二个参数。由上方的解析,我们知道p指向的对象是一个StagefrightPlayer
对象,所以p->setDataSource()的实现,我们就应当去StagefrightPlayer类中寻找。找到响应的代码如下:
[/frameworks/av/media/libmediaplayerservice/StagefrightPlayer.cpp]


1 status_t StagefrightPlayer::setDataSource(int fd, int64_t offset, int64_t length) {

2     ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);

3     return mPlayer->setDataSource(dup(fd), offset, length);

4 }



 


本来是应用StagefrightPlayer的属性mPlayer去实现的,前面我们也说到了stagefrightPlayer.mPlayer指向的是
AwesomePlayer.到这儿我们到此为止吧。
  到这里,在MediaPlayerService端的的setDataSource()的工作也停止了,总结一下就是:从Java应用法度中的
MediaPlayer的setDataSource()会传递到Native层中的MediaPlayer的setDataSource()去履行,而
MediaPlayer会把这个办法交给MediaPlayerservice去履行。MediaPlayerService的是应用stagefrightPlayer
实现的,最后,最后,我们的setdataSource还是交给了AwesomePlayer去履行了。这个流程把MediaPlayer和
MediaPlayerService之间的接洽建树起来,同时又把MediaPlayerService是如何应用stagefright实现的关系建树了
起来。到这里,我们的解析MediaPlayer的流程的目标也算是根蒂根基达到了。若是再持续解析MediaPlayer的话,我们可
以分为两个标的目标了,一个是解析stagefright是如何解码的;一个是解析MediaPlayer与AudioTrack,AudioFlinger
之间的关系了。由此看来,将来的任务和路子还是任重道远的。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值