Re: [PATCH 1/6 v4] V4L: add two new ioctl()s for multi-size videobuffer management

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

 



On Monday, August 22, 2011 12:40:25 Guennadi Liakhovetski wrote:
> Hi Hans
> 
> On Mon, 22 Aug 2011, Hans Verkuil wrote:
> 
> > Sorry for starting this discussion and then disappearing. I've been very
> > busy lately, so my apologies for that.
> > 
> > On Tuesday, August 16, 2011 18:14:33 Pawel Osciak wrote:
> > > Hi Guennadi,
> > > 
> > > On Tue, Aug 16, 2011 at 06:13, Guennadi Liakhovetski
> > > <g.liakhovetski@xxxxxx> wrote:
> > > > On Mon, 15 Aug 2011, Guennadi Liakhovetski wrote:
> > > >
> > > >> On Mon, 15 Aug 2011, Hans Verkuil wrote:
> > > >>
> > > >> > On Monday, August 15, 2011 13:28:23 Guennadi Liakhovetski wrote:
> > > >> > > Hi Hans
> > > >> > >
> > > >> > > On Mon, 8 Aug 2011, Hans Verkuil wrote:
> > > >
> > > > [snip]
> > > >
> > > >> > > > but I've changed my mind: I think
> > > >> > > > this should use a struct v4l2_format after all.
> > > >>
> > > >> While switching back, I have to change the struct 
vb2_ops::queue_setup()
> > > >> operation to take a struct v4l2_create_buffers pointer. An earlier 
> > version
> > > >> of this patch just added one more parameter to .queue_setup(), which 
is
> > > >> easier - changes to videobuf2-core.c are smaller, but it is then
> > > >> redundant. We could use the create pointer for both input and output. 
The
> > > >> video plane configuration in frame format is the same as what is
> > > >> calculated in .queue_setup(), IIUC. So, we could just let the driver 
fill
> > > >> that one in. This would require then the videobuf2-core.c to parse 
struct
> > > >> v4l2_format to decide which union member we need, depending on the 
buffer
> > > >> type. Do we want this or shall drivers duplicate plane sizes in 
separate
> > > >> .queue_setup() parameters?
> > > >
> > > > Let me explain my question a bit. The current .queue_setup() method is
> > > >
> > > >        int (*queue_setup)(struct vb2_queue *q, unsigned int 
*num_buffers,
> > > >                           unsigned int *num_planes, unsigned int 
sizes[],
> > > >                           void *alloc_ctxs[]);
> > > >
> > > > To support multiple-size buffers we also have to pass a pointer to 
struct
> > > > v4l2_create_buffers to this function now. We can either do it like 
this:
> > > >
> > > >        int (*queue_setup)(struct vb2_queue *q,
> > > >                           struct v4l2_create_buffers *create,
> > > >                           unsigned int *num_buffers,
> > > >                           unsigned int *num_planes, unsigned int 
sizes[],
> > > >                           void *alloc_ctxs[]);
> > > >
> > > > and let all drivers fill in respective fields in *create, e.g., either 
do
> > > >
> > > >        create->format.fmt.pix_mp.plane_fmt[i].sizeimage = ...;
> > > >        create->format.fmt.pix_mp.num_planes = ...;
> > > >
> > > > and also duplicate it in method parameters
> > > >
> > > >        *num_planes = create->format.fmt.pix_mp.num_planes;
> > > >        sizes[i] = create->format.fmt.pix_mp.plane_fmt[i].sizeimage;
> > > >
> > > > or with
> > > >
> > > >        create->format.fmt.pix.sizeimage = ...;
> > > >
> > > > for single-plane. Alternatively we make the prototype
> > > >
> > > >        int (*queue_setup)(struct vb2_queue *q,
> > > >                           struct v4l2_create_buffers *create,
> > > >                           unsigned int *num_buffers,
> > > >                           void *alloc_ctxs[]);
> > > >
> > > > then drivers only fill in *create, and the videobuf2-core will have to
> > > > check create->format.type to decide, which of create->format.fmt.* is
> > > > relevant and extract plane sizes from there.
> > > 
> > > 
> > > Could we try exploring an alternative idea?
> > > The queue_setup callback was added to decouple formats from vb2 (and
> > > add some asynchronousness). But now we are doing the opposite, adding
> > > format awareness to vb2. Does vb2 really need to know about formats? I
> > > really believe it doesn't. It only needs sizes and counts. Also, we
> > > are actually complicating things I think. The proposal, IIUC, would
> > > look like this:
> > > 
> > > driver_queue_setup(..., create, num_buffers, [num_planes], ...)
> > > {
> > >     if (create != NULL && create->format != NULL) {
> > >         /* use create->fmt to fill sizes */
> > 
> > Right.
> > 
> > >     } else if (create != NULL) { /* this assumes we have both format or 
> > sizes */
> > >         /* use create->sizes to fill sizes */
> > 
> > No, create->format should always be set. If the application can fill in 
the
> > sizeimage field(s), then there is no need for create->sizes.
> > 
> > >     } else {
> > >         /* use currently selected format to fill sizes */
> > 
> > Right.
> > 
> > >     }
> > > }
> > > 
> > > driver_s_fmt(format)
> > > {
> > >     /* ... */
> > >     driver_fill_format(&create->fmt);
> > >     /* ... */
> > > }
> > 
> > ???
> > 
> > > 
> > > driver_create_bufs(create)
> > > {
> > >     vb2_create_bufs(create);
> > > }
> > > 
> > > vb2_create_bufs(create)
> > > {
> > >     driver_queue_setup(..., create, ...);
> > >     vb2_fill_format(&create->fmt); /* note different from
> > > driver_fill_format(), but both needed */
> > 
> > Huh? Why call vb2_fill_format? vb2 should have no knowledge whatsoever 
about
> > formats. The driver needs that information in order to be able to allocate
> > buffers correctly since that depends on the required format. But vb2 
doesn't
> > need that knowledge.
> 
> It would be good if you also could have a look at my reply to this Pawel's 
> mail:
> 
> http://article.gmane.org/gmane.linux.drivers.video-input-
infrastructure/36905
> 
> and, specifically, at the vb2_parse_planes() function in it. That's my 
> understanding of what would be needed, if we preserve .queue_setup() and 
> use your last suggestion to include struct v4l2_format in struct 
> v4l2_create_buffers.

vb2_parse_planes can be useful as a utility function that 'normal' drivers can 
call from the queue_setup. But vb2 should not parse the format directly, it
should just pass it on to the driver through the queue_setup function.

You also mention: "All frame-format fields like fourcc code, width, height, 
colorspace are only input from the user. If the user didn't fill them in, they 
should not be used."

I disagree with that. The user should fill in a full format description, just 
as with S/TRY_FMT. That's the information that the driver will use to set up 
the buffers. It could have weird rules like: if the fourcc is this, and the 
size is less than that, then we can allocate in this memory bank.

It is also consistent with REQBUFS: there too the driver uses a full format 
(i.e. the last set format).

I would modify queue_setup to something like this:

int (*queue_setup)(struct vb2_queue *q, struct v4l2_format *fmt,
                     unsigned int *num_buffers,
                     unsigned int *num_planes, unsigned int sizes[],
                     void *alloc_ctxs[]);

Whether fmt is left to NULL in the reqbufs case, or whether the driver has to 
call g_fmt first before calling vb2 is something that could be decided by what 
is easiest to implement.

Regards,

	Hans

> However, from your reply I couldn't understand your attitude to removing 
> .queue_setup() altogether. Do you see any disadvantages in doing so? Is it 
> serving any special role, that we are overseeing?
> 
> Thanks
> Guennadi
> 
> > 
> > > }
> > > 
> > > vb2_reqbufs(reqbufs)
> > > {
> > >    driver_queue_setup(..., NULL, ...);
> > > }
> > > 
> > > The queue_setup not only becomes unnecessarily complicated, but I'm
> > > starting to question the convenience of it. And we are teaching vb2
> > > how to interpret format structs, even though vb2 only needs sizes, and
> > > even though the driver has to do it anyway and knows better how.
> > 
> > No, vb2 just needs to pass the format information from the user to the
> > driver.
> > 
> > There seems to be some misunderstanding here.
> > 
> > The point of my original suggestion that create_bufs should use 
v4l2_format
> > is that the driver needs the format information in order to decide how and
> > where the buffers have to be allocated. Having the format available is the
> > only reliable way to do that.
> > 
> > This is already done for REQBUFS since the driver will use the current 
format
> > to make these decisions.
> > 
> > One way of simplifying queue_setup is actually to always supply the 
format.
> > In the case of REQBUFS the driver might do something like this:
> > 
> > driver_reqbufs(requestbuffers)
> > {
> > 	struct v4l2_format fmt;
> > 	struct v4l2_create_buffers create;
> > 
> > 	vb2_free_bufs(); // reqbufs should free any existing bufs
> > 	if (requestbuffers->count == 0)
> > 		return 0;
> > 	driver_g_fmt(&fmt);	// call the g_fmt ioctl op
> > 	// fill in create
> > 	vb2_create_bufs(create);
> > }
> > 
> > So vb2 just sees a call requesting to create so many buffers for a 
particular
> > format, and it just hands that information over to the driver *without*
> > parsing it.
> > 
> > And the driver gets the request from vb2 to create X buffers for format F, 
and
> > will figure out how to do that and returns the buffer/plane/allocator 
context
> > information back to vb2.
> > 
> > Regards,
> > 
> > 	Hans
> > 
> > > As for the idea to fill fmt in vb2, even if vb2 was to do it in
> > > create_bufs, some code to parse and fill the format fields would need
> > > to be in the driver anyway, because it still has to support s_fmt and
> > > friends. So adding that code to vb2 would duplicate it, and if the
> > > driver wanted to be non-standard in a way it filled the format fields,
> > > we'd not be allowing that.
> > > 
> > > My suggestion would be to remove queue_setup callback and instead
> > > modify vb2_reqbufs and vb2_create_bufs to accept sizes and number of
> > > buffers. I think it should simplify things both for drivers and vb2,
> > > would keep vb2 format-unaware and save us some round trips between vb2
> > > and driver:
> > > 
> > > driver_create_bufs(...) /* optional */
> > > {
> > >     /* use create->fmt (or sizes) */
> > >     ret = vb2_create_bufs(num_buffers, num_planes, buf_sizes,
> > > plane_sizes, alloc_ctxs);
> > >     fill_format(&create->fmt) /* because s_fmt has to do it anyway, so
> > > have a common function for that */
> > >     return ret;
> > > }
> > > 
> > > driver_reqbufs(...)
> > > {
> > >     /* use current format */
> > >     return vb2_reqbufs(num_buffers, num_planes, buf_sizes,
> > > plane_sizes, alloc_ctxs);
> > > }
> > > 
> > > And the call to both could easily converge into one in vb2, as the
> > > only difference is that vb2_reqbufs would need to free first, if any
> > > allocated buffers were present:
> > > 
> > > vb2_reqbufs(num_buffers, num_planes, buf_sizes, plane_sizes, alloc_ctxs)
> > > {
> > >     if (buffers_allocated(num_buffers, num_planes, buf_sizes,
> > > plane_sizes, alloc_ctxs)) {
> > >         free_buffers(...);
> > >     }
> > > 
> > >     return vb2_create_bufs(num_buffers, num_planes, buf_sizes,
> > > plane_sizes, alloc_ctxs);
> > > }
> > > 
> > > If the driver didn't want create_bufs, it'd just not implement it.
> > > What do you think?
> > > 
> > > -- 
> > > Best regards,
> > > Pawel Osciak
> > > --
> > > To unsubscribe from this list: send the line "unsubscribe linux-media" 
in
> > > the body of a message to majordomo@xxxxxxxxxxxxxxx
> > > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > > 
> > 
> 
> ---
> Guennadi Liakhovetski, Ph.D.
> Freelance Open-Source Software Developer
> http://www.open-technology.de/
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux