Re: [PATCH v4 2/6] media: v4l2: Add extended buffer operations

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

 



Hi Helen,

On 7/21/20 4:54 PM, Helen Koike wrote:
> Hi,
> 
> On 7/21/20 8:26 AM, Stanimir Varbanov wrote:
>>
>>
>> On 7/17/20 2:54 PM, Helen Koike wrote:
>>> From: Hans Verkuil <hans.verkuil@xxxxxxxxx>
>>>
>>> Those extended buffer ops have several purpose:
>>> 1/ Fix y2038 issues by converting the timestamp into an u64 counting
>>>    the number of ns elapsed since 1970
>>> 2/ Unify single/multiplanar handling
>>> 3/ Add a new start offset field to each v4l2 plane buffer info struct
>>>    to support the case where a single buffer object is storing all
>>>    planes data, each one being placed at a different offset
>>>
>>> New hooks are created in v4l2_ioctl_ops so that drivers can start using
>>> these new objects.
>>>
>>> The core takes care of converting new ioctls requests to old ones
>>> if the driver does not support the new hooks, and vice versa.
>>>
>>> Note that the timecode field is gone, since there doesn't seem to be
>>> in-kernel users. We can be added back in the reserved area if needed or
>>> use the Request API to collect more metadata information from the
>>> frame.
>>>
>>> Signed-off-by: Hans Verkuil <hans.verkuil@xxxxxxxxx>
>>> Signed-off-by: Boris Brezillon <boris.brezillon@xxxxxxxxxxxxx>
>>> Signed-off-by: Helen Koike <helen.koike@xxxxxxxxxxxxx>
>>> ---
>>> Changes in v4:
>>> - Use v4l2_ext_pix_format directly in the ioctl, drop v4l2_ext_format,
>>> making V4L2_BUF_TYPE_VIDEO_[OUTPUT,CAPTURE] the only valid types.
>>> - Drop VIDIOC_EXT_EXPBUF, since the only difference from VIDIOC_EXPBUF
>>> was that with VIDIOC_EXT_EXPBUF we could export multiple planes at once.
>>> I think we can add this later, so I removed it from this RFC to simplify it.
>>> - Remove num_planes field from struct v4l2_ext_buffer
>>> - Add flags field to struct v4l2_ext_create_buffers
>>> - Reformulate struct v4l2_ext_plane
>>> - Fix some bugs caught by v4l2-compliance
>>> - Rebased on top of media/master (post 5.8-rc1)
>>>
>>> Changes in v3:
>>> - Rebased on top of media/master (post 5.4-rc1)
>>>
>>> Changes in v2:
>>> - Add reserved space to v4l2_ext_buffer so that new fields can be added
>>>   later on
>>> ---
>>>  drivers/media/v4l2-core/v4l2-dev.c   |  29 ++-
>>>  drivers/media/v4l2-core/v4l2-ioctl.c | 349 +++++++++++++++++++++++++--
>>>  include/media/v4l2-ioctl.h           |  26 ++
>>>  include/uapi/linux/videodev2.h       |  89 +++++++
>>>  4 files changed, 471 insertions(+), 22 deletions(-)
>>>
>>
>> <cut>
>>
>>> +/**
>>> + * struct v4l2_ext_plane - extended plane buffer info
>>> + * @buffer_length:	size of the entire buffer in bytes, should fit
>>> + *			@offset + @plane_length
>>> + * @plane_length:	size of the plane in bytes.
>>> + * @userptr:		when memory is V4L2_MEMORY_USERPTR, a userspace pointer pointing
>>> + *			to this plane.
>>> + * @dmabuf_fd:		when memory is V4L2_MEMORY_DMABUF, a userspace file descriptor
>>> + *			associated with this plane.
>>> + * @offset:		offset in the memory buffer where the plane starts. If
>>> + *			V4L2_MEMORY_MMAP is used, then it can be a "cookie" that
>>> + *			should be passed to mmap() called on the video node.
>>> + * @reserved:		extra space reserved for future fields, must be set to 0.
>>> + *
>>> + *
>>> + * Buffers consist of one or more planes, e.g. an YCbCr buffer with two planes
>>> + * can have one plane for Y, and another for interleaved CbCr components.
>>> + * Each plane can reside in a separate memory buffer, or even in
>>> + * a completely separate memory node (e.g. in embedded devices).
>>> + */
>>> +struct v4l2_ext_plane {
>>> +	__u32 buffer_length;
>>> +	__u32 plane_length;
>>> +	union {
>>> +		__u64 userptr;
>>> +		__s32 dmabuf_fd;
>>> +	} m;
>>> +	__u32 offset;
>>> +	__u32 reserved[4];
>>> +};
>>> +
>>>  /**
>>>   * struct v4l2_buffer - video buffer info
>>>   * @index:	id number of the buffer
>>> @@ -1055,6 +1086,36 @@ struct v4l2_buffer {
>>>  	};
>>>  };
>>>  
>>> +/**
>>> + * struct v4l2_ext_buffer - extended video buffer info
>>> + * @index:	id number of the buffer
>>> + * @type:	V4L2_BUF_TYPE_VIDEO_CAPTURE or V4L2_BUF_TYPE_VIDEO_OUTPUT
>>> + * @flags:	buffer informational flags
>>> + * @field:	enum v4l2_field; field order of the image in the buffer
>>> + * @timestamp:	frame timestamp
>>> + * @sequence:	sequence count of this frame
>>> + * @memory:	enum v4l2_memory; the method, in which the actual video data is
>>> + *		passed
>>> + * @planes:	per-plane buffer information
>>> + * @request_fd:	fd of the request that this buffer should use
>>> + * @reserved:	extra space reserved for future fields, must be set to 0
>>> + *
>>> + * Contains data exchanged by application and driver using one of the Streaming
>>> + * I/O methods.
>>> + */
>>> +struct v4l2_ext_buffer {
>>> +	__u32 index;
>>> +	__u32 type;
>>> +	__u32 flags;
>>> +	__u32 field;
>>> +	__u64 timestamp;
>>> +	__u32 sequence;
>>> +	__u32 memory;
>>> +	__u32 request_fd;
>>
>> This should be __s32, at least for consistency with dmabuf_fd?
> 
> I see that in struct v4l2_buffer, we have __s32, I don't mind changing it
> to keep the consistency, I just don't see where this value can be a negative
> number.

here
https://elixir.bootlin.com/linux/v5.8-rc4/source/drivers/media/common/videobuf2/videobuf2-v4l2.c#L134

> 
>>
>>> +	struct v4l2_ext_plane planes[VIDEO_MAX_PLANES];
>>> +	__u32 reserved[4];
>>
>> I think we have to reserve more words here for future extensions.
>>
>> I'd like also to propose to add here __s32 metadata_fd. The idea behind
>> this is to have a way to pass per-frame metadata dmabuf buffers for
>> synchronous type of metadata where the metadata is coming at the same
>> time with data buffers. What would be the format of the metadata buffer
>> is TBD.
>>
>> One option for metadata buffer format could be:
>>
>> header {
>> 	num_ctrls
>> 	array_of_ctrls [0..N]
>> 		ctrl_id
>> 		ctrl_size
>> 		ctrl_offset
>> }
>>
>> data {
>> 	cid0	//offset of cid0 in dmabuf buffer
>> 	cid1
>> 	cidN
>> }
> 
> Would it be better if, instead of adding a medatata_fd inside struct v4l2_ext_buffer,
> we create a new ioctl that gets this structs for the controls and sync them using the
> Request API ?

no, this solution has performance drawbacks when the metadata is big,
think of 64K.

> 
> I'd like to avoid too much metadata in the buffer object.
> 
> Regards,
> Helen
> 
>>
>> This will make easy to get concrete ctrl id without a need to parse the
>> whole metadata buffer. Also using dmabuf we don't need to copy data
>> between userspace <-> kernelspace (just cache syncs through
>> begin/end_cpu_access).
>>
>> The open question is who will validate the metadata buffer when it comes
>> from userspace. The obvious answer is v4l2-core but looking into DRM
>> subsytem they give more freedom to the drivers, and just provide generic
>> helpers which are not mandatory.
>>
>> I guess this will be a voice in the wilderness but I wanted to know your
>> opinion.
>>
>>> +};
>>> +
>>>  #ifndef __KERNEL__
>>>  /**
>>>   * v4l2_timeval_to_ns - Convert timeval to nanoseconds
>>> @@ -2520,6 +2581,29 @@ struct v4l2_create_buffers {
>>>  	__u32			reserved[6];
>>>  };
>>>  
>>> +/**
>>> + * struct v4l2_ext_create_buffers - VIDIOC_EXT_CREATE_BUFS argument
>>> + * @index:	on return, index of the first created buffer
>>> + * @count:	entry: number of requested buffers,
>>> + *		return: number of created buffers
>>> + * @memory:	enum v4l2_memory; buffer memory type
>>> + * @capabilities: capabilities of this buffer type.
>>> + * @format:	frame format, for which buffers are requested
>>> + * @flags:	additional buffer management attributes (ignored unless the
>>> + *		queue has V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS capability
>>> + *		and configured for MMAP streaming I/O).
>>> + * @reserved:	extra space reserved for future fields, must be set to 0
>>> + */
>>> +struct v4l2_ext_create_buffers {
>>> +	__u32				index;
>>> +	__u32				count;
>>> +	__u32				memory;
>>> +	struct v4l2_ext_pix_format	format;
>>> +	__u32				capabilities;
>>> +	__u32				flags;
>>> +	__u32 reserved[4];
>>> +};
>>> +
>>>  /*
>>>   *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
>>>   *
>>> @@ -2623,6 +2707,11 @@ struct v4l2_create_buffers {
>>>  #define VIDIOC_G_EXT_PIX_FMT	_IOWR('V', 104, struct v4l2_ext_pix_format)
>>>  #define VIDIOC_S_EXT_PIX_FMT	_IOWR('V', 105, struct v4l2_ext_pix_format)
>>>  #define VIDIOC_TRY_EXT_PIX_FMT	_IOWR('V', 106, struct v4l2_ext_pix_format)
>>> +#define VIDIOC_EXT_CREATE_BUFS	_IOWR('V', 107, struct v4l2_ext_create_buffers)
>>> +#define VIDIOC_EXT_QUERYBUF	_IOWR('V', 108, struct v4l2_ext_buffer)
>>> +#define VIDIOC_EXT_QBUF		_IOWR('V', 109, struct v4l2_ext_buffer)
>>> +#define VIDIOC_EXT_DQBUF	_IOWR('V', 110, struct v4l2_ext_buffer)
>>> +#define VIDIOC_EXT_PREPARE_BUF	_IOWR('V', 111, struct v4l2_ext_buffer)
>>>  
>>>  /* Reminder: when adding new ioctls please add support for them to
>>>     drivers/media/v4l2-core/v4l2-compat-ioctl32.c as well! */
>>>
>>

-- 
regards,
Stan



[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