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 _______________________________________________ linux-dvb mailing list linux-dvb@linuxtv.org http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb