最近写一个程序将接收到的RTP流送到DirectShow中进行播放,结果发现播放的效果断断续续的,于是,在程序里加了代码,打印出每次收到一个RTP包距上一个RTP包的间隔。
我发送的RTP包应该是20ms一个,可是在接收的代码中,打印出来的间隔却大部分是15、16ms,偶尔也有30几ms的,这就奇怪了,如果有延时,30几ms还说得过去,可是15、16ms的怎么解释?是Socket底层缓存了一些包再报给我,还是RTP发送端不是严格按照20ms来发送的?于是用Wireshark抓包,结果发现RTP包间隔的确为20ms左右,那问题就出在RTP的接收端了。
这时我怀疑我的计时代码有问题,因为Windows有好多提供计时功能的函数,而我此时用的是GetTickCount,它返回系统启动的毫秒数。在网上查了一下,发现大家对这个函数还是比较认可的,不过,还有一个更为精确的API:QueryPerformanceCounter;这个函数返回的是高精度的硬件时钟计数,与此函数一起使用的还需要QueryPerformanceFrequency来取得时钟频率。
于是用新的API来偿试一下:
所以,以后如果想得到十分精确的时间的话,可以使用这个函数试试。
我发送的RTP包应该是20ms一个,可是在接收的代码中,打印出来的间隔却大部分是15、16ms,偶尔也有30几ms的,这就奇怪了,如果有延时,30几ms还说得过去,可是15、16ms的怎么解释?是Socket底层缓存了一些包再报给我,还是RTP发送端不是严格按照20ms来发送的?于是用Wireshark抓包,结果发现RTP包间隔的确为20ms左右,那问题就出在RTP的接收端了。
这时我怀疑我的计时代码有问题,因为Windows有好多提供计时功能的函数,而我此时用的是GetTickCount,它返回系统启动的毫秒数。在网上查了一下,发现大家对这个函数还是比较认可的,不过,还有一个更为精确的API:QueryPerformanceCounter;这个函数返回的是高精度的硬件时钟计数,与此函数一起使用的还需要QueryPerformanceFrequency来取得时钟频率。
于是用新的API来偿试一下:
//首先取得时钟周期
//m_cpuFreq为LARGE_INTEGER类型,可以到MSDN上查看这个类型的定义
QueryPerformanceFrequency(&m_cpuFreq);
//
//在接收数据的循环中加入如下代码:
LARGE_INTEGER current_time; //取得当前计数
QueryPerformanceCounter(¤t_time);
static LARGE_INTEGER last_time = current_time; //记录上一次的计数,初始为当前计数
//如果要得到毫秒级的时间数据,记得要将计数值乘1000
TRACE("RTP interval:%d ms\n", (current_time.QuadPart-last_time.QuadPart)*1000/m_cpuFreq.QuadPart);
last_time = current_time;
这次显示得RTP包间隔就顺利回到19-21毫秒之间了。//m_cpuFreq为LARGE_INTEGER类型,可以到MSDN上查看这个类型的定义
QueryPerformanceFrequency(&m_cpuFreq);
//
//在接收数据的循环中加入如下代码:
LARGE_INTEGER current_time; //取得当前计数
QueryPerformanceCounter(¤t_time);
static LARGE_INTEGER last_time = current_time; //记录上一次的计数,初始为当前计数
//如果要得到毫秒级的时间数据,记得要将计数值乘1000
TRACE("RTP interval:%d ms\n", (current_time.QuadPart-last_time.QuadPart)*1000/m_cpuFreq.QuadPart);
last_time = current_time;
所以,以后如果想得到十分精确的时间的话,可以使用这个函数试试。