RTP TRCP API

1 主要介绍

简介
RTP是实时传输协议的缩写,用来定义在因特网上传输音频和视频的标准包格式,在RFC 1889中予以定义。它由音频和视频传输工作组制订,并于1996年颁布。
RTP和RTCP连接紧密,RTP实施实际数据的传输,RTCP则就服务质量做出反馈。

RTP定义
实时传输协议(RTP)为数据提供了具有实时特征的端对端传送服务,如在组播或单播网络服务下的交互式视频音频或模拟数据。应用程序通常在UDP上运行 RTP 以便使用其多路结点和校验服务;这两种协议都提供了传输层协议的功能。但是 RTP 可以与其它适合的底层网络或传输协议一起使用。如果底层网络提供组播方式,那么 RTP 可以使用该组播表传输数据到多个目的地。
RTP 本身并没有提供按时发送机制或其它服务质量(QoS)保证,它依赖于低层服务去实现这一过程。 RTP 并不保证传送或防止无序传送,也不确定底层网络的可靠性。 RTP 实行有序传送, RTP 中的序列号允许接收方重组发送方的包序列,同时序列号也能用于决定适当的包位置,例如:在视频解码中,就不需要顺序解码。

RTP组成
RTP 由两个紧密链接部分组成:
RTP ― 传送具有实时属性的数据; RTP 控制协议(RTCP) ― 监控服务质量并传送正在进行的会话参与者的相关信息。RTCP 第二方面的功能对于“松散受控”会话是足够的,也就是说,在没有明确的成员控制和组织的情况下,它并不非得用来支持一个应用程序的所有控制通信请求。

定义在RFC
使用RTP协议的应用程序运行在RTP之上,而执行RTP的程序运行在UDP的上层,目的是为了使用UDP的端口号和检查和。如图1所示,RTP可以看成是传输层的子层。由多媒体应用程序生成的声音和电视数据块被封装在RTP信息包中,每个RTP信息包被封装在UDP消息段中,然后再封装在IP数据包中。
信息包的结构包含广泛用于多媒体的若干个域,包括声音点播(audio-on-demand)、影视点播(video on demand)、因特网电话(Internet telephony)和电视会议(videoconferencing)。RTP的规格没有对声音和电视的压缩格式制定标准,它可以被用来传输普通格式的文件。例如,WAV或者GSM(Global System for Mobile communications)格式的声音、MPEG-1和MPEG-2的电视,也可以用来传输专有格式存储的声音和电视文件。
从应用开发人员的角度来看,可把RTP执行程序看成是应用程序的一部分,因为开发人员必需把RTP集成到应用程序中。在发送端,开发人员必需把执行RTP协议的程序写入到创建RTP信息包的应用程序中,然后应用程序把RTP信息包发送到UDP的套接接口(socket interface),如图2所示;同样,在接收端,RTP信息包通过UDP套接接口输入到应用程序,因此开发人员必需把执行RTP协议的程序写入到从RTP信息包中抽出媒体数据的应用程序。
现以用RTP传输声音为例来说明它的工作过程。假设音源的声音是64 kb/s的PCM编码声音,并假设应用程序取20毫秒的编码数据为一个数据块(chunk),即在一个数据块中有160个字节的声音数据。应用程序需要为这块声音数据添加RTP标题生成RTP信息包,这个标题包括声音数据的类型、顺序号和时间戳。然后RTP信息包被送到UDP套接接口,在那里再被封装在UDP信息包中。在接收端,应用程序从套接接口处接收RTP信息包,并从RTP信息包中抽出声音数据块,然后使用RTP信息包的标题域中的信息正确地译码和播放声音。
如果应用程序不使用专有的方案来提供有效载荷类型(payload type)、顺序号或者时间戳,而是使用标准的RTP协议,应用程序就更容易与其他的网络应用程序配合运行,这是大家都希望的事情。例如,如果有两个不同的公司都在开发因特网电话软件,他们都把RTP合并到他们的产品中,这样就有希望:使用不同公司电话软件的用户之间能够进行通信。
这里需要强调的是,RTP本身不提供任何机制来确保把数据及时递送到接收端或者确保其他的服务质量,它也不担保在递送过程中不丢失信息包或者防止信息包的次序不被打乱。的确,RTP的封装只是在系统端才能看到,中间的路由器并不区分那个IP数据报是运载RTP信息包的。
RTP允许给每个媒体源分配一个单独的RTP信息包流,例如,摄像机或者麦克风。例如,有两个团体参与的电视会议,这就可能打开4个信息包流:两台摄像机传送电视流和两个麦克风传送声音流。然而,许多流行的编码技术,包括MPEG-1和MPEG-2在编码过程中都把声音和电视图像捆绑在一起以形成单一的数据流,一个方向就生成一个RTP信息包流。
RTP信息包没有被限制只可应用于单目标广播,它们也可以在一对多(one-to-many)的多目标广播树或者在多对多(many-to-many)的多目标广播树上传送。例如,多对多的多目标广播,在这种应用场合下,所有发送端通常都把他们的RTP信息包流发送到具有相同多目标广播地址的多目标广播树上。

RTP信息包标题域
RTP标题由4个信息包标题域和其他域组成:有效载荷类型(payload type)域,顺序号(sequence number)域,时间戳(timestamp)域和同步源标识符(Synchronization Source Identifier)域等[1]。
1)有效载荷类型,RTP信息包中的有效载荷域(Payload Type Field)的长度为7位,因此RTP可支持128种不同的有效载荷类型。对于声音流,这个域用来指示声音使用的编码类型,例如PCM、自适应增量调制或线性预测编码等等。如果发送端在会话或者广播的中途决定改变编码方法,发送端可通过这个域来通知接收端。表1列出了目前RTP所能支持的声音有效载荷类型。对电视流,有效载荷类型可以用来指示电视编码的类型,例如motion JPEG, MPEG-1,MPEG-2或者H.231等等。发送端也可以在会话或者期间随时改变电视的编码方法。表16-02列出了目前RTP所能支持的某些电视有效载荷类型。
2)顺序号,顺序号(Sequence Number Field)域的长度为16位。每发送一个RTP信息包顺序号就加1,接收端可以用它来检查信息包是否有丢失以及按顺序号处理信息包。例如,接收端的应用程序接收到一个RTP信息包流,这个RTP信息包在顺序号86和89之间有一个间隔,接收端就知道信息包87和88已经丢失,并且采取措施来处理丢失的数据。
3)时间戳,时间戳(Timestamp)域的长度为32字节。它反映RTP数据信息包中第一个字节的采样时刻(时间)。接收端可以利用这个时间戳来去除由网络引起的信息包的抖动,并且在接收端为播放提供同步功能。
4)s同步源标识符,同步源标识符(Synchronization Source Identifier,SSRC)域的长度为32位。它用来标识RTP信息包流的起源,在RTP会话或者期间的每个信息包流都有一个清楚的SSRC。SSRC不是发送端的IP地址,而是在新的信息包流开始时源端随机分配的一个号码。


2 协议格式


RTP报文由两部分组成:报头和有效载荷。其中:
V:RTP协议的版本号,占2位,当前协议版本号为2。
P:填充标志,占1位,如果P=1,则在该报文的尾部填充一个或多个额外的八位组,它们不是有效载荷的一部分。
X:扩展标志,占1位,如果X=1,则在RTP报头后跟有一个扩展报头。
CC:CSRC计数器,占4位,指示CSRC 标识符的个数。
M: 标记,占1位,不同的有效载荷有不同的含义,对于视频,标记一帧的结束;对于音频,标记会话的开始。
同步信源(SSRC)标识符:占32位,用于标识同步信源。该标识符是随机选择的,参加同一视频会议的两个同步信源不能有相同的SSRC。
特约信源(CSRC)标识符:每个CSRC标识符占32位,可以有0~15个。每个CSRC标识了包含在该RTP报文有效载荷中的所有特约信源。
PT: 有效载荷类型,占7位,用于说明RTP报文中有效载荷的类型,如GSM音频、JPEM图像等。
序列号:占16位,用于标识发送者所发送的RTP报文的序列号,每发送一个报文,序列号增1。接收者通过序列号来检测报文丢失情况,重新排序报文,恢复数据。

时戳(Timestamp):占32位,时戳反映了该RTP报文的第一个八位组的采样时刻。接收者使用时戳来计算延迟和延迟抖动,并进行同步控制。


3 JRTPLIB 主要类结构和API
3.1 类的主要结构
3.2 全部的API描述

3.2.1 库版本,头文件:rtplibraryversion.h
RTPLibraryVersion类有一个静态成员创建了该类的一个对象。


static RTPLibraryVersion GetVersion()
使用者可以通过下面的函数获取版本信息。

int GetMajorNumber() const
-----返回主版本号。

int GetMinorNumber() const
-----返回副版本号。

int GetDebugNumber() const
-----返回调试版本号。

std::string GetVersionString() const
-----返回版本描述字符串。


3.2.2 错误码,头文件:rtperrors.h
除非特别指出,否则返回int的函数如果返回值为负则表明出现了一个错误,为0或者正则标志成功。一个关于错误码的描述可以通过使用下面的函数获取:

std::string RTPGetErrorString(int errcode)


3.2.3 实用时间工具,头文件:rtptimeutilities.h
RTPNTPTime

这是NTP时间戳的MSW(最高有效字)和LSW(最低有效字)的一个简单的包装,该类有下列成员:

RTPNTPTime(uint32_t m, uint32_t l);
-----该构造函数创建一个MSW为m,LSW为l的类对象。

uint32_t GetMSW() const
-----返回最高有效字。

uint32_t GetLSW() const
-----返回最低有效字。

RTPTime
该类用于描述时钟时间,延迟间隔等。其中保存一个以秒s数据和一个毫秒ms数据,接口如下:

RTPTime(uint32_t seconds, uint32_t microseconds)
-----创建一个对应s和ms分别为seconds和microseconds的对象。

RTPTime(double t)
-----创建一个代表以秒为单位的时间t的RTPTime实例。

RTPTime(RTPNTPTime ntptime)
-----创建一个对应时间为ntptime的对象,如果无法完成转换那么,对象的秒和毫秒都将设为0。

uint32_t GetSeconds() const
-----返回对象中保存的秒数值。

uint32_t GetMicroSeconds() const
----返回对象中保存的毫秒数值。

Double GetDouble() const
-----返回对象中存储的以秒为单位的时间。


RTPNTPTime GetNTPTime() const
-----返回对象中保存时间的对应NTP时间。

Static RTPTime CurrentTime()
-----返回代表当前时钟时间的RTPTime对象,该值是自从1970年1月1日00:00:00 UTC 以来的秒数。

Static void Wait(const RTPTime &delay)
-----该函数等待一段由delay指定的时间。

RTPTime类还定义了以下操作符:
operator-=
operator+=
operator<
operator>
operator<=
operator>=


3.2.4 RTPRandom,头文件:rtprandom.h
RTPRandom类可用来产生随机数,成员函数如下:

uint8_t GetRandom8()
-----返回随机8比特值。

uint16_t GetRandom16()
-----返回随机16比特值。

uint32_t GetRandom32()
-----返回随机32比特值。

double GetRandomDouble()
-----返回0.0到1.0之间的随机数。

3.2.5 RTPSDESInfo,头文件:rtcpsdesinfo.h
类RTPSDESInfo是RTCP中SDES信息的一个容器,接口如下:

void Clear()
-----清除所有的SDES信息。

int SetCNAME(const uint8_t *s, size_t l)
-----设置SDES的CNAME项为指向s的长度为l一块内存的值。

int SetName(const uint8_t *s, size_t l)
-----设置SDES的name项为指向s的长度为l一块内存的值。

int SetEMail(const uint8_t *s, size_t l)
-----设置SDES的e-mail项为指向s的长度为l一块内存的值。

int SetPhone(const uint8_t *s, size_t l)
-----设置SDES的phone项为指向s的长度为l一块内存的值。

int SetLocation(const uint8_t *s, size_t l)
-----设置SDES的location项为指向s的长度为l一块内存的值。

int SetTool(const uint8_t *s, size_t l)
-----设置SDES的tool项为指向s的长度为l一块内存的值。

int SetNote(const uint8_t *s, size_t l)
-----设置SDES的note项为指向s的长度为l一块内存的值。

uint8_t *GetCNAME(size_t *len) const
-----返回SDES的CNAME项的,并把长度存放到len中。

uint8_t *GetName(size_t *len) const
-----返回SDES的name项的,并把长度存放到len中。

uint8_t *GetEMail(size_t *len) const
-----返回SDES的e-mail项的,并把长度存放到len中。

uint8_t *GetPhone(size_t *len) const
-----返回SDES的phone项的,并把长度存放到len中。

uint8_t *GetLocation(size_t *len) const
-----返回SDES的location项的,并把长度存放到len中。

uint8_t *GetTool(size_t *len) const
-----返回SDES的tool项的,并把长度存放到len中。

uint8_t *GetNote(size_t *len) const
-----返回SDES的Note项的,并把长度存放到len中。

int SetPrivateValue(const uint8_t *prefix, size_t prefixlen, const uint8_t *value, size_t valuelen)
-----设置前缀串的输入为长度为prefixlen的prefix指向的内容,用于包含长度为valuelen的由value指向的值串,如果达到了前缀串的最大允许长度,则将返回错误码ERR_RTP_SDES_MAXPRIVITEMS。

int DeletePrivatePrefix(const uint8_t *s, size_t len)
-----删除由s指向的长度为len的前缀串的输入。

void GotoFirstPrivateValue()
-----开始遍历SDES中存储的前缀条目和它们相关联的数据。

bool GetNextPrivateValue(uint8_t **prefix, size_t *prefixlen, uint8_t **value, size_t *valuelen)
-----如果可用将返回true,并且将下一个SDES私有前缀条目存入prefix,将长度存入prefixlen,将相关数据和长度存入value和valuelen。若不可用则返回false。

bool GetPrivateValue(const uint8_t *prefix, size_t prefixlen, uint8_t **value, size_t *valuelen) const
-----查找SDES中私有条目为prefix长度为prefixlen的输入,如果找到返回true,并且将相关联的值和长度分别存入value和valuelen中。


3.2.6 RTPTransmitter,头文件:rtptransmitter.h
抽象类RTPTransmitter指出了实际用于传输的组件的接口。当前实现了三种,分别是:基于IPv4的UDP发送器;基于IPv6的UDP发送器【译注:另一种??】。

TransmissionProtocol类型用于指出是哪种发送器:
enum TransmissionProtocol{IPv4UDPProto, IPv6UDPProto, UserDefinedProto };

当使用RTPSession类时,使用UserDefinedProto可用来选择你自己的传输组件,这是你需要自己实现NewUserDefinedTransmitter()函数,这个函数应该返回一个你自己的RTPTransmitter的继承类的指针。

可以使用ReceiveMode类型来指定3种接收模式:
Enum ReceiveMode{ AcceptAll, AcceptSome, IgnoreSome};
根据模式的设置,到达的数据将会进行不同的处理:
AcceptAll,-----不论从哪里发送的,所有数据都将接收。
AcceptSome,-----只有指定源发送的数据才会被接收。
IgnoreSome,-----除了指定源的不接收,其他的全部接收。

由RTPTransmission类定义的接口如下

int Init(bool threadsafe)
-----必须在使用transmission组件之调用该函数,组件是否是线程安全的将由参数threadsafe指定。

int Create(size_t maxpacketsize, const RTPTransmissionParams *transparams)
-----为组件的使用做准备,参数maxpacketsize指出了一个包的最大值,如果包大小大于该值,则将不会发送。参数transparams是一个指向RTPTranmissionParams对象的指针。RTPTranmissionParams也是个抽象类,实际使用时根据不同组件,通过继承RTPTranmissionParams类来定义自身的参数。如果参数为null,那么将使用该组件传输参数的默认值。

int Destroy()
-----调用该函数之后,将清理存储区,并且该组件也不能再使用。只有当重新调用Create函数之后该组件才可以继续使用。

RTPTransmissionInfo *GetTransmissonInfo()
-----函数将返回一个指向RTPTransmissionInfo对象的指针,从该对象中可以获得关于传输器的更多信息(例如:本地IP地址的列表)。当前(版本中)根据使用的传输器的种类既可以返回RTPUDPv4TransmissionInfo也可以返回RTPUDPv6TransmissionInfo。当对象不再使用时,使用者需要(手动)删除该对象。

int GetLocalHostName(uint8_t *buffer, size_t *bufferlength)
-----基于本地主机地址的内部信息查询主机名,该函数可能会花费比较长的时间用于DNS查询。bufferlength应该被初始化为buffer中可能会存储的字节个数,如果函数函数成功,则bufferlength中就是buffer中存储的字节数。需要注意的是在buffer中存储的并非是以NULL结尾的数据。如果分配的存储空间不够的话,函数将失败并且返回ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL,并将需要的字节数存入bufferlength中。

bool ComesFromThisTransmitter(const RTPAddress *addr)
-----如果由addr指出的地址是传输器的一个地址则返回true。

size_t GetHeaderOverhead()
-----返回将要由网络的底层(不包括链路层)加入到RTP包中的字节数。

int Poll()
-----检查到达的数据并保存。

bool NewDataAvailable()
-----当可以使用函数GetNextPacket获取数据包时返回true。

RTPRawPacket *GetNextPacket()
-----(在Poll函数中)返回在RTPRawPacket对象中收到的RTP数据包的原始数据。

int WaitForIncomingData(const RTPTime &dalay, bool *dataavailable =0)
-----等待最多由delay指出的时间直到接收到数据。如果dataavailable不是NULL,那么如要要读取数据的话应该设为true,否则设为false

int AbortWait()
-----如果上一个函数被调用了,本函数将中止等待。

int SendRTPData(const void *data, size_t len)
-----向所有当前目的地址列表中的RTP地址发送长度为len的data数据。

int SendRTCPData(const void *data, size_t len)
-----向所有当前目的地址列表中的RTCP地址发送长度为len的data数据。

void ResetPacketCount()
-----传输器会跟踪所有发送的RTP和RTCP数据包的个数,该函数复位这些计数。

uint32_t GetNumRTPPacketsSent()
-----返回已发送的RTP包的个数。

uint32_t GetNumRTCPPacketsSent()
-----返回已发送的RTCP包的个数。

int AddDestination(const RTPAddress &addr)
-----将参数addr指定的地址加入到目的地址列表中。

int DeleteDestination(const RTPAddress &addr)
-----将参数addr指定的地址从目的地址列表中删除。

void ClearDestination()
-----清空目的地址列表。

bool SupportMulticasting()
-----如果传输组件支持组播则返回true。

int JoinMulticastGroup(const RTPAddress &addr)
-----加入由参数addr指定的组播组。

int LeaveMulticastGroup(const RTPAddress &addr)
-----退出由参数addr指定的组播组。

void LeaveAllMulticastGroups()
-----退出所有的加入的组播组

int SetReceiveMode(RTPTransmitter::ReceiveMode m)
-----将接收模式设置为m,m的取值可以是下列之一:RTPTransmitter::AcceptAll, RTPTransmitter::AcceptSome, RTPTransmitter::IgnoreSome。注意!如果模式改变了,则所有关于接收或者忽略地址的信息将全部丢失。

int AddToIgnoreList(const RTPAddress &addr)
-----将地址addr加入到忽略地址列表中。

int DeleteFromIgnoreList(const RTPAddress &addr)
-----将地址addr从忽略地址列表中删除。

void ClearIgnoreList()
-----清除忽略地址列表。

int AddToAcceptList(const RTPAddress &addr)
-----将地址addr加入到接收地址列表中。

int DeleteFromAcceptList(const RTPAddress &addr)
-----将地址addr从接收地址列表中删除。

void ClearAcceptList()
-----清除接收地址列表。

int SetMaximumPacketSize(sizt_t s)
-----将传输器允许的最大数据包大小设置为s。

基于IPv4的UDP传输器,头文件:rtpudpv4transmitter.h,继承自:RTPTransmitter类
类RTPUDPv4Transmitter继承了类RTPTransmitter的接口,成为一个传输组件,使用基于IPv4的UDP协议来传输RTP和RTCP数据。
该组件的参数由类RTPUDPv4TransmissionParams来描述,关于该参数类的详细参见3.2.7节。形参为RTPAddress的函数需要传递一个类型为RTPIPv4Address的参数,关于RTPIPv4Address由3.2.9节详细描述。RTPUDPv4Transmitter类的成员函数GetTransmissionInfo返回一个RTPUDPv4TransmissionInfo对象,该类详细参见3.2.8节。

基于IPv6的UDP传输器,头文件:rtpudpv6transmitter.h,继承自:RTPTransmitter类
类RTPUDPv6Transmitter继承了类RTPTransmitter的接口,成为一个传输组件,使用基于IPv6的UDP协议来传输RTP和RTCP数据。
该组件的参数由类RTPUDPv6TransmissionParams来描述,关于该参数类的详细参见3.2.7节。形参为RTPAddress的函数需要传递一个类型为RTPIPv6Address的参数,关于RTPIPv6Address由3.2.9节详细描述。RTPUDPv6Transmitter类的成员函数GetTransmissionInfo返回一个RTPUDPv6TransmissionInfo对象,该类详细参见3.2.8节。


3.2.7 RTPTransmissionParams类,头文件:rtptransmitter.h
RTPTransmissionParams类是一个抽象基类,特定的传输组件需要特定的继承实现。所有的实现都继承下面的函数,用来确定对这些参数来说哪个传输组件是有效的
RTPTransmitter::TransmissionProtocol GetTransmissionProtocol()

基于IPv4的UDP传输器的参数,头文件:rtpudpv4transmitter.h,继承自:RTPTransmissionParams
RTPUDPv4TransmissionParams
类代表基于IPv4的UDP传输组件使用的参数。默认的TTL设置为1,端口号设为5000,类的接口如下:

void SetBindIP(uint32_t ip)
-----将与套接字绑定的IP设置为ip。

void SetPortbase(uint16_t  pbase)
-----将RTP的端口号设为pbase,该数值必须是偶数!

void SetMulticastTTL(uint8_t mcastTTL)
-----设置组播的TTL为mcastTTL。

void SetLocalIPList(std::list<uint32_t> &iplist)
-----传递一组将要作为本地IP地址的IP地址列表。

void ClearLocalIPList()
-----清除本地IP地址列表,一个空的表将使得传输组件自己决定使用的本地IP地址。

uint32_t GetBindIP() const
-----返回套接字将绑定的IP地址。

uint16_t GetPortbase() const
-----返回RTP将要使用的端口号。

uint8_t GetMulticastTTL() const
-----返回要使用的组播TTL。

const std::list<uint32_t> &GetLocalIPList() const
-----返回本地IP地址列表。

基于IPv6的UDP传输器的参数,头文件:rtpudpv6transmitter.h,继承自:RTPTransmissionParams
RTPUDPv6TransmissionParams类代表基于IP64的UDP传输组件使用的参数。默认的TTL设置为1,端口号设为5000,类的接口如下:

void SetBindIP(in6_addr ip)
-----将与套接字绑定的IP设置为ip。

void SetPortbase(uint16_t  pbase)
-----将RTP的端口号设为pbase,该数值必须是偶数!

void SetMulticastTTL(uint8_t mcastTTL)
-----设置组播的TTL为mcastTTL。

void SetLocalIPList(std::list<in6_addr> &iplist)
-----传递一组将要作为本地IP地址的IP地址列表。

void ClearLocalIPList()
-----清除本地IP地址列表,一个空的表将使得传输组件自己决定使用的本地IP地址。

in6_addr GetBindIP() const
-----返回套接字将绑定的IP地址。

uint16_t GetPortbase() const
-----返回RTP将要使用的端口号。

uint8_t GetMulticastTTL() const
-----返回要使用的组播TTL。

const std::list<in6_addr> &GetLocalIPList() const
-----返回本地IP地址列表。


3.2.8 RTPTransmissionInfo,头文件:rtptransmitter.h
类RTPTransmissionInfo
是一个抽象基类,根据特定的传输组件有特定的(继承)实现。所有的具体实现都继承下面的函数,用来确定对这些参数来说哪个传输组件是有效的(【译注:就是说该函数是用来指出实际使用的传输组件类型的,原文:All actual implementations inherit the following function which identify the component type for which these parameters are valid】):
RTPTransmitter::TransmissionProtocol GetTransmissionProtocol()

关于基于IPv4的UDP传输器的信息,头文件:rtpudpv4transmitter.h
类RTPUDPv4TransmissionInfo给出了关于基于IPv4的UDP传输组件的更多信息,可用的成员函数如下:

std::list<uint32_t> GetLocalIPList() const
-----返回传输器可选择作为本机IP地址的IPv4地址列表。

int GetRTPSocket() const
-----返回用于收发RTP数据包的套接字描述子。

int GetRTCPSocket() const
-----返回用于收发RTCP数据包的套接字描述子。

关于基于IPv6的UDP传输器的信息,头文件:rtpudpv6transmitter.h
类RTPUDPv6TransmissionInfo给出了关于基于IPv6的UDP传输组件的更多信息,可用的成员函数如下:

std::list<in6_addr> GetLocalIPList() const
-----返回传输器可选择作为本机IP地址的IPv6地址列表。

int GetRTPSocket() const
-----返回用于收发RTP数据包的套接字描述子。

int GetRTCPSocket() const
-----返回用于收发RTCP数据包的套接字描述子。


 
3.2.9 RTPAddress,头文件:rtpaddress.h
类RTPAddress
是一个用来指出单播目的地址或者组播组的抽象基类。该类定义了下面的参数用来确定具体实现所使用的(地址类型)。
enum AddressType {IPv4Address, IPv6Address, UserDefinedAddress};
基于IPv4的UDP传输器使用类型RTPAddress::IPv4Address,基于IPv6的UDP传输器使用类型RTPAddress::IPv6Address。当使用用户自定义类型的传输组件时RTPAddress:: UserDefinedAddress会很有用。
类定义了以下接口:

AddressType GetAddressType() const
-----返回具体实现所代表的地址类型。

RTPAddress *CreateCopy() const
-----创建一个RTPAddress对象的拷贝。

bool IsSameAddress(const RTPAddress *addr) const
-----检查对象使用的地址是否与地址addr相同,具体实现需要能够处理参数为NULL的情况。

bool IsFromSamHost(const RTPAddress *addr) const
-----检查地址addr所代表的主机是否与对象是同一个,具体实现需要能够处理参数为NULL的情况。

RTPIPv4Address,头文件:rtpipv4address.h
该类在基于IPv4的UDP传输组件中使用,类定义了下面的函数:

RTPIPv4Address(uint32_t ip=0, uint16_t port=0)
-----创建一个IP地址为ip,端口号为port的对象,两个参数都是主机字节序表示。

RTPIPv4Address(const uint8_t ip[4], uint16_t port=0)
-----创建一个IP地址为ip,端口号为port的对象,两个参数都是主机字节序表示。

void SetIP(uint32_t ip)
-----将对象的IP地址设为ip,ip是用主机字节序表示。

void SetPort(uint16_t port)
-----将对象的端口号设为port,port是用主机字节序表示。

uint32_t GetIP() const
-----返回以主机字节序表示的对象IP地址。

Uint16_t GetPort() const
-----返回以主机字节序表示的对象端口号。
当RTPIPv4Address地址用于传输器的组播函数的任意一个时,端口号将被忽略。当该类的对象用于传输器的接受或者拒绝函数中的一个时,0号端口将代表指定IP地址的所有端口。

RTPIPv6Address,头文件:rtpipv6address.h
该类在基于IPv6的UDP传输组件中使用,类定义了下面的函数:

RTPIPv6Address()
-----创建一个IP地址和端口号都为0的对象。

RTPIPv6Address(const uint8_t ip[16], uint16_t port=0)
-----创建一个IP地址为ip,端口号为port的对象,两个参数都是主机字节序表示。

RTPIPv6Address(in6_addr ip, uint16_t port=0)
-----创建一个IP地址为ip,端口号为port的对象,两个参数都是主机字节序表示。

void SetIP(in6_addr ip)
-----将对象的IP地址设为ip。

void SetIP(const uint8_t ip[16])
-----将对象的IP地址设为ip。  

void SetPort(uint16_t port)
-----将对象的端口号设为port,port是用主机字节序表示。

void GetIP(uint8_t ip[16]) const
-----拷贝对象IP地址到ip。

in6_addr GetIP() const
-----返回对象IP地址。

Uint16_t GetPort() const
-----返回以主机字节序表示的对象端口号。
当RTPIPv6Address地址用于传输器的组播函数的任意一个时,端口号将被忽略。当该类的对象用于传输器的接受或者拒绝函数中的一个时,0号端口将代表指定IP地址的所有端口。

3.2.10 RTPRawPacket,头文件:rtprawpacket.h
类RTPRawPacket
被传输组件用来保存收到的RTP和RTCP数据。接口如下:

RTPRawPacket(uint8_t *data, size_t datalen, RTPAddress *address, RTPTime &recvtime, bool rtp)
-----创建一个对象用来保存长度为datalen的data中的数据,注意:只保存指向数据的指针而不会复制数据!数据包的发送地址和收到的时间将分别保存到address和recvtime中。rtp标志用来区分收到的数据是RTP数据还是RTCP数据。

uint8_t *GetData()
-----返回指向数据包中数据的地址。

size_t GetDataLength() const
-----返回该对象所代表的数据包的长度。

RTPTime GetReceiveTime() const
-----返回收到数据包的时间。

const RTPAddress *GetSenderAddress() const
-----返回数据包中保存的(发送方)地址。

bool IsRTP() const
-----如果数据是RTP数据返回true,否则返回false代表是RTCP数据。

void ZeroData()
-----将指向数据包中保存的数据的指针设为0,这将阻止在调用类的析构函数时对实际数据进行的delete调用。该函数在类RTPPacket和RTCPCompoundPacket用来获取数据包数据而又不需要复制数据时使用,用来确保当RTPRawPacket的析构函数调用时不会删除数据。

 
3.2.11 RTPPacket,头文件:rtppacket.h
类RTPPacket用来在RTPRawPacket对象表示一个RTP数据时解析(数据包)。该类也可以用来根据用户指定的参数生成一个RTP数据包,接口如下:

RTPPacket(RTPRawPacket &rawpacket)
-----基于rawpacket中的数据生成一个RTPPacket对象。

RTPPacket(uint8_t payloadtype, const void *payloaddata, size_t payloadlen, uint16_t seqnr, uint32_t timestamp, uint32_t ssrc, bool gotmaker, uint8_t numcsrcs, const uint32_t *csrcs, bool gotextension, uint16_t extionid, uint16_t extensionlen_numwords, const void *extensiondata, size_t maxpacksizt=0)
-----为RTP数据包生成一个新的缓冲区,并根据给定的参数填充各个域。如果maxpacksize不等于0,则当总的数据包大小超过maxpacksize时将产生一个错误。该构造函数的参数都是自解释的,需要注意的是扩展头的大小由一个32位的字指定。

RTPPacket(uint8_t payloadtype, const void *payloaddata, size_t payloadlen, uint16_t seqnr, uint32_t timestamp, uint32_t ssrc, bool gotmaker, uint8_t numcsrcs, const uint32_t *csrcs, bool gotextension, uint16_t extionid, uint16_t extensionlen_numwords, const void *extensiondata, void *buffer, size_t buffersize)
-----与上一个函数基本一样的函数,不同点在于数据是存储在一个由buffer指定的大小为buffersize的缓冲区中。

int GetCreationError() const
-----如果构造函数发生错误,该函数返回错误码。

bool HasExtension() const
-----如果RTP数据包有扩展头则返回true,否则返回false。

bool HasMarker() const
-----如果marker标志位被置位,返回true,否则返回false。

int GetCSRCCount() const
-----返回数据包中的CSRC数。

uint32_t GetCSRC(int num) const
-----返回指定的CSRC标识符,参数num可以从0到GetCSRCCount()-1。

uint8_t GetPayloadType() const
-----返回数据包的负载类型。

uint32_t GetExtendedSequenceNumber() const
-----返回数据包的扩展序列号。当数据包刚刚收到时,只有底16位被设置,高16位随后填充。

uint16_t GetSequenceNumber() const
-----返回数据包的序列号。

void SetExtendedSequenceNumber(uint32_t seq)
-----将数据包的扩展序列号设置为seq。

void GetTimestamp() const
-----返回数据包的时间戳。

uint32_t GetSSRC() const
-----返回数据包中的SSRC标识符。

uint8_t *GetPacketData() const
-----返回指向整个数据包的指针。

uint8_t *GetPayloadData() const
-----返回指向实际负载数据的指针。

size_t GetPacketLength() const
-----返回整个数据包的大小。

size_t GetPayloadLength() const
-----返回整个负载数据的大小。

uint16_t GetExtensionID() const
-----如果有扩展头,则该函数将返回扩展标识符。

uint8_t *GetExtensionData() const
-----返回指向扩展头数据的指针。

size_t GetExtensionLength() const
-----返回扩展头数据的大小。

RTPTime GetReceiveTime() const
-----当一个RTPPacket对象从RTPRawPacket对象中创建时,原始数据的接收时间将保存到RTPPacket对象中,该函数用来获取这个时间。


 
3.2.12 RTPCompoundPacket,头文件:rtpcompoundpacket.h
该类描述RTCP复合数据包,接口如下:

RTCPCompoundPacket(RTPRawPacket &rawpack)
-----根据rawpack的数据生成一个RTCPCompoundPacket对象。

int GetCreationError()
-----如果在构造函数中的原始数据包无法解析,则该函数将返回出错原因的错误码。如果包的格式不合法则将返回ERR_RTP_RCTPCOMPOUND_INVALIDPACKET。

uint8_t *GetCompoundPacketData()
-----返回指向整个RTCP复合数据包数据的指针。

size_t GetCompoundPacketLength()
-----返回整个RTCP复合数据包的长度。

void GotoFirstPacket()
-----开始遍历整个RTCP复合数据包中的单个RTCP数据包。

RTCPPacket *GetNextPacket()
-----返回指向下一个独立RTCP数据包的指针。注意:返回的RTCPPacket对象可能不调用delete。RTCPPacket类的介绍如下:

RTCPPacket,头文件:rtppacket.h
类RTCPPacket是具体类型的RTCP数据包的基类。在类中定义的下面的类型指出了不同的具体数据包类型:
enum PacketType{ SR, RR, SDES, BYE, APP, Unknown };
类定义的成员函数有:

bool IsKnownFormat() const
-----如果子类可以解析数据则返回true,否则返回false。

PacketType GetPacketType() const
-----返回子类实现的具体的包类型:
--RTCPPacket::SR:表明是一个RTCPSRPacket对象。
--RTCPPacket::RR:表明是一个RTCPRRPacket对象。
--RTCPPacket::SDES:表明是一个RTCPSDESPacket对象。
--RTCPPacket::BYE:表明是一个RTCPBYEPacket对象。
--RTCPPacket::APP:表明是一个RTCPAPPPacket对象。
--RTCPPacket::Unkown:表明是一个RTCPUnknownPacket对象。

uint8_t *GetPacketData()
-----返回指向RTCP数据包中的数据的指针。

size_t GetPacketLength() const
-----返回RTCP数据包的长度。

RTCPSRPacket,头文件:rtcpsrpacket.h,继承自:RTCPPacket
类描述了一个RTCP发送方报告数据包,接口如下:

RTCPSRPacket(uint8_t *data, size_t datalen)
-----基于长度为datalen的数据data创建一个RTCPSRPacket数据包对象。因为data指向的数据在类内部被引用(即不复制数据),所以必须确保在该对象存在期间data指针指向的内存是有效合法的。

uint32_t GetSenderSSRC() const
-----返回发送该数据包的(会话)参与者的SSRC。

RTPNTPTime GetNTPTimestamp() const
-----返回发送发报告中的NTP时间戳。

uint32_t GetRTPTimestamp() const
-----返回发送方报告中的RTP时间戳。

uint32_t GetSenderPacketCount() const
-----返回在发送方报告中的发送方数据包计数。

uint32_t GetSenderOctetCount() const
-----返回在发送方报告中的发送方字节计数。

int GetReceptionReportCount() const
-----返回数据包中的接收报告块的个数。

uint32_t GetSSRC(int index) const
-----返回由index指定的接收报告块的SSRC,index的取值范围从0到GetReceptionReportCount()-1。注意:(函数)并不检查index范围的合法性。

uint8_t GetFractionLost(int index) const
-----返回index指定的接收报告中的丢包率属性(or字段?)。index的取值范围与上面一样,同样不检查index的范围的合法性。

int32_t GetLostPacketCount(int index) const
-----返回由index指出的接受报告中的丢失的数据包的个数。关于index的描述与上面相同。

uint32_t GetExtendedHighestSequenceNumber(int index) const
-----返回由index指出的接收报告中的扩展的最高序列号(??),index同上。

uint32_t GetJitter(int index) const
-----返回index指出的接收报告中的抖动属性,index同上。

uint32_t GetLSR(int index) const
-----返回index指出的接受报告中的LSR属性,index同上。

uint32_t GetDLSR(int index) const
-----返回index指出的接受报告中的DLSR属性,index同上。

RTCPRRPacket,头文件:rtcprrpacket.h,继承自:RTCPPacket
类描述了一个RTCP接收方报告数据包,接口如下:

RTCPRRPacket(uint8_t *data, size_t datalen)
-----基于长度为datalen的数据data创建一个RTCPRRPacket数据包对象。因为data指向的数据在类内部被引用(即不复制数据),所以必须确保在该对象存在期间data指针指向的内存是有效合法的。

uint32_t GetSenderSSRC() const
-----返回发送该数据包的(会话)参与者的SSRC。

int GetReceptionReportCount() const
-----返回数据包中的接收报告块的个数。

uint32_t GetSSRC(int index) const
-----返回由index指定的接收报告块的SSRC,index的取值范围从0到GetReceptionReportCount()-1。注意:(函数)并不检查index范围的合法性。

uint8_t GetFractionLost(int index) const
-----返回index指定的接收报告中的丢包率属性。index的取值范围与上面一样,同样不检查index的范围的合法性。

int32_t GetLostPacketCount(int index) const
-----返回由index指出的接受报告中的丢失的数据包的个数。关于index的描述与上面相同。

uint32_t GetExtendedHighestSequenceNumber(int index) const
-----返回由index指出的接收报告中的扩展的最高序列号(??),index同上。

uint32_t GetJitter(int index) const
-----返回index指出的接收报告中的抖动属性,index同上。

uint32_t GetLSR(int index) const
-----返回index指出的接受报告中的LSR属性,index同上。

uint32_t GetDLSR(int index) const
-----返回index指出的接受报告中的DLSR属性,index同上。

RTCPSDESPacket,头文件:rtcpsdespacket.h,继承自:RTCPPacket
该类描述了RTCP 的SDES数据包,类中定义了如下的类型:
enum ItemType{ None, CNAME, NAME, EMAIL, PHONE, LOC, TOOL, NOTE, PRIV, Unknown};
这些类型用来确定SDES每一个项的类型,None用来指出遍历所有项的结束,Unknown用来指出确实有一项存在,但是该项不是标准类型。
类的接口如下:

RTCPSDESPacket(uint8_t *data, size_t datalen)
-----基于长度为datalen的数据data创建一个RTCPSDESPacket数据包对象。因为data指向的数据在类内部被引用(即不复制数据),所以必须确保在该对象存在期间data指针指向的内存是有效合法的。

int GetChunkCount() const
-----返回SDES数据包中SDES数据块的个数,每个数据块都有自己的标识符。

bool GotoFirstChunk()
-----开始遍历,如果没有SDES数据块存在,函数返回false,否则返回true并将当前数据块设置为第一个数据块。

bool GotoNextChunk()
-----将当前数据块设置为下一个有效的数据块,如果没有数据块可用了,则返回false,否则返回true。

uint32_t GetChunkSSRC() const
-----返回当前数据块的SSRC标识符。

bool GotoFirstItem()
-----在当前数据块上开始遍历SDES的各项,如果没有SDES项存在,则返回false,否则返回true并将第一项设为当前项。

bool GotoNextItem()
-----如果当前数据块中还存在项(条目?),将当前项设置为下一项,并返回true,否则返回false。

ItemType GetItemType() const
-----返回当前数据块的当前数据项的类型。

size_t GetItemLength() const
-----返回当前数据块的当前数据项的长度。

uint8_t *GetItemData()
-----返回当前数据块的当前数据项的数据。如果在编译库的时候选择了支持SDES私有项,那么在当前项SDES是私有项时下列函数也可用。

size_t GetPRIVPrifixLength()
-----返回私有项的前缀字符串长度。

uint8_t *GetPRIVPrefixData()
-----返回私有项中前缀字符串的实际数据。

size_t GetPRIVValueLength()
-----返回私有项的值字符串的长度。

uint8_t *GetPRIVValueData()
-----返回私有项中值字符串的实际数据。

RTCPAPPPacket,头文件:rtcpapppacket.h,继承自:RTCPPacket
类RTCPAPPPacket描述了RTCP 的APP包,接口如下:

RTCPAPPPacket(uint8_t *data, size_t datalen)
-----基于长度为datalen的数据data创建一个RTCPAPPPacket数据包对象。因为data指向的数据在类内部被引用(即不复制数据),所以必须确保在该对象存在期间data指针指向的内存是有效合法的。

uint8_t GetSubType() const
-----返回APP数据包的子类型。

uint32_t GetSSRC() const
-----返回发送数据包的源的SSRC。

uint8_t *GetName()
-----返回在APP包中包含的名字,由四个不是以null结尾的字节组成。

uint8_t *GetAPPData()
-----返回指向实际数据的指针。

size_t GetAPPDataLength() const
-----返回实际数据的长度。

RTCPBYEPacket,头文件:rtcpbyepacket.h,继承自:RTCPPacket
类RTCPBYEPacket描述了RTCP 的BYE包,接口如下:

RTCPBYEPacket(uint8_t *data, size_t datalen)
-----基于长度为datalen的数据data创建一个RTCPBYEPacket数据包对象。因为data指向的数据在类内部被引用(即不复制数据),所以必须确保在该对象存在期间data指针指向的内存是有效合法的。

int GetSSRCCount() const
-----返回BYE数据包中存在的SSRC标识符的个数。

uint32_t GetSSRC(int index) const
-----返回由index指出的SSRC,index的范围可以是0到GetSSRCCount()-1,注意index没有范围的有效性检查。

bool HasReasonLength() const
------如果BYE包中包含离开原因则返回true。

size_t GetReasonLent() const
-----返回源离开的原因字符串长度。

uint8_t *GetReasonData()
-----返回实际的原因数据。

RTCPUnknownPacket,头文件:rtcpunknownpacket.h,继承自:RTCPPacket  
这个类除了继承的函数外,没有其他的成员函数,注意:因为未知的数据包格式没有什么可检查的,所以IsKnownFormat函数只是单纯的返回一个true。只有构造函数是可用的。

RTCPUnKnownPacket(uint8_t *data, size_t datalen)
-----基于长度为datalen的数据data创建一个RTCPBYEPacket数据包对象。因为data指向的数据在类内部被引用(即不复制数据),所以必须确保在该对象存在期间data指针指向的内存是有效合法的。


3.2.13 RTCPCompoundPacketBuilder,头文件:rtpcompoundpacketbuilder.h继承自:RTCPCompoundPacket
类RTCPCompoundPacketBuilder可用来构造一个RTCP复合数据包,一旦成功构建就可以继承RTCPCompoundPacket类的成员函数来获取复合数据包的信息。下列函数如果超出了最大允许(包)的大小将返回ERR_RTP_RTCPCOMPPACKBUILDER_NOTEN-OUGHBYTESLEFT。
接口如下:

int InitBuild(size_t maxpacketsize)
-----开始构建一个最大大小为maxpacksize的RTCP复合数据包,将分配新的内存来存储数据包。

int InitBuild(void *externalbuffer, size_t buffersize)
-----开始构建数据包,数据将被存储在外部由externalbuffer指定的最大存储量为buffersize个字节的地方。

int StartSenderReport(uint32_t senderssrc, const RTPNTPTime, &ntptimestamp, uint32_t rtptimestamp, uint32_t packcount, uint32_t octetcount)
-----告知数据包构建器需要以一个包含有函数参数指定的发送者信息的发送者报告为开头构建数据包。一旦发送者报告开始了,可以使用函数AddReportBlock来加入发送数据块。

int StartReceiverReport(uint32_t senderssrc)
-----告知数据包构建器数据包应该以一个包含由senderssrc指定的发送者SSRC的接受者报告开头。一旦发送者报告开始了,可以使用函数AddReportBlock来加入发送数据块。

int AddReportBlock(uit32_t ssrc, uint8_t fractionlost, int32_t packetslost, uint32_t exthighestseq, uint32_t jitter, uint32_t lsr, uint32_t dlsr)
-----加入由函数参数指定的报告块信息,如果加入的报告块个数大于31个,则构建器将自动使用新的RTCP接受者报告数据包。

int AddSDESSource(uint32_t ssrc)
-----为参与者ssrc开始构建SDES数据块(译注:Starts an SDES chunk for participant ssrc)。

int AddSDESNormalItem(RTCPSDESPacket::ItemType t, const void *itemdata, uint8_t itemlength)
-----将一个类型为t的常规(非私有)SDES项加入到SDES数据块中。项值是长度为itemlength的itemdata数据。

int AddBYEPacket(uint32_t *ssrc, uint8_t numssrcs, const void *reasondata, uint8_t reasonlength)
-----在复合数据包中加入一个BYE包。包中将包含由ssrcs指定的numssrcs源标识符,并且由长度为reasonlength的reasondata字符串指出离开原因。(译注:It will contain numssrcs source identifiers specified in ssrcs)

int AddAPPPacket(uint8_t subtype, uint32_t ssrc, const uint8_t name[4], const void *appdata, size_t appdatalen)
-----在复合数据包中加入由参数指定的APP数据包,注意:appdatalen必须是4的倍数。

int EndBuild()
-----结束构建复合数据包。如果成功RTCPCompoundPacket的成员函数就可以用来获取RTCP数据包的数据。

int AddSDESPrivateItem(const void *prefixdata, uint8_t prefixlength, const void *valuedata, uint8_t valuelength)
-----在当前SDES数据块中加入由函数参数描述的SDES PRIV项。


3.2.14 RTPSources,头文件:rtpsources.h
类RTPSources代表一张保存参与会话的源的信息的表。类有成员函数来迭代遍历参与者,处理RTP和RTCP数据。注意:地址NULL用于标识从我们自己的会话发出的包,类提供了许多可重载的函数用来获取特定的事件(新的SSRC, SSRC冲突等)。
如果开启了试用支持,则你可以选择下面三种试用类型之一:
enum ProbationType { NoProbation, ProbationDiscard, ProbationStore};
当选择了NoProbation,则试用算法将不会用来验证新的源;当使用了ProbationDiscard,试用算法将会激活但是收到的数据包都会丢弃直到(数据)源得到验证。要激活试用路由并且在(数据)源验证前保存收到的数据包,应该选择ProbationStore模式。
类RTPSources 接口如下所示:

RTPSources(ProbationType probationtype = ProbationStore)
------在构造函数中你可以选择任何你喜欢的试用类型,这仅仅在编译时选择了试用支持时才有区分。

void Clear()
-----清除源表。

int CreateOwnSSRC(uint32_t ssrc)
-----为自己的SSRC标识符创建一个条目。

int DeleteOwnaSSRC()
-----删除自己的SSRC标识符的条目。

void SentRTPPacket()
-----对于自己的SSRC条目来说,发送者标志是基于正在发送的数据包而不是正在接受的数据包来更新的。如果我们自己的会话发送了一个RTP数据包,这个函数应该被调用。

int ProcessRawPacket(RTPRawPacket *rawpack, RTPTransmitter *trans, bool acceptownpackets)
-----处理一个原始数据包rawpacket。对象trans将会用来检查该数据包是否是我们自己的包。标志acceptownpackets指出我们的包是应该接受还是忽略。

int ProcessRTPPacket(RTPPacket *rtppacket, const RTPTime &receivetime, const RTPAddress *senderaddress, bool *stored)
-----处理在receivetime时刻收到的发自senderaddress的RTPPacket对象数据包rtppacket。如果数据包是本机发送的则senderaddress必须是NULL。标志stored指出包是否存入表中,如果(设置为true)rtppacket对象可能不会被删除。

int ProcessRTCPCompoundPacket(RTCPCompoundPacket *rtcpcompack, const RTPTime &receivetime, const RTPAddress *senderaddress)
-----处理在receivetime时刻收到的发自senderaddress地址的RTCP复合数据包rtcpcompack,如果数据包是发自本机的,则senderaddress必须是NULL。

int ProcessRTCPSenderInfo(uint32_t ssrc, const RTPNTPTime &ntptime, uint32_t rtptime, uint32_t packetcount, uint32_t octetcount, const RTPTime &receivetime, const RTPAddress *senderaddress)
-----处理在receivetime时刻收到的发自senderaddress的发送者信息的SSRC信息ssrc,放入(数据)源表中。如果数据包是发自本机的,则senderaddress必须是NULL。

int ProcessRTCPReportBlock(uint32_t ssrc, uint8_t fractionlost, int32_t lostpackets, uint32_t exthightseqnr, uint32_t jitter, uint32_t lst, uint32_t dlsr, const RTPTime &receivetime, const RTPAddress *senderaddresss)
-----处理在receivetime时刻收到的发自senderaddress的参与者ssrc的报告数据块信息,放入(数据)源表中。如果数据包是发自本机的,则senderaddress必须是NULL。

int ProcessSDESNormalItem(uint32_t ssrc, RTCPSDESPacket::ItemType t, size_t itemlength, const void *itemdata, const RTPTime &receivetime, const RTPAddress *senderaddress)
-----处理在receivetime时刻收到的发自senderaddress的参与者ssrc的非私有SDES项信息,放入(数据)源表中。如果数据包时发自本机的,则senderaddress必须是NULL。

int ProcessBYE(uint32_t ssrc, size_t reasonlength, const void *reasondata, const RTPTime &receivetime, const RTPAddress *senderaddress)
-----处理在receivetime时刻收到的发自senderaddress的参与者ssrc的BYE信息。如果数据包是发自本机的,则senderaddress必须是NULL。

int UpdateReceiveTime(uint32_t ssrc, const RTPTime &receivetime, const RTPAddress *senderaddress)
-----如果我们监听到了源ssrc,但是却没有实际的数据放入到源表中(例如:没有对我们有意义的报告数据块),该函数可以用来指出从源收到了一些信息。这将阻止该参与者过早的达到超时时间。【译注:This will prevent a premature timeout for this participant.】该信息是发自senderaddress的并且在receivetime时刻收到。如果数据包是发自本机的,则senderaddress必须是NULL。

bool GotoFirstSource()
-----从表的第一个成员开始遍历参与者。如果发现了成员则返回true,否则返回false。

bool GotoNextSource()
-----将表中的下一个源设置为当前源,如果已经是最后一个源,则函数返回false,否则返回true。

bool GotoPreviousSource()
-----将表中前一个源设置为当前源,如果已经是第一个源,则函数返回false,否则返回true。

bool GotoFirstSourceWithData()
-----将表中第一个包含还没有提取的RTPPacket对象的源设置为当前源,如果没有这样的源找到,则返回false,否则返回true。

bool GotoNextSourceWithData()
-----将表中下一个包含还没有提取的RTPPacket对象的源设置为当前源,如果没有这样的源找到,则返回false,否则返回true。

bool GotoPreviousSourceWithData()
-----将表中前一个包含还没有提取的RTPPacket对象的源设置为当前源,如果没有这样的源找到,则返回false,否则返回true。

RTPSourceData *GetCurrentSourceInfo()
-----返回当前选择的参与者的RTPSourceData对象。

RTPSourceData *GetSourceInfo(uint32_t ssrc)
-----返回由参与者标志ssrc指出的RTPSourceData对象,如果没有这样的对象存在则返回NULL。

RTPPacket *GetNextPacket()
-----从当前参与者收到的数据包队列中提取下一个数据包。

bool GotEntry(uint32_t ssrc)
-----如果参与者ssrc的项存在,则返回true,否则返回false。

RTPSourceData *GetOwnSourceInfo()
-----如果出现,则将返回由CreateOwnSSRC创建的RTPSourceData对象的项。

void Timeout(const RTPTime &curtime, const RTPTime &timeoutdelay)
-----假设当前时间是curtime,暂停(超时?)在上一个时间间隔timeoutdelay没有监听到的对象【译注:tiem out the members from whom we haven’t heard during the previous time interval timeoutdelay】

void SenderTimeout(const RTPTime &curtime, const RTPTime &timeoutdelay)
-----假设当前时间是curtime,将发送者标记从在上一个时间间隔timeoutdelay就没有收到RTP数据包的对象中移除。

void BYETimeout(const RTPTime &curtime, const RTPTime &timeoutdelay)
-----假设当前时间是curtime,将在时间间隔timeoutdelay之前发送BYE数据包的对象移走。【remove the members who sent a BYE packet more than the time interval timeoutdelay.】

Void NoteTimeout(const RTPTime &curtime, const RTPTime &timeoutdelay)
-----假设当前时间是curtime,,将在时间间隔timeoutdelay期间没有更新的SDES NOTE项清除。

void MultipleTimeout(const RTPTime &curtime, const RTPTime &sendertimeout, const RTPTime &byetimeout, const RTPTime &generaltimeout, const RTPTime &notetimeout)
-----上面的四个函数的组合,该函数比调用上面的四个函数(每个一遍)更有效率,因为该函数仅需遍历一遍。

int GetSenderCount() const
-----返回标记为发送者的参与者的个数。

int GetTotalCount() const
-----返回源表中的所有的项【参与者】的个数。

int GetActiveMemberCount() const
-----返回确认的而且还没有发送BYE数据包的成员个数。

int ProcessSDESPrivateItem(uint32_t ssrc, size_t prefixlen, const void *prefixdata, size_t valuelen, const void *valuedata, const RTPTime &receivetime, const RTPAddress *senderaddress)
-----将在receivetime时刻收到的发自senderaddress的来自ssrc的SDES私有数据放入源表中。如果数据包是从本机发出则senderaddress必须设为NULL。
通过继承RTPSources类,并且重载下面的一个或多个函数,你的类可以收到特定的事件。

void OnRTPPacket(RTPPacket *pack, const RTPTime &receivetime, const RTPAddress *senderaddress)
-----在一个RTP数据包将要处理时被调用。

void OnRTCPCompoundPacket(RTCPCompoundPacket *pack, const RTPTime receivetime, const RTPAddress *senderaddress)
-----在一个RTCP数据包将要处理时被调用。

void OnSSRCCollision(RTPSourceData *srcdat, const RTPAddress *senderaddrss, bool isrtp)
-----当检测到一个SSRC冲突是被调用。对象srcdat是源表中的当前项,。。。【译注:这句实在不会翻译,原文:The instance srcdat is the one present in the table, the address senderaddress is the one that collided with one of the addresses and isrtp indicates against which address of srcdat the check failed.】

void OnCNAMECollision(RTPSourceData *srcdat, const RTPAddress *senderaddress, const uint8_t *cname, size_t cnamelength)
-----【Is called when another CNAME was received than the one already present for source srcdat.】

void OnNewSource(RTPSourceData *srcdat)
-----新的项srcdat加入源表中时被调用。

void OnRemoveSource(RTPSourceData *srcdat)
-----项srcdat要从源表中删除时被调用。

void OnTimeout(RTPSourceData *srcdat)
-----参与者srcdat超时时调用。

void OnBYETimeout(RTPSourceData *srcdat)
-----当参与者srcdat发送了BYE包之后调用。

void OnAPPPacket(RTCPPacket *apppacket, const RTPTime &receivetime, const RTPAddress *senderaddress)
-----在receivetime时刻收到senderaddress发出的RTCP  APP数据包apppacket时调用。

void OnUnknownPacketType(RTCPPacket *rtcppack, const RTPTime &receivetime, const RTPAddress *senderaddress)
-----当收到一个未知类型的RTCP数据包时被调用。

void OnUnknownPacketFormat(RTCPPacket *rtcppak, const RTPTime &receivetime, const RTPAddress *senderaddress)
-----当检测到已知包类型的未知包格式时被调用。

void OnNoteTimeout(RTPSourceData *srcdat)
-----当源srcdat的SDES NOTE项超时时调用。


3.2.15 RTPSourceData,头文件:rtpsourcedata.h
类RTPSourceData包含会话成员的所有信息,类接口如下:

uint32_t GetSSRC() const
-----返回该成员的SSRC标识符。

bool HasData() const
-----如果RTP数据包可以提取,则返回true。

RTPPacket *GetNextPacket()
-----提取参与者RTP数据包队列的第一个数据包。

void FlushPackets()
-----清除参与者RTP包列表。

bool IsOwnSSRC() const
-----如果参与者是通过RTPSources的成员函数CreateOwnSSRC加入的,则返回true,否则返回false。

bool IsCSRC() const
-----如果源标识符实际是来自RTP数据包的CSRC则返回true。

bool IsSender() const
-----如果该成员被标记为发送者,则返回true,否则返回false。

bool IsValidated() const
-----如果参与者是有效的则返回true,即连续收到了该参与者的一定数量的RTP包或者收到了该参与者的CNAME项。

bool IsActive() const
-----如果源是有效的并且没有发送BYE包则返回true。

void SetProcessedInRTCP(bool v)
-----函数在RTCPPacketBuilder类中被调用来标记参与者信息是否已经在报告数据块中处理过了。

bool IsProcessedInRTCP() const
-----函数在RTCPPacketBuilder类中被调用来标记参与者是否已经在报告数据块中处理过了。

bool IsRTPAddressSet() const
-----如果该参与者的RTP数据包发送源地址已经设定好了则返回true。

bool IsRTCPAddressSet() const
-----如果该参与者的RTCP数据包发送源地址已经设定好了则返回true。

const RTPAddress *GetRTPDataAddress() const
-----返回发送该参与者RTP包的源地址。如果该地址已经设定了返回值为NULL,这表示数据包时来自本地参与者。

const RTPAddress *GetRTCPDataAddress() const
------返回发送该参与者RTCP包的源地址。如果该地址已经设定了返回值为NULL,这表示数据包时来自本地参与者。

bool ReceivedBYE() const
-----如果收到了该参与者的BYE信息则返回true,否则返回false。

uint8_t *GetBYEReason(size t *len) const
-----返回在BYE包中的参与者的离开原因,原因字符串的长度由len指出。

RTPTime GetBYETime() const
-----返回发送BYE包的时间。

void SetTimestampUnit(double tsu)
-----设置收到该参与者数据时用于抖动计算的时间戳单位数值。如果没有设置,库计算两个连续的RTCP发送者报告(中的信息)来估计时间戳单位。时间戳定义为:一段时间的采样数除以这段时间间隔,对于8000Hz的音频来说是1.0/8000.0。

double GetTimestampUnit() const
-----返回该参与者的时间戳单位。

bool SR_HasInfo() const
-----如果收到了该参与者的发送者报告则返回true。

RTPNTPTime SR_GetNTPTimestamp() const
-----返回在上一个发送者报告中的NTP时间戳。

uint32_t SR_GetRTPTimestamp() const
-----返回在上一个发送者报告中的RTP时间戳。

uint32_t SR_GetPacketCount() const
-----返回上一个发送者报告中的包个数。

uint32_t SR_GetByteCount() const
-----返回上一个发送者报告中的字节个数。

RTPTime SR_GetReceiveTime() const
-----返回上个发送者报告的收到时间。

bool SR_Prev HasInfo() const
-----如果收到了不止一个RTCP发送者报告则返回true。

RTPNTPTime SR_Prev_GetNTPTimestamp() const
-----返回收到的倒数第二个发送者报告中的NTP时间戳。

uint32_t SR_Prev_GetRTPTimestamp() const
-----返回倒数第二个发送者报告中的RTP时间戳。

uint32_t SR_Prev_GetPacketCount() const
-----返回倒数第二个发送者报告中数据包个数。

uint32_t SR_Prev_GetByteCount() const
-----返回倒数第二个发送者报告中字节数。

RTPTime SR_Prev_GetReceiveTime() const
-----返回倒数第二个发送者报告的接收时间。

bool RR_HasInfo() const
-----如果参与者发送了一个关于我们接收数据的信息的接受者报告则返回true。

double RR_GetFractionLost() const
-----返回上一个报告中的丢包率。

int32_t RR_GetPacketsLost() const
-----返回上一个报告中的丢包数。

uint32_t RR_GetExtendedHighestSequenceNumber() const
-----返回上个报告中的扩展最高序列号。

uint32_t RR_GetJitter() const
-----返回上个报告中的抖动值。

uint32_t RR_GetLastSRTimestamp() const
-----返回上个报告中的LSR值。

uint32_t RR_GetDelaySinceLastSR() const
-----返回上个报告中的DLSR值。

RTPTime RR_GetReceiveTime() const
-----返回上个报告的接收时间。

bool RR_Prev_HasInfo() const
-----如果参与者发送了不止一个关于我们接受数据信息的接受者报告则返回true。

double RR_Prev_GetFractionLost() const
-----返回倒数第二个(接收者)报告中的丢包率。

int32_t RR_Prev_GetPacketsLost() const
-----返回倒数第二个(接收者)报告中的丢包个数。

uint32_t RR_Prev_GetExtendedHighestSequenceNumber() const
-----返回倒数第二个(接收者)报告中的扩展最高序列号。

uint32_t RR_Prev_GetJitter() const
-----返回倒数第二个(接收者)报告中的抖动值。

uint32_t RR_Prev_GetLastSRTimestamp() const
-----返回倒数第二个(接收者)报告中的

uint32_t RR_Prev_GetDelaySinceLastSR() const
-----返回倒数第二个(接收者)报告中的LSR值。

RTPTime RR_Prev_GetReceiveTime() const
-----返回倒数第二个(接收者)报告中的DLSR。

bool INF_HasSentData() const
-----如果收到了该参与者的有效RTP数据包则返回true。

int32_t INF_GetNumPacketsReceived() const
-----返回从该参与者收到的所有的数据包数。

uint32_t INF_GetBaseSequenceNumber() const
-----返回该参与者的基数序列号。

uint32_t INF_GetExtendedHighestSequenceNumber() const
-----返回从该参与者收到的扩展最高序列号。

uint32_t INF_GetJitter() const
-----返回该参与者的当前抖动值。

RTPTime INF_GetLastMessageTime() const
-----返回上次从该成员听到【收到?】任何消息的时间。

RTPTime INF_GetLastRTPPacketTime() const
-----返回上次收到RTP数据包的时间。

double INF_GetEstimatedTimestampUnit() const
-----返回估计的时间戳单位。该估计是基于两个连续的发送者报告(来计算的)。

uint32_t INF_GetNumPacketsReceivedInInterval() const
-----返回由INF_StartNewInterval启动的新的时间间隔期间收到的数据包数量。

uint32_t INF_GetSavedExtendedSequenceNumber() const
-----返回调用INF_StartNewInterval()保存的扩展序列号。

void INF_StartNewInterval()
-----开始一个新的用于计数接收到的数据包的时间间隔。同时还保存当前的扩展最高序列号以用于计算时间间隔内的丢包。

RTPTime INF_GetRoundtripTime() const
-----使用上一个接受者报告的LSR和DLSR估计往返时间。

RTPTime INF_GetLastSDESNoteTime() const
-----返回上次收到SDES NOTE项时的时间。

uint8_t *SDES_GetCNAME(size_t *len) const
-----返回一个指向该参与者的SDES CNAME项的指针,并将其长度存入len。

uint8_t *SDES_GetName(size_t *len) const
-----返回一个指向该参与者的SDES 名字项的指针,并将其长度存入len。

uint8_t *SDES_GetEMail(size_t *len) const
-----返回一个指向该参与者的SDES e-mail项的指针,并将其长度存入len。

uint8_t *SDES_GetPhone(size_t *len) const
-----返回一个指向该参与者的SDES phone项的指针,并将其长度存入len。

uint8_t *SDES_GetLocation(size_t *len) const
-----返回一个指向该参与者的SDES 位置项的指针,并将其长度存入len。

uint8_t *SDES_GetTool(size_t *len) const
-----返回一个指向该参与者的SDES 工具项的指针,并将其长度存入len。

uint8_t *SDES_GetNote(size_t *len) const
-----返回一个指向该参与者的SDES 通知项的指针,并将其长度存入len。

void SDES GotoFirstPrivat_Value()
-----开始遍历保存的SDES私有项的前缀以及它们关联的值。

bool SDES_GetNextPrivateValue(uint8 t **prefix, size_t *prefixlen, uint8_t **value, size_t *valuelen)
-----如果有效,则返回true,并且将SDES的私有项前缀存入prefix,长度存入prefixlen,关联的值以及长度分别存入value和valuelen。否则返回false。

bool SDES_GetPrivateValue(uint8_t *prefix, size_t prefixlen, uint8_t **value, size_t *valuelen) const
-----查找与SDES的私有项前缀为prefix长度为prefixlen对应的项,如果找到则返回true并且将关联的值和长度分别存入value和valuelen中。


3.2.16 RTPPacketBuilder,头文件:rtppacketbuilder.h
该类可以用来构建RTP数据包,比RTPPacket类高级一点:可以产生SSRC标识符,跟踪时间戳,序列号等。接口如下:

int Init(size_t maxpacksize)
-----初始化构建器使得允许的包大小小于maxpack。

void Destroy()
-----清理构建器。

uint32_t GetPacketCount()
-----返回与当前SSRC标识符一块创建的包的数量。

uint32_t GetPayloadOctetCount()
-----返回由该SSRC标识符产生的负载字节数。

int SetMaximumPacketSize(size_t maxpacksize)
-----将最大允许包大小设置为maxpacksize。

int AddCSRC(uint32_t csrc)
-----在RTP包要保存的CSRC链表中加入一个SSRC。

int DeleteCSRC(uint32_t csrc)
-----从要保存入RTP包的CSRC表中删除一个SSRC。

void ClearCSRCList()
-----清除CSRC链表。

int BuildPacket(const void *data, size_t len)
-----构建一个负载为data长度为len的数据包,负载类型,标识,时间戳增量等使用后面的SetDefault函数设置的值。

int BuildPacket(const void *data, size_t len, uint8_t pt, bool mark, uint32_t timestampinc)
-----构建一个负载为data长度为len的数据包,负载类型为pt,标识位为mark,包构建成功之后时间戳增量为temstamp。

int BuildPacketEx(const void *data, size_t len, uint16_t hdrextID, const void *hdrextdata, size_t numhdrextwords)
-----构建一个负载为data长度为len的数据包,负载类型,标识,时间戳增量等使用后面的SetDefault函数设置的值。该数据包还将包含一个标识符为hdrextID数据为hdrextdata的RTP扩展头,扩展数据头的长度由一个32位的字numhdrextwords给出。

int BuildPacketEx(const void *data, size_t len, uint8_t pt, bool mark, uint32_t timestampinc, uint16_t hdrextID, const void *hdrextdata, size_t numhdrextwords)
-----构建一个负载为data长度为len的数据包,负载类型为pt,标识位为mark,包构建成功之后时间戳增量为temstamp。该数据包还将包含一个标识符为hdrextID数据为hdrextdata的RTP扩展头,扩展数据头的长度由一个32位的字numhdrextwords给出。

uint8_t *GetPacket()
-----返回指向上次构建的RTP数据包数据的指针。

size_t GetPacketLength()
-----返回上次构建的RTP数据包的长度。

int SetDefaultPayloadType(uint8_t pt)
-----设置默认负载类型为pt。

int SetDefaultMark(bool m)
-----设置默认标志位为m。

int SetDefaultTimestampIncrement(uint32_t timestampinc)
-----设置默认时间戳增量为timestampinc。

int IncrementTimestamp(uint32_t inc)
-----函数以给定的inc来增加时间戳。该函数有时候是有用的,例如:当数据包只包含静默而不发送时,该函数应该被调用以按照合适的量来增加时间戳,这样才可以使得其他主机可以在正确的时间播放下一个数据包。

int IncrementTimestampDefault()
-----函数使用由SetDefaultTimestampIncrement指定的量来增加时间戳。该函数是有用的,例如:当数据包只包含静默而不发送时,该函数应该被调用以按照合适的量来增加时间戳,这样才可以使得其他主机可以在正确的时间播放下一个数据包。

uint32_t CreateNewSSRC()
-----在产生的数据包中创建一个新的SSRC,这将产生一个新的时间戳以及序列号增量。

uint32_t CreateNewSSRC(RTPSources & sources)
-----产生的数据包中创建一个新的SSRC,这将产生一个新的时间戳以及序列号增量。源表sources用来确保选择的SSRC不会被其他的参与者使用。

uint32_t GetSSRC()
-----返回当前的SSRC标识符。

uint32_t GetTimestamp()
-----返回当前的RTP时间戳。

uint16_t GetSequenceNumber()
-----返回当前的序列号。

RTPTime GetPacketTime()
-----返回数据包的生成时间。这不必是上一个RTP包生成的时间,如果时间戳增量为0,则时间将不会更新。

uint32_t GetPacketTimestamp()
-----返回对应于上一个函数返回的时间的RTP时间戳。


3.2.17 RTCPPacketBuilder,头文件:rtcppacketbuilder.h
类RTCPPacketBuilder可以用来构建RTCP复合数据包。该函数比类RTCPCompoundPacketBuilder高级一点:它使用RTPPacketBuilder对象和RTPSources对象的信息来自动产生下一个需要发送的复合数据包,而且类还提供函数用来决定是SDES项而不是CNAME项应该被发送。类的接口如下:

RTCPPacketBuilder(RTPSources &sources,RTPPacketBuilder &rtppackbuilder)
-----创建一个RTCPPacketBuilder对象,使用源表sources和RTP数据包构建器rtppacketbuiler决定的下一个RTCP复合数据包中包含的信息。

int Init(size_t maxpacksize, double timestampunit, const void *cname, size_t cnamelen)
-----使用最大允许包大小maxpacksize,时间戳单位timestampunit以及由长度为cnamelen的cname给出的SDES CNAME项来初始化构建器。时间戳单位定义为:一段时间内采样数除以该段时间长度,对于8000Hz的音频来说就是1.0/8000.0。

void Destroy()
-----清除构建器。

int SetTimestampUnit(double tsunit)
-----设置时间戳单位为tsunit,时间戳单位定义为:一段时间内采样数除以该段时间长度,对于8000Hz的音频来说就是1.0/8000.0。

int SetMaximumPacketSize(size_t maxpacksize)
-----设置最大允许的RTCP复合数据包大小为maxpacksize。

int SetPreTransmissionDelay(const RTPTime &delay)
-----函数允许你通知RTCP数据包构建器第一个采样包到发送包之间的延迟时间,当用于交互式多媒体的同步时,将会考虑进延迟来计算RTP时间戳和时钟时间之间的关系。

int BuildNextPacket(RTCPCompoundPacket **pack)
-----构建下一个保存在pack中的要发送的RTCP复合数据包。

int BuildBYEPacket(RTCPCompoundPacket **pack, const void *reason, size_t reasonlength, bool useSRifpossible = true)
-----构建一个由长度为reasonlength的reason给出离开原因的BYE数据包。如果useSRifpossible设为true,如果允许则RTCP复合数据包将以发送者报告开始,否则将以接受者报告开始。

void SetNameInterval(int count)
-----当源表中所有的源都已处理完之后,类会检查是否需要发送其他的SDES项,如果count为0或者负,则不会发生什么,如果为正,则在源表中的源被处理完count次之后将在后面加入一条SDES name项。

void SetEMailInterval(int count)
-----当源表中所有的源都已处理完之后,类会检查是否需要发送其他的SDES项,如果count为0或者负,则不会发生什么,如果为正,则在源表中的源被处理完count次之后将在后面加入一条SDES e-mail项。

void SetLocationInterval(int count)
-----当源表中所有的源都已处理完之后,类会检查是否需要发送其他的SDES项,如果count为0或者负,则不会发生什么,如果为正,则在源表中的源被处理完count次之后将在后面加入一条SDES location项。

void SetPhoneInterval(int count)
-----当源表中所有的源都已处理完之后,类会检查是否需要发送其他的SDES项,如果count为0或者负,则不会发生什么,如果为正,则在源表中的源被处理完count次之后将在后面加入一条SDES phone项。

void SetToolInterval(int count)
-----当源表中所有的源都已处理完之后,类会检查是否需要发送其他的SDES项,如果count为0或者负,则不会发生什么,如果为正,则在源表中的源被处理完count次之后将在后面加入一条SDES tool项。

void SetNoteInterval(int count)
-----当源表中所有的源都已处理完之后,类会检查是否需要发送其他的SDES项,如果count为0或者负,则不会发生什么,如果为正,则在源表中的源被处理完count次之后将在后面加入一条SDES note项。

int SetLocalName(const void *s, size t len)
-----将本地参与者的SDES name项设置为长度为len,值为value。

int SetLocalEMail(const void *s, size t len)
-----将本地参与者的SDES E-mai项设置为长度为len,值为value。

int SetLocalLocation(const void *s, size t len)
-----将本地参与者的SDES location项设置为长度为len,值为value。

int SetLocalPhone(const void *s, size t len)
-----将本地参与者的SDES phone项设置为长度为len,值为value。

int SetLocalTool(const void *s, size t len)
-----将本地参与者的SDES tool项设置为长度为len,值为value。

int SetLocalNote(const void *s, size t len)
-----将本地参与者的SDES note项设置为长度为len,值为value。


3.2.18 RTPCollisionList,头文件:rtpcollisionlist.h
类代表一个SSRC冲突检测到的一个地址列表。接口如下:

void Clear()
-----清除地址列表。

int UpdateAddress(const RTPAddress *addr, const RTPTime &receivetime, bool *created)
-----更新在receivetime时刻检测到的由addr指出的一个冲突的(相关)项,如果没有该项则created将被设为true,否则设为false。

bool HasAddress(const RTPAddress *addr) const
-----如果addr在地址列表中则返回true。

void Timeout(const RTPTime &currenttime, const RTPTime &timeoutdelay)
-----假设当前时间由currenttime给出,函数将timeoutdelay指定的上个时间间隔中没有更新的项设为超时。


3.2.19 RTCPScheduler,头文件:rtcpscheduler.h
该类决定何时应该发送一个RTCP复合数据包,类接口如下:

RTCPScheduler(RTPSources &sources)
-----使用源表RTPSources创建一个(调度器)对象来决策什么时候应该调度一个RTCP复合数据包。为正确保证执行(创建)动作sources对象应该有关于自己的SSRC的信息(通过CreateOwnSSRC加入的)。

void Reset()
-----重置调度器。

void SetParameters(const RTCPSchedulerParams &params)
-----将调度参数设为params,RTCPSchedulerParams类将在后面介绍。

RTCPSchedulerParams GetParameters() const
-----返回当前使用的调度参数。

void SetHeaderOverhead(size_t numbytes)
-----将底层协议头开销设为numbytes(例如UDP 和IP)

size t GetHeaderOverhead() const
-----返回当前头开销。

void AnalyseIncoming(RTCPCompoundPacket &rtcpcomppack)
-----对于每一个接收到的RTCP复合数据包,为使调度器正常工作都要调用该函数。

void AnalyseOutgoing(RTCPCompoundPacket &rtcpcomppack)
-----对于每一个发送的RTCP复合数据包,为使调度器正常工作都要调用该函数。

void ActiveMemberDecrease()
-----每次有成员超时或者发送了BYE数据包都要调用该函数。

void ScheduleBYEPacket(size_t packetsize)
-----请求调度器调度一个包含BYE包的RTCP复合数据包,复合数据包长度为packetsize。

RTPTime GetTransmissionDelay()
-----返回一个RTCP复合包应该被发送后的延迟,IsTime成员函数需要随后调用,以确保确实是发送一个RTCP复合包的时候到了。

bool IsTime()
-----当确实是应该发送一个RTCP复合包时函数返回true,否则返回false。如何返回true则下一次一个包应该发送的时间也已经计算好了,所以如果函数又被立刻调用则返回false。

RTPTime CalculateDeterministicInterval(bool sender = false)
-----计算此时决定性的时间间隔,这将和一个乘数一起被用来作为成员,发送器等的超时(标准)。

RTCPSchedulerParams,头文件:rtcpscheduler.h
类RTCPSchedulerParams描述了被调度器使用的参数,接口如下:

int SetRTCPBandwidth(double bw)
------将RTCP使用的带宽设为bw(单位为比特每秒)。

double GetRTCPBandwidth() const
-----返回以比特每秒为单位的RTCP当前使用的带宽。

int SetSenderBandwidthFraction(double fraction)
-----将RTCP为发送器保留的带宽比率设为fraction

double GetSenderBandwidthFraction() const
-----返回RTCP为发送器保留的带宽比率。

int SetMinimumTransmissionInterval(const RTPTime &t)
-----设置两个RTCP复合包的最小(决定性的)时间间隔为t。

RTPTime GetMinimumTransmissionInterval() const
-----返回两个RTCP复合包的最小时间间隔。

void SetUseHalfAtStartup(bool usehalf)
-----如果usehalf为true,则在发送第一个RTCP复合包之前只使用一半的最小间隔。

bool GetUseHalfAtStartup() const
-----返回在发送第一个RTCP复合包之前是否只使用一半的最小间隔。

void SetRequestImmediateBYE(bool v)
-----如果v为true,则调度器将在允许时立刻调度一个BYE包发送。

bool GetRequestImmediateBYE()
-----如果调度器在允许时立刻调度一个BYE包发送则返回true。

参数的默认值为:
RTCP带宽:1000字节每秒。
发送器带宽比率:25%。
最小时间间隔:5秒。
在开始时使用半个最小间隔:是。
允许时立刻发送BYE包:是。


3.2.20 RTPSessionParams,头文件:rtpsessionparams.h
描述了要被一个RTPSession对象使用的参数。注意!自己的时间戳单位必须设为一个有效的数值,否则会话将不会创建。类的接口如下:

int SetUsePollThread(bool usethread)
-----如果usethread设为了true则会话将使用一个线程池自动的处理收到的数据以及在需要的时候发送RTCP数据包。

bool IsUsingPollThread() const
-----返回会话是否使用了线程池。

void SetMaximumPacketSize(size_t max)
-----设置会话允许的最大包大小。

size_t GetMaximumPacketSize() const
-----返回最大允许的包大小。

void SetAcceptOwnPackets(bool accept)
-----如果参数为true则会话会接受自己的数据包并且放入对应的源表中。

bool AcceptOwnPackets() const
-----如果会话可以接受自己的数据包,则返回true。

void SetReceiveMode(RTPTransmitter::ReceiveMode recvmode)
-----设置会话将使用的接收模式。

RTPTransmitter::ReceiveMode GetReceiveMode() const
-----返回当前使用的接收模式。

void SetOwnTimestampUnit(double tsunit)
-----为我们自己的数据设置时间戳单位。时间戳单位定义为一段时间内的采样数除以这段时间(以秒为单位)。例如:对于80000Hz的音频数据,时间戳单位就是1.0/8000.0.因为这个值初始设置为一个非法的值,所以使用者必须设置为一个允许的值才可以创建一个会话。

double GetOwnTimestampUnit() const
-----返回当前使用的时间戳单位。

void SetResolveLocalHostname(bool v)
-----如果v设置为true,则会话将请求传输器在基于它的本地IP地址列表中的IP地址寻找一个主机名。如果设置为false,将调用gethostname或者类似的函数来找出本地主机名。注意:方法一(即设为true)将会花费一些时间。

bool GetResolveLocalHostname() const
-----返回本地主机名是否应该由传输器的本地IP地址列表决定。

void SetProbationType(RTPSources::ProbationType probtype)
-----如果使能了试用支持,则该函数将设置使用的试用类型。

RTPSources::ProbationType GetProbationType() const
-----返回使用的试用类型。

void SetSessionBandwidth(double sessbw)
-----设置会话带宽(单位为字节/秒)。

double GetSessionBandwidth() const
-----返回以字节/秒为单位的会话带宽。

void SetControlTrafficFraction(double frac)
-----设置控制传输将使用的会话带宽百分比。

double GetControlTrafficFraction() const
-----返回控制传输使用的会话带宽的百分比。

void SetSenderControlBandwidthFraction(double frac)
-----设置发送器将使用的最小控制传输百分比。

double GetSenderControlBandwidthFraction() const
-----返回发送器使用的最小控制传输百分比。

void SetMinimumRTCPTransmissionInterval(const RTPTime &t)
-----设置发送RTCP数据包的最小时间间隔。

RTPTime GetMinimumRTCPTransmissionInterval() const
-----返回发送RTCP数据包的最小时间间隔。

void SetUseHalfRTCPIntervalAtStartup(bool usehalf)
-----如果usehalf设置为true,则会话将在发送第一个RTCP数据包之前只等待半个计算的RTCP间隔。

bool GetUseHalfRTCPIntervalAtStartup() const
-----返回会话是否将在发送第一个RTCP数据包之前只等待半个计算的RTCP间隔。

void SetRequestImmediateBYE(bool v)
-----如果v为true,会话将在允许的时候立即发送一个BYE包。

bool GetRequestImmediateBYE() const
-----返回是否会话将在允许的时候立即发送一个BYE包。

void SetSenderReportForBYE(bool v)
-----当发送一个BYE包时,这指出了它是否是一个以发送者报告或接收者报告开头的RTCP复合数据包的一部分。当然发送者报告仅仅在允许的时候才会使用。

bool GetSenderReportForBYE() const
-----如果在一个以发送者报告开头的RTCP复合数据包中发送一个BYE包则返回true,如果使用了接收者报告,则函数将返回false。

void SetSenderTimeoutMultiplier(double m)
-----设置发送者超时将使用的乘数【译注:Set the multiplier to be used when timing out senders.】

double GetSenderTimeoutMultiplier() const
-----返回发送者超时将使用的乘数。

void SetSourceTimeoutMultiplier(double m)
-----设置成员超时将使用的乘数。

double GetSourceTimeoutMultiplier() const
-----返回成员超时将使用的乘数。

void SetBYETimeoutMultiplier(double m)
-----设置成员发送完一个BYE包后超时将使用的乘数。

double GetBYETimeoutMultiplier() const
-----返回成员发送完一个BYE包后超时将使用的乘数。

void SetCollisionTimeoutMultiplier(double m)
-----设置冲突表中的项的超时乘数。

double GetCollisionTimeoutMultiplier() const
-----返回冲突表中的项的超时乘数。

void SetNoteTimeoutMultiplier(double m)
-----设置SDES NOTE信息的超时乘数。

double GetNoteTimeoutMultiplier() const
-----返回SDES NOTE信息的超时乘数。

参数的默认值如下:
。使用线程池:yes
。最大允许包大小:1400字节
。接受自己的数据包:no
。接收模式:接受所有的数据包
。解析本地主机名:no
。试用类型:ProbationStore
。会话带宽:10000字节每秒
。控制传输百分比:5%。
。发送者占的控制传输百分比:25%
。最小RTCP时间间隔:5秒
。在开始时使用半个最小时间间隔:yes
。允许时立即发送BYE包:yes
。为BYE包使用发送者报告:yes
。发送者超时乘数:2
。成员超时乘数:5
。发送BYE包后的超时乘数:1
。冲突表中的项的超时乘数:10
。SDES NOTE项的超时乘数:25


3.2.21 RTPSession,头文件:rtpsession.h
对于大多数的基于RTP的应用来说,RTPSession类可能是唯一需要使用的。它完全在内部自动处理RTCP部分,所以使用者可以把精力集中在处理发送和接收实际数据上。
注意:类RTPSession并不意味着是线程安全的,使用者需要使用锁机制来阻止不同线程使用同一个RTPSession对象。   
RTPSession类的接口如下:

RTPSession(RTPTransmitter::TransmissionProtocol proto = RTPTransmitter::IPv4UDPProto)
-----使用由proto给出的传输组件创建一个RTPSession对象。如果proto指出了是使用的用户自定义的传输器则NewUserDefinedTransmitter()成员函数需要给出实现。

int Create(const RTPSessionParams &sessparams, const RTPTransmissionParams *transparams = 0)
-----以会话参数sessparams和传输参数transparams创建一个会话实例,如果transparams为NULL,则将使用传输器需要的默认值。

void Destroy()
-----离开会话但是不发送BYE包。

void BYEDestroy(const RTPTime &maxwaittime, const void *reason, size_t reasonlength)
-----发送一个BYE包并且离开会话,最多等待maxwaittime时间来发送BYE包,如果时间到了,将直接离开会话而不发送BYE包。BYE包中包含长度为reasonlength的离开原因。

bool IsActive()
-----返回会话是否创建。

uint32 t GetLocalSSRC()
-----返回自己的SSRC。

int AddDestination(const RTPAddress &addr)
-----把地址addr加入到目的地址列表中。

int DeleteDestination(const RTPAddress &addr)
-----从目的地址列表中删除addr地址。

void ClearDestinations()
-----清空目的地址列表。

bool SupportsMulticasting()
-----如果支持组播则返回true。

int JoinMulticastGroup(const RTPAddress &addr)
-----加入由addr指出的组播组。

int LeaveMulticastGroup(const RTPAddress &addr)
-----离开由addr指出的组播组。

void LeaveAllMulticastGroups()
-----离开所有的组播组。

int SendPacket(const void *data, size_t len)
-----发送一个含有长度为len的负载数据data的RTP数据包。负载类型,标记位,时间戳增量将使用由成员函数SetDefault给出的值。

int SendPacket(const void *data, size_t len, uint8_t pt, bool mark, uint32_t timestampinc)
-----发送一个含有长度为len的负载数据data的RTP数据包。负载类型为pt,标记位为mark,时间戳增量为timestampinc。

int SendPacketEx(const void *data, size_t len, uint16_t hdrextID, const void *hdrextdata, size_t numhdrextwords)
-----发送一个含有长度为len的负载数据data的RTP数据包。包中将包含一个以hdrextID为标识符,数据为hdrextdata的扩展头。数据的长度由一个32位的字numhdrextwords给出。负载类型t,标记位,时间戳增量将使用由成员函数SetDefault给出的值。

int SendPacketEx(const void *data, size_t len, uint8_t pt, bool mark, uint32_t timestampinc, uint16_t hdrextID, const void *hdrextdata, size_t numhdrextwords)
-----发送一个含有长度为len的负载数据data的RTP数据包。负载类型为pt,标记位为mark,时间戳增量为timestampinc。包中将包含一个以hdrextID为标识符,数据为hdrextdata的扩展头。数据的长度由一个32位的字numhdrextwords给出。

int SetDefaultPayloadType(uint8_t pt)
-----设置RTP包的默认负载类型为pt。

int SetDefaultMark(bool m)
-----设置RTP包的默认标记位为mark。

int SetDefaultTimestampIncrement(uint32_t timestampinc)
-----设置RTP包的默认时间戳增量为timestampinc。

int IncrementTimestamp(uint32_t inc)
-----函数使用inc来增加时间戳,这有时是很有用的。例如:当包只有静默数据则不发送时,该函数应该被调用来增加一个合适的时间戳增量以使得下一个数据包可以在其他主机上载正确的时间被播放。

int IncrementTimestampDefault()
-----该函数使用由SetDefaultTimestampIncrement函数给出的时间戳增量来增加时间戳。这有时是很有用的,例如:当包只有静默数据则不发送时,该函数应该被调用来增加一个合适的时间戳增量以使得下一个数据包可以在其他主机上载正确的时间被播放。

int SetPreTransmissionDelay(const RTPTime &delay)
-----函数允许你通知(RTP)库采集第一个数据包和发送数据包之间的时间延迟。该延迟将在计算用于多媒体同步的RTP时间戳和时钟时间关系时计入考虑。

RTPTransmissionInfo *GetTransmissionInfo()
-----函数将返回一个RTPTransmissionInfo的分类,该类将给出关于传输器的更多附加信息(例如一个本地IP地址的列表等)。当不再需要时使用者需要手动清除该类的实例。

int Poll()
-----如果没有使用线程池,则该函数应该定期调用,以处理到达的数据和在需要时发送RTCP数据包。

int WaitForIncomingData(const RTPTime &delay,bool *dataavailable= 0)
-----等待最多delay时间知道检测到收到了数据。仅仅在没有使用线程池时有效。如果dataavailable非NULL则当数据确实读到了时应该设为true,否则设为false。

int AbortWait()
-----如果上一个函数调用了,则该函数将跳出等待。也是仅仅在没有使用线程池时有效。

RTPTime GetRTCPDelay()
-----返回一个RTCP复合数据包可能需要发送的时间间隔,仅仅在没有使用线程池时有效。

int BeginDataAccess()
-----下面的成员函数(直到EndDataAccess)需要在调用BeginDataAccess和EndDataAccess之间调用,BeginDataAccess保证线程池没有同时访问源表,当调用EndDataAccess之后源表的锁重新释放。

bool GotoFirstSource()
-----从源表中第一个成员开始遍历参与者,如果有成员找到,则返回true,否则返回false。

bool GotoNextSource()
-----将源表中下一个源设置为当前源。如果已经是最后一个源则返回false,否则返回true。

bool GotoPreviousSource()
-----将源表中上一个源设置为当前源。如果已经是第一个源则返回false,否则返回true。

bool GotoFirstSourceWithData()
-----将源表中第一个还没有提取的含有RTPPacket对象的源设置为当前源,如果没有成员找到则返回false,否则返回true。

bool GotoNextSourceWithData()
-----将源表中下一个还没有提取的含有RTPPacket对象的源设置为当前源,如果没有成员找到则返回false,否则返回true。

bool GotoPreviousSourceWithData()
-----将源表中上一个还没有提取的含有RTPPacket对象的源设置为当前源,如果没有成员找到则返回false,否则返回true。

RTPSourceData *GetCurrentSourceInfo()
-----返回当前选定的参与者的RTPSourceData对象。

RTPSourceData *GetSourceInfo(uint32_t ssrc)
-----返回标识符为ssrc的参与者的RTPSourceData对象,如果不存在该项则返回NULL。

RTPPacket *GetNextPacket()
-----从当前参与者的接收包队列中提取下一个包。

int EndDataAccess()
-----见BeginDataAccess。

int SetReceiveMode(RTPTransmitter::ReceiveMode m)
将接收模式设为m,m的取值可以如下:
–    RTPTransmitter::AcceptAll,所有的到达数据一律接收,无论来自哪里。
–    RTPTransmitter::AcceptSome,仅仅接收来自特定源的数据。
–    RTPTransmitter::IgnoreSome,除了指定数据源集的外,其余全部接收。

int AddToIgnoreList(const RTPAddress &addr)
-----将地址addr加入忽略地址列表。

int DeleteFromIgnoreList(const RTPAddress &addr)
-----从忽略地址列表中删除addr。

void ClearIgnoreList()
-----清空忽略地址列表。

int AddToAcceptList(const RTPAddress &addr)
-----将地址addr加入接收地址列表。

int DeleteFromAcceptList(const RTPAddress &addr)
-----将addr从接收地址列表中删除。

void ClearAcceptList()
-----清空接收地址列表。

int SetMaximumPacketSize(size t s)
-----将最大允许包大小设置为s。

int SetSessionBandwidth(double bw)
-----将会话带宽设置为bw,单位为字节/秒。

int SetTimestampUnit(double u)
-----将时间戳单位设置为u。时间戳单位的定义

void SetNameInterval(int count)
-----源表中所有可能的源处理完之后,RTCP包构建器将检查是否有其他的(非CNAME)SDES项需要发送。如果count为0或者小于0,则无动作,如果为正,一个SDES name项将在源表中的源处理完count次之后加入。

void SetEMailInterval(int count)
-----源表中所有可能的源处理完之后,RTCP包构建器将检查是否有其他的(非CNAME)SDES项需要发送。如果count为0或者小于0,则无动作,如果为正,一个SDES e-mail项将在源表中的源处理完count次之后加入。

void SetLocationInterval(int count)
-----源表中所有可能的源处理完之后,RTCP包构建器将检查是否有其他的(非CNAME)SDES项需要发送。如果count为0或者小于0,则无动作,如果为正,一个SDES location项将在源表中的源处理完count次之后加入。

void SetPhoneInterval(int count)
 -----源表中所有可能的源处理完之后,RTCP包构建器将检查是否有其他的(非CNAME)SDES项需要发送。如果count为0或者小于0,则无动作,如果为正,一个SDES phone项将在源表中的源处理完count次之后加入。

void SetToolInterval(int count)
-----源表中所有可能的源处理完之后,RTCP包构建器将检查是否有其他的(非CNAME)SDES项需要发送。如果count为0或者小于0,则无动作,如果为正,一个SDES tool项将在源表中的源处理完count次之后加入。

void SetNoteInterval(int count)
-----源表中所有可能的源处理完之后,RTCP包构建器将检查是否有其他的(非CNAME)SDES项需要发送。如果count为0或者小于0,则无动作,如果为正,一个SDES note项将在源表中的源处理完count次之后加入。

int SetLocalName(const void *s, size_t len)
-----将本地参与者的SDES name项设置为长度为len的s值。

int SetLocalEMail(const void *s, size_t len)
-----将本地参与者的SDES e-mail项设置为长度为len的s值。

int SetLocalLocation(const void *s, size_t len)
-----将本地参与者的SDES location项设置为长度为len的s值。

int SetLocalPhone(const void *s, size_t len)
-----将本地参与者的SDES phone项设置为长度为len的s值。

int SetLocalTool(const void *s, size_t len)
-----将本地参与者的SDES tool项设置为长度为len的s值。

int SetLocalNote(const void *s, size_t len)
-----将本地参与者的SDES note项设置为长度为len的s值。

RTPTransmitter *NewUserDefinedTransmitter()
该函数返回的RTPTransmitter对象将用来发送和接收RTP和RTCP数据包。注意:当会话销毁时,RTPTransmitter对象也将被delete调用销毁。
通过从RTPSession类继承自己的类,并且重载下面的函数,可用来检测特定的事件。

void OnRTPPacket(RTPPacket *pack, const RTPTime &receivetime, const RTPAddress *senderaddress)
-----当要处理一个到达的RTP数据包时,将会调用该函数。

void OnRTCPCompoundPacket(RTCPCompoundPacket *pack, const RTPTime &receivetime, const RTPAddress *senderaddress)
-----当要处理一个到达的RTCP数据包时,将会调用该函数。

void OnSSRCCollision(RTPSourceData *srcdat, const RTPAddress *senderaddress, bool isrtp)
-----将在检测到一个SSRC冲突时调用。srcdat对象是表中的当前值,senderaddress是与地址发生冲突的地址,【译注:不会翻译了⊙﹏⊙b汗。原文:the address senderaddress is the one that collided with one of the addresses and isrtp indicates against which address of srcdat the check failed.】

void OnCNAMECollision(RTPSourceData *srcdat, const RTPAddress *senderaddress,const uint8_t *cname, size_t cnamelength)
-----当接收到一个与当前源srcdat不同的CNAME时被调用。

void OnNewSource(RTPSourceData *srcdat)
-----当一个新的srcdat项加入到源表中时被调用。

void OnRemoveSource(RTPSourceData *srcdat)
-----当srcdat项要从源表中清除时被调用。

void OnTimeout(RTPSourceData *srcdat)
-----当参与者srcdat超时时被调用。

void OnBYETimeout(RTPSourceData *srcdat)
-----当参与者srcdat已经发送了一个BYE包之后调用。

void OnBYEPacket(RTPSourceData *srcdat)
-----当源srcdat的一个BYE包已经处理之后调用。

void OnAPPPacket(RTCPAPPPacket *apppacket, const RTPTime &receivetime, const RTPAddress *senderaddress)
-----当在receivetime接收到一个来自senderaddress地址的RTCP APP包apppacket时调用。

void OnUnknownPacketType(RTCPPacket *rtcppack, const RTPTime &receivetime, const RTPAddress *senderaddress)
-----当检测到一个未知的RTCP包类型时调用。

void OnUnknownPacketFormat(RTCPPacket *rtcppack, const RTPTime &receivetime, const RTPAddress *senderaddress)
-----当检测到一个已知包类型的未知的包格式时调用。

void OnNoteTimeout(RTPSourceData *srcdat)
-----当srcdat的SDES NOTE项超时时调用。

void OnSendRTCPCompoundPacket(RTCPCompoundPacket *pack)
-----当一个RTCP复合数据包发送完时调用,检查即将发送的RTCP数据时有用。

void OnPollThreadError(int errcode)
-----当在线程池中检测到errcode时调用。

void OnPollThreadStep()
-----每次线程池循环时调用,这发生在每次检测到有数据到达或者要发送RTCP复合数据包时。


4 示例代码

#include "rtpsession.h"  
#include "rtpsessionparams.h"  
#include "rtpudpv4transmitter.h"   
#include "rtpipv4address.h"  
#include "rtptimeutilities.h"  
#include "rtppacket.h"  
#include <stdlib.h>  
#include <iostream>  
   
using namespace jrtplib;  
  
int main(void)   
{  
#ifdef WIN32  
       WSADATA dat;  
       WSAStartup(MAKEWORD(2,2),&dat);  
#endif // WIN32  
       RTPSession session;  
       RTPSessionParams sessionparams;  
       sessionparams.SetOwnTimestampUnit(1.0/8000.0);  
       RTPUDPv4TransmissionParams transparams;  
       transparams.SetPortbase(8000);  
       int status = session.Create(sessionparams,&transparams);  
  
       if (status < 0)  
       {  
              std::cerr << RTPGetErrorString(status) << std::endl;  
              exit(-1);  
       }  
  
       uint8_t localip[]={127,0,0,1};  
       RTPIPv4Address addr(localip,9000);  
       status = session.AddDestination(addr);  
  
       if (status < 0)  
       {  
              std::cerr << RTPGetErrorString(status) << std::endl;  
              exit(-1);  
       }  

       session.SetDefaultPayloadType(96);  
       session.SetDefaultMark(false);  
       session.SetDefaultTimestampIncrement(160);       
       uint8_t silencebuffer[160];  
  
       for (int i = 0 ; i < 160 ; i++)  
              silencebuffer[i] = 128;  
  
       RTPTime delay(0.020);  
       RTPTime starttime = RTPTime::CurrentTime();  
       bool done = false;  
  
       while (!done)  
       {  
              status = session.SendPacket(silencebuffer,160);  
  
              if (status < 0)  
              {  
                     std::cerr << RTPGetErrorString(status) << std::endl;  
                     exit(-1);  
              }  
  
              session.BeginDataAccess();  
  
              if (session.GotoFirstSource())  
              {  
                     do  
                     {  
                            RTPPacket *packet;  
  
                            while ((packet = session.GetNextPacket()) != 0)  
                            {  
                                   std::cout << "Got packet with "  
                                             << "extended sequence number "   
                                             << packet->GetExtendedSequenceNumber()   
                                             << " from SSRC " << packet->GetSSRC()   
                                             << std::endl;  
                                   session.DeletePacket(packet);//此处使用成员函数清理  
                             }  
                     } while (session.GotoNextSource());  
              }  
  
              session.EndDataAccess();  
              RTPTime::Wait(delay);  
              RTPTime t = RTPTime::CurrentTime();  
              t -= starttime;  
  
              if (t > RTPTime(60.0))  
                     done = true;  
       }  
 
       delay = RTPTime(10.0);  
       session.BYEDestroy(delay,"Time's up",9);  
  
#ifdef WIN32  
        WSACleanup();  
#endif // WIN32  
  
       return 0;  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值