Opened 4 years ago

Closed 3 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 in reply to: ↑ description Changed 3 years ago by cehoyos

  • Keywords v4l2 added

Replying to burek:

As you can see, the input is set to "rawvideo (YUY2 / 0x32595559)" mode (which is wrong)

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"

comment:2 Changed 3 years ago by burek

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 Changed 3 years ago by cehoyos

Does it (h264 input from v4l2) work with current FFmpeg for you?

Last edited 3 years ago by cehoyos (previous) (diff)

comment:4 Changed 3 years ago by burek

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 :)

Last edited 3 years ago by burek (previous) (diff)

comment:5 follow-up: Changed 3 years ago by dronus

The bug is still there. -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.

Version 0, edited 3 years ago by dronus (next)

comment:6 in reply to: ↑ 5 Changed 3 years ago by cehoyos

  • Resolution set to fixed
  • Status changed from new to closed

Replying to dronus:

h264 is now available, but -pixel_format is needed to set the pixel format again already selected by v4l2-ctl before.

This indicates that this particular ticket was fixed.

For the remaining problem, please use ticket #2305, no matter how this will be fixed.

Note: See TracTickets for help on using tickets.