第二部分 MediaPlayer的接口与架构
第二部分 MediaPlayer的接口与架构
2.1 整体框架图 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在运行的时候,可以大致上分成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正是提供实现功能的接口。
第二部分 MediaPlayer的接口与架构的更多相关文章
- Android Multimedia框架总结(七)C++中MediaPlayer的C/S架构补充及MediaService介绍
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼,文章链接: http://blog.csdn.net/hejjunlin/article/details/52465168 前面一篇主要介绍 ...
- was集群下基于接口分布式架构和开发经验谈
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/luozhonghua2014/article/details/34084935 某b项目是我首 ...
- 【Android 多媒体开发】 MediaPlayer 状态机 接口 方法 解析
作者 : 韩曙亮 转载请著名出处 : http://blog.csdn.net/shulianghan/article/details/38487967 一. MediaPlayer 状态机 介绍 ...
- Android接口与架构(驱动开发)翻译官方文档
Android接口与架构 Android在设备的规格与驱动方面给了你很大的自由来实现.HAL层提供了一个标准的方式来打通Android系统层与硬件层.Android系统是开源的,所以你能够在接口和性能 ...
- Android Multimedia框架总结(六)C++中MediaPlayer的C/S架构
转载请把头部出处链接和尾部二维码一起转载,本文出自: http://blog.csdn.net/hejjunlin/article/details/52435789 前面几节中,都是通过java层调用 ...
- 前端笔记之NodeJS(四)MongoDB数据库&Mongoose&自制接口&MVC架构思想|实战
一.MongoDB数据库 1.1 NoSQL简介 随着互联网web2.0网站的兴起,传统的SQL数据库(关系数据库)在应付web2.0网站,特别是超大规模和高并发的SNS(social network ...
- Hibernate(八)__级联操作、struts+hibernate+接口编程架构
级联操作 所谓级联操作就是说,当你进行主对象某个操作时,从对象hibernate自动完成相应操作. 比如: Department <---->Student 对象关系,我希望当我删除一个d ...
- Java SE 第二十二讲----接口interface
1.接口:interface:接口的地位等同于class,接口中的所有方法都是抽象方法.在声明接口中的方法的时候,可以使用abstract关键字也可以不使用.通常情况下,都会省略掉abstract关键 ...
- JAVAEE企业级应用开发浅谈第二辑:MVC和三层架构
上海尚学堂警句:一份信心,一份努力,一份成功:十分信心,十分努力,十分成功. Step1.情景概要 Hello,小伙伴们,昨天跟大家分享了JAVA EE 企业级应用开发中大家耳熟能详的概念-三层架构, ...
随机推荐
- Java.lang.RuntimeException: Unable to instantiate activity ComponentInfo
如果你更新了ADT的新版本,而工程文件中使用了其他的jar包,也可能会出现"java.lang.RuntimeException: Unable to instantiate activit ...
- angularJs--$apply和$watch,$digest方法的意思
这个视图对应的控制器是 这样的话,这个date变量,是不会发生改变的,没有触发脏检查,所以这时候要$apply方法,所有自定义的方法都要用$apply来触发脏检查 这样那个日期就会变化了 $diges ...
- JavaScript笔记(一)
JavaScript组成 EcmaScript:核心部分 作为解释器.几乎没有兼容性问题 DOM:Document Object Model,操作HTML页面的入口.有些操作不兼容. BOM:Brow ...
- php 随机显示图片的函数(实例)
转自:http://www.jbxue.com/article/12695.html 发布:thatboy 来源:Net [大 中 小] 本文分享一个php实现的随机显示图片的函数,可 ...
- lnmp安装--php安装
版本:php5.6.4 x86_64 centos 6.6 x86_64 安装php之所以难,是因为要安装的扩展多,依赖关系复杂. 安装前的准备: 先看你想要安装哪些扩展.需要哪些包.下载地址:htt ...
- python自定义线程池
关于python的多线程,由与GIL的存在被广大群主所诟病,说python的多线程不是真正的多线程.但多线程处理IO密集的任务效率还是可以杠杠的. 我实现的这个线程池其实是根据银角的思路来实现的. 主 ...
- 怎样下载安装Firebug和使用Firebug
Firebug是基于火狐(FireFox)浏览器的一个插件,它的作用是给Web页面开发者一个很好的测试前端页面代码的工具.所以深受网页开发者或网页布局爱好者的喜爱.像我们用DIV+CSS和html所写 ...
- 2014年辛星完全解读Javascript第三节
经过第一节的入门和第二节的运算符,那么接下来我们就可以学习Javascript的函数了,当然了,不管大家之前学习的是什么编程语言,都会有函数的概念,如果大家学的是Pascal,还会有”过程“的概念,但 ...
- SQL优化的四个方面,缓存,表结构,索引,SQL语句
一,缓存 数据库属于 IO 密集型的应用程序,其主要职责就是数据的管理及存储工作.而我们知道,从内存中读取一个数据库的时间是微秒级别,而从一块普通硬盘上读取一个IO是在毫秒级别,二者相差3个数量级.所 ...
- Servlet一次乱码排查后的总结(转)
原文地址:http://my.oschina.net/looly/blog/287255 由来 在写一个小小的表单提交功能的时候,出现了乱码,很奇怪request上来的参数全部是乱码,而从数据库查询出 ...