组件:c语言2幂采样平均帧率统计

背景介绍

帧率统计常用于游戏限帧,视频音画同步等地方。是时间类组件的重要部分。

基本思路

1.2幂长度的环形缓存区能便于计算。
2.每帧采样并计算帧间间隔填入缓存区。
3.每帧都利用统计的帧缓冲计算平均帧率。

使用这种方式,每一帧都能得到正确的平均帧率,仅计算进出缓冲的时间间隔效率高。

1.最终使用案例

https://bitbucket.org/mm_longcheng/mm-core/src/dev/mm/src/core/mmFrameStats.h

static void MyTestFrameStats(void)
{
    int i;

    struct mmFrameStats stats;

    mmFrameStats_Init(&stats);

    // 可选,设置初始帧率
    mmFrameStats_SetAverage(&stats, 60.0);

    for (i = 0; i < 60; i++)
    {
        // 休眠一段时间
        mmMSleep(16);

        // 更新帧率统计
        mmFrameStats_Update(&stats);
    }

    mmFrameStats_Destroy(&stats);
}

2.前置数据结构组件

// 每秒的毫秒数
#define MM_USEC_PER_SEC 1000000

// 秒表,用来计时
struct mmClock;

3.主要数据结构

enum
{
    // [0x00, 0xFF] 0x40 = 64 . 
    // Very close to the commonly used 60 frame rate.
    mmFrameStatsCacheSize = 0x40,
    mmFrameStatsCacheMask = mmFrameStatsCacheSize - 1,
    mmFrameStatsCacheTime = mmFrameStatsCacheSize * MM_USEC_PER_SEC,
};

// Frame rate statistics based on circular queues
struct mmFrameStats
{
    // time clock.
    struct mmClock clock;

    // frame number, reset api can assign 0.
    mmUInt64_t number;

    // average fps.
    double average;

    // current frame interval.
    double interval;

    // frame interval total.
    double total;

    // frame interval cache.
    double cache[mmFrameStatsCacheSize];

    // cache index.
    mmUInt8_t index;
};

4.主要处理函数

MM_EXPORT_DLL void mmFrameStats_UpdateInterval(struct mmFrameStats* p, double interval)
{
    // cache the last frame interval.
    p->interval = interval;

    // accumulate the frame number.
    p->number++;

    // sub the index cache interval.
    p->total -= p->cache[p->index];
    // insert to back current interval.
    p->cache[p->index] = interval;
    // add the current interval.
    p->total += interval;

    // index++
    p->index++;
    // index %= CacheSize
    p->index &= mmFrameStatsCacheMask;

    // fps value update.
    // if total == 0.0 the fps_avge will be +inf, but it's correct.
    p->average = ((double)mmFrameStatsCacheTime) / p->total;
}

5.原理

更新时间时,我们仅减掉出队的间隔时间,加上进队的间隔时间,然后求平均,能避免遍历反复累加全体时间缓冲。利用2幂的特性,我们使用位操作可以快速回环索引,避免求余操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值