Re: Question concerning v4l2 backward compatibility layer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



Michael Hunold wrote:
> 
> Hello all,
> 
> my v4l2 saa7146 driver now supports the v4l backward
> compatibility layer of v4l2, too -- except from
> capturing.
> 
> To overcome this, I wrote a simple test
> program that does the following:
> 
> ----------------schnipp---------------------
>         if(ioctl(fd, VIDIOCGMBUF, &mbuf)<0) {
>                 perror("VIDIOCGMBUF");
>                 return -1;
>         }
> 
>         printf("size:%d, frames:%d ",mbuf.size, mbuf.frames);
>         for(i = 0; i < mbuf.frames;i++) {
>                 printf(", offset %d: %d", i, mbuf.offsets[i]);
>         }
>         printf("\n");
> 
>         if((signed int)(map = mmap(0, mbuf.size, PROT_READ|PROT_WRITE,
>                         MAP_SHARED, fd, 0)) < 0) {
>                 perror("mmap");
>                 return -1;
>         }
> ----------------schnapp---------------------
> 
> The programs wants two capture frames of
> 884736 bytes each, a total of 1769472 bytes:
> 
> > size:1769472, frames:2 , offset 0: 0, offset 1: 884736
> > mmap: Invalid argument
> 
> But my driver then says:
> 
> Mar 28 18:54:18 michael kernel: saa7146_v4l2.o: v4l2_mmap called.
> Mar 28 18:54:18 michael kernel: saa7146_v4l2.o:
> mmap_stream_buffer_from_offset called.
> Mar 28 18:54:18 michael kernel: saa7146_v4l2.o: mmap(): Wrong
>         length parameter (884736<=>1769472)
> 
> As we all know, v4l maintains the capture memory as
> one big chunk of memory. The different capture buffers
> are located at position 0, "picture_size", "picture_size"*2
> and so on in this block.
> 
> v4l2 however maintains each capture buffer separately, e.g.
> you have to do one mmap() for every buffer.
> 
> So, my v4l2 driver behaves correctly in my eyes here -- it
> refuses to mmap() the big 1769472 bytes chunk here, because
> there is no such block.
> 
> But whose problem is this now? No v4l program that uses
> double buffering currently works with my driver.
> 
> Is this an issue for the compatibility layer? Doesn't have
> it to translate the v4l mmap() call to meet the specifications
> of v4l2? As far as I know it simply passes the data down
> to the driver...
> 
> I've seen that bttv2 does some magic using "btvc->cap_contig"
> in "v4l2_mmap()" -- Justin, can you tell me what the idea
> behind this is?

OK - True v4l compatibility requires the driver to support the
REQ_CONTIG_MAP flag to REQBUFS.  When your driver receives a REQBUF
request with this flag set, it should allocate the buffers in "virtual"
contiguous memory, and return the requestbuffers struct with the flag
still set.

Alternatively, simply return requestbuffers with the REQ_CONTIG_MAP flag
cleared.  This will tell the compatibility layer that your driver cannot
do contiguous buffers, it will then tell the v4l app that there is only
1 buffer available.  If the v4l app is correctly written, it should
handle this correctly, and simply capture without double buffering. 
Some apps do not handle this correctly, in such a case, simply send the
maintainer e-mail explaining that his/her app MUST honour the "frames"
field returned by GMBUF correctly.

-justin





[Index of Archives]     [Linux DVB]     [Video Disk Recorder]     [Asterisk]     [Photo]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Free Photo Albums]     [Fedora Users]     [Fedora Women]     [ALSA Users]     [ALSA Devel]     [Linux USB]

Powered by Linux