分享

MediaPlayer-MediaPlayerService-MediaPlayerService::Client的三角关系

 开花结果 2012-05-31

1. MediaPlayer是客户端

2. MediaPlayerService和MediaPlayerService::Client是服务器端。

2.1 MediaPlayerService实现IMediaPlayerService定义的业务逻辑,其主要功能是根据MediaPlayer::setDataSource输入的URL调用create函数创建对应的Player.

2.2 MediaPlayerService::Client实现IMediaPlayer定义的业务逻辑,其主要功能包括start, stop, pause, resume...,其实现方法是调用MediaPlayerService create的Player中的对应方法来实现具体功能。

2.3 它们的三角恋如下图所示:

 3. IXX是什么东东?

在一个BnXXX或BpXXX都派生于两个类,具体情况如下:

class BpXXX : public IXXX, public BpRefBase

class BnXXX : public IXXX, public BBinder

3.1 看到了吧,BpXXX和BnXXX都派生于IXXX,哪IXXX又是做什么的呢? 明确地告诉你,定义业务逻辑,但在BpXXX与BnXXX中的实现方式不同:

1) 在BpXXX中,把对应的binder_transaction_data打包之后通过BpRefBase中的mRemote(BpBinder)发送出去,并等待结果

2) 在BnXXX中,实现对应的业务逻辑,通过调用BnXXX派生类中的方法来实现,如MediaPlayerService::Client

懂了吧, IXXX定义业务逻辑

3.2 哪另外一个做什么呢?

从上图可以看出,是用来进行进程间通信用的。

BpRefBase中有一个mRemote(BpBinder)用来与Binder驱动交互用的。

BBinder是用来从Binder驱动中接收相关请求,并进行相关处理的。

 

4. 不得不说的MediaPlayerService

class MediaPlayerService : public BnMediaPlayerService

它本身用来实现IMediaPlayerService中定义的业务逻辑,可以看看IMediaPlayerService到底定义了些什么东东?

  1. class IMediaPlayerService: public IInterface  
  2. {  
  3. public:  
  4.     DECLARE_META_INTERFACE(MediaPlayerService);  
  5.   
  6.     virtual sp<IMediaRecorder>  createMediaRecorder(pid_t pid) = 0;  
  7.     virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid) = 0;  
  8.     virtual sp<IMediaPlayer>    create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url, const KeyedVector<String8, String8> *headers = NULL) = 0;  
  9.     virtual sp<IMediaPlayer>    create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length) = 0;  
  10.     virtual sp<IMediaConfig>    createMediaConfig(pid_t pid ) = 0;  
  11.     virtual sp<IMemory>         decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;  
  12.     virtual sp<IMemory>         decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;  
  13.     virtual sp<IOMX>            getOMX() = 0;  
  14.   
  15.     // Take a peek at currently playing audio, for visualization purposes.  
  16.     // This returns a buffer of 16 bit mono PCM data, or NULL if no visualization buffer is currently available.  
  17.     virtual sp<IMemory>         snoop() = 0;  
  18. };  


从上面可以看出,还说自己是一个MediaPlayerService,而且还向大内总管ServiceManager进行了注册,就这么个create和decode,能做什么呢? 我们最熟悉的start ,stop, pause, resume...怎么不见呢?没有这些东东,MediaPlayer需要的功能如何实现呢?

 带着这么多疑问,我们先看看MediaPlayerService是如何实现上述功能的,它到底做了些什么?

还是让代码自己说话吧:

  1. sp<IMediaPlayer> MediaPlayerService::create(  
  2.         pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,  
  3.         const KeyedVector<String8, String8> *headers)  
  4. {  
  5.     int32_t connId = android_atomic_inc(&mNextConnId);  
  6.     sp<Client> c = new Client(this, pid, connId, client);  
  7.     LOGV("Create new client(%d) from pid %d, url=%s, connId=%d", connId, pid, url, connId);  
  8.     if (NO_ERROR != c->setDataSource(url, headers))  
  9.     {  
  10.         c.clear();  
  11.         return c;  
  12.     }  
  13.     wp<Client> w = c;  
  14.     Mutex::Autolock lock(mLock);  
  15.     mClients.add(w);  
  16.     return c;  
  17. }  

原来如此,它负责创建MediaPlayer需要的对应功能,创建了Client(MediaPlayerService),MediaPlayerService::Client的定义如下:

class Client : public BnMediaPlayer, 它实现了IMediaPlayer定义的业务逻辑,哪就看看IMediaPlayer定义了些什么:

  1. class IMediaPlayer: public IInterface  
  2. {  
  3. public:  
  4.     DECLARE_META_INTERFACE(MediaPlayer);  
  5.   
  6.     virtual void            disconnect() = 0;  
  7.   
  8.     virtual status_t        setVideoSurface(const sp<ISurface>& surface) = 0;  
  9.     virtual status_t        setSurfaceXY(int x,int y) = 0;  /*add by h00186041   add interface for surface left-up position*/  
  10.     virtual status_t        setSurfaceWH(int w,int h) = 0;  /*add by h00186041  add interface for surface size*/  
  11.     virtual status_t        prepareAsync() = 0;  
  12.     virtual status_t        start() = 0;  
  13.     virtual status_t        stop() = 0;  
  14.     virtual status_t        pause() = 0;  
  15.     virtual status_t        isPlaying(bool* state) = 0;  
  16.     virtual status_t        seekTo(int msec) = 0;  
  17.     virtual status_t        getCurrentPosition(int* msec) = 0;  
  18.     virtual status_t        getDuration(int* msec) = 0;  
  19.     virtual status_t        reset() = 0;  
  20.     virtual status_t        setAudioStreamType(int type) = 0;  
  21.     virtual status_t        setLooping(int loop) = 0;  
  22.     virtual status_t        setVolume(float leftVolume, float rightVolume) = 0;  
  23.     virtual status_t        suspend() = 0;  
  24.     virtual status_t        resume() = 0;  
  25.   
  26.     // Invoke a generic method on the player by using opaque parcels  
  27.     // for the request and reply.  
  28.     // @param request Parcel that must start with the media player  
  29.     // interface token.  
  30.     // @param[out] reply Parcel to hold the reply data. Cannot be null.  
  31.     // @return OK if the invocation was made successfully.  
  32.     virtual status_t        invoke(const Parcel& request, Parcel *reply) = 0;  
  33.   
  34.     // Set a new metadata filter.  
  35.     // @param filter A set of allow and drop rules serialized in a Parcel.  
  36.     // @return OK if the invocation was made successfully.  
  37.     virtual status_t        setMetadataFilter(const Parcel& filter) = 0;  
  38.   
  39.     // Retrieve a set of metadata.  
  40.     // @param update_only Include only the metadata that have changed  
  41.     //                    since the last invocation of getMetadata.  
  42.     //                    The set is built using the unfiltered  
  43.     //                    notifications the native player sent to the  
  44.     //                    MediaPlayerService during that period of  
  45.     //                    time. If false, all the metadatas are considered.  
  46.     // @param apply_filter If true, once the metadata set has been built based  
  47.     //                     on the value update_only, the current filter is  
  48.     //                     applied.  
  49.     // @param[out] metadata On exit contains a set (possibly empty) of metadata.  
  50.     //                      Valid only if the call returned OK.  
  51.     // @return OK if the invocation was made successfully.  
  52.     virtual status_t        getMetadata(bool update_only,  
  53.                                         bool apply_filter,  
  54.                                         Parcel *metadata) = 0;  
  55. }  


终于找到了思念已久的start, stop, pause, resume...

所以MediaPlayer::setDataSource返回时,会创建一个与MediaPlayerService::Client对应的BpMediaPlayer,用于获取MediaPlayerService::Client的各项功能。

4. 1 MediaPlayer又是如何找到MediaPlayerService::Client的呢? 只有MediaPlayerService才向ServiceManager进行了注册,所以MediaPlayer必须先获取BpMediaPlayerService,然后通过BpMediaService的管理功能create,来创建一个MediaPlayerService::Client.

4.2 为什么不直接定义一个MediaPlayer向ServiceManager注册呢?

也许是为了系统简化吧,MediaPlayerService包含的功能不只是Client, 还有AudioOutput,AudioCache,MediaConfigClient功能。现在明白了吧,MediaPlayerService就是一个媒体服务的接口,它先把客人接回来,再根据客人的需求,安排不同的员工去做,就这么简单。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多