一、RTP是进行实时流媒体传输的标准合同和关键技术
实时传输合同(Real-timeTransportProtocollinux jrtplib 使用,PRT)是在Internet上处理多媒体数据流的一种网路合同,借助它能否在一对一(unicast,时隙)或则一对多(multicast,多播)的网路环境中实现传流媒体数据的实时传输。RTP一般使用UDP来进行多媒体数据的传输,但若果须要的话可以使用TCP或则ATM等其它合同。
合同剖析:每一个RTP数据报都由颈部(Header)和负载(Payload)两个部份组成,其中腹部前12个字节的涵义是固定的,而负载则可以是音频或则视频数据。
RTP是目前解决流媒体实时传输问题的最好办法,要在Linux平台上进行实时传送编程,可以考虑使用一些开放源代码的RTP库linux 论坛,如LIBRTP、JRTPLIB等。JRTPLIB是一个面向对象的RTP库,它完全遵守RFC1889设计,在好多场合下是一个十分不错的选择。JRTPLIB是一个用C++语言实现的RTP库,这个库使用socket机制实现网路通信因而可以运行在Windows、Linux、FreeBSD、Solaris、Unix和VxWorks等多种操作系统上。
二、JRTPLIB库的使用方式及程序实现
(1)JRTPLIB函数的使用
a、在使用JRTPLIB进行实时流媒体数据传输之前,首先应当生成RTPSession类的一个实例来表示这次RTP会话,之后调用Create()方式来对其进行初始化操作。RTPSession类的Create()方式只有一个参数,拿来指明这次RTP会话所采用的端标语。
RTPSessionsess;sess.Create(5000);
b、设置恰当的时戳单元,是RTP会话初始化过程所要进行的另外一项重要工作,这是通过调用RTPSession类的SetTimestampUnit()方式来实现的,该方式同样也只有一个参数,表示的是以秒为单元的时戳单元。
sess.SetTimestampUnit(1.0/8000.0);
c、当RTP会话成功构建上去以后,接下去就可以开始进行流媒体数据的实时传输了。首先须要设置好数据发送的目标地址linux jrtplib 使用,RTP合同容许同一会话存在多个目标地址,这可以通过调用RTPSession类的AddDestination()、DeleteDestination()和ClearDestinations()技巧来完成。诸如,下边的句子表示的是让RTP会话将数据发送到本地主机的6000端口:
unsignedlongaddr=ntohl(inet_addr("127.0.0.1"));
sess.AddDestination(addr,6000);
d、目标地址全部指定以后,接着就可以调用RTPSession类的SendPacket()方式,向所有的目标地址发送流媒体数据。SendPacket()是RTPSession类提供的一个重载函数
对于同一个RTP会话来讲,负载类型、标识和时戳增量一般来讲都是相同的,JRTPLIB准许将它们设置为会话的默认参数,这是通过调用RTPSession类的SetDefaultPayloadType()、SetDefaultMark()和SetDefaultTimeStampIncrement()方式来完成的。为RTP会话设置这种默认参数的用处是可以简化数据的发送,比如,倘若为RTP会话设置了默认参数:
sess.SetDefaultPayloadType(0);
sess.SetDefaultMark(false);
sess.SetDefaultTimeStampIncrement(10);
然后在进行数据发送时只需指明要发送的数据及其厚度就可以了:
sess.SendPacket(buffer,5);
e、对于流媒体数据的接收端,首先须要调用RTPSession类的PollData()方式来接收发送过来的RTP或则RTCP数据报。因为同一个RTP会话中容许有多个参与者(源),你既可以通过调用RTPSession类的GotoFirstSource()和GotoNextSource()方式来遍历所有的源,也可以通过调用RTPSession类的GotoFirstSourceWithData()和GotoNextSourceWithData()方式来遍历这些携带有数据的源。在从RTP会话中检测出有效的数据源以后,接下去就可以调用RTPSession类的GetNextPacket()方式从中抽取RTP数据报,当接收到的RTP数据报处理完以后,一定要记得及时释放。
JRTPLIB为RTP数据报定义了三种接收模式,其中每种接收模式都具体规定了什么抵达的RTP数据报将会被接受,而什么抵达的RTP数据报将会被拒绝。通过调用RTPSession类的SetReceiveMode()方式可以设置下述这种接收模式:
RECEIVEMODE_ALL缺省的接收模式,所有抵达的RTP数据报都将被接受;
RECEIVEMODE_IGNORESOME不仅个别特定的发送者之外,所有抵达的RTP数据报都将被接受,而被拒绝的发送者列表可以通过调用AddToIgnoreList()、DeleteFromIgnoreList()和ClearIgnoreList()方式来进行设置;
RECEIVEMODE_ACCEPTSOME不仅个别特定的发送者之外,所有抵达的RTP数据报都将被拒绝,而被接受的发送者列表可以通过调用AddToAcceptList()、DeleteFromAcceptList和ClearAcceptList()方式来进行设置。下边是采用第三种接收模式的程序示例。
if(sess.GotoFirstSourceWithData()){
do{
sess.AddToAcceptList(remoteIP,allports,portbase);
sess.SetReceiveMode(RECEIVEMODE_ACCEPTSOME);
RTPPacket*pack;
pack=sess.GetNextPacket();//处理接收到的数据
deletepack;}
while(sess.GotoNextSourceWithData());
(2)程序流程图
发送:获得接收端的IP地址和端标语创建RTP会话指定RTP数据接收端设置RTP会话默认参数发送流媒体数据
接收:获得用户指定的端标语创建RTP会话设置接收模式接受RTP数据检索RTP数据源获取RTP数据报删掉RTP数据报
三、环境搭建及编译方式
(1)Toolchain的安装
首先找到xscale-arm-toolchain.tgz文件,假定该文件包置于/tmp/下
#cd/
#tar-zxvf/tmp/xscale-arm-toolchain.tgz
再设置环境变量
#exportPATH=/usr/local/arm-linux/bin:$PATH
最后检测一下交叉编译工具是否安装成功
#arm-linux-g++--version
看是否显示arm-linux-g++的版本,如有则安装成功。
(2)JRTPLIB库的交叉编译及安装
首先从JRTPLIB的网站下载最新的源码包,此处使用的是jrtplib-2.8.tar,假定下载后的源码包置于/tmp下,执行下边的对其解压缩:
#cd/tmp
#tar-zxvfjrtplib-2.8.tar
之后要对jrtplib进行配置和编译
#cdjrtplib-2.8
#./configureCC=arm-linux-g++cross-compile=yes
更改Makefile文件
将链接ld和ar改为arm-linux-ld和arm-linux-ar
#make
最后再执行如下就可以完成JRTPLIB的安装:
#makeinstall
(3)程序编译
a、配置编译环境
可以用export来配置北京linux培训,也可以用编撰Makefile的方式。这儿采用Makefile。
编撰Makefile&:
INCL=-I/usr/local/include
CFLAGS=-pipe-O2-fno-strength-reduce
LFLAGS=/usr/local/lib/libjrtp.a-L/usr/X11R6/lib
LIBS=-LX11-LXext/usr/local/lib/libjrtp.a
CC=arm-linux-g++
main:main.o
$(CC)$(LFLAGS)$(INCL)-omainmain.o$(LIBS)
main.o:main.cpp
clean:
rm-fmain
rm-f*.o
.SUFFIXES:.cpp
.cpp.o:
$(CC)-c$(CFLAGS)$(INCL)-o$@$GetPayloadLength();
RawData=packet->GetPayload();
for(i=0;i
temp[i]=RawData[i];
printf("%c",temp[i]);
temp[i]='';
printf("timestamp:%dlengh=%ddata:%sn",timestamp1,lengh,&temp);
//删掉RTP数据报
deletepacket;
}while(sess.GotoNextSourceWithData());
}while(1);
return0;
本文原创地址://lrxjmw.cn/sscsxyrdmtsj.html编辑:刘遄,审核员:暂无