【问题标题】:How to get video frames into GL Textures in WebGL?如何将视频帧放入 WebGL 中的 GL 纹理?
【发布时间】:2011-10-15 15:33:29
【问题描述】:

我有兴趣将来自glfx.js 的过滤器应用于实时视频。我已经成功地按照我的意愿导入和处理帧,但是这种方法效率低下。在我的页面设置中,我这样做:

var fbCanvas = document.getElementById('framebuffer');
var fb = fbCanvas.getContext('2d');
var video = document.getElementById('video');
var output = fx.canvas();

然后,以 25hz(视频的播放速率),我这样做:

fb.drawImage(video, 0, 0);
var frame = output.texture(fbCanvas);
output.draw(frame).hueSaturation(-0.5, 0).update();

但我希望能够做到这一点:

var frame = output.texture(video);
output.draw(frame).hueSaturation(-0.5, 0).update();

对 output.texture 的调用只是 gl.texImage2D 的一个包装器,它似乎只接受图像或画布——而不是视频元素。

我的问题是,通过对隐藏的画布执行额外的 drawImage,我对性能有多大影响?将视频帧放入 GL 纹理以便我可以在它们上实时运行 GL 着色器的最快方法是什么?

谢谢。

【问题讨论】:

标签: html canvas html5-video webgl


【解决方案1】:

使用桌面 openGL 进行实时视频处理(视频输入/输出,而不是仅录制或播放)通常是多线程完成的,但这需要支持上下文共享列表(以便单独线程中的单独上下文可以引用相同的资源句柄空间。)OpenGL ES 中支持上下文共享列表,但 WebGL(还)不支持,尽管我认为它在 WebCL 中受支持。因此,尽管支持 WebWorkers,但 WebGL 的使用似乎实际上仅限于单个线程。

但是,当(不是如果)WebGL 支持上下文共享列表时,我相信最快的方法是在具有共享列表的上下文的辅助线程中隔离纹理的准备,然后在主线程中对它们运行 GL 着色器堆肥线。

在桌面 openGL 中,完成此操作的一种方法是通过自己的上下文声明屏幕外 1x1 窗口(画布元素),并与执行准备的唯一线程相关联。这些上下文与发生最终合成的主线程共享列表。

当(我认为,不是如果)WebGL 支持共享列表时,请在 getContext() 上寻找允许与另一个上下文共享列表的替代签名。

如果您尝试单线程执行这种视频处理,您将遇到“两个时钟”问题。 (输入视频合同,输出视频合同。)您必须通过 FIFO/缓存和多线程将处理延迟与这些硬时钟隔离,否则您将在输出上出现故障或丢失输入帧。 FIFO/缓存的必要性引入了视频处理延迟,如果您绕过音频,则需要延迟音频以匹配。您可以使用在记录和播放之间有偏移的循环循环缓冲区轻松做到这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-14
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    • 2014-12-05
    • 1970-01-01
    • 2020-09-17
    • 1970-01-01
    相关资源
    最近更新 更多