Hi,
I’m trying to get a USB webcam to run on a Colibri iMX8X, but - as I don’t know much about Linux, Docker OR Portainer - am stuck and can’t really tell what to search for / try next.
My goal is to eventually display the webcam feed in a Python (PySide) GUI and be able to take pictures. For that, I managed to make a project using the VS Code plugin with a Weston container and a Pyside2 container that currently displays an empty GUI trying to display webcam images using OpenCV.
Please bare with me, this is an experimental project, someone else set up the hardware many months ago and I only really know my way around the Python parts of all this.
Trying to follow How to use cameras on Torizon and other things I googled, I added permissions and mounts to my docker compose file and v4l-utils to my Dockerfile:
docker-compose.yml
#version: "3.9"
services:
pyside-container-debug:
build:
context: .
dockerfile: Dockerfile.debug
image: ${LOCAL_REGISTRY}:5002/pyside-container-debug:${TAG}
ports:
- ${DEBUG_SSH_PORT}:${DEBUG_SSH_PORT}
- ${DEBUG_PORT1}:${DEBUG_PORT1}
volumes:
- type: bind
source: /tmp
target: /tmp
- type: bind
source: /dev
target: /dev
# for camera access:
- type: bind
source: /sys
target: /sys
- type: bind
source: /var/run/dbus
target: /var/run/dbus
# trying to add webcam:
devices:
#- /dev/video0:/dev/video0
#- /dev/video0:/dev/video1
#- /dev/video0:/dev/video2
#- /dev/video0:/dev/video3
- /dev/video0:/dev/video4
- /dev/video0:/dev/video5
- /dev/video0:/dev/video6
- /dev/video0:/dev/video7
device_cgroup_rules:
# ... for tty
- "c 4:* rmw"
# ... for /dev/input devices
- "c 13:* rmw"
- "c 199:* rmw"
# ... for /dev/dri devices
- "c 226:* rmw"
depends_on: [
weston
]
weston:
image: commontorizon/weston${GPU}:3.3.2
environment:
- ACCEPT_FSL_EULA=1
# Required to get udev events from host udevd via netlink
network_mode: host
volumes:
- type: bind
source: /tmp
target: /tmp
- type: bind
source: /dev
target: /dev
- type: bind
source: /run/udev
target: /run/udev
# for camera access:
- type: bind
source: /sys
target: /sys
- type: bind
source: /var/run/dbus
target: /var/run/dbus
# trying to add webcam:
devices:
#- /dev/video0:/dev/video0
#- /dev/video0:/dev/video1
#- /dev/video0:/dev/video2
#- /dev/video0:/dev/video3
- /dev/video0:/dev/video4
- /dev/video0:/dev/video5
- /dev/video0:/dev/video6
- /dev/video0:/dev/video7
cap_add:
- CAP_SYS_TTY_CONFIG
# Add device access rights through cgroup...
device_cgroup_rules:
# ... for tty
- "c 4:* rmw"
# ... for /dev/input devices
- "c 13:* rmw"
- "c 199:* rmw"
# ... for /dev/dri devices
- "c 226:* rmw"
Dockerfile.debug
# ARGUMENTS --------------------------------------------------------------------
##
# Board architecture
##
ARG IMAGE_ARCH=
##
# Base container version
##
ARG BASE_VERSION=3.3.1
##
# Debug port
##
ARG DEBUG_SSH_PORT=
##
# Run as
##
ARG SSHUSERNAME=
##
# Directory of the application inside container
##
ARG APP_ROOT=
##
# Board GPU vendor prefix
##
ARG GPU=
FROM --platform=linux/${IMAGE_ARCH} \
commontorizon/qt5-wayland${GPU}:${BASE_VERSION} AS debug
ARG IMAGE_ARCH
ARG GPU
ARG DEBUG_SSH_PORT
ARG SSHUSERNAME
ARG APP_ROOT
# SSH for remote debug
EXPOSE ${DEBUG_SSH_PORT}
EXPOSE 6512
ENV QT_QPA_PLATFORM="wayland"
# Make sure we don't get notifications we can't answer during building.
ENV DEBIAN_FRONTEND="noninteractive"
# for vivante GPU we need some "special" sauce
RUN apt-get -q -y update && \
if [ "${GPU}" = "-vivante" ] || [ "${GPU}" = "-imx8" ]; then \
apt-get -q -y install \
imx-gpu-viv-wayland-dev \
; else \
apt-get -q -y install \
libgl1 \
; fi \
&& \
apt-get clean && apt-get autoremove && \
rm -rf /var/lib/apt/lists/*
# your regular RUN statements here
# Install required packages
RUN apt-get -q -y update && \
apt-get -q -y install \
v4l-utils \
openssl \
openssh-server \
rsync \
file \
screen \
python3-minimal \
python3-pip \
python3-setuptools \
python3-venv \
qml-module-qtquick-controls \
qml-module-qtquick-controls2 \
qml-module-qtquick2 \
python3-pyside2.qtwidgets \
python3-pyside2.qtgui \
python3-pyside2.qtqml \
python3-pyside2.qtcore \
python3-pyside2.qtquick \
python3-pyside2.qtnetwork \
qml-module-qtquick-dialogs \
qtwayland5 \
&& apt-get clean && apt-get autoremove && \
rm -rf /var/lib/apt/lists/*
# edge case for amd64
# this prevent the error: texture atlas allocation failed
RUN apt-get -q -y update && \
if [ "${IMAGE_ARCH}" = "amd64" ]; then \
apt-get -q -y install \
libqt5quick5 \
; fi \
&& \
apt-get clean && apt-get autoremove && \
rm -rf /var/lib/apt/lists/*
# automate for torizonPackages.json
RUN apt-get -q -y update && \
apt-get -q -y install \
# DO NOT REMOVE THIS LABEL: this is used for VS Code automation
# __torizon_packages_dev_start__
# __torizon_packages_dev_end__
# DO NOT REMOVE THIS LABEL: this is used for VS Code automation
&& \
apt-get clean && apt-get autoremove && \
rm -rf /var/lib/apt/lists/*
# Create virtualenv
RUN python3 -m venv ${APP_ROOT}/.venv --system-site-packages
# Install pip packages on venv
COPY requirements-debug.txt /requirements-debug.txt
RUN . ${APP_ROOT}/.venv/bin/activate && \
pip3 install --upgrade pip && pip3 install -r requirements-debug.txt && \
rm requirements-debug.txt
# ⚠️ DEBUG PURPOSES ONLY!!
# THIS CONFIGURES AN INSECURE SSH CONNECTION
# create folders needed for the different components
# configures SSH access to the container and sets environment by default
RUN mkdir /var/run/sshd && \
sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' \
-i /etc/pam.d/sshd && \
if test $SSHUSERNAME != root ; \
then mkdir -p /home/$SSHUSERNAME/.ssh ; \
else mkdir -p /root/.ssh ; fi && \
echo "PermitUserEnvironment yes" >> /etc/ssh/sshd_config && \
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config && \
echo "Port ${DEBUG_SSH_PORT}" >> /etc/ssh/sshd_config && \
echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config && \
echo "PermitEmptyPasswords yes" >> /etc/ssh/sshd_config && \
su -c "env" $SSHUSERNAME > /etc/environment && \
echo "$SSHUSERNAME:" | chpasswd -e
RUN rm -r /etc/ssh/ssh*key && \
dpkg-reconfigure openssh-server
# Copy the application source code in the workspace to the $APP_ROOT directory
# path inside the container, where $APP_ROOT is the torizon_app_root
# configuration defined in settings.json
COPY --chown=$SSHUSERNAME:$SSHUSERNAME ./src ${APP_ROOT}/src
CMD [ "/usr/sbin/sshd", "-D" ]
I commented out devices 0-3 because of the output of these two commands, not sure if that’s correct:
devices
torizon@colibri-imx8x-07329158:~$ ls -ltrh /dev/video*
crw-rw---- 1 root video 81, 1 Dec 18 17:17 /dev/video1
crw-rw---- 1 root video 81, 0 Dec 18 17:17 /dev/video0
crw-rw---- 1 root video 81, 3 Dec 18 17:17 /dev/video3
crw-rw---- 1 root video 81, 2 Dec 18 17:17 /dev/video2
crw-rw---- 1 root video 81, 5 Jan 8 11:21 /dev/video5
crw-rw---- 1 root video 81, 6 Jan 8 11:21 /dev/video6
crw-rw---- 1 root video 81, 4 Jan 8 11:21 /dev/video4
crw-rw---- 1 root video 81, 7 Jan 8 11:21 /dev/video7
torizon@colibri-imx8x-07329158:~$ for I in /sys/class/video4linux/*; do cat $I/name; done
amphion-vpu-decoder
amphion-vpu-encoder
mxc-jpeg-dec
mxc-jpeg-enc
Logitech BRIO
Logitech BRIO
Logitech BRIO
Logitech BRIO
Plugging in the webcam, dmesg says this:
[ 3889.518830] usb 1-1.2.1.3.2: Found UVC 1.00 device Logitech BRIO (046d:085e)
[ 3889.524534] input: Logitech BRIO as /devices/platform/bus@5b000000/5b110000.usb/5b130000.usb/xhci-hcd.1.auto/usb1/1-1/1-1.2/1-1.2.1/1-1.2.1.3/1-1.2.1.3.2/1-1.2.1.3.2:1.0/input/input9
Running v4l2-ctl --list-devices
doesn’t print anything for the webcam though:
amphion vpu decoder (platform: amphion-vpu):
/dev/video0
I don’t really know where to go from here. I’m not sure if I even need the v4l stuff (rather GStreamer?), but what it currently prints indicates to me that the webcam isn’t correctly recognized.
How to get it to do that I don’t know, some threads on this forum make it sound like it should “just work”.
I’m also confused by the users. The output from v4l2-ctl
I got using a “Container console” on Portainer running as root user, whereas when ssh-ing with the torizon user (the other console outputs I posted), v4l2-ctl
is an unrecognized command.
tdx-info Output
Software summary
------------------------------------------------------------
Bootloader: U-Boot
Kernel version: 5.15.129-6.5.0+git.6f8fd49366db #1-TorizonCore SMP PREEMPT Fri Dec 22 11:15:52 UTC 2023
Kernel command line: root=LABEL=otaroot rootfstype=ext4 quiet logo.nologo vt.global_cursor_default=0 plymouth.ignore-serial-consoles splash fbcon=map:3 ostree=/ostree/boot.1/torizon/7e7d5c182b8db9a981d1f942cee2a808b3535fa86862471d67f718c4959f44df/0
Distro name: NAME="TorizonCore"
Distro version: VERSION_ID=6.5.0-build.8
Distro variant: VARIANT="Docker"
Hostname: colibri-imx8x-07329158
------------------------------------------------------------
Hardware info
------------------------------------------------------------
HW model: Toradex Colibri iMX8QXP on Colibri Evaluation Board V3
Toradex version: 0038 V1.0D
Serial number: 07329158
Processor arch: aarch64
------------------------------------------------------------