本文是对freerdp wiki里的Multimedia Redirection所作的翻译。里面包含了一些音视频方面的知识,用蓝色标出。
根据【MS-RDPEV】,Multimedia Redirection(多媒体重定向)是将同步的audio和video数据从server端传输到client端。client使用RDP协议提供的时间信息来同步播放audio和video,因此也叫做Video Redirection(视频重定向)。
Usage
Server Requirement
Windows 2008 R2: 需手动使能audio和video重定向。
Win7 Ultimate/Enterprise: 随便用。
目前只有Windows Media Player支持重定向功能。
Compilation
必须编译以下开发包:
FFmpeg(libavcodec-dev)
ALSA(libasound2-dev)或者PulseAudio(libpulse-dev)
XVideo(libxv-dev)
Quick Start
为使用重定向功能,需要将tsmf动态虚拟通道注册到系统里:
xfreerdp --plugin drdynvc --data tsmf -- (server)
Audio Device
freerdp默认会探测PulseAudio是否可用,然后回退成ALSA,再使用默认的音频设备。用户可以通过在tsmf后添加参数来强制性指定audio backend和sound device。
下面例子是强制使用PulseAudio作为默认的音频设备:
xfreerdp --plugin drdynvc --data tsmf:audio:pulse -- (server)
下面例子是强制使用plughw:0,0的ALSA:
xfreerdp --plugin drdynvc --data tsmf:audio:alsa:plughw:0,0 -- (server)
注意:无须注册rdpsnd plugin。tsmf plugin支持的音频质量比rdpsnd好。
XVideo Adaptor
freerdp默认选择最新可用的XVideo adaptor(在大多数情况下可用)的端口。但是有时候用户也会手动选择不同的端口,比如默认的adaptor工作状态不理想,或者该端口被其他进程占用。可以用--xv-port参数来指定端口:
xfreerdp --xv-port (port) --plugin drdynvc --data tsmf -- (server)
注意:运行命令xvinfo来查看系统中可用的adaptor和port。
Demuxing and Decoding
每个video file都是由2个步骤构成的。
首先,Encoding(编码)。用一些算法将raw video/audio streams(原始码流)编码,这些算法叫做codec,比如video有H264,AVC1,WMV3,WVC1,audio有MP3,AC3,AAC,WMA2等。
然后,Muxing。用特定的容器格式将已经编码的码流打包进一个单独的文件里,这些容器格式有Matroska(mkv),AVI,MP4等。
播放一个video文件的时候,要经过Demuxing和Decoding(解码)两个过程。本地播放video时这两步明显可以完成。但是当要使用多媒体重定向时,Demuxing和Decoding是在不同的host上和不同的阶段执行的:先由server来demuxing,然后client来decoding。因此,当一个video文件在sever上打开时,media player播放器先parsing(解析)video file container,获得所需的全部header信息,把文件内容分离成video和audio码流,然后传送到client端,client则准备必需的codec算法来decode这些码流并播放。
很显然,为了重定向video file,server必须要理解container的格式。比如,Windows Media Player默认不支持Matroska,所以就需要server安装Matroska Filter来播放mkv文件。但是,server并不需要安装相应的codec,因为一旦demuxing完毕,原始码流内容会被送到client来decoding。
Supported Codecs
当前freerdp支持以下codec。
Video:WVC1,WMV3,H264/AVC1
Audio:WMA2,MP3,AAC,AC3
Bandwidth
基于一些观察值,100M以太网可以很好的播放HD720P,和本地播放的效果差不多。当用54M的Wifi(有更高的延时)做测试,DVD质量的video依然可以流畅播放,但是有时候会出现明显的丢帧。
Attribute
码流有三个重要属性:Major Type,Sub Type和Format Type。
Major Type
仅有2个major type:video和audio,具有确定的GUID。freerdp里将major type映射为tsmf_constants.h里的常量。还有一个比较有用的major type是subtitle,但是Windows Media Player似乎并不支持它的重定向,即使video文件里有subtitle stream。
Sub Type
Sub Type实际上是用来解码码流的codec,也具有确定的GUID。当然,freerdp里将sub type映射为tsmf_constants.h里的常量。当sub type传递给FFmpeg,codec常量就会被映射到FFmpeg codec的枚举常量里。将映射过程分为两步并具有freerdp自己的抽象层是很重要的,因为FFmpeg是被设计成一个sub-plugin的,以后freerdp会支持其他解码库。
Format Type
Codec需要相应的信息来正确解码。比如video的大小。许多codec还需要codec-specific extra data。在Matroska的规格说明书里,extra data被称作CodecPrivate。在RDP协议里,这些信息被打包进一个数据结构里,叫做Format Type,大部分在Media Foundation或DirectShow API里定义。每个Format Type被赋予确定的GUID,当然,freerdp也把它们映射为自己的常量。
有时候从Format Type数据结构里获取codec extra data比较复杂,在这种情况下,Matroska的容器格式可能比较容易获取,因为可以用一些EBML tree viewer应用程序能分析它们。
Pixel Format
解码后的video frame输出的是含有像素的原始图像。这些像素被打包成pixel format,通常是YUV。然后图像被直接传递给XVideo来供硬件解码和缩放。
目前freerdp支持的video codec普遍处理成最常见的I420格式,如果video驱动不支持,也可以将I420转换成YV12,但这就得先看看其他的pixel formats是否存在。
FAQ
Q:TSMF是什么?
A:TSMF(Terminal Service Media Foundation)是多媒体重定向协议的一个通道名称,目前在微软的官方文档里还没有解释。
Q:有足够的带宽,并且已经注册了tsmf插件,为什么video就像播放幻灯片一样?
A:video codec还不支持,因此video frame是在sever上解码,作为普通的RDP位图送入client。查看标准输出可获得一些有用信息。
Q:注册了tsmf插件,可是听不见声音。如果注册rdpsnd就能听见声音。
A:audio codec还不支持,因此audio samples在server上解码后通过rdpsnd插件送入client。如果不注册rdpsnd插件,就听不到声音。注意,即使能通过rdpsnd听到声音,audio/video还可能不同步。所以最好的解决方法是寻求audio codec的支持。
【参考文献】
https://github.com/FreeRDP/FreeRDP/wiki/Multimedia-Redirection