Opened 13 years ago
Closed 12 years ago
#1387 closed defect (fixed)
v4l2 uses wrong (default) parameters
Reported by: | burek | Owned by: | |
---|---|---|---|
Priority: | normal | Component: | undetermined |
Version: | unspecified | Keywords: | v4l2 |
Cc: | Blocked By: | ||
Blocking: | Reproduced by developer: | no | |
Analyzed by developer: | no |
Description
Using web cameras, usual way of setting web cam parameters is by using v4l2-ctl tool, to set the default width, height, pixel_format, frame_rate, etc. so that when we use:
ffmpeg -f v4l2 -i /dev/video0 ...
FFmpeg should use those defaults (after all, that's the purpose of such tool). But that doesn't happen. For example, I've got a usb web cam that supports input using H264 stream (beside raw and mjpeg), which is confirmed by v4l2-ctl:
$ v4l2-ctl --list-formats ioctl: VIDIOC_ENUM_FMT Index : 0 Type : Video Capture Pixel Format: 'YUYV' Name : YUV 4:2:2 (YUYV) Index : 1 Type : Video Capture Pixel Format: 'H264' (compressed) Name : H.264 Index : 2 Type : Video Capture Pixel Format: 'MJPG' (compressed) Name : MJPEG
so, setting up some web cam defaults like this:
$ v4l2-ctl --all Driver Info (not using libv4l2): Driver name : uvcvideo Card type : HD Pro Webcam C920 Bus info : usb-0000:00:1d.7-8 Driver version: 3.2.17 Capabilities : 0x04000001 Video Capture Streaming Format Video Capture: Width/Height : 640/480 Pixel Format : 'H264' Field : None Bytes per Line: 1280 Size Image : 614400 Colorspace : SRGB Crop Capability Video Capture: Bounds : Left 0, Top 0, Width 640, Height 480 Default : Left 0, Top 0, Width 640, Height 480 Pixel Aspect: 1/1 Video input : 0 (Camera 1: ok) Streaming Parameters Video Capture: Capabilities : timeperframe Frames per second: 30.000 (30/1) Read buffers : 0
should make Ffmpeg's command work in such way that it grabs the input from web cam using frame size of 640x480 and pixel_format of 'H264' (or was it -vcodec in FFmpeg, I'm not sure). But, running the FFmpeg command gives this:
$ ffmpeg -f v4l2 -i /dev/video0 -vcodec copy out.ts ffmpeg version N-41142-g8f61526 Copyright (c) 2000-2012 the FFmpeg developers built on May 30 2012 13:40:37 with gcc 4.6.3 configuration: --enable-static --enable-shared --enable-gpl --enable-nonfree --enable-postproc --enable-libx264 --enable-libaacplus --enable-libmp3lame --enable-libopenjpeg --enable-zlib libavutil 51. 55.100 / 51. 55.100 libavcodec 54. 23.100 / 54. 23.100 libavformat 54. 6.101 / 54. 6.101 libavdevice 54. 0.100 / 54. 0.100 libavfilter 2. 77.100 / 2. 77.100 libswscale 2. 1.100 / 2. 1.100 libswresample 0. 15.100 / 0. 15.100 libpostproc 52. 0.100 / 52. 0.100 [video4linux2,v4l2 @ 0x9fee420] Estimating duration from bitrate, this may be inaccurate Input #0, video4linux2,v4l2, from '/dev/video0': Duration: N/A, start: 175879.115402, bitrate: 147456 kb/s Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 640x480, 147456 kb/s, 30 tbr, 1000k tbn, 30 tbc [mpegts @ 0x9febaa0] muxrate VBR, pcr every 3 pkts, sdt every 200, pat/pmt every 40 pkts Output #0, mpegts, to 'out.ts': Metadata: encoder : Lavf54.6.101 Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 640x480, q=2-31, 147456 kb/s, 90k tbn, 30 tbc Stream mapping: Stream #0:0 -> #0:0 (copy) Press [q] to stop, [?] for help frame= 113 fps= 30 q=-1.0 Lsize= 73103kB time=00:00:03.76 bitrate=158903.9kbits/s video:67800kB audio:0kB global headers:0kB muxing overhead 7.822064%
As you can see, the input is set to "rawvideo (YUY2 / 0x32595559)" mode (which is wrong) and frame size is set to 640x480 (which is correct). Further testing shows that setting various default frame sizes, using v4l2-ctl, is properly detected in FFmpeg, but input pixel_format of H264/MJPG is not.
P.S.
Using the following command, I can get FFmpeg to "recognize" that I want input format to be mjpeg instead of raw:
$ ffmpeg -f v4l2 -vcodec mjpeg -i /dev/video0 ... ... Input #0, video4linux2,v4l2, from '/dev/video0': Duration: N/A, start: 176610.262086, bitrate: N/A Stream #0:0: Video: mjpeg, yuvj422p, 352x288, -5 kb/s, 30 tbr, 1000k tbn, 30 tbc
but, I can't get the same for H264, because I get error instead:
$ ffmpeg -y -f v4l2 -vcodec h264 -i /dev/video0 ... ... [video4linux2,v4l2 @ 0x8ca24a0] Cannot find a proper format for codec_id 28, pix_fmt -1.
So, this is either some kind of bug in FFmpeg or unimplemented feature or something, so I don't know how to correctly flag this report.
Change History (6)
comment:1 by , 12 years ago
Keywords: | v4l2 added |
---|
comment:2 by , 12 years ago
You can close this ticket, the problem was that uvc driver did not support h264 pixel format back then when the ticket was created.
comment:3 by , 12 years ago
Does it (h264) work with current FFmpeg?
comment:4 by , 12 years ago
I need to get the h264 web cam in my possession again in order to test it on this matter. As soon as I do that, I'll test it and post results here :)
follow-up: 6 comment:5 by , 12 years ago
The bug is still there. h264 is now available, but -pixel_format is needed to set the pixel format again already selected by v4l2-ctl before.
And for the worse, this will in turn reset some other settings done by v4l2-ctl. For example, exposure mode is changed on some cameras. It seems that the format decision is assumed to take place prior to the other settings. The format can only be changed in close state, while the controls can be changed while capturing. So it may be incorrect to change the pixel format by ffmpeg without the ability to reapply the control settings.
I suggest either add a full control interface, or remove the pixel format setup from v4l2.c and just honor what was set by tools like v4l2-ctl before.
Adding an control interface is the issue of https://ffmpeg.org/trac/ffmpeg/ticket/2305 too.
comment:6 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Replying to burek:
Do you mean "wrong" in the sense that the output is broken (because the input data is not really yuy2 rawvideo) - I suspect this would indicate a driver bug but I may miss something - or do you mean "wrong" in the sense that you would prefer if the input data were h264? In this case, please test "ffmpeg -vcodec h264 -f v4l2 -i /dev/video0"