TensorFlow.js 中的 nextFrame() 方法到底做了什么?

What exactly does the nextFrame() method in TensorFlow.js do?

我正在尝试使用 TensorFlow.js 处理实时视频源。

我使用的是基于我见过的其他示例的类似以下内容:

while(true) {
  const results = await model.classify(videoElem);
  console.log(results);
  await tf.nextFrame();
}

我正在尝试了解 tf.nextFrame() 的确切作用。

我在想,当我 运行 model.classify(videoElem) 时,它会从视频流中提取一个帧并使用模型对其进行处理。

我想主要有两种情况:

  1. 视频生成帧的速度比 JavaScript 对它们进行分类要快。
  2. JavaScript 处理帧的速度比生成帧的速度快。

tf.nextFrame() 方法是否可以处理场景 #2,从而使单个帧永远不会被处理两次?

文档是这样描述的:

Returns a promise that resolve when a requestAnimationFrame has completed.

This is simply a sugar method so that users can do the following: await tf.nextFrame();

我无法理解这意味着什么。任何人都可以确认我所描述的是否是 tf.nextFrame() 所做的?如果我的解释有误,那么 tf.nextFrame() 究竟做了什么?

在重新阅读文档提供的定义后,我意识到 requestAnimationFrame 是一个我不熟悉的 browser API

The window.requestAnimationFrame() method tells the browser that you wish to perform an animation and requests that the browser calls a specified function to update an animation before the next repaint. The method takes a callback as an argument to be invoked before the repaint.

如果我的解释正确的话,似乎 window.requestAnimationFrame() returns 下一次可用的重绘。因此,这应该会停止我的问题中描述的场景 #2,其中单个帧被处理两次。

requestAnimationFrame() 函数提供了一个进入 javascript 事件循环的挂钩,允许在下一次渲染之前执行回调函数。这可以用作在将动画绘制到屏幕之前更新动画的高效方式,而不会引入强制回流的风险。

然而,在这种情况下,rAF 最重要的细节是在回调函数执行后,主线程的控制在任何其他代码执行之前进入浏览器渲染进程。这减轻了阻塞,阻塞可能导致浏览器 UI 卡顿甚至冻结。

在示例中,等待对 tf.nextFrame() 的调用允许 UI 在执行循环的下一次迭代之前每次更新。这可能确实具有防止给定第二种情况的效果,假设允许浏览器呈现其下一帧更新输入 videoElem。但是,即使输入不依赖于屏幕的视觉元素,此技术也可用于防止在长时间 运行 操作期间阻塞 UI,但需要注意的是,这可能会限制循环性能到主机显示器的刷新率。