Programming, electronics, lifestyle
Навигация по серии статей:
Во многих прикладных задачах возникает необходимость работы с видеопотоками на одноплатных компьютерах (single board computer – SBC).
Для себя ставлю задачу изложить в этой статье накопленные теоретико-практические знания по организации работы с видеопотоками на SBC:
Для изложения я буду описывать процесс на примере самых распространённых SBC на 2020 год. Это одноплатные компьютеры Raspberry Pi 3го и 4го поколения. Однако материал изложенный в этой статье применим и для других SBC.
Еще пару хороших ссылочек на обзор плат от Кравченко Виктора:
Для начала предлагаю рассмотреть устройство плат и задаться вопросами: «откуда берется видеопоток?», «как он передается?», «где обрабатывается?» и «где хранится?».
Видеопоток снимаемый по шине USB (например, плата видеозахвата LinuxTV EasyCAP, веб-камера);
В этом варианте нужно иметь ввиду, что
v4l2
драйвер Raspberry Pi не позволит работать более чем с одним устройством единовременно.
Видеопоток передаваемый по сети (например видеопоток с IP-камеры, передаваемый по протоколу RTSP
).
Видеопоток генерируемый из файла находящимся на блочном USB устройстве или на внешнем сервере в сети.
Устройство подключенное к шине Camera serial interface (CSI): обычно это Raspicam, однако в этот порт можно подключить HDMI-конвертор; Некоторые ссылочки по CSI:
HDMI->CSI конвертор
Большинство таких решений построено на базе чипа Toshiba TC358743XBG (Datasheet).
Кстати по теме, прикольный проект pikvm
- позволяет аппаратно подключиться к серверу и предоставить доступ к его монитору, клавиатуре доступ.
Далее видеопоток необходимо передать. На диаграмме для Raspberry Pi 3 gen можно выделить 2 основных узких места:
CSI шина
между Raspberry Pi
и внешним устройством
– 2Gbit/s (250MBytes/s);USB 2.0 шина
между USB/LAN-контроллером
и процессором
– 480Mbit/s (60MByte/s);
Здесь нужно разделять: Ethernet / Wi-Fi, тк они подключены к процессору по разным шинам.
После того как мы завели в устройство видеопоток, его необходимо обработать. Обычно основную часть обработки, если мы работаем с камерами, занимает кодирование (операция упаковки (сжатия) видео в некий контейнер, например mjpeg, H.264, H.265).
Некоторые USB-камеры умеют кодировать видеопоток на встроенном контроллере.
В основном эти операции делаются средствами CPU
, однако контроллер Raspberry Pi в своем составе имеет GPU co-processor
, который может выполнить некоторые операции по кодированию и декодированию (при этом не отнимая вычислительное время у CPU
).
Нужно понимать, что CPU – достаточно универсальная штука, однако её ресурс ограничен, и если можно переложить часть задач на GPU – это высвободит процессорное время для других задач.
Здесь есть пара ограничений:
Тут нужно пояснить, что Video Core и есть GPU co-processor встроенный в Broadcom чип, подробнее на wiki и доп. ссылочки:
Затем необходимо либо отдать видеопоток, либо сохранить его в файл, сделать это мы можем следующими способами:
Ethernet
/ Wi-Fi
;HDMI
, AV
, DSI
выход Raspberry Pi
;USB-устройство
;microSD
карту.Тут главное понять с какой скоростью потребитель может принять эту информацию, например какая скорость записи на флешкарте или внешнем носителе.
Думаю после вводной теории будет правильным поговорить о количестве информации.
На практике зачастую используют видеокамеры со встроенными кодеками которые обеспечивают сжатие передаваемых данных. Однако наравне с этим для некоторых задач взаимодействие происходит с несжатыми данными.
Например, при обработке видеопотока на процессоре с применением технологии так называемого “технического зрения”, чтобы не раскодировать на процессоре обратно сжатый видеопоток, можно сразу работать с несжатым.
Давайте рассмотрим какое количество информации будет передавать некая камера в несжатом формате (не путать с RAW) в FullHD разрешении (1920x1080 пикселей).
Если для примера взять распространенную RGB модель кодирования, состоящую из 3-х основных цветов: красного, зеленого, синего, каждый из которых в свою очередь имеет по 256 оттенков, то можно посчитать: 1 цвет из 256 оттенков = 8 бит = 1 байт.
Учитывая, что RGB модель имеет 3 цвета (по 256 оттенков каждый), получаем, что для кодирования одного пикселя используется 3 байта.
Получается – один FullHD фрейм весит: 1920[px] x 1080[px] x 3[byte] = 6,220,800[byte] ≈ 6MByte
Тут нужно сделать ремарку, что не везде используется
RGB
кодирование, чаще с камер снимаетсяYUV
, подробнее в этой статье «Захват и сырой формат аудио/видео: микроликбез».
Эта модель кодирования занимает в два раза меньше информации по сравнению с RGB моделью.
Далее я буду оперировать данными для кодирования вRGB
. Поделив это напополам, вы получите данные дляYUV
кодирования.
Для удобства сравнения следующие данные представлю в bit/s (это в 8 раз меньше, чем byte/s): 6[MByte/s] = 49,7[Mbit/s] ≈ 50[Mbit/s]
Думаю после сравнения цифр стало ясно, что Raspberry Pi 3 не сможет банально принять FullHD картинку 60 кадров / сек в несжатом виде. Максимальное, что можно выжать из этого SBC – это подключить Raspicam
к CSI порту и снять FullHD, 40 кадров / сек.
Ситуация с Raspberry Pi 4B иная, ввиду наличия PCI Express шины пропускной способностью в 5Gbit/s и подключенного к ней контроллера USB 3.0. Теоретически с Raspbbery Pi 4B можно снять FullHD, 60 кадров / сек с одного порта, + со второго ещё FullHD, 40 кадров / сек. Оговорюсь, что это только теоретические цифры, на практике скорости будут несколько меньше.
Вообще возможности
BCM2711
используемого в Rasbperry Pi 4 больше, однако не все реализованы на плате, подробнее на raspberrypi.org.
Думаю теперь подобный расчет вы сможете сделать сами для вашего формата данных, разрешения, частоты и способа подключения камеры к компьютеру.
В этой статье были рассмотрены аппаратные характеристики и ограничения при работе с несжатым видеопотоком. В дополнение написана вторая статья про софт для видеозахвата на Raspberry Pi.