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

Michael Niedermayer michaelni at gmx.at
Wed Feb 13 00:07:24 CET 2013


On Tue, Feb 12, 2013 at 07:53:29PM +0100, Giorgio Vazzana wrote:
> 2013/2/12 Michael Niedermayer <michaelni at gmx.at>:
> > On Tue, Feb 12, 2013 at 06:01:10PM +0100, Giorgio Vazzana wrote:
> >> 2013/2/12 Michael Niedermayer <michaelni at gmx.at>:
> >> > On Tue, Feb 12, 2013 at 12:40:21PM +0100, Giorgio Vazzana wrote:
> >> >> 2013/2/12 Michael Niedermayer <michaelni at gmx.at>:
> >> >> +static void mmap_release_buffer(AVPacket *pkt)
> >> >> +{
> >> >> +    struct buff_data *buf_descriptor = pkt->priv;
> >> >> +
> >> >> +    if (pkt->data == NULL)
> >> >> +        return;
> >> >> +
> >> >> +    if (buf_descriptor->buffer_copied) {
> >> >> +        av_free(pkt->data);
> >> >> +    } else {
> >> >> +        if (!enqueue_buffer(buf_descriptor->fd, buf_descriptor->index))
> >> >
> >> >> +            (*buf_descriptor->buffers_dequeued)--;
> >> >
> >> > the deallocation of packets could happen from different thread(s)
> >> > so i think this needs either a mutex, an atomic decrement or some
> >> > lockless algorithm to achive the same
> >>
> >> Ok, I've tried to implement the solution using the mutex. Please comment.
> >>
> >> We can use this approach, or the easiest (and slightly slower?)
> >> solution would be copying every frame/buffer to the memory allocated
> >> for the corresponding packet.
> >
> > if you want to avoid the dependancy on pthreads, one way that should
> > work is to use an array which size matches the maximum number of
> > buffers, inited to 0 each time a buffer is allocated its entry is set
> > to 1, when its freed its set to 0. to find out how many buffers are
> > left the whole array would need to be scanned and remaining 0 elements
> > counted.
> 
> I will have to think about this in the following days, but for now I
> do not see how this can work: suppose we consider the following
> example:
> 
> Initialization:
> // let's suppose the number of buffers allocated by the v4l2
> // driver is 10. This is also the lenght of the incoming and
> // outgoing queues, which are organized as FIFO
> buffers_obtained = 10;
> 
> // allocate and clear array
> int *array = calloc(buffers_obtained, sizeof(*array));
> 
> // enqueue all the buffers to the incoming FIFO and start capturing
> start_streaming();
> 
>

> Thread0 will do this:
> // when we want to read a frame, we dequeue a buffer from the
> // outgoing FIFO
> dequeue_buffer(&buf);
> // signal that a particular buffer has been dequeued
> array[buf.index] = 1;
> 
> 
> Thread1 will do this:
> // count the numbers of buffers still in the incoming FIFO
> int i, count = 0;
> for (i = 0; i < buffers_obtained; i++)
>     if (array[i] == 0)
>         count++;

This is not possible
you imply that v4l2s read packet is itself called from 2 threads at
the same time
The only thing that can allocate packets/dequeue buffers is v4l2s
read packet
The only thing that has to count the available buffers is v4l2s read
packet (that is for choosing where to allocate the next packet)


[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

If a bugfix only changes things apparently unrelated to the bug with no
further explanation, that is a good sign that the bugfix is wrong.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20130213/937ae51c/attachment.asc>


More information about the ffmpeg-devel mailing list