基于延迟确定帧率

时间:2010-09-06 05:37:15

标签: winapi

在我的应用程序的每一帧上,我可以调用timeGetTime()来检索当前经过的毫秒数,并从前一帧中减去timeGetTime()的值以获得两帧之间的时间。但是,要获得应用程序的帧速率,我必须使用以下公式:fps = 1000 / delay(ms)。因此,例如,如果延迟是16毫秒,则1000/16 = 62.5(在存储器中存储为62)。然后让我们说延迟变为17毫秒,然后是1000/17 = 58,依此类推:

十分之千= 100
十一分之一千= 90
12分之1000= 83
十三分之千= 76
14分之1000= 71
十五分之一千= 66
十六分之一千= 62
1000年至1017年58 =
1000至1018年= 55
1000年至1019年= 52
1000/20 = 50

正如您可以看到延迟的连续实例,帧速率存在相当大的差距。那么像FRAPS这样的程序如何确定这些值之间的应用程序的帧速率(例如51,53,54,56,57等)?

4 个答案:

答案 0 :(得分:2)

为什么你会在每一帧都这样做?你会发现如果你在每个第十个帧上进行,然后将该值除以10,你就可以轻松地在你看到的空白中获得帧速率。你也可能会发现你的帧率更高,因为你在循环中做的管理工作较少: - )

换句话说,像(伪代码):

chkpnt = 10
cntr = chkpnt
baseTime = now()
do lots of times:
    display next frame
    cntr--
    if cntr == 0:
        cntr = chkpnt
        newTime = now()
        display "framerate = " (newTime - baseTime) / chkpnt
        baseTime = newTime

答案 1 :(得分:2)

除了@Marko建议使用更好的计时器之外,平滑变化和更好地近似评估帧率的关键技巧是使用移动平均值 - 不要只考虑你观察到的最新延迟,考虑最后五个的平均值。您可以将后者计算为浮点数,以获得更多可能的帧速率值(当然,您仍然可以舍入到最接近的整数)。

对于最小化计算,考虑最后5个延迟的“fifo队列”(伪代码)......:

array = [16, 16, 16, 16, 16]   # initial estimate
totdelay = 80
while not Done:
    newest = latestDelay()
    oldest = array.pop(0)
    array.append(newest)
    totdelay += (newest - oldest)
    estimatedFramerate = 200 / totdelay
    ...

答案 2 :(得分:0)

不确定,但也许你需要更好的(高分辨率)计时器。检查QueryPerformanceTimer

答案 3 :(得分:0)

而不是移动平均线(如@Alex建议的那样)我建议使用低通滤波器。它更容易计算,并且可以调整为具有任意数量的值平滑,而不会改变性能或内存使用。简而言之(在JavaScript中演示):

var smoothing = 10; // The larger this value, the more smoothing
var fps = 30;       // some likely starting value
var lastUpdate = new Date;
function onFrameUpdate(){
  var now = new Date;
  var frameTime = now - lastUpdate;
  var frameFPS  = 1/frameTime;
  // Here's the magic
  fps += (frameFPS - fps) / smoothing;
  lastUpdate = now;
}

有关此功能的漂亮演示,请参阅此处的实时示例:
http://phrogz.net/JS/framerate-independent-low-pass-filter.html

相关问题