Собираем
информацию
по крупицам

Linux: как перестать удивляться, и начать работать

Как в Linux превратить DV-камеру в WEB-камеру
14-12-2012
21:51:42

У меня есть старенькая Mini-DV камера Sony DCR-HC42E. В свое время это была очень хорошая бытовая видео-камера с 12-ти кратным оптическим зумом. Под Windows эта камера легко цепляется как через интерфейс IEEE 1394 (FireWire), так и через USB в режиме WEB-камеры.

 

Но, как сказали на каком-то форуме, случаев подключения этой камеры в Linux в виде WEB-камеры в интернете не обнаружены. При подключении через USB камера нормально определяется как USB-устройство, и на этом всё заканчивается. Устройства /dev/videoX не создается, ибо в ядерных драйверах поддержки данной камеры нет и, видимо, никогда не будет.

 

Но не лежать же камере без дела! Тем более что бабушка из далекого города удивляется, почему она может настроить скайп с камерой, чтобы мы ее видели, а такие продвинутые компьютерщики как я - нет. Мне стало обидно, и я решил во что бы то ни стало завести эту камеру под Linux-ом.

 

* * *

 

Итак, выяснилось, что некоторые умельцы подключают DV-камеры по шнуру FireWire, а потом, воспользовавшись модулем ядра  vloopback, создают устройство /dev/video0. Это стандартный файл устройства веб-камеры, с ним могут работать такие программы как Kopete и Skype. Полностью описания данного процесса и нужные команды нигде не нашел, поэтому начал разбираться, так сказать, с нуля.

 

Первое, что выяснилось - это то, что модуль vloopback существует только для ядер 2.6.x, и его реализации для 3.2.x нет в природе. А у меня система Debian Testing Squeezy с ядром 3.2.0-4-686-pae. Собрать vloopback из исходников для ядра 3.2.x тоже не получилось, а на официальном сайте ни слова про поддержку ядер версии 3.

 

Через пару дней выяснилось, что в ядрях 3-й версии изменен интерфейс video4linux, и теперь он называется v4l2. Соответственно, модуль обратной петли для видеоданных называется v4l2loopback. И в официальную поставку ядра он не входит. Страничка этого модуля находится здесь:

 

http://code.google.com/p/v4l2loopback/

 

Для установки данного модуля необходимо установить пакеты с заголовочными файлами ядра, которые обычно называются linux-headers*. В моем случае это был пакет linux-headers-3.2.0-4-common. Я его установил, после чего распаковал архив v4l2loopback и запустил компиляцию с установкой:

  1. make (от пользователя)
  2. make install (от рута)

В результате модуль был скомпилирован и установлен в систему. Автозапуск модуля нигде  инсталл-скриптом не прописывается, на первых порах его можно запускать руками:

 

modprobe v4l2loopback

 

В случае удачного запуска модуля, в системе будет создан файл /dev/video0, а в списке модулей (можно посмотреть через команду lsmod) появятся строчки:

 

v4l2loopback 22660 0
videodev 61658 1 v4l2loopback

 

Можно считать, что половина дела сделана.

 

* * *

 

Далее необходимо проверить, принимает ли Linux-система данные по FireWire. Помятуя о том, что начиная с какой-то версии ядра 2.6.x в Linux удалили модуль raw1394, и заменили его модулями firewire_ohci + firewire_core, с которыми половина софта не работает, я приготовился к  долгому ковырянию. Но, на удивление, монтажная программа Kino бодро показала картинку с камеры. Я обрадовался и стал проверять, можно ли передать FireWire поток в mplayer/mencoder.

 

Для начала я просто проверил каптюринг в файл через консольную программу dvgrab:

 

dvgrab -noavc

 

В результате был создан файл в формате DV, в котором лежало заснятое камерой видео.

 

Далее я проверил, может ли mplayer показывать потоковые данные с камеры. Программа dvgrab может передавать FireWire данные в стандартный поток. Для этого надо в конце команды поставить знак "-". А программа mplayer может принимать данные из стандартного потока. Для этого в конце команды тоже нужно поставить знак "-".

 

В результате, сформировалась вот такая команда:

 

dvgrab -noavc - | mplayer -noconsolecontrols -

 

Можно посмотреть поток FireWire и через VLC:

 

dvgrab -noavc - | vlc -

 

Но VLC отображает картинку с сильным лагом по сравнению с MPlayer.

 

Теперь нужно сделать следующее:

  1. получить данные из FireWire;
  2. перекодировать их в формат, который обычно генерируют WEB-камеры;
  3. засунуть этот поток в файл /dev/video0 (в чем нам должен помочь модуль v4l2loopback);
  4. проверить, есть ли какое-нибудь изображение с помощью просмотрщика вебкамеры.

Первые три пункта реализуются следующей командой:

 

dvgrab -noavc - | mencoder -ovc raw -nosound -vf tfields=0,detc,scale=320:340,format=yuy2 -o /dev/video0 -

 

Пробежимся кратко по опциям mencoder-а.

  • -ovc raw обозначает, что выходной поток выстреливается в явном виде, без какой-либо кодировки кодеками;
  • -nosound обозначает, что звука в выходном видео не будет. Он нам и не нужен, при разговоре по скайпу будем пользоваться обычным микрофоном;
  • -vf tfields=0,detc,scale=320:340,format=yuy2 говорит о том, какие фильры будут применяться к видеопотоку. Фильтры применяются друг за другом, в порядке перечисления.
    • tfields=0,detc - деинтерлейсинг и борьба со стробированием картинки;
    • scale=320:340 - в какой размер смасштабировать видеокадр. По-хорошему, надо бы указать 320:240, но камера дает широкую HD-картинку с неквадратыми пикселями и отношением сторон 16/9. Причем из-за интерлейса, размер картинки, которая выглядит пропорционально, составляет 320:160 точек. Но нужно указывать двойную высоту плюс учет неквадратности пикселя, что в итоге выливается в такой странный размер 320:340;
    • format=yuy2 - это именно та часть команды, которая отвечает за то, в каком виде несжатые видеоданные будут передваться в loopback-файл. Данный формат, по всей видимости, понимают программы, работающие с вебкамерами.
  • -o /dev/video0 обозначает, что вывод будет направляться в файл /dev/video0.

Запускаем данную команду, и переходим к пункту 4. В Linux есть простой просмотрщик потока с вебкамеры, называется Camorama. Попробуем запустить его. Хм, выдается ошибка:

 

Could not connect to video device (/dev/video0).

Pleace check connection.

 

Говорят, что эта ошибка возникает из-за того, что пользователь не включен в группу video. Проверяем - мой пользоватьель в группе video. Тогда в чем же дело?

 

Долгая пытка гуглом показала, что с файлом устройства /dev/video0 не всё так просто. Нельзя просто так взять, и направить в него поток данных, пусть даже в системе и есть модуль v4l2loopback. Его нужно вначале проинициализировать, и оставить в "открытом" состоянии. После чего можно будет писать в него видеопоток. А как это сделать - нигде небыло написано.

 

К счастью, в дистрибутиве модуля v4l2loopback оказался каталог /examples. В нем две программы - test и yuv4mpeg_to_v4l2. Программа test инициализирует v4l2loopback интерфейс  в формат yuy2 и передает в него однотонную картинку 640x480 пикселей. После запуска этой программы, Camorama смогла показать видеопоток. Но что это была за картинка!

 

 

Картинка мерцала, была вся в зеленых и синих полосках, цвет отсутствовал как таковой. Ох и долго же я разбирался почему так. В конце концов так и не разобрался, но частично смог обойти проблему.

 

Почему зеленоватый оттенок? Потому что в README программы test написано:

 

... since all pixels are set to "0" it will be green.

 

В общем, тестовая картинка состоит из нулей, а ноль обозначает зеленый цвет. Он почему-то и "наследуется" в видеоизображении. Значит, задача состоит в том, чтобы найти, как сгенерировать картинку черного или белого цвета, чтобы картинка не была зеленой.

 

Я плюнул на всё, залез в исходник test.c,  рядом с глобальной переменной debug завел глобальную переменную pixel_byte:

 

static int debug=0;
__u8 pixel_byte=128;

 

В коде нашел заполнение памяти константой 0:

 

memset(buffer, 0, framesize);
memset(check_buffer, 0, framesize);
for (i = 0; i < framesize; ++i) {
   //buffer[i] = i % 2;
   check_buffer[i] = 0;
}

 

Очень странный, честно говоря, код... Цикл здесь вроде ненужен. Ну да ладно,  наверно автор лучше меня знает что он делает.  Заменил я этот код на другой:

 

memset(buffer, pixel_byte, framesize);
memset(check_buffer, pixel_byte, framesize);
for (i = 0; i < framesize; ++i) {
   buffer[i] = pixel_byte;
   check_buffer[i] = pixel_byte;
}

 

Скомпилировал, запустил, и подобрал значение константы pixel_byte=128. При ней выдается картинка в серых тонах, а не в зеленых. В ходе подбора и перезапуска программы test, неожиданно обнаружил, что после трех-пяти запусков программы test исчезает весь цифровой шум, и картинка становится четкой, без каких либо артефактов:

 

 

Получить цветную картинку, я как ни старался, не смог. Ну да ладно, в черно-белом видео есть свой особый шарм. Оставалось только проверить, будет ли работать Skype с такой виртуальной WEB-камерой.

 

* * *

 

Скайп сразу без проблем подхватил видеокамеру, и я сделал звонок товарищу на MacOs-овский скайп. Товарищ сказал, что я звоню с черно-белого лазерного принтера, в котором пора поменять картридж.

 

Я попросил его сделать скриншот картинки, который выдает скайп на его стороне. И вот что я увидел:

 

Посмотреть реальный размер

 

Закроем глаза на то, что мы видим уставшего немытого мужика, которому давно пора спать, а он долбается с линухом чтобы показаться по скайпу бабушке. Давайте обратим внимание на сам видеокард.

 

С одной стороны - отвратительные вертикальные полоски неизвестного происхождения. С другой стороны, имеем разрешение 720x360 (почему, интересно? mencoder должен был смасштабировать поток до 320x160~170). На линейке читаются цифры, и видна миллимитровая разметка. Для того, чтобы собеседник получил представление о том, с кем он говорит, такого "качества" достаточно.

 

Вообще, я считаю, что эта картинка гораздо лучше, чем выдают ширпотребные WEB-камеры за 700-800 руб. Только черно-белая.

 

Подводя итог, можно сказать, что сделать из DV-камеру WEB-камеру в ОС Linux можно. Весь вопрос в удаче и качестве конечной картинки. Возможно, у кого-то получится лучше меня. Например, получится сделать видео в цвете. Удачи.

 


К списку "Компьютерное"

Интересное на сайте


Игры под DOS » Udav (Удав)

Игра, написанная за одну ночь для тренировки работы с компилятором Borland C/C++. Как говорится, классика жанра - PC Speaker + TextMode, управление с...


Mplayer / Mencoder » Mplayer: как выбрать звуковую дорожку при просмотре фильма

Иногда попадаются файлы, в которых MPEG4-фильм записан таким образом, что перевод идёт дополнительным аудиопотоком, и по-умолчанию плейер его не видит...


KDE 4 » Классическая тема оформления Redmond 125% для KDE 4

Мне часто приходится работать как в Linux, так и в Microsoft Windows. Моторные навыки наработаны годами, и для быстрой и точной работы необходимо имет...

RSS подписка

Подпишитесь на новости сайта по RSS


О, смотри-ка какое хорошее место. Дайте два!

Внимание!

На этом сайте разрабатывается программа MyTetra и её родственные проекты.

Доступны к просмотру следующие базы знаний:

База Xintrea (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)

База Rarrugas (1, 2)

База Balas

База YellowRaven

База Yurons

База Lesnik757

База Shandor

База Sirrichar

 

Подробности на странице MyTetra Share.

 WebHamster.Ru
 Домик любопытного хомячка
Яндекс индекс цитирования
Почтовый ящик