我正在尝试为数字电视创建低抖动组播源。有问题的程序应缓冲输入,根据流中的PCR值计算预期时间,然后以相对精确的间隔发送数据包。但是,这不是在RTOS上运行,因此预计会出现一些时序差异。
这是基本代码(相关变量已初始化,我在这里省略了代码):
while (!sendstop) {
//snip
//put 7 MPEG packets in one UDP packet buffer "outpkt"
//snip
waittime = //calculate from PCR values - value is in microseconds
//waittime is in the order of 2000 -> 2ms
sleeptime=curtime;
sleeptime.tv_nsec += waittime * 1000L;
sleeptime.tv_sec += sleeptime.tv_nsec / 1000000000;
sleeptime.tv_nsec %= 1000000000;
while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &sleeptime, NULL) && errno == EINTR) {
printf("I");
}
sendto(sck,outpkt,1316,0,res->ai_addr,res->ai_addrlen); //send the packet
clock_gettime(CLOCK_MONOTONIC,&curtime);
}
但是,这会导致发送速度太慢(因为某些处理也需要时间),因此缓冲区会填满。所以,我认为我应该在" sleeptime"之间找到区别。 (应该是的时间)和" curtime" (实际时间)并从未来减去#34;等待时间"。这几乎可以工作,但现在有点太快了,现在我得到一个空的缓冲区。
我的下一个想法是在减去它之前将差值乘以某个值,就像这样(在#34之上;而......"):
difn=curtime.tv_nsec-ostime.tv_nsec;
if (difn<0) difn+=1000000000;
sleeptime.tv_nsec = sleeptime.tv_nsec-(difn*difnc)/1000; //difnc - adjustment
if (sleeptime.tv_nsec<0) {
sleeptime.tv_nsec+=1000000000;
sleeptime.tv_sec--;
}
然而,不同的difnc值在一天中的不同时间,服务器等工作。需要根据程序的操作进行某种自动调整。我能想到的最好的方法是每当缓冲区满或空时递增/递减它,然而,这会导致'#34;太快&#34; - &#34;太慢&#34;。我试着调整&#34; difnc&#34;值取决于缓冲区的满/空是多少,但这只是导致&#34;慢速&#34; - &#34;快速&#34;周期。
如何正确地自动导出&#34; difnc&#34;值或是否有一些其他方法可以获得更精确的时间,而不仅仅是&#34; clock_nanosleep&#34;功能但没有忙等待(服务器有其他事情要做)?