1.下载软件包 jthread-1.3.1.tar.bz2 和jrtplib-3.9.1.tar.bz2 。网址:http://research.edm.uhasselt.be/~jori/page/index.php?n=CS.Jrtplib
2. 下载cmake-2.8.0-win32-x86.exe ,编译生成VS2008的工程文件,使jrtplib-3.9.1.tar.bz2 能在VS2008的环境中运行。
RTP通信的流程:
1.建立时间戳单元,这是通过调用RTPSession类的
SetTimestampUnit()方法来实现的,该方法同样也只有一个参数,表示的是以秒为单元的时戳单元。例如,当使用RTP会话传输8000Hz
采样的音频数据时,由于时戳每秒钟将递增8000,所以时戳单元相应地应该被设置成1/8000:
sess.SetTimestampUnit(1.0/8000.0);
2.建立会话,设置目标地址
当RTP 会话成功建立起来之后,接下去就可以开始进行流媒体数据的实时传输了。首先需要设置好数据发送的目标地址,
RTP协议允许同一会话存在多个目标地址,这可以通过调用RTPSession类的AddDestination()、
DeleteDestination()和ClearDestinations()方法来完成。例如,下面的语句表示的是让RTP会话将数据发送到本地主
机的6000端口(注意:如果是需要发到另一个NAT设备后面终端,则需要通过NAT穿透,见后):
unsigned long addr = ntohl(inet_addr("127.0.0.1"));
sess.AddDestination(addr, 6000);
3.向目标地址发送数据
目标地址全部指定之后,接着就可以调用RTPSession类的SendPacket()方法,向所有的目标地址发送流媒体数据。SendPacket()是RTPSession类提供的一个重载函数,它具有下列多种形式:
int SendPacket(void *data,int len)
int SendPacket(void *data,int len,unsigned char pt,bool mark,unsigned long timestampinc)
int SendPacket(void *data,int len,unsigned short hdrextID,void *hdrextdata,int numhdrextwords)
int SendPacket(void *data,int len,unsigned char pt,bool mark,unsigned long timestampinc,
unsigned short hdrextID,void *hdrextdata,int numhdrextwords)
SendPacket()最典型的用法是类似于下面的语句,其中第一个参数是要被发送的数据,而第二个参数则指明将要发送数据的长度,再往后依次是RTP负载类型、标识和时戳增量。
sess.SendPacket(buffer, 5, 0, false, 10);
对于同一个RTP会话来讲,负载类型、标识和时戳增量通常来讲都是相同的,JRTPLIB允许将它们设置为会话的默认参数,这是通过调用
RTPSession类的SetDefaultPayloadType()、SetDefaultMark()和
SetDefaultTimeStampIncrement()方法来完成的。为RTP会话设置这些默认参数的好处是可以简化数据的发送,例如,如果为
RTP会话设置了默认参数:
sess.SetDefaultPayloadType(0);
sess.SetDefaultMark(false);
sess.SetDefaultTimeStampIncrement(10);
之后在进行数据发送时只需指明要发送的数据及其长度就可以了:
sess.SendPacket(buffer, 5);
4.数据接收
对于流媒体数据的接收端,首先需要调用RTPSession类的PollData()方法来接收发送过来的RTP或者
RTCP数据报。由于同一个RTP会话中允许有多个参与者(源),你既可以通过调用RTPSession类的GotoFirstSource()和
GotoNextSource()方法来遍历所有的源,也可以通过调用RTPSession类的GotoFirstSourceWithData()和
GotoNextSourceWithData()方法来遍历那些携带有数据的源。在从RTP会话中检测出有效的数据源之后,接下去就可以调用
RTPSession类的GetNextPacket()方法从中抽取RTP数据报,当接收到的RTP数据报处理完之后,一定要记得及时释放。下面的代码
示范了该如何对接收到的RTP数据报进行处理:
if (sess.GotoFirstSourceWithData()) {
do {
RTPPacket *pack;
pack = sess.GetNextPacket();
// 处理接收到的数据
delete pack;
} while (sess.GotoNextSourceWithData());
}
JRTPLIB为RTP数据报定义了三种接收模式,其中每种接收模式都具体规定了哪些到达的RTP数据报将会被接受,而哪些到达的RTP数据报将会被拒绝。通过调用RTPSession类的SetReceiveMode()方法可以设置下列这些接收模式:
RECEIVEMODE_ALL 缺省的接收模式,所有到达的RTP数据报都将被接受;
RECEIVEMODE_IGNORESOME
除了某些特定的发送者之外,所有到达的RTP数据报都将被接受,而被拒绝的发送者列表可以通过调用AddToIgnoreList()、
DeleteFromIgnoreList()和ClearIgnoreList()方法来进行设置;
RECEIVEMODE_ACCEPTSOME
除了某些特定的发送者之外,所有到达的RTP数据报都将被拒绝,而被接受的发送者列表可以通过调用AddToAcceptList
()、DeleteFromAcceptList和ClearAcceptList ()方法来进行设置。
注:控制信息已高度封装,或者也可由自己设定。
JRTPLIB
是一个高度封装后的RTP库,程序员在使用它时很多时候并不用关心RTCP数据报是如何被发送和接收的,因为这些都可以由JRTPLIB自己来完成。只要
PollData()或者SendPacket()方法被成功调用,JRTPLIB就能够自动对到达的
RTCP数据报进行处理,并且还会在需要的时候发送RTCP数据报,从而能够确保整个RTP会话过程的正确性。
而另一方面,通过调用RTPSession类提供的SetLocalName()、SetLocalEMail()、
SetLocalLocation()、SetLocalPhone()、SetLocalTool()和SetLocalNote()方法,
JRTPLIB又允许程序员对RTP会话的控制信息进行设置。所有这些方法在调用时都带有两个参数,其中第一个参数是一个char型的指针,指向将要被设
置的数据;而第二个参数则是一个int型的数值,表明该数据中的前面多少个字符将会被使用。例如下面的语句可以被用来设置控制信息中的电子邮件地址:
sess.SetLocalEMail("
[email=xiaowp@linuxgam.comxiaowp@linuxgam.com]xiaowp@linuxgam.comxiaowp@linuxgam.com[/email]
",19);
在RTP 会话过程中,不是所有的控制信息都需要被发送,通过调用RTPSession类提供的
EnableSendName()、EnableSendEMail()、EnableSendLocation()、EnableSendPhone
()、EnableSendTool()和EnableSendNote()方法,可以为当前RTP会话选择将被发送的控制信息。