umlaeute / v4l2loopback

v4l2-loopback device
GNU General Public License v2.0
3.69k stars 523 forks source link

Invalid IOCTL call in 4.16 #172

Closed sarnex closed 6 years ago

sarnex commented 6 years ago

Enviroment

Problem

I cannot use v4l2loopback in 4.16. Reverting to 4.15 works fine. When I try, I get an error about invalid arguments to an IOCTL.

[v4l2 @ 0x55e3b5747220] ioctl(VIDIOC_G_FMT): Invalid argument
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Error initializing output stream 0:0 -- 

Steps to reproduce:

1) Load v4l2loopback

2) Run this script in FFMPEG:

ffmpeg -f x11grab -r 30 -s 2560x1440 -i :0.0+1920,0 -vcodec rawvideo -pix_fmt yuv420p -threads 16 -f v4l2 /dev/video0

Results of above:

ffmpeg version 3.4.2 Copyright (c) 2000-2018 the FFmpeg developers                                                                                                                           
  built with gcc 7.3.0 (Gentoo 7.3.0 p1.0)                                                                                                                                                   
  configuration: --prefix=/usr --libdir=/usr/lib64 --shlibdir=/usr/lib64 --docdir=/usr/share/doc/ffmpeg-3.4.2-r1/html --mandir=/usr/share/man --enable-shared --cc=x86_64-pc-linux-gnu-gcc --cxx=x86_64-pc-linux-gnu-g++ --ar=gcc-ar --optflags='-flto=16 -fuse-linker-plugin -floop-interchange -ftree-loop-distribution -floop-strip-mine -floop-block -ftree-vectorize -march=native -O2 -pipe -mindirect-branch=thunk' --disable-static --enable-avfilter --enable-avresample --disable-stripping --enable-nonfree --disable-indev=oss --disable-indev=jack --disable-outdev=oss --enable-bzlib --disable-runtime-cpudetect --disable-debug --disable-gcrypt --disable-gnutls --disable-gmp --enable-gpl --enable-hardcoded-tables --enable-iconv --disable-lzma --enable-network --disable-opencl --enable-openssl --enable-postproc --disable-libsmbclient --enable-ffplay --enable-sdl2 --enable-vaapi --enable-vdpau --enable-xlib --enable-libxcb --enable-libxcb-shm --enable-libxcb-xfixes --enable-zlib --disable-libcdio --disable-libiec61883 --disable-libdc1394 --disable-libcaca --disable-openal --enable-opengl --disable-libv4l2 --enable-libpulse --disable-libdrm --disable-libopencore-amrwb --disable-libopencore-amrnb --disable-libfdk-aac --disable-libopenjpeg --enable-libbluray --disable-libcelt --disable-libgme --disable-libgsm --disable-mmal --disable-libmodplug --disable-libopus --disable-libilbc --disable-librtmp --disable-libssh --disable-libspeex --enable-librsvg --enable-libvorbis --disable-libvpx --disable-libzvbi --disable-appkit --disable-libbs2b --disable-chromaprint --disable-libflite --disable-frei0r --disable-libfribidi --disable-fontconfig --disable-ladspa --disable-libass --enable-libfreetype --disable-librubberband --disable-libzmq --disable-libzimg --disable-libsoxr --enable-pthreads --disable-libvo-amrwbenc --enable-libmp3lame --disable-libkvazaar --disable-nvenc --disable-libopenh264 --disable-libsnappy --disable-libtheora --disable-libtwolame --disable-libwavpack --enable-libwebp --enable-libx264 --disable-libx265 --enable-libxvid --disable-armv5te --disable-armv6 --disable-armv6t2 --disable-neon --disable-vfp --disable-vfpv3 --disable-armv8 --disable-mipsdsp --disable-mipsdspr2 --disable-mipsfpu --disable-altivec --disable-amd3dnow --disable-amd3dnowext --disable-fma4 --disable-xop --cpu=host --enable-lto --disable-doc --disable-htmlpages --enable-manpages
  libavutil      55. 78.100 / 55. 78.100
  libavcodec     57.107.100 / 57.107.100
  libavformat    57. 83.100 / 57. 83.100
  libavdevice    57. 10.100 / 57. 10.100
  libavfilter     6.107.100 /  6.107.100
  libavresample   3.  7.  0 /  3.  7.  0
  libswscale      4.  8.100 /  4.  8.100
  libswresample   2.  9.100 /  2.  9.100
  libpostproc    54.  7.100 / 54.  7.100
[x11grab @ 0x55f0964d6420] Stream #0: not enough frames to estimate rate; consider increasing probesize
Input #0, x11grab, from ':0.0+1920,0':
  Duration: N/A, start: 1523211730.953105, bitrate: N/A
    Stream #0:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 2560x1440, 30 fps, 1000k tbr, 1000k tbn, 1000k tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> rawvideo (native))
Press [q] to stop, [?] for help
HERE 1
4
BEFORE
[v4l2 @ 0x55f0964e2220] ioctl(VIDIOC_G_FMT): Invalid argument
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Error initializing output stream 0:0 -- 
Conversion failed!

I was not able to find what changed in 4.16 through the kernel release notes.

Thank you, and let me know if you need any more information

Sarnex

sarnex commented 6 years ago

@umlaeute Hey, is there anything I can do to help debug this? I don't know if the issue is in the kernel, ffmpeg, or v4l2loopback.

Thank you, Sarnex

umlaeute commented 6 years ago

i don't know (and will wait until 4.16 shows up in Debian/unstable to do any testing myself).

in the meantime, you can enable debugging in the module, and see whether it gives you any additional information:

rmmod v4l2loopback
modprobe v4l2loopback debug=2
[...]
dmesg
sarnex commented 6 years ago

Thanks. I tried it and didnt see any extra output when running ffmpeg, only the same spam.

Also, the Ubuntu kernel from below would likely work if you are willing to test it: http://kernel.ubuntu.com/%7Ekernel-ppa/mainline/v4.16/

eldog commented 6 years ago

Hi I have the same problem on 4.16.5

Loading the module with modprobe v4l2loopback debug=2

Then running gst-launch-1.0 -v videotestsrc ! video/x-raw, width=640, height=480 ! videoconvert ! v4l2sink device=/dev/video0

With print out on dmesg -wH

[Apr30 20:41] /var/lib/dkms/v4l2loopback/0.11.0.r0.g05a03e2/build/v4l2loopback.c:1827[v4l2_loopback_open]
[  +0.000003] v4l2-loopback[1851]: opened dev:00000000f6e8a94f with image:          (null)
[  +0.000001] /var/lib/dkms/v4l2loopback/0.11.0.r0.g05a03e2/build/v4l2loopback.c:1852[v4l2_loopback_open]
[  +0.000004] video0: VIDIOC_QUERYCAP: driver=v4l2 loopback, card=Dummy video device (0x0000), bus=platform:v4l2loopback-000, version=0x00041005, capabilities=0x85208003, device_caps=0x85208003
[  +0.000009] /var/lib/dkms/v4l2loopback/0.11.0.r0.g05a03e2/build/v4l2loopback.c:1308[vidioc_enum_input]
[  +0.000001] video0: VIDIOC_ENUMINPUT: index=0, name=loopback, type=2, audioset=0x0, tuner=0, std=0x00000000, status=0x0, capabilities=0x0
[  +0.000012] /var/lib/dkms/v4l2loopback/0.11.0.r0.g05a03e2/build/v4l2loopback.c:1308[vidioc_enum_input]
[  +0.000000] video0: VIDIOC_ENUMINPUT: error -22: index=1, name=, type=0, audioset=0x0, tuner=0, std=0x00000000, status=0x0, capabilities=0x0
[  +0.000003] video0: VIDIOC_ENUMSTD: error -25: index=0, id=0x0, name=, fps=0/0, framelines=0
[  +0.000006] video0: VIDIOC_QUERYCTRL: id=0x980001, type=6, name=User Controls, min/max=0/0, step=0, default=0, flags=0x00000044
[  +0.000003] video0: VIDIOC_QUERYCTRL: id=0x98f900, type=2, name=keep_format, min/max=0/1, step=1, default=0, flags=0x00000000
[  +0.000003] video0: VIDIOC_QUERYCTRL: id=0x98f901, type=2, name=sustain_framerate, min/max=0/1, step=1, default=0, flags=0x00000000
[  +0.000003] video0: VIDIOC_QUERYCTRL: id=0x98f902, type=1, name=timeout, min/max=0/100000, step=1, default=0, flags=0x00000000
[  +0.000003] video0: VIDIOC_QUERYCTRL: id=0x98f903, type=2, name=timeout_image_io, min/max=0/1, step=1, default=0, flags=0x00000000
[  +0.000004] video0: VIDIOC_QUERYCTRL: error -22: id=0x8098f903, type=0, name=, min/max=0/0, step=0, default=0, flags=0x00000000
[  +0.000003] video0: VIDIOC_G_STD: error -25: std=0x00000000
[  +0.000003] video0: VIDIOC_G_OUTPUT: error -25: value=0
[  +0.110405] video0: VIDIOC_ENUM_FMT: error -22: index=0, type=vid-out, flags=0x0, pixelformat=
[  +0.000008] video0: VIDIOC_CROPCAP: error -25: type=vid-out, bounds wxh=0x0, x,y=0,0, defrect wxh=0x0, x,y=0,0, pixelaspect 0/0
[  +0.000343] /var/lib/dkms/v4l2loopback/0.11.0.r0.g05a03e2/build/v4l2loopback.c:1861[v4l2_loopback_close]
[  +0.000003] /var/lib/dkms/v4l2loopback/0.11.0.r0.g05a03e2/build/v4l2loopback.c:1976[try_free_buffers]
[  +0.000001] /var/lib/dkms/v4l2loopback/0.11.0.r0.g05a03e2/build/v4l2loopback.c:1959[free_buffers]
[  +0.000002] v4l2-loopback[1960]: freeing image@          (null) for dev:00000000f6e8a94f
[  +0.000001] /var/lib/dkms/v4l2loopback/0.11.0.r0.g05a03e2/build/v4l2loopback.c:1880[v4l2_loopback_close]

I don't know what to look for at the moment, but I have noticed that in 4.16.5 at least meta nodes have been added for each device (now when I plug in a real webcam I get to devices /dev/videoX and /dev/videoX+1, the /dev/videoX+1 node is for meta data). I believe it's to do with this patch in the kernel.

I can see that there are errors in dmesg starting with

VIDIOC_ENUMINPUT: error -22: index=1, name=, type=0, audioset=0x0, tuner=0, std=0x00000000, status=0x0, capabilities=0x0

I may be wrong but is this looking for the meta node at the next index? Update I'm wrong on the enum input ioctl, reading the docs you enumerate inputs of a device by increasing the index until it returns -1, so this is the correct behaviour.

It does seem that ready_for_capture is never set to 1 so it fails.

Version used:

VennStone commented 6 years ago

Have the same issue on Ubuntu 17.10 with 4.16.8.

MikkoMMM commented 6 years ago

I'm on Arch Linux. I had to modify the command a bit but this produces the aforementioned output as well: ffmpeg -f x11grab -r 30 -s 2560x1440 -i :0.0+0,0 -vcodec rawvideo -pix_fmt yuv420p -threads 16 -f v4l2 /dev/video0

Also, this results in the same error:

[mikko@localhost video]$ ffmpeg -i test.avi -f v4l2 /dev/video0
ffmpeg version 3.4.2 Copyright (c) 2000-2018 the FFmpeg developers
  built with gcc 7.3.0 (GCC)
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avresample --enable-fontconfig --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libiec61883 --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-shared --enable-version3 --enable-omx
  libavutil      55. 78.100 / 55. 78.100
  libavcodec     57.107.100 / 57.107.100
  libavformat    57. 83.100 / 57. 83.100
  libavdevice    57. 10.100 / 57. 10.100
  libavfilter     6.107.100 /  6.107.100
  libavresample   3.  7.  0 /  3.  7.  0
  libswscale      4.  8.100 /  4.  8.100
  libswresample   2.  9.100 /  2.  9.100
  libpostproc    54.  7.100 / 54.  7.100
Invalid return value 0 for stream protocol
    Last message repeated 1 times
Input #0, avi, from 'test.avi':
  Metadata:
    encoder         : MEncoder dev-CVS-060415-01:32-3.4.6
  Duration: 00:24:06.94, start: 0.000000, bitrate: 1234 kb/s
    Stream #0:0: Video: h264 (Main) (h264 / 0x34363268), yuv420p(progressive), 720x576, 1005 kb/s, SAR 65536:65535 DAR 16384:13107, 25 fps, 25 tbr, 25 tbn, 50 tbc
    Stream #0:1: Audio: mp3 (U[0][0][0] / 0x0055), 48000 Hz, stereo, s16p, 216 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> rawvideo (native))
Press [q] to stop, [?] for help
[v4l2 @ 0x557761f52160] ioctl(VIDIOC_G_FMT): Invalid argument
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Error initializing output stream 0:0 -- 
Conversion failed!
code 1
Xohwie1i commented 6 years ago

I have the same problem.

I'm running Arch Linux on a X1 Carbon, 5th gen., with a vanilla 4.18.8-1 kernel and v4l2loopback-dkms installed from the AUR.

Running the command:

sudo modprobe v4l2loopback video_nr=1 card_label="test"

gives:

$ v4l2-ctl --list-devices
test (platform:v4l2loopback-000):
  /dev/video2

Integrated Camera: Integrated C (usb-0000:00:14.0-8):
  /dev/video0
  /dev/video1

And running:

ffmpeg -f x11grab -r 10 -s 2560x1440 -vf "scale=640:360" -f v4l2 /dev/video2

gives:

 ffmpeg version 4.0 Copyright (c) 2000-2018 the FFmpeg developers
   built with gcc 8.1.0 (GCC)
   configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avresample --enable-fontconfig --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa
 --enable-libass --enable-libbluray --enable-libdrm --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libiec61883 --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264
 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-nvenc --enable-omx --enable-shared --enable-version3
   libavutil      56. 14.100 / 56. 14.100
   libavcodec     58. 18.100 / 58. 18.100
   libavformat    58. 12.100 / 58. 12.100
   libavdevice    58.  3.100 / 58.  3.100
   libavfilter     7. 16.100 /  7. 16.100
   libavresample   4.  0.  0 /  4.  0.  0
   libswscale      5.  1.100 /  5.  1.100
   libswresample   3.  1.100 /  3.  1.100
   libpostproc    55.  1.100 / 55.  1.100
 Output #0, v4l2, to '/dev/video2':
 Output file #0 does not contain any stream
notfood commented 6 years ago

Same thing over here. ArchLinux v4l2loopback-dkms-git 0.11.0.r0.g05a03e2 ffmpeg 4.0

$ v4l2-ctl --list-devices
loopback 1 (platform:v4l2loopback-000):
        /dev/video0
$ ffmpeg -f x11grab -r 10 -s 2560x1440 -vf "scale=640:360" -f v4l2 /dev/video0 
ffmpeg version 4.0 Copyright (c) 2000-2018 the FFmpeg developers
  built with gcc 8.1.0 (GCC)
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avresample --enable-fontconfig --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libdrm --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libiec61883 --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-nvenc --enable-omx --enable-shared --enable-version3
  libavutil      56. 14.100 / 56. 14.100
  libavcodec     58. 18.100 / 58. 18.100
  libavformat    58. 12.100 / 58. 12.100
  libavdevice    58.  3.100 / 58.  3.100
  libavfilter     7. 16.100 /  7. 16.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  1.100 /  5.  1.100
  libswresample   3.  1.100 /  3.  1.100
  libpostproc    55.  1.100 / 55.  1.100
Output #0, v4l2, to '/dev/video0':
Output file #0 does not contain any stream

It's enough to write

ffmpeg -f v4l2 /dev/video0

for it to fail

sarnex commented 6 years ago

@umlaeute It looks like 4.16 is available in Debian unstable. Are you able to take a look into this issue?

Thanks.

umlaeute commented 6 years ago

yep. so far I've been able to reproduce the problem (but haven't had time to dig into it)

flipreverse commented 6 years ago

@umlaeute The 'solution' is quiet easy: Change line 2096 (https://github.com/umlaeute/v4l2loopback/blob/master/v4l2loopback.c#L2096) to #if LINUX_VERSION_CODE >= LINUX_KERNEL_VERSION(3,7,0) Checking the presumably old definition of VFL_DIR_M2M, leads to an uninitialized member vfl_dir. That in turn results in is_tx=0 in check_fmt() in drivers/media/v4l2-core/v4l2-ioctl.c which leads to -EINVAL being returned.

I put solution in quotation marks, because I know too little about v4l2 to guarantee that this change is side effect free.

sarnex commented 6 years ago

It seems the macro is really called KERNEL_VERSION, and if I use that instead everything seems to work.

I also don't know if it's correct but it seems to fix this bug. Thanks flipreverse!

MikkoMMM commented 6 years ago

I can confirm that changing line 2096 on v4l2loopback.c to #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) worked for me as well. Thanks.

YodaEmbedding commented 6 years ago

Has this been committed into a stable release? I'm still getting the error on version 0.11.0.

EDIT: I'm stupid. But it would be nice to get it stable nonetheless. ;)

nimatrueway commented 5 years ago

I had the exact problem and the solution @flipreverse suggested worked for me. Now it is line v4l2loopback.c : 2271 that needs to be changed from #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) to #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) (in struct v4l2_loopback_ioctl_ops)

umlaeute commented 5 years ago

@nimatrueway are you saying that when compiling against linux-4.x, you get different results for KERNEL_VERSION(2,6,29) resp KERNEL_VERSION(3,7,0)?

that looks very fishy to me (the #if clause should evaluate to true in both cases, as 4.0.0>3.7.0 and 4.0.0>2.6.29)

umlaeute commented 5 years ago

@SicariusNoctis yes, it's in v0.12.0

nimatrueway commented 5 years ago

@umlaeute Yeah, that's what screwed with my head too. So I tried everything all over again, but this time a bit more carefully, and I realized that I was wrong. Sorry!

For everyone else who reads this later:

Make sure you remove any older version of v4l2loopback installed your system first:

sudo modprobe -r v4l2loopback find "/lib/modules/$(uname -r)" | grep v4l2loopback | sudo xargs rm

maxsupermanhd commented 5 years ago

No success here. Tried all above. Same error. Ubuntu 18.04. @umlaeute Also throwing up compilation errors on any changes.

perk11 commented 5 years ago

Still getting this on Ubuntu 18.04 after removing the old version and compiling 0.12.2. from github

Kernel version is 4.15.0-62-generic

robstewart57 commented 4 years ago

@umlaeute also experiencing this issue.

ffplay /dev/video0
...
[video4linux2,v4l2 @ 0x7fef40000bc0] ioctl(VIDIOC_G_FMT): Invalid argument
umlaeute commented 4 years ago

@robstewart57 you need a producer first.

potassium-chloride commented 4 years ago

Can you publish a signed version of patched module? I have some problems with inserting unsigned module on my machine with secure boot and sudo echo x > /proc/sysrq-trigger doesn't fix it. Kernel: 5.3.0-46-generic

umlaeute commented 4 years ago

i only publish source code. but you need the binary to be signed (so: sign yourself :-))

d3m3n7 commented 4 years ago

Can you publish a signed version of patched module? I have some problems with inserting unsigned module on my machine with secure boot and sudo echo x > /proc/sysrq-trigger doesn't fix it. Kernel: 5.3.0-46-generic

I think I have the same exact issue. I've looked up every post online that talks about v4l2loopback issues and nothing has worked so far. My knowledge about kernels, signing binaries and secure boot is 0 so I can't even understand how to use the solutions given above.

What I've tried so far

First I installed the v4l2loopback in a machine without secure boot and everything worked flawlessly. I could use pyfakewebcam or ffmpeg to create streams without any issues.

Then I tried installing v4l2loopback in another machine with secure boot (downloading the code from the repository and following the readme instructions). After the installation I got the following error

$ sudo modprobe v4l2loopback
modprobe: ERROR: could not insert 'v4l2loopback': Operation not permitted

After this I uninstalled everything using @nimatrueway comment above and tried the following commands:

$ sudo apt-get install v4l2loopback-dkms`
$ sudo modprobe v4l2loopback

Which worked as expected creating the /dev/video* files. The problem came when I tried to stream to those files using ffmpeg or pyfakewebcam. Executing pyfakewebcam's example I got this:

.../pyfakewebcam.py", line 54, in __init__
fcntl.ioctl(self._video_device, _v4l2.VIDIOC_S_FMT, self._settings)
OSError: [Errno 22] Invalid argument

Executing ffmpeg I got this error

$ sudo ffmpeg -re -i myTestVideo.mp4 -f v4l2 /dev/video2
...
[v4l2 @ 0x561f49542be0] ioctl(VIDIOC_G_FMT): Invalid argument
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Error initializing output stream 0:0 --
zatherz commented 4 years ago

Might be useful if you're stupid like me - I was getting this issue on Arch, and forgot that v4l2loopback comes from the AUR and I didn't update the package (v4l2loopback-dkms) after pacman -Syu.