LINUX.ORG.RU

Запись видео с вебки


0

1

Есть программа на qt, которая берёт кадры от вебки через v4l и отрисовывает их на виджете. нужна возможность записи видео. проблема в том, что /dev/video0 нельзя «распараллелить», то есть это устройство может использовать только одна программа. вебка так же не поддерживает оверлей.

так что у меня в бесконечном цикле есть текущий кадр, хранящийся в переменной типа unsigned char * (из которого последствии формируется QImage и отрисовывается на виджете). как мне из такого набора кадров слепить видео? я пробовал пихать это в именованный пайп, но файл в размерах быстро растёт, да и ffmpeg считывает из него с артефактами. есть ли библиотеки, позволяющие делать видео из набора кадров?


Почему ты не хочешь выделить буфер в разделяемой памяти? Я тебе уже в двух твоих темах об этом говорил!

Или ты меня игнорируешь?

Eddy_Em ☆☆☆☆☆ ()

Для этого есть libav - бывшая ffmpeg. Там есть libavdevice - можно использовать для непосредственно захвата видео взамен того, что есть сейчас. Будет проще и удобнее, но если не хочется переделывать - необязательно её использовать. Там же есть libavcodec - для кодирования. Им ты сможешь сделать полноценный видеопоток. Без кодека ничего сувать в пайп не надо - слишком большие объёмы информации. С минимальными изменениями текущего кода, тебе следует проинициализировать libavcodec, кодировать им поступающие фреймы - те самые данные, которые отправляются для отрисовки на виджет, и затем записывать их на диск или передавать куда-то.

auto12884835 ()
Ответ на: комментарий от Eddy_Em

я просто не знаю как это сделать.

вот, я пишу в цикле в разделяемую память мой кадр. с какими параметрами тогда запускать ffmpeg, чтобы записать видео? я просто знаю, что ffmpeg умеет читать из пайпа, а про разделяемую память я не нашёл инфы.

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

Зачем ffmpeg? Все делать самостоятельно: при помощи v4l2 захватывать видео, производить необходимые манипуляции и складывать результат в, скажем, четырех (этого достаточно обычно) буферах. Пример я уже приводил (мой astriovideoguide так и работал, правда, я его писал года 2-3 назад, сейчас сделал бы попроще и пошустрей).

P.S. С libffmpeg я не работал. Но сдается мне, что она поможет избежать нагромождения кода для поддержки разных видов камер. Хотя, примеров такого кода (которые можно просто стырить почти без изменения) полно.

Eddy_Em ☆☆☆☆☆ ()
Последнее исправление: Eddy_Em (всего исправлений: 1)
Ответ на: комментарий от Eddy_Em

я не понимаю такой момент: вот у меня 4 буфера, как ты сказал. что в них? только текущий кадр, или нет. и что мне потом с этими буферами делать? ты говорил, что с libffmpeg не работал, как тогда ты записывал видео?

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

man циклический буфер: мы поочередно пишем текущий кадр в буфер с номером 0,1,2,3 и далее по кругу.

что мне потом с этими буферами делать?

Куча других программ, которым нужно только считывать видео, просто берут данные из этого буфера.

как тогда ты записывал видео?

Я его не записывал, а транслировал в web. Если бы надо было писать, подключил бы libvorbis.

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

просто из внешних программ я планировал только записывать с помощью консольной ffmpeg. но видимо оно не умеет записывать из буфера.

значит внешние программы мне нужны. видео я буду записывать из своей же программы. тогда зачем мне записывать переменную в разделяемой памяти, если можно использовать внутри моей программы. если я прав, то получается, что твой вариант излишен, тогда наверно буду копать в сторону libav/libffmpeg/libvorbis

memnek ()
Ответ на: комментарий от Eddy_Em

Куча других программ, которым нужно только считывать видео, просто берут данные из этого буфера.

это как? Через shmat чтоли?

Я его не записывал, а транслировал в web.

raw bitmap без кодирования? Не смеши меня. Так каждый кадр под мегабайт будет.

auto12884835 ()
Ответ на: комментарий от memnek

тогда зачем мне записывать переменную в разделяемой памяти, если можно использовать внутри моей программы.

если читать напрямую с камеры вручную при помощи v4l, всё равно нужно будет выделять буфера при помощи VIDIOC_QUERYBUF ioctl и потом mmap'ать их для доступа. В libavdevice то же самое делается, посмотри в исходиках. От 330 строки init_mmap(). Только смысла нет так поступать, раз всё есть в либе. А насчёт разделяемой памяти и как оттуда могут читать внешние программы - я чёто не очень понял. Надеюсь, автор идеи придёт и разьяснит.

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

Через shmat чтоли?

Ага.

Так каждый кадр под мегабайт будет.

И что?

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от auto12884835

как оттуда могут читать внешние программы

Только свои.

Еще как вариант — написать свой модуль ядра, который будет эмулировать /dev/videoX, а задача его будет простейшей — выдавать кадры из буфера.

Просто действительно иногда бывает необходимо до выдачи видео сделать какую-нибудь ообработку оного.

Кстати, если обработка не нужна, то mmap-вариант самого v4l2 по идее должен нормально работать (т.к. здесь уже не идет прямое считывание — а лишь считывание из текущего буфера).

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

Только свои.

тогда какой смысл их наружу выносить?

И что?

как ты это видео по сети отправишь?

Еще как вариант — написать свой модуль ядра, который будет эмулировать /dev/videoX, а задача его будет простейшей — выдавать кадры из буфера.

зачем в ядро, если это в юзерспейсе может работать? Готовые диспетчеры есть уже, зачем очередной велосипед?

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

тогда какой смысл их наружу выносить?

Чтобы конкуренции не было + уменьшить нагрузку.

как ты это видео по сети отправишь?

Элементарно отправляю, mjpeg'ами. быдлоКод я выше приводил. Можешь глянуть.

зачем в ядро, если это в юзерспейсе может работать?

Затем, чтобы эмулировать лишнее /dev/videoX. Сисвызовы ты в юзерспейсе не перехватишь.

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

Чтобы конкуренции не было

какой такой конкуренции?

+ уменьшить нагрузку.

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

Элементарно отправляю, mjpeg'ами. быдлоКод я выше приводил. Можешь

глянуть.

То есть у тебя с камеры уже mjpeg снимается? Тогда ещё может быть для твоего частного случая - если надо только переслать и нарисовать локально. Если нужна какая-то дополнительная обработка, например перекодировать в какой-нибудь mp4 и записать на диск в виде фильма, это только дополнительный оверхед на декодирование mjpeg'ов. А ещё не все камеры поддерживают вывод в mjpeg. Код лень смотреть.

Затем, чтобы эмулировать лишнее /dev/videoX. Сисвызовы ты в юзерспейсе не перехватишь.

1) драйвера давно уже можно писать в юзерспейсе 2) зачем так поступать в данном случае, если есть готовые решения?

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

какой такой конкуренции?

При работе с v4l2.

она же так увеличивается наоборот

уменьшается

Треды намного легче, чем отдельное приложение в отдельном потоке

Можно сделать и fastCGI при большой нагрузке

То есть у тебя с камеры уже mjpeg снимается?

Нет, raw. Обрабатывается и отдается.

зачем так поступать в данном случае, если есть готовые решения?

какие?

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

какой такой конкуренции?

При работе с v4l2.

не понял, кто с кем конкурирует?

уменьшается

что компенсирует тот добавочный оверхед, про который я говорил?

Можно сделать и fastCGI при большой нагрузке

Ну и что? Всё равно это будет добавочный процесс. При большой нагрузке тем более лучше избавиться от дополнительных сущностей и отправлять фреймы в порт сразу после кодирования.

Нет, raw. Обрабатывается и отдается.

Ну ты меня совсем запутал. На каком этапе оно енкодится в mjpeg?

какие?

webcam studio например.

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

На каком этапе оно енкодится в mjpeg?

У меня низкая нагрузка, поэтому кодирование делает CGI, отдающий видео. При высокой нагрузке я бы кодировал демоном, обрабатывающим видео.

webcam studio например

Не слышал про такое.

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