Details
-
Bug
-
Resolution: Incomplete
-
P3: Somewhat important
-
None
-
5.15.0
-
None
Description
Symptoms
When selecting webcams that have a camera interface and a metadata interface, when using v4l2 the metadata interface may be streamed instead of the camera. This results in no frames being received by the client.
Environment
See attached environment_info.txt for additional details
Device | Lenovo ThinkPad Carbon X1, 7th Generation |
OS | Arch Linux, Kernel 5.7.2-arch1-1 |
Desktop | Wayland 1.18-0, Sway 1:1.4-9 |
Camera | Azurewave AM-8GF56BB-A using uvcvideo driver |
Relevant ENVs | QT_QPA_PLATFORM=wayland-egl XDG_CURRENT_DESKTOP=sway also tried changing each and both to QT_QPA_PLATFORM=wayland XDG_CURRENT_DESKTOP=Unity |
Reproduction
It should be possible to reproduce this on any non-virtualized Linux device running kernel 5.7 or above, with a reasonably modern webcam, regardless of desktop environment. Ensure that v4l2-ctl --list-devices shows two separate /dev/video* devices for the webcam.
I do not have a way to test this in isolation, unfortunately, but it should be relatively trivial for an experienced Qt developer to put together a simple test app. This triggered a bug in Zoom (which I will be filing with them), which led me to examine the Qt source, discovering this issue.
It can be verified that the actual camera stream does work in Qt by installing and loading the v4l2loopback kernel module, using ffmpeg -f v4l2 -i /dev/video0 -f v4l2 /dev/video2 to redirect the video to a different device, and selecting the "Dummy video device".
Suspected Cause
Video devices are often referenced by name. When using v4l2, device names are not unique. There may be two devices by the same name (see attached), for the same webcam, only one of which is a camera interface.
CameraBinServicePlugin::defaultDevice returns a device name. However, one of the devices for this name may be a metadata interface. This is in addition to the actual video capture interface discovered by QGstUtils::enumerateCameras.
Through a significantly long code path omitted here, Qt ends up getting a GstElementFactory from GStreamer using that name. From here, I get a bit lost in the code, but my guess is that the GStreamer element includes all source interfaces, including both camera and metadata, with the given name. Qt may not be restricting access to only the camera interface, but instead presenting one as the "primary" and the other as the "secondary".
If this is the case, clients attempting to use this feature may (fairly) assume that any device they get is a camera, and inadvertently choose the wrong one.