首页 > 解决方案 > 使用动态 FPS 在游戏引擎中渲染视频

问题描述

我正在尝试在我的游戏引擎中渲染预先导出的视频,并在尝试安排帧时偶然发现了问题。即,虽然视频以固定 FPS 导出,但引擎具有动态帧速率(可能高于或低于视频)。当尝试选择在当前引擎帧中渲染哪个视频帧时,我的算法不断遇到边缘情况,这会破坏视频的速度或视频帧的分布。

在这一点上,我知道可能没有一种算法可以在所有情况下都完美运行,但是在运行时可能会发生三种情况,算法应该涵盖以下三种情况:

  1. 引擎中的任意稳定帧速率,误差范围约为 5%。(例如,如果平均帧时间为 33.333 毫秒,则所有帧持续时间都将在 31.6666 毫秒 - 35 毫秒范围内。)
  2. 任意半稳定帧速率,<5% 的帧的持续时间超出误差范围。
  3. 稳定帧率,可以在视频播放期间更改为不同的稳定帧率。

在这 3 种情况下,以下情况应该成立:

  1. 在任意时间段内观察时,视频渲染的速度与视频以其原始 FPS 渲染的速度相同。
  2. 当在任意时间段内观察时,引擎有一个稳定的帧率,帧分布应该是平衡的。

考虑到这一切,我尝试了 2 种解决方案,即使采用一些启发式方法也没有产生好的结果。

  1. 一个非常幼稚的解决方案,其中当前帧的增量时间乘以帧速率,结果被四舍五入,视频播放提前那么多帧。虽然此解决方案在某些帧速率下完美运行,但在其他帧速率下速度差异太大。例如,如果视频为 60FPS,引擎渲染为 30FPS,那么引擎每帧都会将视频播放提前 2 帧,这是完美的。但是,即使在 ~39 FPS 时,由于舍入效应,每个引擎帧中的播放仍然只会提前 2 帧,从而导致视频速度下降。
  2. 基于时间线的解决方案,我们跟踪所有先前引擎帧的累积持续时间。将其与当前引擎帧的持续时间相加,然后将其四舍五入到视频帧持续时间的最接近的倍数,我们得到应该在引擎中渲染的近似视频帧。该解决方案完美地平衡了视频速度,但在许多边缘情况下,帧分布变得非常不平衡,从而导致视频卡顿。使用与之前相同的示例,视频为 60FPS,引擎为 30FPS,存在一种边缘情况,即持续时间约为 41.66666 毫秒的一帧将导致视频帧提前为 (1, 3, 1, 3, 1, 3....) 而不是 (2, 2, 2, 2, 2, 2...)。

我想我的问题是:已知算法和启发式算法是否存在问题,可以简化为这个问题?如果没有,是否有一个很好的启发式方法可以在我上面描述的 3 种情况下产生更好的结果?

标签: algorithmvideotimeframeframe-rate

解决方案


我认为您的基于时间线的算法非常接近。我认为你只需要在数学上定义你的欲望。

对于每个帧选择,我们可以考虑两种错误。设w为所选帧显示的挂钟时间与根据视频帧速率显示的时间之间的差。令d为所选帧的显示时间与先前显示的帧之间的差值误差。

定义这些误差的相对权重AB,然后选择最小化Aw 2 + Bd 2的框架


推荐阅读