from://http://blog.csdn.net/goohong/article/details/8536102
http://www.tuicool.com/articles/FJVFnu
ANDROID从版本4.2开始提供了一个显示管理服务DisplayManagerService,支持多种显示类型的多个显示器的镜像显示,包括内建的显示类型(本地)、HDMI显示类型以及支持WIFI Display 协议( MIRACAST),实现本地设备在远程显示器上的镜像显示。
整个架构类图如下:
显示管理服务通过DisplayManager提供对外接口,提供的接口包括如下几个:
1 、public Display getDisplay(int displayId)
根据displayId参数获得一个逻辑显示器的信息
2、 public Display[] getDisplays()
获得当前所有有效的逻辑显示器列表
3、public void registerDisplayListener(DisplayListener listener, Handler handler)
登记一个显示监听对象,用来监听显示器的新增、去除或改变通知事件。
4、public void unregisterDisplayListener(DisplayListener listener)
取消先前登记的一个显示监听对象
5、scanWifiDisplays()
启动WIFI显示器的扫描。
6、 public void connectWifiDisplay(String deviceAddress)
根据设备地址连接WIFI显示器
7、public void disconnectWifiDisplay()
断开WIFI显示器
8、 public void renameWifiDisplay(String deviceAddress, String alias)
为WIFI显示器命名
9、public void forgetWifiDisplay(String deviceAddress)
取消先前记忆的WIFI显示器
10、public WifiDisplayStatus getWifiDisplayStatus()
得到当前的WIFI显示器的状态
显示管理系统还与其它系统交互,实现WIFI显示器的发现、WIFI显示器在窗口系统中的登记、窗口内容在WIFI显示器的显示(源端镜像数据的获取、加密、编码,SINK端接收的镜像数据的解码和播放等)等功能。
通过WifiP2pManager接口与WifiP2pService交互,通过WIFI-DIRECT来实现WIFI显示器的自动发现。
窗口管理服务是显示管理服务的监听对象,窗口管理服务通过DisplayManager接口向DisplayManagerService进行登记,当WIFI显示器被发现和连接成功后以及WIFI显示器断开和状态改变后,都会通过回调向窗口管理服务发送事件,窗口管理服务的相应回调函数onDisplayAdded、onDisplayChanged、onDisplayRemoved被调用,用来在窗口系统中进行WIFI显示器的登记以及取消登记、状态改变等处理。
另外DisplayManagerService服务还通过WindowManagerFuncs窗口管理功能接口直接调用窗口管理服务(WindowManagerService是该接口的实现)的函数,实现窗口内容的刷新。同样DisplayManagerService服务还通过InputManagerFuncs接口直接调用输入管理服务的函数setDisplayViewports,用来设置输入系统需要的显示器的显示视图信息。
显示管理系统还通过IMediaPlayerService接口与MediaPlayerService服务交互。
如调用MediaPlayerService服务的listenForRemoteDisplay函数,用来在媒体服务中实例化一个远端显示器的本地代理对象RemoteDisplay,显示系统通过IRemoteDisplay接口调用媒体服务,目前IRemoteDisplay接口只有dispose一个接口函数,用来断开远端显示器,停止监听新的连接。
显示管理系统的WifiDisplaySource对象还调用MediaPlayerService服务的makeHDCP函数来实例化一个HDCP对象并返回给显示系统一个IHDCP接口,用来实现HDCP加密服务。
显示系统的SINK端的TunnelRenderer对象在其initPlayer中还调用MediaPlayerService服务的create函数来创建一个MediaPlayer对象,并返回一个IMediaPlayer接口给显示系统使用,用来实现SINK端接收的镜像数据的播放。
显示管理系统源端获取的镜像数据经过音视频编码(H264),然后进行HDCP加密和PES packetization及TS流化(转换为TS流)后 ,最后打包成RTP包经过UDP通道发送到SINK端,SINK端要经过相反的处理过程,从UDP通道接收RTP包,然后进行TS解析和PES去packetization化和HDCP解密,最后送给解码器进行解码。解码后的数据送给播放器的呈现器进行呈现。
源端和SINK端的音视频编解码都通过IOMX接口与底层的多媒体框架交互,实现音视频编解码功能。IOMX接口对应的对象OMX也是在MediaPlayerService服务端实例化的,在客户端对象OMXClient的connect函数中通过调用MediaPlayerService服务的getOMX函数返回OMX对应的IOMX接口。OMX对象是对多媒体框架OPENOMX的封装。
源端的音视频编码、TS流化、HDCP加密、RTP打包发送的流程都有PlaybackSession线程类管理和调度,PlaybackSession类初始化时实例化一个SurfaceMediaSource对象,SurfaceMediaSource对象内部实例化一个BufferQueue对象(BufferQueue从ISurfaceTexure中派生)。在与SINK端建立连接后,通过IRemoteDisplayClient接口的回调函数onDisplayConnected把BufferQueue对象传给JAVA层,JAVA层的WifiDisplayAdapter对象收到onDisplayConnected事件后调用Surface类的createDisplay函数在SurfaceFlinger服务中登记一个虚拟显示器,并调用Surface类的setDisplaySurface函数把BufferQueue传给SurfaceFlinger服务虚拟显示器对应的DisplayDeviceState变量中.。因此PlaybackSession可以使用BufferQueue对象从SurfaceFlinger服务读取要镜像的数据。
SINK端WifiDisplaySink对象接收的数据经RTP解码(由RTPSink对象负责)后,送给TunnelRenderer对象进进行呈现, TunnelRenderer对象在initPlayer函数中实例化一个PlayerClient播放客户端,并通过IMediaPlayerService接口调用MediaPlayerService服务的create函数创建一个MediaPlayer对象并返回TunnelRenderer对象IMediaPlayer接口, TunnelRenderer对象使用IMediaPlayer接口对接收到的镜像数据进行播放和呈现, TunnelRenderer对象还在initPlayer函数中通过SurfaceComposerClient对象实例化和获得一个Surface对象,并调用其getSurfaceTexture函数获得Surface对象对应的ISurfaceTexture,并调用IMediaPlayer接口的setVideoSurfaceTexture函数把ISurfaceTexture赋值给播放器,从而实现播放器解码后的显示数据送给SurfaceFlinger显示服务进行显示.
SINK端的WifiDisplaySink对象和源端WifiDisplaySource的对象负责WIFI Display 交互协议的处理,两个对象都包含一个ANetworkSession对象负责两者之间的网络交互会话过程。
如下是WIFI Display 协议的框架图。
ANDROID4.2的开源代码提供了WIFI Display 协议的具体实现,但对SINK端只是作为一个本地测试命令来执行,并且没有提供图中的用户输入功能,而对于WFD Source端则提供了完整的实现代码,这主要是ANDROID系统主要是作为手机平板操作系统使用的缘故。
ANDROID4.2的WIFIDisplay的实现包括JAVA部分和C++部分。JAVA部分的功能主要对应DisplayManagerService服务,DisplayManagerService服务对于WIFIDisplay实例化和登记一个WifiDisplayAdapter对象(派生自DisplayAdapter),用来与对应的显示设备建立连接,每个DisplayAdapter与一个显示设备DisplayDevice类一一对应 。每个显示设备在DisplayManagerService服务中 对应一个LogicalDisplay对象。
DisplayManager发起的对WIFI Display的请求都由DisplayManagerService服务转发给WifiDisplayAdapter对象处理,为了实现异步交互和避免死锁,WifiDisplayAdapter对象对于每个请求都启动一个线程来实际完成请求处理,并实例化一个WifiDisplayController对象来封装这些请求的调用。WifiDisplayAdapter对象内部也实例化一个WifiDisplayController.Listener对象用来监听请求的状态。 WifiDisplayController对象内部实例化一个WifiP2pManager对象用来通过其接口向WifiP2pService服务发起WI-FI DIRECT请求。在与WIFI Display连接时通过实例化一个RemoteDisplay 对象来启动监听底层WIFI Display的连接事件。
C++ 部分位于媒体框架层,处于libstagefright目录的wifi-display目录下,wifi-display目录包含两个sink和source两个子目录(分别对应wifi display的sink和source 对应的程序),wifi-display目录还包含source和SINK公用的程序。
主要包含如下文件:
Sink目录主要包含WifiDisplaySink.cpp、RTPSink.cpp、TunnelRenderer.cpp等C++类文件和相应的头文件,分别负责SINK端的协议协议,RTP接收和镜像数据的呈现过程。而TS解析和PES去packetization化及解码过程都有播放器NuPlayer完成,由于Sink端只是一个测试例程,因此暂没有提供HDCP解码流程。
Source目录主要包括WifiDisplaySource.cpp、PlaybackSession.cpp、MediaPuller.cpp、Converter.cpp、TSPacketizer.cpp、Sender.cpp等C++类文件和相应的头文件,分别负责Source端的协议交互,会话过程管理、镜像媒体读取、编码、TS打包及RTP打包发送等过程。Converter 对象中包括一个MediaCodec对象具体负责编码过程,MediaCodec对象实际通过ACodec对象调用IOMX接口使用OPENOMX媒体框架完成镜像数据的编码。
sink和source使用的公共类文件主要是ANetworkSession.cpp和对应头文件以及一个 启动WifiDisplaySink的主程序wfd.cpp,用来 生成命令wfd。
整个协议主要的流程包括WIFI Display显示设备的连接过程和镜像数据的打包发送和接收流程,具体流程在下一篇博文中阐述。
ANDROID DisplayManager 服务解析一的更多相关文章
-
第十七篇 --ANDROID DisplayManager 服务解析一
ANDROID从版本4.2开始提供了一个显示管理服务DisplayManagerService,支持多种显示类型的多个显示器的镜像显示,包括内建的显示类型(本地).HDMI显示类型以及支持WIFI D ...
-
Android Service完全解析,关于服务你所需知道的一切(下)
转载请注册出处:http://blog.csdn.net/guolin_blog/article/details/9797169 在上一篇文章中,我们学习了Android Service相关的许多重要 ...
-
Android Service完全解析,关于服务你所需知道的一切(上)
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的A ...
-
Android从服务端获取json解析显示在客户端上面
Android从服务端获取json解析显示在客户端上面 百度经验:jingyan.baidu.com 首先说一下Json数据的最基本的特点,Json数据是一系列的键值对的集合,和XML数据来比,Jso ...
-
【转】Android Service完全解析,关于服务你所需知道的一切(下) ---- 不错
原文网址:http://blog.csdn.net/guolin_blog/article/details/9797169 转载请注册出处:http://blog.csdn.net/guolin_bl ...
-
[转]Android Service完全解析,关于服务你所需知道的一切
目录(?)[+] Android Service完全解析,关于服务你所需知道的一切(上) 分类: Android疑难解析2013-10-31 08:10 6451人阅读 评论(39) 收藏 举报 ...
-
(转) Android Service完全解析,关于服务你所需知道的一切(上)
相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Android程序员如果连Service都没听说过的话,那确实也太逊了.Service作为Android四大组件之一,在每一个应用程序 ...
-
Android Service完全解析,关于服务你所需知道的一切(下) (转载)
转自:http://blog.csdn.net/guolin_blog/article/details/9797169 转载请注册出处:http://blog.csdn.net/guolin_blog ...
-
Android Service完全解析,关于服务你所需知道的一切(上) (转载)
转自:http://blog.csdn.net/guolin_blog/article/details/11952435 转载请注明出处:http://blog.csdn.net/guolin_blo ...
随机推荐
-
JS监听键盘的组合按键
Mark 一下: $(document).keydown(function (e) { console.log(e); var keyCode = e.keyCode || e.which || e. ...
-
C#获取网页内容的三种方式
C#通常有三种方法获取网页内容,使用WebClient.WebBrowser或者HttpWebRequest/HttpWebResponse... 方法一:使用WebClient (引用自:http: ...
-
C#时间戳转成php的time()
DateTime timeStamp = new DateTime(1970,1,1); //得到1970年的时间戳 long a = (DateTime.UtcNow.Ticks - timeSt ...
-
U盘装系统详细教程
相信有的朋友去电脑城组装电脑的时候,会看见装机人员安装系统不再需要光驱,而插入U盘安装系统,U盘安装系统方便了许多,电脑光驱容易坏,使用寿命短,一般老电脑的光驱都不怎么好使,而U盘就不需要光驱就能安装 ...
-
css3文本效果
CSS3 包含多个新的文本特性. 在本章中,您将学到如下文本属性: 1. text-shadow 2. word-wrap 浏览器支持 Internet Explorer 10.Firefox.Chr ...
-
设计模式(九)外观模式Facade(结构型)
设计模式(九)外观模式Facade(结构型) 1. 概述 外观模式,我们通过外观的包装,使应用程序只能看到外观对象,而不会看到具体的细节对象,这样无疑会降低应用程序的复杂度,并且提高了程序的可维护性. ...
-
使用内链接(A a inner join B b on a.xx = b.xx)查询2个表中某一列的相同的字段。
这里一句代码就是查询2个表中某一列的相同,可是查询出来之后B表因为有很多重复的id数据,然而查询出来的数据需要插入到临时表中,临时表的oid是不允许有重复的, 因此需要用到 distinct 函数来取 ...
-
解决Android Studio中Refreshing gradle project时间过长的最简单方法
Refreshing gradle project往往出现在Gradle出现更新,需要从墙外的网重新拖下来的前提下.具体可以查看以下文件:/path/to/project/gradle/wrapper ...
-
Amazon新一代云端关系数据库Aurora(上)
本文由 网易云发布. 在2017年5月芝加哥举办的世界*数据库会议SIGMOD/PODS上,作为全球最大的公有云服务提供商,Amazon首次系统的总结 了新一代云端关系数据库Aurora的设计实现 ...
-
linux中增加swap分区文件的步骤方法
一.swap交换分区 Swap分区在系统的物理内存不够用的时候,把硬盘空间中的一部分空间释放出来,以供当前运行的程序使用.那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临 ...