转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼,文章链接:

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介绍的更多相关文章

  1. Android Multimedia框架总结(四)MediaPlayer中从Java层到C++层类关系及prepare及之后其他过程

    转载请把头部出处链接和尾部二维码一起转载,本文出自:http://blog.csdn.net/hejjunlin/article/details/52420803 前言:在上篇中,分析了MediaPl ...

  2. Android Multimedia框架总结(三)MediaPlayer中创建到setDataSource过程

    转载请把头部出处链接和尾部二维码一起转载,本文出自:http://blog.csdn.net/hejjunlin/article/details/52392430 前言:前一篇的mediaPlayer ...

  3. Android Multimedia框架总结(一)MediaPlayer介绍之状态图及生命周期

    请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52349221 前言:从本篇开始,将进入Multimedia框架,包含 ...

  4. Android Multimedia框架总结(二)MediaPlayer框架及播放网络视频案例

    前言:前面一篇我们介绍MediaPlayer相关方法,有人说,没有实际例子,看得不是很明白,今天在分析MediaPlayer时,顺带一个播放网络视频例子.可以自行试试.今天分析的都是下几篇介绍各个模块 ...

  5. Android Multimedia框架总结(六)C++中MediaPlayer的C/S架构

    转载请把头部出处链接和尾部二维码一起转载,本文出自: http://blog.csdn.net/hejjunlin/article/details/52435789 前面几节中,都是通过java层调用 ...

  6. Android Multimedia框架总结(十五)Camera框架之Camera2补充

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52751055 前言:监于5.0之 ...

  7. Android Multimedia框架总结(十一)CodeC部分之AwesomePlayer到OMX服务

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52623882 前言:上篇文< ...

  8. Android Multimedia框架总结(九)Stagefright框架之数据处理及到OMXCodec过程

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼:http://blog.csdn.net/hejjunlin/article/details/52532085 不知不觉到第九篇了,感觉还有 ...

  9. Android Multimedia框架总结(十三)CodeC部分之OpenMAX框架初识及接口与适配层实现

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52629598 前言:上篇中介绍O ...

随机推荐

  1. 常用linux命令备忘

    备忘: 关闭防火墙:# systemctl stop firewalld 查看防火墙状态:#  systemctl status firewalld 停止防火墙:#  systemctl disabl ...

  2. 小白学习java设计模式之策略模式

    策略模式:1.分析项目中的变化部分与不变部分(每个设计模式都要分析的)2.多用组合少用继承;用行为类组合,而不是行为继承,更具有弹性直接上代码: package com.wz.oneStrategis ...

  3. 百度URL 部分参数

    [Baidu URL的部分参数] 1.Baidu Form表单如下: 2.部分参数解析 wd  查询关键字,就是你要搜索的内容. bs 上一次搜索的词或者内容: rn  搜索结果页每页显示的数目,默认 ...

  4. [WC 2014]紫荆花之恋

    Description 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来. 仔细看看的话,这个大树实际上 ...

  5. [HEOI2015]兔子与樱花

    Description 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1个树枝连接 ...

  6. poj3728 商务旅行

    [Description]小 T 要经常进行商务旅行,他所在的国家有 N 个城镇,标号为 1,2,3,...,N,这 N 个城镇构成一棵树.每个城镇可以买入和卖出货物,同一城镇买入和卖出的价格一样,小 ...

  7. ●POJ 3378 Crazy Thairs

    题链: http://poj.org/problem?id=3378 题解: 树状数组维护,高精度. 依次考虑以每个位置结尾可以造成的贡献. 假设当前位置为i,为了达到5个元素的要求,我们需要求出,在 ...

  8. 【HNOI2017】大佬

    题目描述 人们总是难免会碰到大佬.他们趾高气昂地谈论凡人不能理解的算法和数据结构,走到任何一个地方,大佬的气场就能让周围的人吓得瑟瑟发抖,不敢言语. 你作为一个 OIER,面对这样的事情非常不开心,于 ...

  9. ●BZOJ 3545 [ONTAK2010]Peaks(离线)

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3545 http://www.lydsy.com/JudgeOnline/problem.ph ...

  10. IntelliJ IDEA光标变粗 backspace无法删除内容解决方法

    进入了vim插件 1.ctrl+alt+s快捷键打开Settings 2.选择左侧列表中的Plugins 3.在右侧面板的搜索框中搜索IdeaVim 4.将复选框中的钩子去掉 backspace成了其 ...