mik*_*vis 5 html canvas webgl html5-video
我对能够将glfx.js 中的过滤器应用于实时视频很感兴趣。我已成功按我的意愿导入和处理帧,但该方法效率低下。在我的页面设置中,我这样做:
var fbCanvas = document.getElementById('framebuffer');
var fb = fbCanvas.getContext('2d');
var video = document.getElementById('video');
var output = fx.canvas();
Run Code Online (Sandbox Code Playgroud)
然后,在 25hz(视频的播放速率),我这样做:
fb.drawImage(video, 0, 0);
var frame = output.texture(fbCanvas);
output.draw(frame).hueSaturation(-0.5, 0).update();
Run Code Online (Sandbox Code Playgroud)
但我希望能够做到这一点:
var frame = output.texture(video);
output.draw(frame).hueSaturation(-0.5, 0).update();
Run Code Online (Sandbox Code Playgroud)
对 output.texture 的调用只是 gl.texImage2D 的一个包装器,它似乎只接受图像或画布——而不是视频元素。
我的问题是,通过对隐藏画布执行额外的 drawImage 对性能有多大影响?将视频帧放入 GL 纹理以便我可以实时在它们上运行 GL 着色器的最快方法是什么?
谢谢。
小智 0
桌面 openGL 的实时视频处理(视频输入/输出,而不只是录制或播放)通常是多线程完成的,但这需要支持上下文共享列表(以便单独线程中的单独上下文可以引用相同的资源句柄空间。) OpenGL ES 支持上下文共享列表,但 WebGL 尚不支持,尽管我认为 WebCL 也支持它。因此,尽管支持 WebWorkers,但 WebGL 的使用似乎实际上仅限于单个线程。
但是,当(不是如果)WebGL 支持上下文共享列表时,我认为最快的方法是将辅助线程中的纹理准备与共享列表上下文隔离,然后在主合成线程中对其运行 GL 着色器。
在桌面 openGL 中,完成此操作的一种方法是使用自己的上下文声明屏幕外 1x1 窗口(画布元素),并与执行准备工作的唯一线程关联。这些上下文与发生最终合成的主线程共享。
当(我认为,而不是如果)WebGL 支持共享列表时,请在 getContext() 上查找允许与另一个上下文共享列表的备用签名。
如果您尝试进行这种单线程视频处理,那么您就会遇到“两个时钟”问题。(输入视频合同,输出视频合同。)您必须通过 FIFO/缓存和多线程将处理延迟与这些硬时钟隔离,否则您将在输出上出现故障,或错过输入帧。FIFO/缓存的必要性会引入视频处理延迟,如果您绕过音频,则需要延迟音频以匹配。您可以使用在记录和播放之间有偏移的循环环形缓冲区轻松做到这一点。