Войти
видео плеерСтатьи

Баллада о модуле VMem

Автор:

Вступление

Всем доброго времени суток!
В своей последней статье я начал рассказывать о модуле Vmem, входящего в состав LibVLC. В данной статье я более подробно расскажу о том, как его использовать для формирования картинки.

Модуль VMem


Модуль Vmem предназначен для рендеринга видео картинки в память, вместо непосредственного вывода ее на экран. Модуль работает следующим образом:

1. пользователь устанавливает размер буфера и его формат, куда будет рендериться картинка.( libvlc_video_set_format )
2. пользователь устанавливает callbacks функции, которые будут вызываться в момент когда VLC требуется отрисовать новый кадр.(libvlc_video_set_callbacks )
3. вызывается функция libvlc_media_player_play которая запускает всю эту шайтан-машину.

Правим исходники

И все вроде бы просто, но есть один нюанс: при установке размера буфера изменить его далее, во время проигрывания уже нельзя. А размер буфера задается во время загрузки модуля. Это серьезный недостаток, поскольку чтобы установить размер буфера надо знать какой был изначальный. Если сделать буфер слишком маленький, чем оригинальная картинка, то при растягивании она будет выглядеть размазанной и некачественной. Если сделать слишком большой, то будет тратиться много времени на стретч в большее разрешение. Поэтому мне пришлось изменить исходники VMem модуля а именно сделать так, чтобы размер буфера устанавливался по размеру исходной картинки.

Callbacks


Теперь по поводу callbacks. В модуле можно установить три callbacks: lock, unlock, display.

lock - уведомляет о том, что "прилетела" новая картинка. в нем пользователь должен передать указатель на участок памяти, куда будет рендериться картинка
unlock - разблокировка буфера памяти
display - картинку следует вывести на экран

Теперь, применительно к DirectX. Для вывода картинки был сделан следующий ход: создан offscreen plain surface, куда собственно рисуется видео кадр + render texture. Создание именно render texture необходимо в силу ограничения работы StretchRect в IDirect3DDevice9. А теперь немного лирики, если присмотреться, то видно что делается двойная работа: сначала картинка копируется в буфер, затем в текстуру, затем выводится на экран. Именно такая схема используется в модуле VLC direct3d video output - для вывода картинки средствами Direct3D. Я решил улучшить схему, сократив на один шаг, а именно создав DYNAMIC_TEXTURE, но когда я это сделал, тормоза были жуткие, плюс ко всему звук начал лагать. Такой шаг был неприемлем. MANAGED_POOL  у текстуры тоже ничем хорошим не закончился. И потому я решил не мудрствовать лукаво, и воспользоваться способом разработчиков модуля video output direct3d

#DirectX, #VLC

28 декабря 2010