作者:蒋勇 杜中军 鞠飞
1 引言
随着计算机技术、网络技术、视频压缩编码技术等关键技术的飞速发展, 特别是宽带网络的迅速普及, 网络视频传输系统以及其实时性和直观性得到了越来越多的重视。目前视频传输技术正迅速被应用于视频会议、视频点播、IP可视电话、Internet远程教育等领域。同时, 随着大量智能终端的兴起, 浏览器技术得到了广泛的应用, 基于Web的应用在未来的智能终端中将会成为主流。考虑到当今的嵌入式系统处理能力不高及资源的限制, 本文将探讨一种可以播放视频点播和可视电话的视频流的浏览器插件技术, 此方法利用一般视频播放器强大的解码能力, 将视频电话的视频流进行转换,从而在视频播放器中播放。这在一定程度上减轻了对系统的资源消耗, 还解决了在微小系统中不同程序间的焦点问题。经过实践证明, 将不同的视频流整合在一个播放器中, 以浏览器插件的方式实现, 在基于Web的微小系统中可以取得良好的视讯效果。
2 RTP 及RTCP 协议的构成
RTP协议是用于Internet上,针对多媒体数据流的一种实时传输协议,其目的是提供时间信息和基本的差错纠正信息,并能实现流的同步。RTP协议包头的格式组成如图1所示。其中,M域占用1bit,含义由使用者确定; Sequence Number域代表发送的RTP包计数,占用16bits; Timestamp域占用32bits,它反映了RTP包中数据采样的间隔; PT域代表载荷类型,占用7bits; SSRC域占用32bits,标志了会议中不同于其余的信息源,由系统随机产生; CSRC域占用32bits,为负载识别作用源,在混合器中设定。
图1 RTP协议包头的格式
RTCP是RTP协议的控制协议,用于拥塞控制和流控制,主要功能包括提供数据传送的质量反馈、建立标志、根据参与者数量决定控制包传输。RTCP协议定义RTCP包类型:源描述包( SDES) 、发送者报告( SR)和接收者报告(RR) 、BYE包和特殊应用的APP包。RTCP会话中的每个参与者都有一个全局唯一的标志符CNAME用于标志和跟踪每个参与者,进行流间同步以及计算参与者数目。在RTCP会话中,随时掌握与会者数目十分重要,所有与会者都必须使用该值来计算自己发RTCP帧的间隔,以保持RTCP数据流带宽恒定。在RTCP会话中,每个与会者都根据这个间隔周期发送RTCP控制报文。
3 实现不同RTP 流的应用模型
本文主要讨论的是视频客户端的实现,对视频的采集和发送不作阐述。本文将以分模块的方式对同一视频播放器中如何实现来源于视频电话和流媒体的视频流的应用模型进行阐述,其应用模型如图2所示。
图2 视频流的应用模型
图2中RTSP服务器和视频电话分别为不同的视频流的数据源。RTSP服务器提供符合RFC2326的标准媒体流,所能支持的媒体格式有RM,MPEG-4,WMV,MP3;视频电话的媒体格式可以在能力集约束中进行调整。在RTSP处理模块和电话RTP处理模块接收到RTP包后的一般处理步骤如下:
(1)分析RTP包头,判断版本、负载类型等信息;
(2)更新Source对象中的RTP信息,包括收到的视频帧数、包数、序列号等信息;
(3)进行信源同步,重构视频帧;
(4)根据负载类型进行解码,回放图像。同时,在处理模块中的定时器触发下,将会周期性发送RTCP报文,目的是同步协商和带宽调整;客户端在收到RTCP控制报文后将会进行如RTP类似的步骤,首先分析RTCP包头,找出对应的RTP源,然后根据收到的反馈信息采取相应的策略。
播放器采取的是预解码方式。在RTP流到达前播放器应知道流的负载类型。对于RTSP流,因协议的规定,在RTP流到达以前客户端和服务器端有一个协商过程,服务器以Options方法通知视频播放器流的负载类型,过程参考RFC 2326,此处将不再赘述。
对于视频电话,媒体的协商过程在H.323协议栈里完成,在RTP流到达之前播放器不知道流的负载类型。这里采用的方式是修改协议栈的能力集,使H.323协议栈以一种固定媒体格式与对方尽力协商,协商成功后将RTP流传给视频播放器,在播放器中以一种固定的解码器等待接收流。这种方式在实际中已经能够满足需求,此方案应用模型如图3所示。协商过程采用H.245协议,电话端首先设定客户端能力集SetCapability ( 0, 1, newH323 _H263Capability ( 0, 0, 1, 0, 0, videoBitRate, videoFramesPS) ) ;然后进行双方能力交换、主从确定、单向逻辑信道打开和双向逻辑信道打开;在视频媒体通道打开以后,电话端就开始发送和接收RTP流。
图3 视频电话应用模型
在H.323协议中,音频和视频是以不同的RTP流实现的,因此音频的处理和视频的采集、发送仍采用以前电话端的处理模块,只在电话端的RTP分组接收处H323_RTPChannel: : Receive ( )修改原有的对视频RTP分组的处理,将接收到的视频RTP分组经过帧重组后转发给视频播放器。RTP包的组帧算法采用大缓冲区法,即开辟一个足够大的缓冲区,将接收到的RTP分组按一定规则插入队列,然后从链表的首部开始根据时间戳和包序号进行组帧或淘汰。经过此方法处理后的分组已经是有序分组,播放器中只用一个缓冲区处理接收来的数据包。播放器预指定H. 263解码器,载荷类型( Payload Type)固定为34,时钟频率(Clock Rate)固定为90 000 (根据RFC1890修订版) 。电话RTP流处理模块伪代码如下:
4 浏览器视频插件的实现
随着PC的普及,多媒体应用越来越广泛,但在Linux下的多媒体功能却显得单调和缺乏灵活性。网络的兴起和浏览器技术的成熟,使基于Web的应用趋于主流,插件技术将在Web的多媒体应用中显得举足轻重。本文将就Linux下的浏览器插件技术进行探讨,并将前面所讨论的视频播放器嵌入到网页里面实现。
不同于布局引擎,Gecko所广泛采用的组件对象模型XPCOM那样的动态载入和对象注册机制,插件以原生码的动态链接库形式存在。浏览器和插件之间的交流通过固定的应用程序接口(API) ,分为两类和一个共享数据结构集:
(1)插件方函数。在插件中定义,由Gecko调用,以“NPP_”为前缀。这里有两个特殊的接口类型NP_,为Gecko直接访问入口,在实例生成以前使用,下面将进行具体阐述。
(2)浏览器方函数。在Gecko中定义,由插件方调用,以“NPN_”为前缀。
(3)数据结构集。浏览器生成该数据结构,两方形式统一,主要用于两方数据流的传递,以NP为前缀。
浏览器启动时Gecho会在Plugin目录下搜索插件库,读出和注册每个插件所能处理的媒体类型(MIME) ;当打开一个含有嵌入数据的网页时,浏览器会根据其中MIME搜索相应的插件,如果没有找到可用插件则使用独立的帮助程序(HelpApp lication) ,提示是保存还是选择其他的应用程序处理。如果找到插件,则将插件代码载入内存,初始化插件,然后创建一个插件实例。当插件最后一个实例被删除以后,插件的整个代码段被从内存中释放,体系结构如图4所示。
图4 体系结构
(1)获取Plug-in描述信息和M IME类型这两个过程是在Gecko启动时进行的,浏览器会根据提供的信息对插件进行注册。
(2)初始化资源。浏览器调入Plug-in代码时,调用接口NP_ Initialize,在这里分配内存和初始化以后各个实例将要使
用的资源。初始化过程中,浏览器为Plug2in传递了两个函数指针表: NPNetscapeFuncs和NPPluginFuncs。第一个表列举了所有在Plug-in里调用的浏览器方的函数地址,这个表在初始化以前由浏览器填写;第二个表列举了所有Plug-in提供给浏览器调用的函数地址,在Plug-in的初始化过程中填写。在初始化以前所有的Plug-in函数调用都是非法的,因为函数的地址还没有传给浏览器。
(3)初始化实例。在初始化资源完成以后,浏览器调用NPP_New创建实例,NPP_New会以指定的M IME类型创建实例。在这里定义实例私有的数据。浏览器传递一个特定的结构NPP给Plug-in,代表实例本身,此结构体由浏览器创建,可以将实例私有的数据地址保存于此,在以后对同一Plug2in的函数调用时,浏览器将这些实例私有数据依次传下去。
(4)绘制窗口和消息循环。当窗体被创建、移动、改变大小或者销毁时,浏览器调用NPP_SetWindow处理。调用时,一个含有实例窗口大小、位置和特定系统信息的对象NPWindow传给Plug-in,在Plug-in中根据这些信息绘制窗口。窗口类型分为两类: ①有窗体Plug-in,浏览器为Plug-in创造一个Motif窗口部件,并留出一块专用区域。此类Plug-in有自己的消息循环,可以接收所有来自窗口部件的消息。②无窗体Plug-in,没有专用区域并且所有消息都是通过浏览器接口NPP_Han-dleEvent传递。
(5)销毁实例和释放资源。当退出网页、关闭窗口或退出浏览器时,调用NPP_Destroy销毁实例。在这里释放所有初始化实例时所分配的资源。如果有必要也可以通过结构NPSaveData保存实例中的信息,在生成同一URL的新实例时浏览器将这些信息原样传入。在所有实例都销毁后,浏览器调用NP_Shutdown释放所有实例共享的资源。
以上阐述了Linux下浏览器插件的框架结构和标准接口,结合本文前面所讨论的视频播放器,在插件的NPP_SetWindow中以管道调用的方式实现视频插件。在网页中的嵌入数据里M IME类型指定为video/x-h263,URL指定为rtp:/ /(端口号) ,浏览器会根据这些信息调用以上讨论的视频插件在指定端口接收视频流。
5 结束语
本文在阐明RTP /RTCP协议原理的基础上提出了如何实现在一个播放器中播放来自不同源的视频流,并探讨了在Linux下以浏览器插件的方式实现播放。此应用是在原媒体播放器和视频电话基础上进行的重大改进,而且结合插件技术,使Linux下的多媒体功能更加丰富灵活;在资源消耗上,此项改进利用了媒体播放器原有的强大的解码功能,使视频电话从中脱离出来,避免了对资源的重复占用。
来源:http://www.51kaifa.com/html/jswz/200710/read-8548.htm
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。