[FFmpeg-devel] v4l2: bug #1570 and possible solution

Giorgio Vazzana mywing81 at gmail.com
Fri Feb 8 11:11:45 CET 2013


Hello,

I am working at fixing bug #1570. I have added some av_log() to see
what is going on (see patch #1). The problem seems to be that code
outside libavdevice/v4l2.c tries to read more buffers (that is, video
frames, in v4l2 language) than we have obtained, causing the last
ioctl call with VIDIOC_DQBUF to hang:

holden at rye:~/src/ffmpeg$ ./ffplay -loglevel debug -f video4linux2
-channel 1 -video_size 640x480 /dev/video0
ffplay version N-49703-g0d194ee Copyright (c) 2003-2013 the FFmpeg developers
  built on Feb  8 2013 10:12:28 with gcc 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1)
  configuration: --enable-gpl --enable-x11grab --enable-libxvid
--enable-libmp3lame --enable-libtheora --enable-libvorbis
--enable-libopus --enable-libvpx --enable-libx264
  libavutil      52. 17.101 / 52. 17.101
  libavcodec     54. 91.102 / 54. 91.102
  libavformat    54. 61.104 / 54. 61.104
  libavdevice    54.  3.103 / 54.  3.103
  libavfilter     3. 35.101 /  3. 35.101
  libswscale      2.  2.100 /  2.  2.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  2.100 / 52.  2.100
[video4linux2,v4l2 @ 0x2e2aea0] fd:5 capabilities:5010015
[video4linux2,v4l2 @ 0x2e2aea0] Selecting input_channel: 1
[video4linux2,v4l2 @ 0x2e2aea0] input_channel: 1, input_name: Composite1
[video4linux2,v4l2 @ 0x2e2aea0] The V4L2 driver is using the interlaced mode
[video4linux2,v4l2 @ 0x2e2aea0] Current standard: PAL, id: 255,
frameperiod: 1/25
[video4linux2,v4l2 @ 0x2e2aea0] V4L2 buffer obtained: 8
[video4linux2,v4l2 @ 0x2e2aea0] Buffer 0 dequeued.
[video4linux2,v4l2 @ 0x2e2aea0] Buffer 1 dequeued.
[video4linux2,v4l2 @ 0x2e2aea0] Buffer 2 dequeued.
[video4linux2,v4l2 @ 0x2e2aea0] Buffer 3 dequeued.
[video4linux2,v4l2 @ 0x2e2aea0] Buffer 4 dequeued.
[video4linux2,v4l2 @ 0x2e2aea0] Buffer 5 dequeued.
[video4linux2,v4l2 @ 0x2e2aea0] Buffer 6 dequeued.
[video4linux2,v4l2 @ 0x2e2aea0] Buffer 7 dequeued.
^Cholden at rye:~/src/ffmpeg$

Here, we requested 256 buffers to the V4L2 driver, but we obtained
only 8 (this number changes with video_size and pixel_format). The
buffer are dequeued one at a time, but they are not queued again
(nothing calls mmap_release_buffer() ), so at the 9th call the ioctl
to dequeue another buffer blocks, and that's why I think ffplay hangs.

If I reduce -probesize from the command line, everything works as
expected. So, the problem seems to be that code outside
libavdevice/v4l2.c tries to read more data (buffers) than we have
negotiated.
I have added an hack to limit probesize (see patch #2) and it solves
the problem for me:

holden at rye:~/src/ffmpeg$ ./ffplay -loglevel debug -f video4linux2
-channel 1 -video_size 640x480 /dev/video0
ffplay version N-49705-g741f1b4 Copyright (c) 2003-2013 the FFmpeg developers
  built on Feb  8 2013 10:55:18 with gcc 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1)
  configuration: --enable-gpl --enable-x11grab --enable-libxvid
--enable-libmp3lame --enable-libtheora --enable-libvorbis
--enable-libopus --enable-libvpx --enable-libx264
  libavutil      52. 17.101 / 52. 17.101
  libavcodec     54. 91.102 / 54. 91.102
  libavformat    54. 61.104 / 54. 61.104
  libavdevice    54.  3.103 / 54.  3.103
  libavfilter     3. 35.101 /  3. 35.101
  libswscale      2.  2.100 /  2.  2.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  2.100 / 52.  2.100
[video4linux2,v4l2 @ 0x16b0ea0] fd:5 capabilities:5010015
[video4linux2,v4l2 @ 0x16b0ea0] Selecting input_channel: 1
[video4linux2,v4l2 @ 0x16b0ea0] input_channel: 1, input_name: Composite1
[video4linux2,v4l2 @ 0x16b0ea0] The V4L2 driver is using the interlaced mode
[video4linux2,v4l2 @ 0x16b0ea0] Current standard: PAL, id: 255,
frameperiod: 1/25
[video4linux2,v4l2 @ 0x16b0ea0] V4L2 buffer obtained: 8
[video4linux2,v4l2 @ 0x16b0ea0] Buffer 0 dequeued.
[video4linux2,v4l2 @ 0x16b0ea0] Buffer 1 dequeued.
[video4linux2,v4l2 @ 0x16b0ea0] Buffer 2 dequeued.
[video4linux2,v4l2 @ 0x16b0ea0] Buffer 3 dequeued.
[video4linux2,v4l2 @ 0x16b0ea0] Buffer 4 dequeued.
[video4linux2,v4l2 @ 0x16b0ea0] Buffer 5 dequeued.
[video4linux2,v4l2 @ 0x16b0ea0] Buffer 6 dequeued.
[video4linux2,v4l2 @ 0x16b0ea0] Buffer 7 dequeued.
[video4linux2,v4l2 @ 0x16b0ea0] Probe buffer size limit of 3239936 bytes reached
rfps: 1.000000 0.006400
    Last message repeated 1 times
...
...
rfps: 23.976024 0.006705
[video4linux2,v4l2 @ 0x16b0ea0] Estimating duration from bitrate, this
may be inaccurate
Input #0, video4linux2,v4l2, from '/dev/video0':
  Duration: N/A, start: 1360317459.716653, bitrate: 92160 kb/s
    Stream #0:0, 8, 1/1000000: Video: rawvideo (I420 / 0x30323449),
yuv420p, 640x480, 1/1000000, 92160 kb/s, 25 fps, 25 tbr, 1000k tbn,
1000k tbc
Video frame changed from size:0x0 format:none serial:-1 to
size:640x480 format:yuv420p serial:1
[buffer @ 0x16b55c0] Setting entry with key 'video_size' to value '640x480'
[buffer @ 0x16b55c0] Setting entry with key 'pix_fmt' to value '0'
[buffer @ 0x16b55c0] Setting entry with key 'time_base' to value '1/1000000'
[buffer @ 0x16b55c0] Setting entry with key 'pixel_aspect' to value '0/1'
[ffplay_buffer @ 0x16b54e0] w:640 h:480 pixfmt:yuv420p tb:1/1000000
fr:0/1 sar:0/1 sws_param:
[crop @ 0x16b64c0] Setting 'w' to value 'floor(in_w/2)*2'
[crop @ 0x16b64c0] Setting 'h' to value 'floor(in_h/2)*2'
[ffplay_crop @ 0x16b63a0] w:640 h:480 sar:0/1 -> w:640 h:480 sar:0/1
Buffer 0 queued.
Buffer 1 queued.5808.00 A-V:  0.000 fd=   0 aq=    0KB vq= 2700KB sq=
  0B f=0/0
[video4linux2,v4l2 @ 0x16b0ea0] Buffer 0 dequeued.700KB sq=    0B f=0/0
Buffer 2 queued.
Buffer 3 queued.
[video4linux2,v4l2 @ 0x16b0ea0] Buffer 1 dequeued.
Buffer 4 queued.
[video4linux2,v4l2 @ 0x16b0ea0] Buffer 2 dequeued.
Buffer 5 queued.V:  0.000 fd=   0 aq=    0KB vq= 2700KB sq=    0B f=0/0
[video4linux2,v4l2 @ 0x16b0ea0] Buffer 3 dequeued.
[video4linux2,v4l2 @ 0x16b0ea0] Buffer 4 dequeued.250KB sq=    0B f=0/0
Buffer 6 queued.
Buffer 7 queued.
[video4linux2,v4l2 @ 0x16b0ea0] Buffer 5 dequeued.
Buffer 0 queued.
Buffer 1 queued.
Buffer 2 queued.
Buffer 3 queued.
Buffer 4 queued.
Buffer 5 queued.

Now, question for the libavformat/libavdevice experts: are we allowed
to change probesize from libavdevice/v4l2.c like this?

Regards,
Giorgio Vazzana
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Add-some-av_log-s-for-debugging.patch
Type: application/octet-stream
Size: 1399 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20130208/31b67da9/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-lavd-v4l2-limit-probesize-to-a-sensible-value.patch
Type: application/octet-stream
Size: 1075 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20130208/31b67da9/attachment-0001.obj>


More information about the ffmpeg-devel mailing list