注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Mihooke's blog

IT之恋

 
 
 

日志

 
 

Jrtplib源码分析(5)---源码文件功能(中)(二)  

2014-11-24 21:31:47|  分类: jrtplib |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

继续分析,rtcppacketbuilder.cpp则是对整个RTCP包进行构建的源码,里面的几个成员函数很庞大。一个很重要的思想是:所有RTCP复合包(上面我们讲了,发送包必须是复合包)是被周期性地发送的,这个周期称为interval(在.h头文件中有定义,如果机器Audio频率是8000Hz,那么interval就是1/8000),在这个interval时间间隔内构造nextpacket(利用RTPPacketBuilder实例和RTPSources实例尅自动生成下一个要发送的复合包,当然了,也提供包含CNAME结点的发送包),然后等待发送。


rtcpscheduler.cpp是对RTCP包的调度源码,期间用到了一些类型的宏定义(在rtptypes.h中)和随机数(在rtprandom.h中),为了良好的跨平台兼容性,作者可真是煞费苦心啊!特别是在rtprandom.cpp中,好多系统在随机数生成上锁调用的函数是不一样的,而且,为了实现最新版更好用的随机数生成函数rand_s(只可以用在Windows Server 2003XP以后的系统),从char8位)、short16位)到int32位)的系统兼容都有考虑;和UNIX系统上的随机数生成,UNIX-LIKE系统要用到getpid()time()clock()等函数才可以生成较好的随机数,比如在32位系统下生成随机数:

x = (uint32_t)(65536.0*((double)rand_r(&state))/((double)RAND_MAX+1.0));

再比如,得到一个double类型的随机数:

double x = ((double)rand_r(&state))/((double)RAND_MAX+1.0);

调度包还用到了NTP协议(Network Time Protocol),它提供准确时间,但是首先要有准确的时间来源,它可以使计算机对其服务器做同步化,在这里作者以格林威治时间开始since 00:00:00 UTC, January 1, 1970

时间类RTPTimesecond+microsecond,为了方便比较时间,获取准确时间,还重载了运算符><>=<=,下面是<的重载运算:

inline bool RTPTime::operator<(const RTPTime &t) const

{

if (sec < t.sec)

return true;

if (sec > t.sec)

return false;

if (microsec < t.microsec)

return true;

return false;

}

回到我们的rtcpscheduler中,类RTCPScheduler是整个源码中的重点,它决定了什么时候发送复合包,构造函数利用源表RTPSources决定什么时候复合包被调度。

rtpaddress.h头文件枚举了IP地址的类型,RTPAddress是一个用于识别目的地址和多播的类,并对IP地址进程check

 

rtpconllisionlist.h,顾名思义,它的功能应该是检测地址冲突的,类RTPCollisionList展现了一系列在SSRC中检测到的冲突地址。这几个成员函数比较有意思:Clear清除地址列表、UpdateAddress更新输入的地址以表明该地址是被检测是冲突的、HasAddress这是个地址判断函数判断该地址是否在列表中、Timeout这个函数是在指定的时间延迟内暂停没有更新的时间。

 

rtpdebug.h,这个源文件的主要功能就是重载了newnew[]deletedelete[],并定义了一个内存追踪的类MemoryTracker,还有一个保存分配内存的结构体MemoryInfo

struct MemoryInfo

{

void *ptr;//分配的内存指针

size_t size;

int lineno;//行号

char *filename;

MemoryInfo *next;

};

成员函数donew是分配内存的,但是是用malloc分配,对应地,dodelete是释放内的,用的是free

 

rtperrors.cpp则是定义了一下会出错的情况,整个有可能出错的情况封装在一个结构体数组中。

 

rtphashtable.h是映射的hash表,在这里用到了类模板:

template<class Element,class GetIndex,int hashsize>

RTPHashTable类继承于RTPMemoryObject类,私有成员里嵌套了个HashElement类,里面保存了hash元素,还定义了几个实例对象:

HashElement *table[hashsize];//指向hash表的指针数组

HashElement *firsthashelem,*lasthashelem;//表头元素指针、表尾元素指针

HashElement *curhashelem;//当前hash元素指针

然后下面就是对各个RTPHashTable类成员函数的定义了,不过我好奇的是,为什么每个成员函数定义为inline的呢?其中一些成员函数功能简单,代码简短定义为inline我还理解,像添加hash元素的成员函数AddElement代码就不那么简单了。有知道的朋友可相互讨论下~

 

rtpsource.h把来源的信息保存下来,信息包括与来源相参与的表信息,成员函数处理RTPRTCP数据,期间会用NULL来用于标识来自我们session区的包,类RTPSources还提供了一些可以捕获一些诸如创建新的SSRC,发生SSRC冲突等的事件。成员函数还包括一些处理各种类型的包以及来源数据的函数,一些出现超时的操作,一些出现冲突操作的函数。.cpp源码文件则是对这一大坨成员函数的详细定义,如果要想分析这些函数,就必须要对RTP协议的原理搞清楚,协议时怎样处理各种来源信息和包的。

rtpsourcedata.h是对发送方和接收方报告信息的实现,分别别定义了两个相关的类,还有一个描述RTP来源状态的类以及一个描述该类来源表入口的类。

  评论这张
 
阅读(304)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017