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

Giorgio Vazzana mywing81 at gmail.com
Sun Feb 10 13:33:46 CET 2013


2013/2/10 Stefano Sabatini <stefasab at gmail.com>:
> On date Friday 2013-02-08 11:11:45 +0100, Giorgio Vazzana encoded:
>> 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.
>
> What does determine the number of requested buffers?

Well, every application decides what is a reasonable number of buffers
for its purposes, and requests that number to the v4l2 driver. The
actual number of buffers obtained will depend, for example, on how
much physical memory the device itself has onboard and the
resolution/format of the frames. At the moment ffmpeg requests a very
large fixed number of buffers (256) and errors if the drivers
allocates less than 2 buffers.
Link to the doc: http://linuxtv.org/downloads/v4l-dvb-apis/mmap.html

> Also why aren't they dequeued?

In v4l2.c::mmap_read_frame() I see:

609     pkt->data= s->buf_start[buf.index];
610     pkt->size = buf.bytesused;

615     pkt->destruct = mmap_release_buffer;

so:
1) the data in the buffer is not copied to the packet, only a pointer is passed;
2) mmap_release_buffer() will be called when the packet is destroyed,
and it will dequeue the buffer (as far as I can tell, the only code
that can call mmap_release_buffer() is outside of v4l2.c)

This means that as long as we need the packets, we cannot destroy
them, and thus we cannot dequeue the buffers.

I suppose the packets are accumulated and not destroyed until
probesize bytes of data have been read. At that point we still need
the packets to feed them to an encoder, for example. Then they can be
destroyed. (note: this last paragraph is what I *think* it happens,
but I do not know libavformat/libavdevice well enough to be sure)

>> I have added an hack to limit probesize (see patch #2) and it solves
>> the problem for me:
>
> I have no strong objection on this, but I would like to know why there
> is a problem in the first place.

Of course, me too.

Thanks for looking at this!


More information about the ffmpeg-devel mailing list