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

  • 摘要:1.MediaPlayer 是客户端2.MediaPlayerService和MediaPlayerService::Client是服务器端。 2.1MediaPlayerService实现IMediaPlayerService定义的业务逻辑,其主要功能是根据 MediaPlayer::setDataSource输入的URL调用create函数创建对应的 Player.2.2MediaPlayerService::Client实现IMediaPlayer定义的业务逻辑,其主要功能包括
  • 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 它们的三角恋如下图所示:

     

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

     

    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到底定义了些什么东东?


    class IMediaPlayerService: public IInterface
    {
    public:
    DECLARE_META_INTERFACE(MediaPlayerService);
    virtual sp createMediaRecorder(pid_t pid) = 0;
    virtual sp createMetadataRetriever(pid_t pid) = 0;
    virtual sp create(pid_t pid, const sp &; client, const char* url, const KeyedVector *headers = NULL) = 0;
    virtual sp create(pid_t pid, const sp &; client, int fd, int64_t offset, int64_t length) = 0;
    virtual sp createMediaConfig(pid_t pid ) = 0;
    virtual sp decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
    virtual sp decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
    virtual sp getOMX() = 0;
    // Take a peek at currently playing audio, for visualization purposes.
    // This returns a buffer of 16 bit mono PCM data, or NULL if no visualization buffer is currently available.
    virtual sp snoop() = 0;
    };

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

     

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

     

    还是让代码自己说话吧:


    sp MediaPlayerService::create(
    pid_t pid, const sp &; client, const char* url,
    const KeyedVector *headers)
    {
    int32_t connId = android_atomic_inc(&;mNextConnId);
    sp c = new Client(this, pid, connId, client);
    LOGV("Create new client(%d) from pid %d, url=%s, connId=%d", connId, pid, url, connId);
    if (NO_ERROR != c->setDataSource(url, headers))
    {
    c.clear();
    return c;
    }
    wp w = c;
    Mutex::Autolock lock(mLock);
    mClients.add(w);
    return c;
    }

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

     

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


    class IMediaPlayer: public IInterface
    {
    public:
    DECLARE_META_INTERFACE(MediaPlayer);
    virtual void disconnect() = 0;
    virtual status_t setVideoSurface(const sp &; surface) = 0;
    virtual status_t setSurfaceXY(int x,int y) = 0;/*add by h00186041 add interface for surface left-up position*/
    virtual status_t setSurfaceWH(int w,int h) = 0;/*add by h00186041add interface for surface size*/
    virtual status_t prepareAsync() = 0;
    virtual status_t start() = 0;
    virtual status_t stop() = 0;
    virtual status_t pause() = 0;
    virtual status_t isPlaying(bool* state) = 0;
    virtual status_t seekTo(int msec) = 0;
    virtual status_t getCurrentPosition(int* msec) = 0;
    virtual status_t getDuration(int* msec) = 0;
    virtual status_t reset() = 0;
    virtual status_t setAudioStreamType(int type) = 0;
    virtual status_t setLooping(int loop) = 0;
    virtual status_t setVolume(float leftVolume, float rightVolume) = 0;
    virtual status_t suspend() = 0;
    virtual status_t resume() = 0;
    // Invoke a generic method on the player by using opaque parcels
    // for the request and reply.
    // @param request Parcel that must start with the media player
    // interface token.
    // @param[out] reply Parcel to hold the reply data. Cannot be null.
    // @return OK if the invocation was made successfully.
    virtual status_t invoke(const Parcel&; request, Parcel *reply) = 0;
    // Set a new metadata filter.
    // @param filter A set of allow and drop rules serialized in a Parcel.
    // @return OK if the invocation was made successfully.
    virtual status_t setMetadataFilter(const Parcel&; filter) = 0;
    // Retrieve a set of metadata.
    // @param update_only Include only the metadata that have changed
    //since the last invocation of getMetadata.
    //The set is built using the unfiltered
    //notifications the native player sent to the
    //MediaPlayerService during that period of
    //time. If false, all the metadatas are considered.
    // @param apply_filter If true, once the metadata set has been built based
    // on the value update_only, the current filter is
    // applied.
    // @param[out] metadata On exit contains a set (possibly empty) of metadata.
    //Valid only if the call returned OK.
    // @return OK if the invocation was made successfully.
    virtual status_t getMetadata(bool update_only,
    bool apply_filter,
    Parcel *metadata) = 0;
    }

    终于找到了思念已久的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就是 一个媒体服务的接口,它先把客人接回来,再根据客人的需求,安排不同的员工去做,就这么简单。

猜你喜欢

转载自blog.csdn.net/liangtianmeng/article/details/84642635