[linux-dvb] [RFC-final] videobuf tree

Mauro Carvalho Chehab mchehab at infradead.org
Mon Oct 8 11:49:23 CEST 2007


Em Dom, 2007-10-07 às 14:03 -0700, Trent Piepho escreveu:
> On Sun, 7 Oct 2007, Mauro Carvalho Chehab wrote:
> > I took a look at cx23885 code. It seems that there's a serious error on
> > the way you're using cx23885_buffer there:
> >
> > cx23885-dvb.c:  return cx23885_buf_prepare(q, port, (struct
> > cx23885_buffer*)vb, field);
> > cx23885-dvb.c:  cx23885_buf_queue(port, (struct cx23885_buffer*)vb);
> > cx23885-dvb.c:  cx23885_free_buffer(q, (struct cx23885_buffer*)vb);
> >
> > It seems that you are forcing videobuf_buffer to be cx23885_buffer. This
> > is not right!
> >
> > This is what is defined on cx23885.h:
> >
> > struct cx23885_buffer {
> >         /* common v4l buffer stuff -- must be first */
> >         struct videobuf_buffer vb;
> 
> I'm not sure that it is competely wrong.  Say one has a cx23885_buffer that
> contains a videobuf_buffer.  Now suppose you have a pointer to the
> videobuf_buffer, and you want to get a pointer to the cx23885_buffer that
> contains it.  What you should write is:
> 
> struct videobuf_buffer *vb = ...;
> struct cx23885_buffer *buf = container_of(vb, struct cx23885_buffer, vb);
> 
> But since vb is the first field of the cx23885_buffer struct, the container_of
> will turn into just '(struct cx23885_buffer *)(vb)
>
> This code in videobuf-dma-sg.c looks odd to me:
> 
> /* Allocated area consists on 3 parts:
>         struct video_buffer
>         struct <driver>_buffer (cx88_buffer, saa7134_buf, ...)
>         struct videobuf_pci_sg_memory
> 
> static void *__videobuf_alloc(size_t size)
> {
>         struct videbuf_pci_sg_memory *mem;
>         struct videobuf_buffer *vb;
> 
>         vb = kzalloc(size+sizeof(*mem),GFP_KERNEL);
> 
>         mem = vb->priv = ((char *)vb)+size;
> 
> What is 'size', is that the size of the driver buffer?  Shouldn't you
> be
> allocating size + sizeof(*vb) + sizeof(*mem)?
> 
> Is there documentation for videobuf anywhere?  It doesn't look like
> any of
> the videobuf functions have descriptions of that they do or what the
> parameters are.

There aren't any videobuf doc yet. I intend to write one, when I have
some time. IMO, this is the most complex part of V4L core.

For now, let me give a quick explanation of the basics of videobuf.

---

Videobuf uses a memory struct that looks what c++ compilers do when you
use inheritances. 

It is something like:

class videobuf_core {
    public:
	// some data and code
};

class videobuf_dma_sg: public videobuf_core {
    private:
	// some data and code
}

class foo_buffer: public videobuf_dma_sg {
    public:
	// some data
}

The "constructor" for any class derivated from videobuf_dma_sg is:
void *videobuf_pci_alloc (size_t size);

Where size is the size of foo_buffer.

The other videobuf_dma methods are the external functions defined on
videobuf-dma-sg.h. All of them start with videobuf_dma_foo.

A similar inehitance concept happens with videobuf_queue. You have an
abstract videobuf_queue class, defined on videobuf-core, where almost
all methods are virtual, and, currently, two derivated class, that
implements their methods: a DMA Scatter/Gather one (videobuf-dma-sg) and
a vmalloc one (videobuf-vmalloc).

To use the full functionality of videobuf, you will need the
videobuf_queue, that is responsible for controlling the state machine of
the videobuffers. The videobuf_queue constructor will allocate a
videobuf_buffer inherited class. Also, when you need mmapped buffers,
videobuf core will allocate one additional videobuf_buffer inherited
class by each queue (generally, a driver allocates, by default, 8 queues
for receiving data - this avoids data loss, when the machine is with
high workloads).

It is also possible just to use a videobuf_buffer derivated class. ALSA
saa7134 and cx88 drivers implement this way. They have their own state
machine.

-- 
Cheers,
Mauro




More information about the linux-dvb mailing list