Захват видео из окна OpenGL в Windows - PullRequest
11 голосов
/ 01 октября 2008

Я должен предоставить своим пользователям действительно простой способ захвата видеоклипов из главного окна моего приложения OpenGL. Я думаю о добавлении кнопок и / или сочетаний клавиш для запуска и остановки захвата; при запуске я мог бы попросить имя файла и другие варианты, если таковые имеются. Он должен работать в Windows (XP / Vista), но я также не хотел бы закрывать дверь Linux, которую я до сих пор мог держать открытой.

Приложение использует программы фрагментов и шейдеров OpenGL, эффекты, которые мне абсолютно необходимы в видео.

Мне кажется, что может быть даже несколько разных подходов, которые потенциально могут удовлетворить мои требования (но я не знаю, с чего начать):

  • Библиотека кодирования с такими функциями, как startRecording (имя файла), stopRecording и captureFrame. Я мог бы вызвать captureFrame () после каждого рендеринга кадра (или каждую секунду / третье / что угодно). Если из-за этого моя программа будет работать медленнее, это не проблема.

  • Автономная внешняя программа, которой можно программно управлять из моего приложения. В конце концов, отдельная программа, которой можно управлять , а не , почти делает то, что мне нужно ... Но, как уже говорилось, пользователям должно быть очень просто работать, и я также был бы признателен за плавность; мое приложение обычно работает в полноэкранном режиме. Кроме того, должна быть возможность распространять как часть установочного пакета для моего приложения, которое я в настоящее время готовлю, используя NSIS.

  • Используйте Windows API для покадрового захвата снимков экрана, затем используйте (например) одну из библиотек, упомянутых здесь . Кажется, довольно легко найти примеры того, как снимать скриншоты в Windows; Тем не менее, я хотел бы получить решение, которое на самом деле не вынуждает меня сильно пачкать руки на уровне WinAPI.

  • Используйте OpenGL для рендеринга за пределы экрана, а затем используйте библиотеку для создания видео. Я не знаю, возможно ли это вообще, и боюсь, что в любом случае это может быть не путь наименьшей боли. В частности, я не хотел бы, чтобы фактический рендеринг использовал другой путь выполнения в зависимости от того, захватывается видео или нет. Кроме того, я бы избегал всего, что могло бы снизить частоту кадров в обычном режиме без захвата.

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

Что касается формата файла, я не могу ожидать, что мои пользователи начнут поиск в Google для каких-либо кодеков, но пока также отображение видео достаточно простое для пользователя Windows базового уровня, я не очень все равно, что это за формат. Однако было бы замечательно, если бы можно было контролировать качество сжатия на выходе.

Просто чтобы уточнить: мне не нужно снимать видео с внешнего устройства, такого как видеокамера, и я не очень заинтересован в движениях мыши, даже если их получение не причиняет вреда. Там нет никаких требований, касающихся аудио; приложение не производит никакого шума.

Я пишу на C ++ с использованием Visual Studio 2008, для этого самого приложения также используются преимущества GLUT и GLUI. У меня есть четкое понимание в отношении C ++ и связывания в библиотеках и тому подобного, но с другой стороны, OpenGL является для меня совершенно новым: до сих пор я действительно изучил только необходимые биты, чтобы фактически выполнить свою работу.

Мне не нужно срочно решение, так что не стесняйтесь не торопиться:)

Ответы [ 4 ]

8 голосов
/ 01 октября 2008

Здесь есть два разных вопроса - как получить кадры из приложения OpenGL и как превратить их в файл фильма.

Первый вопрос достаточно прост; вы просто захватываете каждый кадр с помощью glReadPixels () (через PBO, если вам нужна производительность).

Второй вопрос немного сложнее, поскольку кроссплатформенные решения (ffmpeg), как правило, бывают GPL или LGPL. LGPL приемлем для вашего проекта? Windows способ сделать это (DirectShow) - это немного головная боль в использовании.

Редактировать: Поскольку LGPL в порядке, и вы можете использовать ffmpeg, см. здесь для примера того, как кодировать видео.

1 голос
/ 01 октября 2008

Это выглядит довольно актуально для слияния с AVI (как предложил Эндрю), однако я действительно надеялся избежать LPBITMAPINFOHEADER и т. Д.

Спасибо за ответы, я сообщу об успехе, если таковые будут:)

В то же время были бы полезны дополнительные советы по кодированию необработанных кадров из glReadPixels в видеоклипы.

Редактировать: До сих пор, ffmpeg, предложенный Майком Ф., кажется, путь. Тем не менее, я еще не попал в реальную реализацию, но надеюсь, что это изменится в ближайшем будущем!

0 голосов
/ 09 сентября 2013

Мне пришлось создать демонстрационный проект записи рендеринга OpenGL в видео. Я использовал glReadPixels для получения данных пикселей и создал видео с OpenCV cvWriteFrame. OpenCV позволяет писать в формате DivX или даже в формате x264 / vp8 (с скомпилированным ffmpeg).

У меня есть более подробная рецензия на мой блог вместе с примером проекта. http://tommy.chheng.com/2013/09/09/encode-opengl-to-video-with-opencv/

0 голосов
/ 01 октября 2008

Самый простой вариант - сохранить каждый визуализированный кадр из вашего приложения, а затем объединить их в AVI. Если у вас есть AVI, есть много доступных библиотек, которые могут преобразовать его в более оптимальный формат или вообще пропустить шаг AVI.

С точки зрения получения каждого кадра, вы можете сделать это либо путем рендеринга в внеэкранную текстуру, как вы предлагаете, либо с помощью обратного буфера непосредственно как источника, если ваше оборудование поддерживает это. Выполнение любого из них (и сохранение каждого кадра) будет затруднено без значительного штрафа на частоте кадров.

Если ваше приложение детерминировано, вы можете "записать" действия пользователя в виде последовательности входов, а затем иметь режим экспорта, который последовательно отображает их на экранной поверхности для генерации AVI.

...