Android音频流程二(Binder部分)

本文详细解析了Android系统中MediaPlayer从应用程序调用到内核层的启动流程,包括JNI层、Binder机制以及MediaPlayerService的作用。

2libmedia MediaPlayer至MediaPlayerService binder


clientservice之间的通信通过android binder机制,只是对于用户而言是透明的。

继续按照上面play调用流程,上面已经调用到了frameworksmediaplayer.cpp方法start

[csharp] view plain copy
  1. status_t MediaPlayer::start()  
  2. {  
  3.     LOGV("start");  
  4.     Mutex::Autolock _l(mLock);  
  5.     if (mCurrentState & MEDIA_PLAYER_STARTED)  
  6.         return NO_ERROR;  
  7.     if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED |  
  8.                     MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) {  
  9.         mPlayer->setLooping(mLoop);  
  10.         mPlayer->setVolume(mLeftVolume, mRightVolume);  
  11.         mPlayer->setAuxEffectSendLevel(mSendLevel);  
  12.         mCurrentState = MEDIA_PLAYER_STARTED;  
  13.         status_t ret = mPlayer->start();  
  14.         if (ret != NO_ERROR) {  
  15.             mCurrentState = MEDIA_PLAYER_STATE_ERROR;  
  16.         } else {  
  17.             if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) {  
  18.                 LOGV("playback completed immediately following start()");  
  19.             }  
  20.         }  
  21.         return ret;  
  22.     }  
  23.     LOGE("start called in state %d", mCurrentState);  
  24.     return INVALID_OPERATION;  
  25. }  

其中mPlayersetDataSource时候创建的播放器的实例,调用到的方法setLooping setVolume等都是在frameworks/base/include/mediaIMediaPlayer.h中声明

Ixx开头的头文件是binder机制的接口文件,每个这种接口文件同级目录下都会有对应一个.cpp文件,这里对应的是IMediaPlayer.cpp

这个C++文件定义binder的本地和代理函数,本地的是以Bn开头,native的意思,BnMediaPlyaer;代理的是以Bp开头,proxy的意思,BpMediaPlayer

这两个类之间调用是通过在kernel驱动的、在dev/下生成的一个binder程序来通信!代理端使用remote()->transact(),本地端响应请求onTransact()

代码如下:

[csharp] view plain copy
  1. class BpMediaPlayer: public BpInterface<IMediaPlayer>  
  2. {  
  3. public:  
  4. //...  
  5.     status_t start()  
  6.     {  
  7.         Parcel data, reply;  
  8.         data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());  
  9.         remote()->transact(START, data, &reply);  
  10.         return reply.readInt32();  
  11. }  
  12. //...  
  13. }  
  14. status_t BnMediaPlayer::onTransact(  
  15.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  16. {  
  17. switch(code) {  
  18. //...  
  19.         case START: {  
  20.             CHECK_INTERFACE(IMediaPlayer, data, reply);  
  21.             reply->writeInt32(start());  
  22.             return NO_ERROR;  
  23.         } break;  
  24. //...  
  25. }  
  26. //...  
  27. }  

播放器实例获得是通过setDataSource函数创建的,而这个函数会调用MediaPlayerService

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


再调用MediaPlayerServicecreatsetDataSource

总结下上面流程应该是:

======================================================================

|Applications                                      Music.apk                                      

|                                                                |                                          

|                                                                |                                          

|Framework                                   MediaPlayer API

======================================================================

--JNI----------------------------------------IMediaPlayer--------------------------------------------------

|                                                                |

|                                                                |

|libmedia                                          MediaPlayer

|                                                                |

--Binder---------------------------------------BpXXX-------------------------------------------------------

-------------------------------------------------BnXXX-------------------------------------------------------

|                                                                |

|                                                                |

|MediaServer                              MediaPlayerService

======================================================================


Binder在直观上看到是直接函数对应调用,实际上是有透过kernel空间的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值