v4l2loopback broken in git ffmpeg #38

Closed
enmaskarado opened this Issue Mar 1, 2013 · 12 comments

Comments

Projects
None yet
5 participants

Newer versions of ffmpeg can't read v4l2loopback stream
ffmpeg -v debug -f video4linux2 -i /dev/video0 -f alsa -i pulse_monitor -vcodec libvpx -vb 300k -r 25 -quality good -cpu-used 0 -s 640x360 -aspect 16:9 -f webm /tmp/fifo2.webm

ffmpeg version N-38414-g997a362 Copyright (c) 2000-2013 the FFmpeg developers
built on Feb 26 2013 18:27:23 with gcc 4.7 (Ubuntu/Linaro 4.7.2-2ubuntu1)
configuration: --enable-gpl --enable-libfaac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvorbis --enable-libx264 --enable-nonfree --enable-version3 --enable-x11grab --enable-libvpx --enable-libxvid --enable-libpulse --enable-libspeex --enable-libfdk-aac --enable-libopus
libavutil 52. 17.103 / 52. 17.103
libavcodec 54. 92.100 / 54. 92.100
libavformat 54. 63.100 / 54. 63.100
libavdevice 54. 3.103 / 54. 3.103
libavfilter 3. 41.100 / 3. 41.100
libswscale 2. 2.100 / 2. 2.100
libswresample 0. 17.102 / 0. 17.102
libpostproc 52. 2.100 / 52. 2.100
Splitting the commandline.
Reading option '-v' ... matched as option 'v' (set libav* logging level) with argument 'debug'.
Reading option '-f' ... matched as option 'f' (force format) with argument 'video4linux2'.
Reading option '-i' ... matched as input file with argument '/dev/video0'.
Reading option '-f' ... matched as option 'f' (force format) with argument 'alsa'.
Reading option '-i' ... matched as input file with argument 'pulse_monitor'.
Reading option '-vcodec' ... matched as option 'vcodec' (force video codec ('copy' to copy stream)) with argument 'libvpx'.
Reading option '-vb' ... matched as AVOption 'vb' with argument '300k'.
Reading option '-r' ... matched as option 'r' (set frame rate (Hz value, fraction or abbreviation)) with argument '25'.
Reading option '-quality' ... matched as AVOption 'quality' with argument 'good'.
Reading option '-cpu-used' ... matched as AVOption 'cpu-used' with argument '0'.
Reading option '-s' ... matched as option 's' (set frame size (WxH or abbreviation)) with argument '640x360'.
Reading option '-aspect' ... matched as option 'aspect' (set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)) with argument '16:9'.
Reading option '-f' ... matched as option 'f' (force format) with argument 'webm'.
Reading option '/tmp/fifo2.webm' ... matched as output file.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option v (set libav* logging level) with argument debug.
Successfully parsed a group of options.
Parsing a group of options: input file /dev/video0.
Applying option f (force format) with argument video4linux2.
Successfully parsed a group of options.
Opening an input file: /dev/video0.
[video4linux2,v4l2 @ 0x2f18d00] fd:3 capabilities:5000003
[video4linux2,v4l2 @ 0x2f18d00] Selecting input_channel: 0
[video4linux2,v4l2 @ 0x2f18d00] input_channel: 0, input_name: loopback
[video4linux2,v4l2 @ 0x2f18d00] Querying the device for the current frame size
[video4linux2,v4l2 @ 0x2f18d00] Setting frame size to 320x240
[video4linux2,v4l2 @ 0x2f18d00] Trying to set codec:rawvideo pix_fmt:yuv420p
Last message repeated 1 times
[video4linux2,v4l2 @ 0x2f18d00] Trying to set codec:rawvideo pix_fmt:yuv422p
[video4linux2,v4l2 @ 0x2f18d00] Trying to set codec:rawvideo pix_fmt:yuyv422
[video4linux2,v4l2 @ 0x2f18d00] ioctl(VIDIOC_ENUMSTD): Invalid argument
/dev/video0: Invalid argument

Owner

umlaeute commented Mar 1, 2013

if ffmpeg is broken, why don't you report an error there?

¿ffmpeg broken? ffmpeg works fine with real v4l2 devices, v4l2loopback is the only one who does not work

I believe that VIDIOC_ENUMSTD is ¿meta?data that asks ffmpeg, but v4l2loopback can not answer (are they not implemented?)

Owner

umlaeute commented Mar 4, 2013

correct, ENUMSTD is not implemented, and there is no reason why it should be implemented: v4l2loopback is not a tuner device or similar, that delivers frame in PAL-G (or whatever).

if ffmpeg depends on a device to provide ENUMSTD, i consider it broken (until someone tells me better)

Owner

umlaeute commented Mar 4, 2013

and other versions ffmpeg can play the streamjust fine (e.g. "0.8.5-6" from the libav fork)

Could we not set v4l2loopback, to answer ENUMSTD with placebo data, or something? ej null

ubitux commented Mar 17, 2013

This problem is now reported here: https://ffmpeg.org/trac/ffmpeg/ticket/2370.

Owner

umlaeute commented Mar 18, 2013

thanks for forwarding the bug.
one possible reason why ffmpeg triggered the problem, is that v4l2loopback already provided placebo ioctls for other STD-ioctls (VIDIOC_G_STD, VIDIOC_S_STD, VIDIOC_QUERYSTD).

i have removed these placebos for now, maybe it helps with ffmpeg (so ffmpeg doesn't think anymore that the loopback device should be able to ENUMSTD).

i'm wondering whether this triggers other regressions.

holdenc commented Mar 18, 2013

Hi,

I'm trying to fix this bug for ffmpeg, but first of all, I tried v4l2loopback (both git head and
5568514, same result) with my application, and this is what I get:

[v4l2] Opening video device '/dev/video1'...
[v4l2] Querying capabilities, inputs and formats...
[v4l2] Capabilities:
[v4l2]   Driver:       v4l2 loopback
[v4l2]   Card:         Dummy video device (0x0000)
[v4l2]   Bus info:     v4l2loopback:0
[v4l2]   Version:      0x00000603
[v4l2]   Capabilities: 0x05000003 V4L2_CAP_VIDEO_CAPTURE V4L2_CAP_VIDEO_OUTPUT V4L2_CAP_READWRITE V4L2_CAP_STREAMING
[v4l2] Input 0:
[v4l2]   Name:         loopback
[v4l2]   Type:         0x00000002 V4L2_INPUT_TYPE_CAMERA
[v4l2]   Audioset:     0x00000000
[v4l2]   Tuner:        0x00000000
[v4l2]   Std:          0x0000000000ffffff
[v4l2]   Status:       0x00000000
[v4l2] Image format 0:
[v4l2]   Flags:        0x00000000
[v4l2]   Description:  [YV12]
[v4l2]   Pixelformat:  0x32315659
[v4l2] Selecting video input 0...
[v4l2]   Std:  0, 0x000000000000b000, NTSC
[v4l2]   Std:  1, 0x0000000000001000, NTSC-M
[v4l2]   Std:  2, 0x0000000000002000, NTSC-M-JP
[v4l2]   Std:  3, 0x0000000000008000, NTSC-M-KR
[v4l2]   Std:  4, 0x0000000000004000, NTSC-443
[v4l2]   Std:  5, 0x00000000000000ff, PAL
[v4l2]   Std:  6, 0x0000000000000007, PAL-BG
[v4l2]   Std:  7, 0x0000000000000008, PAL-H
[v4l2]   Std:  8, 0x0000000000000010, PAL-I
[v4l2]   Std:  9, 0x00000000000000e0, PAL-DK
[v4l2]   Std: 10, 0x0000000000000100, PAL-M
[v4l2]   Std: 11, 0x0000000000000200, PAL-N
[v4l2]   Std: 12, 0x0000000000000400, PAL-Nc
[v4l2]   Std: 13, 0x0000000000000800, PAL-60
[v4l2]   Std: 14, 0x0000000000ff0000, SECAM
[v4l2]   Std: 15, 0x0000000000010000, SECAM-B
[v4l2]   Std: 16, 0x0000000000040000, SECAM-G
[v4l2]   Std: 17, 0x0000000000080000, SECAM-H
[v4l2]   Std: 18, 0x0000000000320000, SECAM-DK
[v4l2]   Std: 19, 0x0000000000400000, SECAM-L
[v4l2]   Std: 20, 0x0000000000800000, SECAM-Lc
[v4l2]   Current std: 0x0000000000ffffff
[v4l2] VIDIOC_ENUMSTD: Invalid argument

I see at least two possible sources of problems:

  1. VIDIOC_ENUMINPUT ioctl on input0 returns an input.std=0x0000000000ffffff which is !=0, claiming this device supports different standards. The documentation at http://linuxtv.org/downloads/v4l-dvb-apis/standard.html says that: "Special rules apply to devices such as USB cameras where the notion of video standards makes little sense. [...] Here the driver shall set the std field of struct v4l2_input and struct v4l2_output to zero and the VIDIOC_G_STD, VIDIOC_S_STD, VIDIOC_QUERYSTD and VIDIOC_ENUMSTD ioctls shall return the ENOTTY error code." So perhaps 0 should be returned for this field.

  2. VIDIOC_G_STD ioctl returns a std_id=0x0000000000ffffff, which again I think is not possible because that would mean that this device current standard is, for example, both NTSC and PAL at the same time.

At the moment ffmpeg errors out because the VIDIOC_ENUMINPUT ioctl reaches the end of the enumeration returning EINVAL without being able to match the current standard with one in the enumeration, which should not happen unless this device falls under the USB exception.

Owner

umlaeute commented Mar 19, 2013

current git/master (as of today: 8bbe208) of v4l2loopback has disabled all STD ioctls (thus all of them should fail, so calling applications should never even think that the device supports any STDs).
please check what this does with ffmpeg.

as for the webcam exception: iirc, currently all applications that use v4l2loopback as an output module provide a "webcam-like" output image, rather than some TV-norm. for these your suggestion makes sense. otoh, v4l2loopback should probably by able to emulate a device capabale of TV-norms (e.g. if the consumer requests PAL or NTSC)

holdenc commented Mar 19, 2013

Okay, I tested current git/master (fd822cf) and I can confirm that ffmpeg now works again.

I only noticed one minor thing with my application: if I feed some video with one of the following commands

A) gst-launch-0.10 -v videotestsrc ! "video/x-raw-yuv,width=352,height=288,framerate=10/1,format=(fourcc)YUY2" ! v4l2sink device=/dev/video1
B) gst-launch-0.10 -v videotestsrc ! "video/x-raw-yuv,width=352,height=288,framerate=25/1,format=(fourcc)YUY2" ! v4l2sink device=/dev/video1

which only differ for the framerate, the VIDIOC_G_PARM ioctl always returns:

[v4l2]   Capture parameters:
[v4l2]     Capability:   0x00000000
[v4l2]     Capturemode:  0x00000000
[v4l2]     Timeperframe: 1/30

Would it be possible to return the correct timeperframe when reading the streaming parameters? Link at the doc: http://linuxtv.org/downloads/v4l-dvb-apis/streaming-par.html .
Note that ffmpeg can work around this if the user specifies a particular framerate for the resulting video, as the OP did with "-r 25".

I tested latest git/master(fd822cf) and FFMPEG too. It's a no problem.
Good job!

Testing Environment:
Debian/GNU Linux Testing + Linux Kernel 3.8.1

@umlaeute umlaeute closed this Mar 28, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment