Open MasinAD opened 3 years ago
I'm unable to reproduce this on Ubuntu 18.04 (kernel 4.15.0-143) using the same v4l2loopback version with/without running ffplay /dev/video0
. Do you see the issue even without having an app connected to the cam? If it only happens with an app, which one is it?
Also, if you choose a specific device you will see a better error message, for example:
with pyvirtualcam.Camera(width=1280, height=720, fps=20, device="/dev/video0") as cam:
This must match the device created by v4l2loopback obviously.
Thanks for your quick response.
This issue occurs even without any consumer connected at any point. I just started a script and quit it (Ctrl+c) and then tried to restart it, resulting in above error.
I also tried specifying the device to use which resulted in this error:
RuntimeError: 'v4l2loopback' backend: Device /dev/video10 is not a video output device.
Until now I didn't try connecting another producer after having run a pyvirtualcam script. I just tried with OBS, and OBS can connect to the loopback device. I even added another v4l2 source in OBS and selected my loopback device, and it worked.
Yesterday, I tried the virtualvideo module which uses ffmpeg for accessing the loopback device. I just tried running their showFish.py sample after having used pyvirtualcam and it worked, too.
Neither dmesg -w
nor journalctl -f
show any messages related to v4l2.
Basically, it looks like pyvirtualcam leaves the loopback device in a state that makes it unaccessible for pyvirtualcam again but not for any other application.
I attached strace
s of the same script file working and failing.
pyvirtualcam_working.trace.txt
pyvirtualcam_failed.trace.txt
Beginning at line 3736 the execution diverges. The working case shows:
ioctl(5, VIDIOC_QUERYCAP, {driver="v4l2 loopback", card="Overlay", bus_info="platform:v4l2loopback-000", version=KERNEL_VERSION(5, 12, 7), capabilities=V4L2_CAP_VIDEO_OUTPUT|V4L2_CAP_VIDEO_M2M|V4L2_CAP_EXT_PIX_FORMAT|V4L2_CAP_READWRITE|V4L2_CAP_STREAMING|V4L2_CAP_DEVICE_CAPS, device_caps=V4L2_CAP_VIDEO_OUTPUT|V4L2_CAP_VIDEO_M2M|V4L2_CAP_EXT_PIX_FORMAT|V4L2_CAP_READWRITE|V4L2_CAP_STREAMING}) = 0
while in the failing case it shows:
ioctl(5, VIDIOC_QUERYCAP, {driver="v4l2 loopback", card="Overlay", bus_info="platform:v4l2loopback-000", version=KERNEL_VERSION(5, 12, 7), capabilities=V4L2_CAP_VIDEO_M2M|V4L2_CAP_EXT_PIX_FORMAT|V4L2_CAP_READWRITE|V4L2_CAP_STREAMING|V4L2_CAP_DEVICE_CAPS, device_caps=V4L2_CAP_VIDEO_M2M|V4L2_CAP_EXT_PIX_FORMAT|V4L2_CAP_READWRITE|V4L2_CAP_STREAMING}) = 0
Interestingly, pyvirtualcam doesn't detect V4L2_CAP_VIDEO_OUTPUT
capability anymore. Which, concidentally, is the same that v4l2-ctl
detects (before):
[masin@luna webcam]$ v4l2-ctl -d /dev/video10 -D
Driver Info:
Driver name : v4l2 loopback
Card type : Overlay
Bus info : platform:v4l2loopback-000
Driver version : 5.12.7
Capabilities : 0x85208002
Video Output
Video Memory-to-Memory
Read/Write
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x05208002
Video Output
Video Memory-to-Memory
Read/Write
Streaming
Extended Pix Format
(after):
[masin@luna webcam]$ v4l2-ctl -d /dev/video10 -D
Driver Info:
Driver name : v4l2 loopback
Card type : Overlay
Bus info : platform:v4l2loopback-000
Driver version : 5.12.7
Capabilities : 0x85208000
Video Memory-to-Memory
Read/Write
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x05208000
Video Memory-to-Memory
Read/Write
Streaming
Extended Pix Format
I am not especially apt in reading strace
s but in the working case's trace log there's an "Inappropriate ioctl for device" in line 3824. I can't tell if that's important or somewhere in its vicinity.
Not exactly sure what's going on. How do you create the device? Are you using exclusive_caps=1
by any chance? Even if, it should still work...
sudo modprobe -r v4l2loopback && sudo modprobe v4l2loopback devices=1 video_nr=10 card_label="Overlay" exclusive_caps=1 max_buffers=2
If I remove exclusive_caps=1
I don't have to unload and reload the kernel module anymore. Thanks a lot! That solves my immediate problem.
There's still the question why every other application but pyvirtualcam isn't bothered by having the loopback device been used before. But that's more out of curiosity than urgency.
On my end I still can't reproduce it with the same modprobe line you've given, with exclusive_caps=1
.
For me, before running the pyvirtualcam script, v4l2-ctl
shows "Video Output". While running it, it shows "Video Capture". After exiting the script with ctrl-c it has "Video Output" again. This is what exclusive_caps=1
does. And if you leave it out, then it always advertises both capture and output. In your case, the weird thing is that you see neither after the script exits, which is something that shouldn't be possible.
I do face the same issue on gentoo linux (pyvirtualcam==0.8.0).
After modprobe, befor using: Driver Info: Driver name : v4l2 loopback Card type : Webcam Bus info : platform:v4l2loopback-000 Driver version : 5.10.61 Capabilities : 0x85208002 Video Output Video Memory-to-Memory Read/Write Streaming Extended Pix Format Device Capabilities Device Caps : 0x05208002 Video Output Video Memory-to-Memory Read/Write Streaming Extended Pix Format
After terminating: Driver Info: Driver name : v4l2 loopback Card type : Webcam Bus info : platform:v4l2loopback-000 Driver version : 5.10.61 Capabilities : 0x85208000 Video Memory-to-Memory Read/Write Streaming Extended Pix Format Device Capabilities Device Caps : 0x05208000 Video Memory-to-Memory Read/Write Streaming Extended Pix Format
I am using Ubuntu 20.04.4 LTS x86_64
with pyvirtualcam at v0.9.1
and face the same problem. The program throws an exception when it can't detect the device as output ( if v4l2_capability hasn't V4L2_CAP_VIDEO_OUTPUT) when using case exlusive_caps=1
. Removing the throw where it checks this capability circumvents the issue.
Since in my case exlusive_caps=1
is essential, I will temporarily create a fork where I ignore whenever the OUTPUT flag fails.
If there is any other additional information that you need to recreate the issue, please ask me : )
I'm experiencing a very similar (perhaps, identical?) problem. If I load v4l2 by running:
modprobe v4l2loopback devices=1 video_nr=9
I can only start pyvirtualcamera once. The second time I do it, I get the following error:
Traceback (most recent call last): File "/home/jedrek/alternatywy/projects/Playground/VirtualCamera/cam_test.py", line 4, in <module> with pyvirtualcam.Camera(width=1280, height=720, fps=20, device="/dev/video9") as cam: File "/home/jedrek/alternatywy/projects/Playground/venv/lib/python3.10/site-packages/pyvirtualcam/camera.py", line 219, in __init__ raise RuntimeError('\n'.join(errors)) RuntimeError: 'v4l2loopback' backend: std::exception
One workaround is to load the module with exclusive_caps=0
, then everything is fine and I can start it multiple times (but I don't see the camera in Chrome).
Details of my system:
Linux version 5.18.12-1-default (geeko@buildhost) (gcc (SUSE Linux) 12.1.1 20220721 [revision 4f15d2234608e82159d030dadb17af678cfad626], GNU ld (GNU Binutils; openSUSE Tumbleweed) 2.38.20220525-6) #1 SMP PREEMPT_DYNAMIC Fri Jul 15 12:08:33 UTC 2022 (3198c22)
I'm using Python 3.10.4.
Same issue for me under Ubuntu 22
with pyvirtualcam.Camera(width = 640, height = 480, fps = 25) as camera:
File "/home/henry/PycharmProjects/facefusion/venv/lib/python3.10/site-packages/pyvirtualcam/camera.py", line 219, in __init__
raise RuntimeError('\n'.join(errors))
RuntimeError: 'v4l2loopback' backend: std::exception
Similar issue for me running Ubuntu 22.04.3 LTS:
sudo modprobe v4l2loopback devices=1 video_nr=0 exclusive_caps=1
, my code crashes if I run it twice in a row (without even actually using the device) and destroying and recreating it with sudo modprobe
fixes it temporarily. Upon creation the device is detected as output only, and after running the code is detected as neither input nor output.sudo modprobe v4l2loopback devices=1 video_nr=0
makes everything work and I can also view the device output in VLC, even though some values in the output of v4l2-ctl get modified (Width/Height, Pixel Format, Bytes per Line, Size Image, Quantization). The device is also always detected as both input and output.This is the code I'm running, it's the basic greyscale animation with a SIGINT handler for a graceful exit (which I thought was the issue...):
This is the output of v4l2-ctl --all -d /dev/video0
when I create the device with before and after the first run of my program:
This is the exception raised by my program:
And this is the output i have creating the device without exclusive_caps=1
, before and after running the code:
The first execution of the same camera is normal, but the execution after ctrl+c is abnormal.
Fix: Stop the video stream before closing the device, e.g: ioctl(vcam->device, VIDIOC_STREAMOFF, &parm) Source: https://github.com/obsproject/obs-studio/pull/7078
A fix might be to insert this before 'close(_camera_fd);':
struct v4l2_streamparm parm = {0};
parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
if (ioctl(_camera_fd, VIDIOC_STREAMOFF, &parm) < 0) {
fprintf(stderr, "Failed to stop streaming on video device: %s\n", strerror(errno));
}
Maybe as an extra function, as the close() is used 3 times.
@GermanWarez Are you able to test this and create a PR if it works?
@letmaik I could add a test that would be executed by github actions, that should fail without the fix and pass with the extra line. But I have no linux device to test. Would be sufficient to accept a PR?
TODO: Add ioctl to set both VIDIOC_STREAMON and VIDIOC_STREAMOFF, using the fix for obs as reference.
I hit the same issue. Wait, nobody tested the PR since March?
Describe the bug After running a script using pyvirtualcam the next run causes this error:
Only after unloading and reloading the kernel module I can run another script using pyvirtualcam.
To Reproduce Every single sample code causes this error.
I even rewrote a script to not use the
with
statement and callcam.close()
(and evencam._backend.close()
) directly.