Android Multimedia框架总结(七)C++中MediaPlayer的C/S架构补充及MediaService介绍
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼,文章链接:
http://blog.csdn.net/hejjunlin/article/details/52465168
前面一篇主要介绍c++中MediaPlayer的C/S架构中和Client相关部分,并中间穿插了mediaplayerservice的部分。但是对于这块C/S部分,没有放大去分析。《Android Multimedia框架总结(四)MediaPlayer中从Java层到C++层类关系及prepare及之后其他过程》是从整体上看的,今天我们把这块C/S模型放大去看下。同样先看下Agenda:
- C/S模型中的三角关系流程图
- MediaPlayerService相关联的类图
- MediaPlayerService的产生过程
- MediaPlayerService添加服务过程
- MediaPlayerService通过BinderDriver和MediaPlayer通信过程
C/S模型中的三角关系流程图
上图总结如下几点:
MediaPlayer是客户端,也就是我们说的C/S中的C端
MediaPlayerService和MediaPlayerService::Client是服务器端。也就是我们说的C/S中的S端。
MediaPlayerService实现IMediaPlayerService定义的业务逻辑,其主要功能是根据MediaPlayer::setDataSource输入的URL调用create函数创建对应的Player.
MediaPlayerService::Client实现IMediaPlayer定义的业务逻辑,其主要功能包括start, stop, pause, resume…,其实现方法是调用MediaPlayerService create的Player中的对应方法来实现具体功能。
此前在第四篇那个图中已经画了个整体,今天再把MediaPlayerService,MediaPlayerService::Client,MediaPlayer放大看下他们在实际业务中交互关系。
MediaPlayerService相关联的类图
以上类关系图,总结如下几点:
在一个BnXXX或BpXXX都派生于两个类,具体情况如下:
- class BpXXX : public IXXX, public BpRefBase
- class BnXXX : public IXXX, public BBinder
BpXXX和BnXXX都派生于IXXX,哪IXXX又是做什么的呢?这里可以理解为,定义业务逻辑,我们此前分析IMediaPlayerClient在作用时,也说过。但在BpXXX与BnXXX中的实现方式不同:
- 在BpXXX中,把对应的binder_transaction_data打包之后通过BpRefBase中的mRemote(BpBinder)发送出去,并等待结果
- 在BnXXX中,实现对应的业务逻辑,通过调用BnXXX派生类中的方法来实现,如MediaPlayerService::Client
从上图可以看出,IBinder是用来进行进程间通信用的。
- BpRefBase中有一个mRemote(BpBinder)用来与Binder驱动交互用的。
- Binder是用来从Binder驱动中接收相关请求,并进行相关处理的。
本文出自逆流的鱼,文章链接: http://blog.csdn.net/hejjunlin/article/details/52465168
MediaPlayerService的产生过程
在了解MediaPlayerService之前,先了解下IMediaPlayerService.cpp,
6.0源码中是在frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp中:
可以看出这里定义一些常规业务相关,接下来开始了解MediaPlayerService
先找到入口,在frameworks/base/media/mediaserver/main_mediaserver.cpp
首先看下defaultServiceManager函数,如下:
用的是一个单例,每个进程只需要一个BpServiceManager代理,ProcessState::self()->getContextObject(NULL),接下来看下getContextObject(NULL)函数,
接着看看ProcessState::self()->getContextObject(NULL)
以上代码总结为:根据传入的句柄handle值为0,表示ServiceManager,new一个BpBinder所以现在相当于:
gDefaultServiceManager = interface_cast(new BpBinder(0));
然后我们看看interface_cast做了什么操作?
位于frameworks/base/include/binder/IInterface.h中,有如下代码:
继续我们跟到IServiceManager里面去:
位于frameworks/base/include/binder/IServiceManager.h中,有如下代码:
总结上述代码:根据句柄handle(0)创建一个new BpBinder(0),根据这个BpBinder创建了一个BpServiceManager代理。
下面来看看BpServiceManager代理:
这里BpInterface是一个模板类,表示这里BpServiceManager同时继承与BpInterface和IServiceManager类
调用了基类BpInterface构造函数:
MediaPlayerService::instantiate();//实例化MediaPlayerService
frameworks/base/media/libmediaplayerservice/MediaPlayerService.cpp
defaultServiceManager()返回的是刚创建的BpServiceManager,调用add函数。
BpMediaPlayService作为服务代理端,那么BnMediaPlayerService一定是实现端,MediaPlayerService继承于BnMediaPlayerService,实现了真正的业务函数,用于处理客户端传递的信息。
本文出自逆流的鱼,文章链接: http://blog.csdn.net/hejjunlin/article/details/52465168
MediaPlayerService添加服务过程
来看看BpServiceManager的addService()函数:
这里remote()就是前面创建的BpBinder(0)对象。
接着看一个有意思的名字,talkWithDriver的实现,顾名思义,和driver谈话:
IPCThreadState::joinThreadPool(), ProcessState::self()->startThreadPool()
进入线程循环talkWithDriver 等待客户端Client请求,从Binder读取命令请求进行处理。
到现在为止MediaPlayerService的服务端已经向服务总管ServiceManager注册了。
MediaPlayerService通过BinderDriver和MediaPlayer通信过程
下面我们看看客户端是如何获得服务的代理并和服务端通信的。
我们以MediaPlayer的业务函数decode解析播放一个网络视频的url为例
这里我们主要分析getMediaPlayerService,客户端是如何向ServiceManager总管查询服务并获得代理的。
- 首先获得BpServiceManager的代理,然后调用getService()函数向服务总管ServiceManager查询名叫String16(“media.player”)的服务。
位于frameworks/base/libs/binder/IServiceManager.cpp中:
- 这里首先将请求打包成Parcel各式,然后调用remote()->transact()函数,前面我们分析过BpServiceManager::remote()返回
的就是前面new BpBinder(0)对应句柄为ServiceManager。继续去BpBinder中寻找实现代码:
在frameworks/base/libs/binder/BpBinder.cpp中
- 最后调用的IPCThreadState的transact()函数,IPCThreadState是专门提供通过Binder进程间通信的接口的。
在这一步,首先通过writeTransactionData函数来填充mOut结构体,mOut里面内容为:
这里binder_transaction_data tr内容为:
tr.data内容为:
这个waitForResponse()函数是等待ProcessState返回信息:
最后返回的是:return reply.readStrongBinder();进入到Parcel的readStrongBinder()函数
这里flat->type是BINDER_TYPE_HANDLE,所以调用ProcessState::getStrongProxyForHandle()函数
这里的handle就是ServiceManager内维护的MediaPlayerService对应的Binder句柄,这个ProcessState根据这个句柄
new 了一个BpBinder,并将其保存起来,这样下次需要从ServiceManager请求获取到相同句柄的时候就可以直接返回了。
最后根据这个返回的BpBinder获得MediaPlayerService的代理:
sMediaPlayerService = interface_cast(binder);
根据前面ServiceManager一样,最后调用的是IMediaPlayerService的asInterface()宏函数
这样就获得了一个代理BpMediaPlayerService对象,它的remote()为BpBinder(handle),这个handle就是向服务总共ServiceManager
查询到的MediaPlayerService对应的Binder句柄。
最后总结下:
- 实际业务中,如MediaPlayer::setDataSource返回时,会创建一个与MediaPlayerService::Client对应的BpMediaPlayer,用于获取MediaPlayerService::Client的各项功能。
- MediaPlayer又是如何找到MediaPlayerService::Client的呢? 只有MediaPlayerService才向ServiceManager进行了注册,所以MediaPlayer必须先获取BpMediaPlayerService,然后通过BpMediaService的管理功能create,来创建一个MediaPlayerService::Client.
- 为什么不直接定义一个MediaPlayer向ServiceManager注册呢?
MediaPlayerService包含的功能不只是Client, 还有AudioOutput,AudioCache,MediaConfigClient功能。MediaPlayerService就是一个媒体服务的窗口(Driver有点类似一个场地,在这个场地,沟通好信息),MediaPlayerService把生意谈好,合同签回来,再根据合同上的要求,安排不同的开人发员去做。
第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。
如果你觉得好,随手点赞,也是对笔者的肯定,也可以分享此公众号给你更多的人,原创不易
Android Multimedia框架总结(七)C++中MediaPlayer的C/S架构补充及MediaService介绍相关推荐
- Android MultiMedia框架完全解析 - 概览
之前的工作中,一直在看Android MultiMedia的一些东西,关注我博客的同学也许知道我换工作了,以后将要从事Camera相关的工作,于是乎,将之前整理存放在有道云笔记里面的一些东西发出来,整 ...
- Android Multimedia框架总结(十七)音频开发基础知识
原文链接:http://blog.csdn.net/hejjunlin/article/details/53078828 近年来,唱吧,全民K歌,QQ音乐,等成为音频软件的主流力量,音频开发一直是多媒 ...
- Android Multimedia框架总结(二十八)NuPlayer到OMX过程
原址 NuPlayer是谷歌新研发的. AwesomePlayer存在BUG,谷歌早已在android m 版本中弃用. sp<MediaPlayerBase> MediaPlayerS ...
- Android Multimedia框架总结(二十四)MediaMuxer实现手机屏幕录制成gif图
原址:http://blog.csdn.net/hejjunlin/article/details/53866405 前言:上篇中,介绍是用MediaMuxer与MediaExtractor进入音视频 ...
- 8. Android MultiMedia框架完全解析 - prepareAsync的过程分析
还是从mediaplayer.cpp文件开始分析: status_t MediaPlayer::prepareAsync() {ALOGV("prepareAsync");Mute ...
- 10. Android MultiMedia框架完全解析 - MediaExtractor::Create函数的解析和FslExtractor分析
先来看看MediaExtractor所处的位置: (一)创建流程 在GenericSource.cpp的NuPlayer::GenericSource::initFromDataSource()函数中 ...
- Android Binder框架实现之Parcel详解之基本数据的读写
Android Binder框架实现之Parcel详解之基本数据的读写 Android Binder框架实现目录: Android Binder框架实现之Binder的设计思想 Android ...
- Android Binder框架实现之bindService详解
Android Binder框架实现之bindService详解 Android Binder框架实现目录: Android Binder框架实现之Binder的设计思想 Android Bi ...
- Android数据库框架-----ORMLite 的基本用法
ORMLite 是一款非要流行的Android平台上的数据库框架,性能优秀,代码简洁: 简述: 优点: 1.轻量级:2.使用简单,易上手:3.封装完善:4.文档全面. 缺点:1.基于反射,效率较低(本 ...
- Android Multimedia Framework overview(多媒体框架概述)--base on jellybean(一)
不知为啥今晚突然脑海中闪现出一个念头:写博客!原因有二,其一就是记录下自己的学习所得,巩固自己的知识,温故而知新吧,以前都是光看光想,都没有记录,而且不写下来,领悟估计就差点了,好记忆不如烂笔头啊!其 ...
最新文章
- 【Flink】Flink 实时超时统计-A发生B不发生事件统计-不发生事件
- .NET Framework 4.8 的 Microsoft 更新目录更新
- python 分类变量xgboost_XGBoost 原理 及 常见面试题
- 为什么说LinkedHashMap是Java中最大的数据结构? 了解一下?
- Markdown使用手册
- 谈谈公司内部的技术分享
- AddType requires at least two arguments, a mime type followed by one or more file extensions
- opencv图像分析与处理(10)- 常见的噪声以及空间滤波器噪声消除方法
- oreo授权系统V1.1开源版
- 美颜SDK有什么用?美颜SDK可以在直播和短视频中有哪些作用?
- 基于TI AM5728(浮点双DSP C66x +双ARM Cortex-A15)的开发板
- Deepin系统无法卸载360的解决方法
- 百度下拉词怎么做?出现负面应该如何处理?此方法适用百度、搜狗、神马
- 2015移动安全挑战赛MSC(第二届)第一题解题思路
- C89标准和C99标准C11标准的区别
- 用户-用户生命周期切分(下)
- python获取人民币汇率数据
- flask_萧井陌视频学习(二)
- 草他妈 胡闹的一天
- Go SCP 通信顺序进程模型chan通道
热门文章
- Java类的域初始化_Java域的初始化
- 怎么做301永久重定向
- 认识ruquest对象
- 论文笔记_S2D.69_用于 LiDAR 里程计和建图的泊松曲面重建
- C++_auto_ptr与unique_ptr智能指针
- 随手记_英语_学术写作_常用句型35个
- 算法笔记_面试题_6.二进制/位运算相关
- Web开发——问题:js/css文件修改提交后,没有效果
- 巨星陨落!图灵奖得主Edmund Clarke感染新冠逝世,教计算机自己检查错误的人走了...
- 设置pyspark 启动时所使用的python版本