图1 发送端的Filter Graph
接收端的实现思路如下:通过一个接收Filter接收发送端发送的数据,然后再用Divx Decoder Filter对接收到的数据进行解码。最后用Video Renderer把解码后的数据播放出来。其Filter Graph如图2所示:
图2 接收端的Filter Graph
3.1 数据采集及编码的实现
3.1.1 采集Filter Graph的实现
采集应用的Filter Graph一般比较复杂,而直接使用Filter Graph Manager上的IGraphBuilder接口构建这种Filter Graph,有时候难度又很大。为此,DirectShow特别提供了一个辅助组件Capture Graph Builder,来简化这种Filter Graph的创建。
首先是创建Filter Graph Manager 组件,核心代码如下:
3.1.2 加入采集Filter
3.1.3加入MPEG-4编码器Filter
这里我们采用Divx 提供的开源编码Filter。安装DivX.Pro.v5.1.1后会自动安装Divx的编码器Filter和解码器Filter(注:解码器 Filter在接收端要用到)。在程序中加入Divx的编码器Filter,实现思想是在Video Compressors目录下枚举到名称为"DivX Pro(tm) 5.1.1 Codec"的Filter项后,把它加入到Filter Graph中即可。
3.2 数据的发送和接收
3.2.1 数据的发送Filter的实现
数据的发送要开发一个发送Filter,为了编程上的方便,这里采用程序内Filter的形式来实现。即用类的形式而不是编写一个成一个后缀为ax的组件 注册后再使用。这里我们定义一个继承自CBaseFilter的类CFilterMpeg4Sender。这个类必须实现以下功能[3]:
(1) 在类中定义CFilterMpeg4Sender上的Pin的实例mInputPin。
(2) 实现继承自CBaseFilter::GetPin,用于返回Filter上各个Pin的对象指针。
(3) 实现继承自CBaseFilter::GetPin,用于返回Filter上各个Pin的数量。
定义一个继承自CRenderedInputPin的类CMpeg4InputPin,用于实现CFilterMpeg4Sender上的输入pin,发送Filter通过该输入pin接收编码Filter输出的数据,然后按一定的规则发送。
这个类必须实现以下功能[2]:
(1) 重写方法EndOfStream。
(2) 实现IPin::BeginFlush和IPin::EndFlush两个函数。
(3) 重写方法CBasePin::CheckMediaType进行连接时媒体类型的检查。
(4) 重写方法CBasePin:: Receive(),接收Sample并发送
3.2.2 数据的接收Filter的实现
数 据的接收其实是要编写一个Source Filter, 这个Source Filter名称为CFilterMpeg4Receiver,也继承自CBaseFilter。这跟发送Filter的实现有些类似,有一点需要注意的 是该Filter输出的MediaType的设置。
Char MediaType[]=//媒体数据类型,通过在发送端把媒体类型写到一个文件中而得到然后通过语句:CFilterMpeg4Receiver:: SetupMediaType((char *)MediaType,88)设置输出数据的MediaType。
CFilterMpeg4Receiver::SetupMediaType再调用CMpeg4OutPin::SetupMediaType()设置、接收到的媒体数据的格式,
3.2.3 数据的网络传输的实现
数据的发送我们采用开源代码JRTPLIB【6】提供的RTP协议栈。最新的JRTPLIB对RFC3550的实现进行了封装,开发人员只要初步了解 RTP协议就可以开发出高质量的音视频传输程序。使用JRTPLIB时,只需要通过继承RTPSession类,再重新以下几个函数就可以实现视频数据的 接收。
在网络带宽比较低的情况下(如十几KBps),数据丢帧现象比较严重,这对于图像质量有很大的影响。我们采用拆帧(拆成1400个字节)以后再发送的方法,来降低丢帧率。接收端收到数据后,再把属于同一视频帧的数据再组起来。
网络发送接收程序流程图如图3所示:
图3 网络发送接收程序流程图
对程序流程图的说明如下:
(1)发送端拆帧的算法如下:
然后把属于同一视频帧的数据组好,发送到解码Filter。
经过测试(在CDMA1.X网络下),采用拆帧方法传输视频数据比直接发送丢包率更低,传输质量有了很大的提高。
3.3 数据解码及回放的实现
解码Filter使用的是Divx提供的开源解码器,在接收Filter的后面接上该解码Filter即可,最后接上Renderer Filter就可以把接收到的数据回放出来。
3.4 实现帧率控制功能
通过在采集设备和编码Filter(DivX Pro(tm) 5.1.1 Codec)之间加入一个帧率控制Filter来实现帧率的控制,该Filter相当于一个视频帧数计数器,每接收到一帧,并不立即把该帧发给下游的编码 Filter,而是把计数器的值加1,当计数器的值达到最大值时才把当前收到的帧发出去。在接收端发控制帧率命令给采集端可以很方便的实现帧率的远端控 制。
程序片断如下:
加了帧率控制Filter的发送端 Filter Graph 如图4所示:
图4 实现了帧率控制的Filter Graph
4 总结
该系统采用了DirectShow技术实现了MPEG-4视频数据的传输,视频数据的传输采用了RTP协议。而且还实现了远端帧率的控制,该系统可以很方 便的移植到未来3G网络的图像传输系统中。对编解码器进行研究,采用H.264技术实现编解码Filter是下一步要完成的工作,当然在传输质量 (QoS)方面也要深入进行研究。