LINUX.ORG.RU

Как рендерить несколько видеопотоков на OpenGL 3.1?

 , , ,


1

1

Есть несколько декодеров, работающих в разных потоках. Они декодируют видео с разной частотой кадров и вообще никак друг с другом не синхронизированы. Могут запускаться и останавливаться.

Нужно всё это дело рендерить в реальном времени в подобие видеостены - прямоугольной сетки, где в каждой ячейке свой видеопоток.

Как у меня сделано сейчас. Декодер хранит последний декодированный кадр. По таймеру поток, отвечающий за обновление экрана, собирает последние кадры от всех декодеров, через glTexSubImage2D обновляет OpenGL текстуры и рендерит их на экран. Чтобы потоки не конфликтовали, чтение и запись последнего декодированного кадра прикрыты мьютексом.

Текущая версия работает, но хочу попросить совета. Есть ли какие-нибудь мысли по оптимизации этого дела и вообще как правильно такое делать? Наверное, это похоже на работу композитора. Есть независимые источники, которые предоставляют готовые данные и их нужно свести воедино и отобразить на экране.

У меня здесь получается только один OpenGL контекст. Слышал что-то про многопоточный рендер. Применим ли он здесь?

OpenGL рендерится в окно Qt приложения через QOpenGLWindow. Версия OpenGL строго не старше 3.1. Нужна кроссплатформенность: топик и оффтопик, т.е. без платформозависимых фич типа dma-buf. Видеокарты в основном интел и нвидия.

★★★★★
Ответ на: комментарий от anonymous

А как шейдер получит доступ к данным, которые он будет писать в текстуры? Данные то в обычной RAM, не в GPU. Опять копировать куда то. Это плюс минус то же самое, что у меня есть.

Но судя по твоим словам у тебя уже написано много и архитектурно пол это не заточено.

Кстати говоря. У меня атласы. Переключение текстур дорогое. Поэтому я создаю одну большую, которая содержит кадры от нескольких декодеров. Потом сортирую команды загрузки данных и отрисовки, чтобы было меньше переключений. Ещё у меня декодеры отдают изображения в формате I420 и NV12. Там несколько plane. Проблем хватает.

ox55ff ★★★★★
() автор топика
Ответ на: комментарий от ox55ff

А как шейдер получит доступ к данным, которые он будет писать в текстуры?

Через uniform передашь в шейдер в шейдере задаёшь 1 бальшую тестуру где по смещению UV через gl_FragData будешь писать результат, стоп……..

У меня атласы

Тоесть у тебя 4 кадра на текстуру можно, ну норм если влезают так и надо.

В таком случае мимо, либо ты пишешь в несколько в разных потоках, но опять же ты же понимаешь что конвеер гпу один хрен это в очередь поставит. Либо готовь кадры в памяти обычной молотя цпу и когда готово отдавай их шейдеру который уже выведет. Если ты пишешь в 1 текстуру несолько ихображений просто смещая UV то ты никак не сможешь в нескольких потоках писать в 1 текстуру.

Вынужден отклонится, гугли и ищи «как в нескольких потоках писать в текстуры и потом эти результаты объединить для вывода»

У тебя и так и так надо будет всё время гонять данные RAM -> GPURAM и

anonymous
()
Ответ на: комментарий от ox55ff

Может просто держать этот атлас в оперативной памяти, каждый из потоков записывает в свой отведенный кусок памяти в текстуре, возможно можно без блокировок и раз в n кадров блокировать этот атлас мьютексом и отправлять на GPU.

Int64 ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.