我有一组30FPS的JPG图像流,我想通过丢弃数据包来降低fps。
我可以通过丢弃每个第二个包来实现15 FPS,如下所示:if(frameCount % 2) continue;
使用if(frameCount % 3) continue;
也可以实现20 FPS。
我正在努力寻找一种适用于所有FPS的条件。
例如,5FPS应该如何处理?理论上,我需要丢弃25fps,但如何管理它,以便帧之间的持续时间大致相同?
我有一组30FPS的JPG图像流,我想通过丢弃数据包来降低fps。
我可以通过丢弃每个第二个包来实现15 FPS,如下所示:if(frameCount % 2) continue;
使用if(frameCount % 3) continue;
也可以实现20 FPS。
我正在努力寻找一种适用于所有FPS的条件。
例如,5FPS应该如何处理?理论上,我需要丢弃25fps,但如何管理它,以便帧之间的持续时间大致相同?
基本上,如果您想要丢弃帧以便每30个输入输出15个,则每个输入帧输出0.5个。同样地,对于30->20的丢弃,每个输入帧输出0.67个。
因此,作为一个简单的解决方案,您可以保持预期输出的分数帧数的计数,并在该计数达到或超过1时输出一帧。
作为一个大致的草图,只需使用整数循环代替帧:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
double sum = 0;
double rate = argc >= 2 ? atoi(argv[1]) / 30.0 : 0.5;
for (int i = 0; i < 30; i++) {
sum += rate;
if (sum >= 1) {
sum -= 1;
/* pretend we output this frame */
printf("%d\n", i);
}
}
}
运行 foo 20
或类似命令,以便在输出的30个中得到20个。
或者大约是30个中的20个。由于舍入问题和2/3不能准确表示为二进制浮点值的事实,这并不完全准确。您可以修改它以使用有理数进行计算,因此可以准确呈现20/30。
当然,任何不能将30整除的分母都会产生抖动的输出。
对于 5 FPS,您可以再次使用模运算,因为 5 恰好能够整除 30。只需将测试的意义从丢弃小数改为接受小数即可,例如 if (framenumber % 5 == 0) { accept frame }
timestamp = get_time(); period = 1/required_fps; while (...) { if (get_time() - timestamp < period) continue; timestamp = get_time(); /* do stuff */ }
- KamilCuk