Как получить видеокадры в GL Textures в WebGL? - PullRequest
4 голосов
/ 29 июля 2011

Меня интересует возможность применения фильтров из glfx.js к живому видео. Мне удалось импортировать и обработать кадры, как я хочу, но метод неэффективен. В моей настройке страницы я делаю это:

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

И затем, на частоте 25 Гц (скорость воспроизведения видео), я делаю это:

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 Textures, чтобы я мог запускать на них шейдеры GL в режиме реального времени?

Спасибо.

1 Ответ

0 голосов
/ 02 августа 2011

Обработка живого видео (вход / выход видео, а не просто запись или просто воспроизведение) с настольным openGL часто выполняется многопоточным, но для этого требуется поддержка совместного использования контекста (так что отдельные контексты в отдельных потоках могут ссылаться на один и тот же дескриптор ресурса). space.) Совместное использование контекста поддерживается в OpenGL ES, но не в WebGL (пока), хотя я думаю, что оно поддерживается в WebCL. Таким образом, хотя WebWorkers и поддерживается, использование WebGL, по-видимому, фактически ограничено одним потоком.

Но, когда (не если) WebGL поддерживает совместное использование контекста, я полагаю, самым быстрым способом будет изолировать подготовку текстур во вспомогательном потоке с общим контентом, а затем запустить на них шейдеры GL в главном компостирующая нить.

В настольном openGL один из способов сделать это - объявить закадровое окно 1x1 (элемент canvas) со своим собственным контекстом, связанным с уникальным потоком, выполняющим подготовку. Эти контексты совместно используются с основным потоком, в котором происходит окончательное наложение.

Когда (я думаю, нет, если) WebGL поддерживает совместное использование, ищите альтернативную подпись в getContext (), которая разрешает совместное использование с другим контекстом.

Если вы попытаетесь сделать этот вид обработки видео однопоточным, вы столкнетесь с проблемой «двух часов». (Входной видео контракт, выходной видео контракт.) Вы должны изолировать задержку обработки от этих жестких часов через FIFO / кэш и многопоточность, иначе вы получите сбой на выходе или пропустите входные кадры. Необходимость FIFO / кеша приводит к задержке обработки видео, и если вы пропускаете звук, вам нужно будет задержать звук для соответствия. Это можно легко сделать с помощью кольцевого буфера с круговым циклом со смещением между записью и воспроизведением.

...