Android下WiFiDisplay功能探究
Posted 魏长志
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android下WiFiDisplay功能探究相关的知识,希望对你有一定的参考价值。
1 WiFiDisplay简介
1.1WiFiDisplay概述
WiFiDisplay(WFD)是WiFi联盟在已有技术的基础上,为了加速视/音频的传输分享而提出来的一个新概念。WiFi联盟对此成立了一个认证项目:Miracast-- 用来认证一个设备是否支持WiFiDisplay功能。
下图是WiFiDisplay功能的技术支撑体系,实际上最重要的部分就是WiFi Direct:也就是两个设备无需AP(AccessPoint)的情况下直接相连,这就奠定了两个带WiFi功能的设备能够随时传递高质/高清视频的前提。另外,其他深蓝色的技术是必须支持的:
11n:即802.11n协议,支持最高传输速度540Mbit/s;
WMM:即WiFi Multimedia的简称,主要针对不同的数据内容保证其传输的稳定和质量;
WPA2:是WiFi联盟对于采用802.11i协议并采用更为复杂加密算法的认证项目;
WiFi ProtectedSteup:也是一个WiFi联盟的一个认证项目:简化用户安装无线局域网和对安全性能的配置工作;
WiFi Direct:表示设备可以实现直接互联,无需AP的参与;
WiFi Miracast:即为是否可以实现wifi-display功能的认证项目。
图 1 WiFiDisplay技术支撑架构
另外,WiFi联盟还描述了WiFiDisplay的简化工作模型(图2)。在这个工作模型中,Miracast定义传输视/音频数据的一方为source端;接受数据并重新呈现的为sink端。从图中可以看到,source端要有数据内容的存储和下载/生成能力;对数据进行编码能力。而sink端则需要对数据的解码能力;对视/音频进行再度呈现的能力。而Miracast则是定义了这两个设备之间,怎样保持会话;可以传输数据的格式标准;会话控制等内容。
图 2 WiFiDisplay的工作模型
1.2 WiFiDisplay重要规范及标准
WiFi联盟定义了Miracast支持的视/音频格式标准:
图 3 Miracast支持的显示、视频、音频格式标准
同时,Miracast也规范了设备连接后进行协商(图4)、建立会话的流程(图5)。详细描述了设备在建立物理连接后,通过标准步骤来完成WiFi Display的会话建立,然后开始数据传输。关于各个标准步骤的详细信息,请见Miracast官方解释。
图 4 Miracast定义的设备协商标准过程
图5 Miracast定义的显示会话建立过程标准
2 主要模块介绍
由于WFD功能主要涉及wifiP2P功能和display功能,现对Android中涉及的两个模块wifiP2pService和SurfaceFlinger做一些介绍。
2.1 WiFiP2P
2.1.1 WiFiP2P简介
WiFiP2P是WiFi联盟提出的一项重要技术规范,它定义了两个wifi设备如何在没有路由的情形下连接并通信。根据定义,支持WiFiP2P的设备需要扮演P2P GroupOwner或P2P Client角色来形成一个P2P Group:
图6 WiFiP2P工作组模型
其中P2P Group Owner的设备需要发挥传统路由的功能:控制WiFiP2P工作组,使能设备通信等;P2PClient设备则需要连接上P2P Group Owner设备来形成一个工作组来通信。
在以上的工作模型基础上,WiFiP2P细化了以下技术项:
图7 WiFiP2P定义的P2PDiscovery规范
在P2P Discovery规范中,定义了发现设备(Device Discovery )并构建工作组(GroupFormation )的细节。其中发现设备规定设备首先进入扫描阶段(ScanPhase),去发送Probe Request帧;然后进入寻找阶段(Find Phase),在这个阶段中设备会在SearchState和Listen State中切换:两个阶段分别是发送Probe Request帧、监听ProbeRequest帧并发送Probe Response帧。当找到附近的P2P设备后,就可以来构建一个工作组:包括决定谁是Group Owner的协商(GONegotiation )和设备交换安全配置信息(Provisioning),用于Client设备利用安全配置信息连接GO。
另外,WiFiP2P还定义了GroupOperation技术项,具体描述了和工作组交互的场景和流程:
·P2P Device Join GO(Group Owner)
·P2P Device Join GC(Group Client)
·GC invite P2P Device
·GO invite P2P Device
… …
2.12 android中WiFiP2P
Android中关于WiFiP2P模块主要涉及以下几个部分:
图8 Android中WiFiP2P涉及模块
WiFiP2PSettings 是用来和用户交互的部分,主要是提供UI给用户选择打开/开闭WiFiP2P功能、呈现搜寻到的P2P设备给用户等;WiFiP2PSettings实现的功能调用的是WiFiP2PManager中的接口;WiFiP2PManager最终会与WiFiP2PService交互,它们依靠Android的Binder机制来实现进程间的通信,WiFiP2PService则是用来管理Android中WiFiP2P功能的核心模块:
图9 Android中WiFiP2P涉及模块
在WiFiP2PService类中有一个内部类P2pStateMachine(状态机)用来管理WiFiP2P的不同状态然后执行不同的操作;另外WiFiP2PService还会创建一个WifiMonitor对象用于接收来自wpa_supplicant的消息并根据接收到的消息给P2pStateMachine传值来推动状态机的工作。从图中可以看到,WiFiP2PService或WifiMonitor交互的是WiFiNative.Java中的接口,这里面的都是一些native函数;这是因为wap_supplicant进程是C语言实现,Android是通过JNI机制调用android_net_wifi_Wifi.cpp 里面的本地接口,这些本地接口来最终和wpa_supplicant交互(wifi.c里面是对发送到wpa_supplicant里面消息的封装)。
wpa_supplicant是一个开源项目,实现了WiFi联盟规范中的众多功能,详见官方文档。下图是wpa_supplicant及与下层部件的一个草图:
图10 wpa_supplicant及底层部件草图
2.2 SurfaceFlinger
总所周知,SurfaceFlinger是Android中对图形画面进行管理并交由FrameBuffer实际显示的重要模块,它需要收集系统中所有应用程序绘制的图像数据,然后集中处理后显示到物理屏幕上。下图是Android下图形显示的一个简略框图:
图11 Android显示系统简略框图
上图描述的是使用OpenGL ES图形开发规范下的情况。首先,每个应用程序在自己的窗口上进行绘图,这里的窗口(Window-2)实际上对应的是一些缓冲区;然后SurfaceFlinger则会对这些缓冲区进行统一管理;最后每一帧的图形数据会被送到FrameBuffer上并实际显示在设备上。
对于上层应用来说,Window-2在Android中的实现为SurfaceTextureClient类。由于是在OpenGL ES的开发框架下,SurfaceTextureClient实际上是继承自ANativeWindow同时在本地实现了一些接口(参见EGL知识):
图12 上层应用的window实现
hook_dequeueBuffer()和hook_queueBuffer()是框架定义中需要实现的本地函数,上层应用作图时需要从缓冲队列得到缓冲区;作图完成后需要把缓冲区送还给缓冲队列。具体情形如下:
图13 本地窗口和缓冲队列交互图
如上图,本地窗口实际上是从BufferQueue来得到缓冲区;画图后再将缓冲区入列到缓冲队列。而BufferQueue是在应用程序创建Surface(在SurfaceFlinger端对应Layer)的时候生成的,本地窗口通过返回的ISurface对象得到ISurfaceTexture对象来最终和BufferQueue交互。
对于SurfaceFlinger侧的本地窗口Window-1(图11)来说,SurfaceTextureClient也是作为本地窗口的功能。不过在SurfaceFlinger端通过标准的OpenGL ES接口进行请求缓冲区操作和入列缓冲区操作的对象就不一样了;而且在入列缓冲区后所进行的操作也不一样:
图14 SurfaceFlinger的本地窗口
如上图,在SurfaceFlinger端的本地窗口Window-1,会有自己的BufferQueue对象,而最终和HAL层的Gralloc模块交互实际分配缓冲区的时候,会根据功用不同来分配不同类型的缓冲区:上层应用分配的缓冲区是给OpenGL绘图用的;SurfaceFlinger这边分配的缓冲区是要送显FrameBuffer的(详见gralloc.h中定义)。
对于上层应用来说,填充好缓冲区后处理端(consumer&producter模型)会调用到Layer文件的onFrameQueued()函数,如果需要渲染图形这时候需要等待一个VSYNC信号(详见Android的Project Butter),收到VSYNC信号后会对需要渲染的Buffer按照Z轴计算可见区域并进行图像混合;而对于SurfaceFlinger端来说,缓冲区入列后consumer会最终调用fb的HAL层接口完成实际显示。
3 Android下实现详述
Android自从4.2后就支持WiFiDisplay功能了。以下是Miracast官方公布的WFD工作模块框图:
图15WiFiDisplay的工作模块框图
在以上工作模型的基础上,Android主要做了以下工作:
·新加了WiFiDisplay的setting部分,用来为用户提供操作选项;
·新加DisplayDevice类用来描述不同的显示设备,WiFiDisplay作为一个虚拟显示设备;
·修改了SurfaceFlinger模块来支持WiFiDisplay,通过SF把显示内容投放到不同的设备上;
·新加了DisplayManagerService来对系统的显示设备进行统一管理
·根据Miracast规定的会话建立管理流程,实现了source端和sink端的程序
3.1 应用程序端
对于WiFiDisplay功能,Android提供了相应接口给应用程序使用,以实现在第二显示设备上进行显示。具体内容参考官方描述,其中关键步骤见图16:
图16 Android上WFD应用编程简要步骤
可以看到主要包括Presentation和MediaRouter两个class。实际上它们都会调用一个重要的class提供的功能 – DisplayManager,而DisplayManager接口的具体实现在另外一个进程中的DisplayManagerService.java文件中。
3.2 DisplayManagerService及相关
DisplayManagerService是Android中管理WiFiDisplay功能的核心服务:
图17 DisplayManagerService简图
每一种显示设备(LocalDisplayDevice、WiFiDisplayDevice)都有一个对应的DisplayAdapter,DisplayManagerService通过管理这些Adapter来管理不同的显示设备。比如DisplayManager发起的对WiFiDisplay的操作请求,都会由DisplayManagerService转给WifiDisplayAdapter来实际完成。另外DisplayManagerService服务还通过WindowManagerFuncs窗口管理功能接口直接调用WindowManagerService的函数,实现窗口内容的刷新;同样DisplayManagerService服务还通过InputManagerFuncs接口直接调用InputManagerService的函数,用来设置输入系统需要的显示器的显示视图信息。
而WifiDisplayAdapter的操作最终会实现在WifiDisplayController中,去实现设备扫描、设备连接等操作:
图18 WifiDisplayController简图
关于和其他设备的WiFiDirect连接,Android有专门的一个WifiP2pService来管理,这里对于设备的连接就是直接调用WifiP2pManager(和WifiP2pService交互)所提供的接口来完成。
3.3 Source/Sink设备会话管理端
在设备建立WiFi连接后,会在RemoteDisplay上监听RTSP的连接,用于后续创建session和传输实时流数据。
图19 监听RTSP连接流程简图
如上图,实际的监听最终流程会走到RemoteDisplay中,即一个RemoteDisplay对象的创建。通过创建这个本地的RemoteDisplay对象将会创建一个ANetworkSession对象,用于管理网络部分的操作;创建一个ALooper对象,实现各类消息的派发和处理;创建一个WifiDisplaySource对象(由于搭载Android系统的大多数设备在WiFiDisplay场景中,多数会扮演source端的角色,因此这里创建的是WifiDisplaySource对象),具体处理各类消息:
图20 RemoteDisplay简图
另外,Source目录还包括PlaybackSession.cpp、MediaPuller.cpp、Converter.cpp、TSPacketizer.cpp、Sender.cpp等C++类文件和相应的头文件,分别负责Source端的会话过程管理、镜像媒体读取、编码、TS打包及RTP打包发送等过程。Converter 对象中包括一个MediaCodec对象具体负责编码过程,MediaCodec对象实际通过ACodec对象调用IOMX接口使用OPENOMX媒体框架完成镜像数据的编码。
3.4 视/音频数据获取方式
图21 source端的媒体数据获取简图
如图,source设备端程序对要在远端设备进行呈现的视/音频数据通过MediaSource类进行管理。上图中的SurfaceMediaSource和Audiosource都是继承自MediaSource类,它们分别对应视频数据和音频数据,根据不同的情景,source设备端程序可以添加视频或者音频数据源到当前程序中来,而且每一个MediaSource会对应创建一个Converter对象和一个MediaPuller对象,用于媒体数据的编码和数据读取等操作。下图是获取视频数据的程序片段,调用MediaSource的通用接口read来实现。
图22 获取视频数据程序片段
3.4.1 视频数据源
由图22可知,视频数据是从一个BufferQueue中读取的。上层应用正是将需要显示的视频数据放到和这个BufferQueue对应的Surface中,实现视频数据的远端设备投递。
图23 SurfaceFlinger管理不同显示设备简图
较详细来说,上文中的surface是由WiFiDisplayDevice所持有的,这部分内容还和SurfaceFlinger为支持画面投递到不同的设备上而进行的改动有关。如图23,主要是抽象了DisplayDevice来表述本地显示设备和WiFiDisplay等显示设备,在SurfaceFlinger.cpp的handleTransactionLocked函数中可以看到:
图24 SurfaceFlinge对不同显示设备处理代码片段
对于virtualDisplay的话(WiFiDisplay设备),mFramebufferSurface为空;SurfaceTextureClient直接使用了State信息中携带的surface变量。这个Surface正是当RTSP建立后,在回调函数onDisplayConnected中注册到SufaceFlinger中的(3.3节描述监听连接),这样SurfaceFlinger会将上层应用的显示数据投递到这个Surface上面,而source端的程序则会从这个surface上取出数据。
3.4.2 音频数据源
由图21可以看到,音频数据的获取是通过AudioRecod来得到。Android系统对于Audio系统抽象了AudioTrack对象和AudioRecord对象来分别用于音频数据的输出和音频数据的采集/获取。对于WiFiDisplay情景下的音频数据处理,Android也是在不破坏原有架构的情况进行的:
图25 WFD情景下音频简单架构图
AudioRecord通过AudioSystem对象来获得AudioFlinger和AudioPolicyService的远端接口进行操作,最终和HAL层的module交互,实际上完成的是从一个管道中的读取操作;而AndroidTrack也是基于同样的模型,只不过流程相反,完成的是向HAL层的一个对应管道中的写操作。其中AudioPolicyService在Android关于Audio的各个组件中扮演着核心角色:
图26 AudioPolicyService核心与其他组件交互图
如上图,详细来说:AudioPolicyService直接交互的是一个称为‘POLICY’的HAL层模块,这个模块提供了通用接口;然后通用接口会调用到一个具体的策略管理类中提供的接口,对应上图的AudioPolicyManagerALSA;最终,会根据不同的调用参数来获取真正的HAL层模块,和硬件交互,而AudioFlinger得到具体的HAL层模块后,就可以直接对其操作了。
这些具体的HAL模块,ID名称都为AUDIO_HARDWARE_MODULE_ID ,只是被编译成了不同名称的库文件,而对应于WiFiDisplay的HAL层模块不需要和具体的硬件打交道,实际实现为一个管道:
图27 WiFiDisplay的HAL模块程序片段
因此,对于需要通过WiFiDisplay到远端设备进行呈现的音频数据,只需要使用AudioTrack的接口来把音频数据放到上文HAL模块中的管道;而WiFiDisplay的source程序端也只需要调用AudioRecord的接口取出数据即可。最发送前的编码,音频/视频打包则专门去处理,不破坏原有的系统架构。
4 WiFiDisplay应用场景及相关产品
4.1 主要应用场景
WiFiDisplay技术实现视/音频数据的无线远端呈现,目前涉及视/音频数据处理的设备较多,常用的应用场景有:
1、数字播放器和数字电视工作场景:在这个应用场景下,由于source端设备不具有用户交互屏幕,因此sink端设备需要和用户交互完成设备的配对、传输的控制等工作;
图28 WFD应用场景1
2、下图描述的是一个数字机顶盒和DTV加上一个AP的工作模型,source设备在这个模型中同时连接到AP和sink设备,source端的数据此时是从网络获取的。这在WiFiDirect模型中是允许的,对于P2P连接在底层实际上对应的一个虚拟地址。
图28 WFD应用场景2
3、下图是描述的是有两个sink端设备的应用场景,此时source设备需要发现和连接两个sink设备,并发送视频/音频数据到不同的sink设备上。同时两个sink设备也需要彼此通信,来做同步和其他信息交换。
图28 WFD应用场景3
4.2 相关应用产品
WiFiDisplay的应用产品,市场上已经有一些,比如百度推出的百度影音棒、小米盒子等。其中百度影音棒的工作情况如下:(官方说明)
图29 百度影音棒2S工作简图
百度开发出的百度影音棒系列,实际上一种充分考虑现实情况的一套无线视频播放方案。由上图可知,考虑到现有电视的实际情形(大多数只带HDMI功能),这套方案对于TV还是使用HDMI和BaiDu 2S有线连接,而真正的无线模块则是这里的BaiDu 2S。这里的source设备即为手机,sink端设备其实就是BaiDu 2S。
小米盒子和上图的工作模型基本一致,不过根据官方说明支持音乐远端播放以及AirPlay协议和DLNA协议(官方说明)。
5 DLNA技术和AirPlay技术
5.1 DLNA技术
DLNA(Digital Living Network Alliance)是由Sony、Intel、Microsoft等发起成立的一个认证组织,其目的也是实现消费电子产品通过有线/无线网络实现设备互联、数据互通。相比于Miracast认证项目,DLNA有着自己的一套框架和相应标准:首先DLNA将市场上几乎所有的电子产品进行了分类(图30),一方面可以便于DLNA对众多的设备进行规范认证,另一方面也是DLNA为不同设备间进行交互制定标准的基础。
图30 DLNA定义的设备类别和类型
其次DLNA定义了设备工作架构(图31),其中UpnP是实现设备设备发现、连接、控制的重要协议层(参考文章),而媒体数据的传输则是使用HTTP传输协议或者是RTP协议。
图31 DLNA系统架构图
5.2 AirPlay技术
AirPlay是苹果公司实现的在苹果产品或是其认证产品之间传输媒体信息的一套解决方案。AirPlay技术可以实现产品之间自动地互相发现,并且轻松地互相传输音乐、图片及视频文件。
AirPlay以组播DNS(Multicast DomainName Server—mDNS)协议和DNS服务发现(DNS Service Discovery,简称DNS-SD)协议为基础,它们是IETFn Zeroconf工作组提出的用于自动寻找设备及服务的网络协议,苹果公司以这两个协议为基础,实现了苹果公司数字家庭网络框架。
AirPlay协议消息发送格式及规则基于mDNS协议,mDNS协议基于组播技术,定义了家庭各个设备之间的消息的基本格式和接收/发送规则。该协议以DNS协议为基础,并对其消息格式和消息收发顺序作出了一些修改。例如对DNS消息包头进行了简化,使其专注于实现家庭设备的互相发现;另外,考虑到使用组播技术,mDNS在降低网络拥塞和消息冗余方面也作出了很多改进,使得局域网内设备和服务的发现不会引起过多的消息交互。
在mDNS协议的基础上,DNS-SD协议规定了一个服务宣告及使用的完整过程。即设备必须发送什么样的mDNS消息才能完整地宣告并描述自己服务。DNS-SD协议使用PTR、SRV和TXT三种类型的记录全面描述了一个服务的类型,名称以及所在主机的IP和端口号等。
当使用DNS-SD协议实现了对设备及服务的发现和描述后,苹果公司的AirPlay协议规定了图片、音频及视频的传输和控制消息格式,从而实现了智能设备之间的媒体共享和协同动作。在通过DNS-SD获得了其他设备及服务的信息(即设备或服务的IP地址及端口号)之后,AirPlay使用HTTP消息实现了图片和视频的传输及控制,使用RSTP协议实现了音频的传输和控制
AirPlay工作模型和WiFiDisplay技术和DLNA技术基本一致,只不过它是苹果公司的私有方案,因此没有公开的规范资料(非官方协议协议标准)。
PDF下载:http://download.csdn.net/detail/srw11/7645371
以上是关于Android下WiFiDisplay功能探究的主要内容,如果未能解决你的问题,请参考以下文章
android4.2 wifidisplay远程显示修改为保存文件
Android WifiDisplay分析二:Wifi display连接过程
android4.2 WifiDisplay远程显示修改为保存文件