Работа с CSI камерой
На CSI разъеме CAM поддерживается подключение MIPI CSI камеры. В сборке доступен overlay слой для работы с камерой OV5647.
Ревизия платы Eltay SC rev.1.0.0
В ревизии платы Eltay SC rev.1.0.0 линии I2C на разъеме CSI перепутаны местами. Для обхода этой особенности используется программная I2C-шина i2c-gpio.
При включении overlay-файла камеры аппаратный интерфейс I2C1, используемый также для HDMI, отключается. Поэтому на данной ревизии платы камера CSI и HDMI не могут использоваться одновременно.
Также не поддерживается одновременная работа камеры и дисплея, подключенных к разъемам CAM и LCD соответственно.
В предоставленном слое работа с камерой OV5647 выполняется через стек Felix/ISP производителя платформы. Слой подготавливает аппаратную часть: включает CSI/ISP, включает программную I2C-шину и включает питание камеры. Overlay-файл описывает камеру OV5647 штатной compatible-строкой ovti,ov5647, поэтому после загрузки сенсор может быть автоматически привязан к kernel-драйверу ov5647. Для работы через Felix/ISP сенсор необходимо предварительно отвязать от kernel-драйвера, так как дальнейшее управление сенсором выполняется стеком Felix.
Для включения камеры нужно добавить слой eltay-sc-soft-i2c-ov5647.dtbo в конфигурационный файл /boot/extlinux/extlinux.conf:
fdtoverlays /boot/overlays/eltay-sc-soft-i2c-ov5647.dtbo
После сохранения изменений и перезагрузки устройства необходимо вручную загрузить драйвер программной I2C-шины и освободить сенсор от стандартного драйвера ядра. Эти команды необходимо выполнять после каждой перезагрузки системы перед началом работы с камерой:
modprobe i2c-gpio
modprobe ov5647 2>/dev/null || true
echo 5-0036 > /sys/bus/i2c/drivers/ov5647/unbind 2>/dev/null || true
После загрузки драйвера должна появиться программная I2C-шина камеры:
i2cdetect -l
Ожидаемый результат:
i2c-5 i2c i2c-gpio-camera I2C adapter
Также можно проверить, что устройство камеры создано на шине i2c-5:
ls -l /sys/bus/i2c/devices/5-0036
Ожидаемый результат — наличие устройства 5-0036.
Ревизия платы Eltay SC rev.1.0.1
В ревизии платы Eltay SC rev.1.0.1 разъем CSI камеры подключен к аппаратной шине I2C1. Программная I2C-шина i2c-gpio для камеры не используется. При включении камеры аппаратный интерфейс I2C1 не отключается, поэтому HDMI и камера могут оставаться включенными одновременно на уровне I2C-шины.
В предоставленном слое работа с камерой OV5647 выполняется через стек Felix/ISP производителя платформы. Overlay-файл подготавливает аппаратную часть: включает CSI/ISP, добавляет устройство OV5647 на аппаратную шину I2C1 и включает питание камеры. Сенсор описывается штатной compatible-строкой ovti,ov5647, поэтому после загрузки он может быть автоматически привязан к kernel-драйверу ov5647. Для работы через Felix/ISP сенсор необходимо предварительно отвязать от kernel-драйвера, так как дальнейшее управление сенсором выполняется стеком Felix.
Для включения камеры нужно добавить overlay-файл eltay-sc-i2c1-ov5647.dtbo в конфигурационный файл /boot/extlinux/extlinux.conf:
fdtoverlays /boot/overlays/eltay-sc-i2c1-ov5647.dtbo
После сохранения изменений и перезагрузки устройства необходимо вручную освободить сенсор от стандартного драйвера ядра. Эти команды необходимо выполнять после каждой перезагрузки системы перед началом работы с камерой:
modprobe ov5647 2>/dev/null || true
echo 1-0036 > /sys/bus/i2c/drivers/ov5647/unbind 2>/dev/null || true
Аппаратная шина I2C1 должна быть зарегистрирована в Linux как i2c-1:
i2cdetect -l
Ожидаемый результат — наличие адаптера i2c-1, соответствующего аппаратному контроллеру I2C1.
Также можно проверить, что устройство камеры создано на шине i2c-51:
ls -l /sys/bus/i2c/devices/1-0036
Ожидаемый результат — наличие устройства 1-0036.
Работа с камерой
Для проверки камеры можно выполнить:
cd /etc/felix/ov5647 || exit
felix-sensor-test \
-sensor OV5647_0 \
-sensorMode 0 \
-usleeptime 1000000
Признаки успешной проверки:
Read device ID 0x5647
Sensor OV5647_0 mode 0
Mipi Lanes: 2
enabled (MIPI) - frame count 30
enabled (MIPI) - frame count 60
CRC Error 0x0
ECC Error 0x0
SOT Error Count 0x0
Счетчик frame count должен расти.
Ошибки CRC, ECC, SOT должны оставаться равными 0x0.
Для захвата видео с камеры можно использовать GStreamer:
cd /etc/felix/ov5647 || exit
gst-launch-1.0 -e felixsrc setup-file=/etc/felix/ov5647/ov5647-arducam.cfg sensor=OV5647_0 sensor-mode=0 num-buffers=150 alloc-buffers=10 buf-mode=query exposure-auto=true awb-enable=true awb-algorithm=pid awb-mode=high-lum ! queue max-size-buffers=1 ! video/x-raw,format=NV12 ! omxh264enc control-rate=constant target-bitrate=10000000 ! filesink location=/tmp/ov5647.h264
Здесь:
felixsrc— элемент GStreamer, источник видеоданных из ISP/Felix.setup-file=/etc/felix/ov5647/ov5647-arducam.cfg— файл настроек ISP/Felix для камеры OV5647.sensor=OV5647_0— имя используемого сенсора. В данном случае используется первая камера OV5647.sensor-mode=0— режим работы сенсора. Для OV5647 режим0соответствует захвату 1920x1080.num-buffers=150— количество кадров, которое нужно получить перед завершением pipeline. При частоте около 30 кадров/с это примерно 5 секунд видео.alloc-buffers=10— количество буферов, выделяемых для работы Felix/GStreamer pipeline.buf-mode=query— режим работы с буферами Felix.exposure-auto=true— включить автоматическую экспозицию.awb-enable=true— включить автоматический баланс белого.awb-algorithm=pid— выбрать алгоритм автоматического баланса белого.awb-mode=high-lum— задать режим работы автоматического баланса белого.queue max-size-buffers=1— добавить очередь в pipeline и ограничить ее одним буфером.video/x-raw,format=NV12— задать формат видеоданных NV12.omxh264enc— аппаратный кодировщик H.264.control-rate=constant— режим постоянного битрейта кодировщика.target-bitrate=10000000— целевой битрейт H.264, в данном примере 10 Мбит/с.filesink location=/tmp/ov5647.h264— сохранить видеопоток в файл/tmp/ov5647.h264.
Файл /tmp/ov5647.h264 содержит сырой H.264-поток. Для удобного просмотра на ПК его можно упаковать в контейнер MP4 без перекодирования:
ffmpeg -y -framerate 30 -i /tmp/ov5647.h264 -c copy /tmp/ov5647.mp4
В результате будет создан файл /tmp/ov5647.mp4.
Для извлечения кадров из видео, например, по одному кадру в секунду, можно выполнить:
rm -f /tmp/ov5647-frame-*.jpg
ffmpeg -y -i /tmp/ov5647.mp4 -vf fps=1 -q:v 2 /tmp/ov5647-frame-%03d.jpg
Здесь:
-i /tmp/ov5647.mp4— входной видеофайл.-vf fps=1— извлекать один кадр в секунду.-q:v 2— качество JPEG. Чем меньше значение, тем выше качество./tmp/ov5647-frame-%03d.jpg— шаблон имени выходных файлов.
После выполнения команды в каталоге /tmp появятся JPEG-файлы:
/tmp/ov5647-frame-001.jpg
/tmp/ov5647-frame-002.jpg
/tmp/ov5647-frame-003.jpg
...