第二部分 MediaPlayer的接口与架构

第二部分 MediaPlayer的接口与架构

2.1 整体框架图         MediaPlayer的各个库之间的结构比较复杂,可以用下图的表示

第二部分 MediaPlayer的接口与架构    在各个库中,libmedia.so位于核心的位置,它对上层的提供的接口主要是MediaPlayer类,类libmedia_jni.so通过调用MediaPlayer类提供对JAVA的接口,并且实现了android.media.MediaPlayer类。 libmediaplayerservice.so是Media的服务器,它通过继承libmedia.so的类实现服务器的功能,而libmedia.so中的另外一部分内容则通过进程间通讯和libmediaplayerservice.so进行通讯。libmediaplayerservice.so的真正功能通过调用OpenCore Player来完成。     MediaPlayer部分的头文件在frameworks/base/include/media/目录中,这个目录是和libmedia.so库源文件的目录frameworks/base/media/libmedia/相对应的。主要的头文件有以下几个:
IMediaPlayerClient.h mediaplayer.h IMediaPlayer.h IMediaPlayerService.h MediaPlayerInterface.h
    在这些头文件mediaplayer.h提供了对上层的接口,而其他的几个头文件都是提供一些接口类(即包含了纯虚函数的类),这些接口类必须被实现类继承才能够使用。     整个MediaPlayer库和调用的关系如下图所示:

第二部分 MediaPlayer的接口与架构

整个MediaPlayer在运行的时候,可以大致上分成Client和Server两个部分,它们分别在两个进程中运行,它们之间使用Binder机制实现IPC通讯。从框架结构上来看,IMediaPlayerService.h、IMediaPlayerClient.h和MediaPlayer.h三个类定义了MeidaPlayer的接口和架构,MediaPlayerService.cpp和mediaplayer.coo两个文件用于MeidaPlayer架构的实现,MeidaPlayer的具体功能在PVPlayer(库libopencoreplayer.so)中的实现。

2.2 头文件IMediaPlayerClient.h   
        IMediaPlayerClient.h用于描述一个MediaPlayer客户端的接口,描述如下所示:
class IMediaPlayerClient: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaPlayerClient);
    virtual void notify(int msg, int ext1, int ext2) = 0;
};

class BnMediaPlayerClient: public BnInterface<IMediaPlayerClient>
{
public:
    virtual status_t  onTransact( uint32_t code,
                                  const Parcel& data,
                                  Parcel* reply,
                                  uint32_t flags = 0);
};
        在定义中,IMediaPlayerClient类继承IInterface,并定义了一个MediaPlayer客户端的接口,BnMediaPlayerClient继承了BnInterface<IMediaPlayerClient>,这是为基于Android的基础类Binder机制实现在进程通讯而构建的。事实上,根据BnInterface类模版的定义BnInterface<IMediaPlayerClient>类相当于双继承了BnInterface和ImediaPlayerClient。这是Android一种常用的定义方式。

2.3 头文件mediaplayer.h
        mediaplayer.h是对外的接口类,它最主要是定义了一个MediaPlayer类:
class MediaPlayer : public BnMediaPlayerClient
{
public:
    MediaPlayer();
    ~MediaPlayer();
    void onFirstRef();
    void disconnect();
    status_t    setDataSource(const char *url);
    status_t    setDataSource(int fd, int64_t offset, int64_t length);
    status_t    setVideoSurface(const sp<Surface>& surface);
    status_t    setListener(const sp<MediaPlayerListener>& listener);
    status_t    prepare();
    status_t    prepareAsync();
    status_t    start();
    status_t    stop();
    status_t    pause();
    bool        isPlaying();
    status_t    getVideoWidth(int *w);
    status_t    getVideoHeight(int *h);
    status_t    seekTo(int msec);
    status_t    getCurrentPosition(int *msec);
    status_t    getDuration(int *msec);
    status_t    reset();
    status_t    setAudioStreamType(int type);
    status_t    setLooping(int loop);
    status_t    setVolume(float leftVolume, float rightVolume);
    void    notify(int msg, int ext1, int ext2);
    static    sp<IMemory>    decode(const char* url, uint32_t *pSampleRate, int* pNumChannels);
    static    sp<IMemory>    decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels);
//……
}
    从接口中可以看出MediaPlayer类刚好实现了一个MediaPlayer的基本操作,例如播放(start)、停止(stop)、暂停(pause)等。
    另外的一个类DeathNotifier在MediaPlayer类中定义,它继承了IBinder类中的DeathRecipient类:
class DeathNotifier: public IBinder:: DeathRecipient
{
public:
    DeathNotifier() {}
    virtual ~DeathNotifier();
    virtual void binderDied(const wp<IBinder>& who);
};
        事实上,MediaPlayer类正是间接地继承了IBinder,而MediaPlayer:: DeathNotifier类继承了IBinder:: DeathRecipient,这都是为了实现进程间通讯而构建的。

2.4 头文件IMediaPlayer.h
        IMediaPlayer.h主要的的内容是一个实现MediaPlayer功能的接口,它的主要定义如下所示:
class IMediaPlayer: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaPlayer);
    virtual void    disconnect() = 0;
    virtual status_t    setVideoSurface(const sp<ISurface>& surface) = 0;
    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    getVideoSize(int* w, int* h) = 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;
};
class BnMediaPlayer: public BnInterface<IMediaPlayer>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,   
                                    Parcel* reply,
                                    uint32_t flags = 0);
};
        在IMediaPlayer类中,主要定义MediaPlayer的功能接口,这个类必须被继承才能够使用。值得注意的是,这些接口和MediaPlayer类的接口有些类似,但是它们并没有直接的关系。事实上,在MediaPlayer类的各种实现中,一般都会通过调用IMediaPlayer类的实现类来完成。

2.5 头文件IMediaPlayerService.h
        IMediaPlayerService.h用于描述一个MediaPlayer的服务,定义方式如下所示:
class IMediaPlayerService: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaPlayerService);
    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url) = 0;
    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length) = 0;
    virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels) = 0;
    virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels) = 0;
};
class BnMediaPlayerService: public BnInterface<IMediaPlayerService>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

由于具有纯虚函数,IMediaPlayerService 以及BnMediaPlayerService必须被继承实现才能够使用,在IMediaPlayerService定义的create和decode等接口,事实上是必须被继承者实现的内容。注意,create的返回值的类型是sp<IMediaPlayer>,这个IMediaPlayer正是提供实现功能的接口。

上一篇:简单linux块设备驱动程序


下一篇:linux 块设备-整理(一)