2021-05-07 10:41:35

by Louis Kuo

[permalink] [raw]
Subject: [RESENT PATCH V0 0/4] media: some framework interface extension for new feature of Mediatek Camsys driver

Hello,

This is the first version of the patch series extending V4L2 and media
framework to support some advanced camera function, for example, to change
the sensor when ISP is still streaming. A typical scenario is the wide-angle
sensor and telephoto sensor switching in camera application. When the user
is using the zooming UI, the application needs to switch the sensor from
wide-angle sensor to telephoto sensor smoothly.

To finish the function, we may need to modify the links of a pipeline and
the format of pad and video device per request. Currently, the link,
pad and video device format and selection settings are not involved in
media request's design. Therefore, we try to extend the related interface
to support the request-based operations. In the early version, we added
request fd to the parameters of MEDIA_IOC_SETUP_LINK,
VIDIOC_S_FMT, VIDIOC_SUBDEV_S_SELECTION, VIDIOC_SUBDEV_S_FMT.
The driver uses media_request_get_by_fd() to retrieve the media request
and save the pending change in it, so that we can apply the pending change
in req_queue() callback then.

Here is an example:

int mtk_cam_vidioc_s_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
struct mtk_cam_device *cam = video_drvdata(file);
struct mtk_cam_video_device *node = file_to_mtk_cam_node(file);
struct mtk_cam_request_stream_data *stream_data;
struct mtk_cam_request *cam_req;
struct media_request *req;
s32 fd;

fd = s->request_fd;
if (fd < 0)
return -EINVAL;

req = media_request_get_by_fd(&cam->media_dev, fd);

/* .... */

cam_req = to_mtk_cam_req(req);
stream_data = &cam_req->stream_data[node->uid.pipe_id];
stream_data->vdev_selection_update |= (1 << node->desc.id);
stream_data->vdev_selection[node->desc.id] = *s;

/* .... */

media_request_put(req);

return 0;
}

I posted interface change to discuss first and would like some
review comments.

Thank you very much.

media: v4l2-core: extend the v4l2 format to support request
media: subdev: support which in v4l2_subdev_frame_interval
media: v4l2-ctrl: Add ISP Camsys user control
media: pixfmt: Add ISP Camsys formats

drivers/media/mc/mc-device.c | 7 +-
drivers/media/v4l2-core/v4l2-ioctl.c | 153 ++++++++++++++++++++++++++-
include/media/media-entity.h | 3 +
include/uapi/linux/media.h | 3 +-
include/uapi/linux/v4l2-controls.h | 4 +
include/uapi/linux/v4l2-subdev.h | 8 +-
include/uapi/linux/videodev2.h | 109 ++++++++++++++++++-
7 files changed, 275 insertions(+), 12 deletions(-)



2021-05-07 11:02:27

by Louis Kuo

[permalink] [raw]
Subject: [RESENT PATCH V0 3/4] media: v4l2-ctrl: Add ISP Camsys user control

This patch is to add V4L2_CID_USER_MTK_CAM_BASE for Mediatek ISP-only
features. For example, we have some hits from user to let driver select
internal path and resource usage.
(e.g. use multiple engine or bining the image or use higher clk and power).

Signed-off-by: Louis Kuo <[email protected]>
---
include/uapi/linux/v4l2-controls.h | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index d43bec5f1afd..5f664b98fc58 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -194,6 +194,10 @@ enum v4l2_colorfx {
* We reserve 16 controls for this driver. */
#define V4L2_CID_USER_IMX_BASE (V4L2_CID_USER_BASE + 0x10b0)

+/* The base for the mediatek camsys driver controls */
+/* We reserve 48 controls for this driver. */
+#define V4L2_CID_USER_MTK_CAM_BASE (V4L2_CID_USER_BASE + 0x10d0)
+
/*
* The base for the atmel isc driver controls.
* We reserve 32 controls for this driver.
--
2.18.0

2021-05-07 11:02:27

by Louis Kuo

[permalink] [raw]
Subject: [RESENT PATCH V0 2/4] media: subdev: support which in v4l2_subdev_frame_interval

This patch is to support try or set of VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL
through which parameter.
This behavior is already supported in some similar V4L2 IOCTLs such as
VIDIOC_SUBDEV_ENUM_FRAME_SIZE for the same reason.

Signed-off-by: Louis Kuo <[email protected]>
---
include/uapi/linux/v4l2-subdev.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/v4l2-subdev.h b/include/uapi/linux/v4l2-subdev.h
index d6ffd5981c68..9d64feaa693b 100644
--- a/include/uapi/linux/v4l2-subdev.h
+++ b/include/uapi/linux/v4l2-subdev.h
@@ -120,12 +120,13 @@ struct v4l2_subdev_frame_size_enum {
* struct v4l2_subdev_frame_interval - Pad-level frame rate
* @pad: pad number, as reported by the media API
* @interval: frame interval in seconds
- * @reserved: drivers and applications must zero this array
+ * @which: format type (from enum v4l2_subdev_format_whence)
*/
struct v4l2_subdev_frame_interval {
__u32 pad;
struct v4l2_fract interval;
- __u32 reserved[9];
+ __u32 which;
+ __u32 reserved[8];
};

/**
--
2.18.0

2021-05-07 11:02:50

by Louis Kuo

[permalink] [raw]
Subject: [RESENT PATCH V0 1/4] media: v4l2-core: extend the v4l2 format to support request

This patch is to extend the related interface to support the request-based
operations. We added request fd to the parameters of MEDIA_IOC_SETUP_LINK,
VIDIOC_S_FMT, VIDIOC_SUBDEV_S_SELECTION, VIDIOC_SUBDEV_S_FMT.
The driver uses media_request_get_by_fd() to retrieve the media request and
save the pending change in it, so that we can apply the pending change in
req_queue() callback then.

Signed-off-by: Louis Kuo <[email protected]>
---
drivers/media/mc/mc-device.c | 7 ++++++-
drivers/media/v4l2-core/v4l2-ioctl.c | 8 ++++----
include/media/media-entity.h | 3 +++
include/uapi/linux/media.h | 3 ++-
include/uapi/linux/v4l2-subdev.h | 3 ++-
include/uapi/linux/videodev2.h | 8 ++++++--
6 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c
index 9e56d2ad6b94..f46ae4c38102 100644
--- a/drivers/media/mc/mc-device.c
+++ b/drivers/media/mc/mc-device.c
@@ -203,6 +203,7 @@ static long media_device_setup_link(struct media_device *mdev, void *arg)
struct media_link *link = NULL;
struct media_entity *source;
struct media_entity *sink;
+ int ret;

/* Find the source and sink entities and link.
*/
@@ -221,10 +222,14 @@ static long media_device_setup_link(struct media_device *mdev, void *arg)
if (link == NULL)
return -EINVAL;

+ link->request_fd = linkd->request_fd;
memset(linkd->reserved, 0, sizeof(linkd->reserved));

/* Setup the link on both entities. */
- return __media_entity_setup_link(link, linkd->flags);
+ ret = __media_entity_setup_link(link, linkd->flags);
+ link->request_fd = 0;
+
+ return ret;
}

static long media_device_get_topology(struct media_device *mdev, void *arg)
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 2673f51aafa4..823ebd175f3a 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1634,7 +1634,7 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane))
break;
- CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
+ CLEAR_AFTER_FIELD(p, fmt.pix_mp.request_fd);
for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
bytesperline);
@@ -1665,7 +1665,7 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane))
break;
- CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
+ CLEAR_AFTER_FIELD(p, fmt.pix_mp.request_fd);
for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
bytesperline);
@@ -1736,7 +1736,7 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane))
break;
- CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
+ CLEAR_AFTER_FIELD(p, fmt.pix_mp.request_fd);
for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
bytesperline);
@@ -1767,7 +1767,7 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane))
break;
- CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
+ CLEAR_AFTER_FIELD(p, fmt.pix_mp.request_fd);
for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i],
bytesperline);
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 09737b47881f..30ad665c4413 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -128,6 +128,8 @@ struct media_pipeline {
* link.
* @flags: Link flags, as defined in uapi/media.h (MEDIA_LNK_FL_*)
* @is_backlink: Indicate if the link is a backlink.
+ * @request_fd: The media request triggered the media link change, it is only
+ * meaningful in media_device_setup_link()
*/
struct media_link {
struct media_gobj graph_obj;
@@ -145,6 +147,7 @@ struct media_link {
struct media_link *reverse;
unsigned long flags;
bool is_backlink;
+ int request_fd;
};

/**
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
index 200fa8462b90..a331f80afe2d 100644
--- a/include/uapi/linux/media.h
+++ b/include/uapi/linux/media.h
@@ -231,7 +231,8 @@ struct media_link_desc {
struct media_pad_desc source;
struct media_pad_desc sink;
__u32 flags;
- __u32 reserved[2];
+ __s32 request_fd;
+ __u32 reserved[1];
};

struct media_links_enum {
diff --git a/include/uapi/linux/v4l2-subdev.h b/include/uapi/linux/v4l2-subdev.h
index 658106f5b5dc..d6ffd5981c68 100644
--- a/include/uapi/linux/v4l2-subdev.h
+++ b/include/uapi/linux/v4l2-subdev.h
@@ -50,7 +50,8 @@ struct v4l2_subdev_format {
__u32 which;
__u32 pad;
struct v4l2_mbus_framefmt format;
- __u32 reserved[8];
+ __s32 request_fd;
+ __u32 reserved[7];
};

/**
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 311a01cc5775..6641194b3fab 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -1246,6 +1246,7 @@ struct v4l2_crop {
* defined in v4l2-common.h; V4L2_SEL_TGT_* .
* @flags: constraints flags, defined in v4l2-common.h; V4L2_SEL_FLAG_*.
* @r: coordinates of selection window
+ * @request_fd: fd of the request that trigger the set selection operation
* @reserved: for future use, rounds structure size to 64 bytes, set to zero
*
* Hardware may use multiple helper windows to process a video stream.
@@ -1257,7 +1258,8 @@ struct v4l2_selection {
__u32 target;
__u32 flags;
struct v4l2_rect r;
- __u32 reserved[9];
+ __s32 request_fd;
+ __u32 reserved[8];
};


@@ -2266,6 +2268,7 @@ struct v4l2_plane_pix_format {
* @hsv_enc: enum v4l2_hsv_encoding, HSV encoding
* @quantization: enum v4l2_quantization, colorspace quantization
* @xfer_func: enum v4l2_xfer_func, colorspace transfer function
+ * @request_fd: fd of the request that trigger the set format operation
* @reserved: drivers and applications must zero this array
*/
struct v4l2_pix_format_mplane {
@@ -2284,7 +2287,8 @@ struct v4l2_pix_format_mplane {
};
__u8 quantization;
__u8 xfer_func;
- __u8 reserved[7];
+ __s32 request_fd;
+ __u8 reserved[3];
} __attribute__ ((packed));

/**
--
2.18.0

2021-06-14 11:12:12

by Hans Verkuil

[permalink] [raw]
Subject: Re: [RESENT PATCH V0 0/4] media: some framework interface extension for new feature of Mediatek Camsys driver

Hi Louis,

On 07/05/2021 09:46, Louis Kuo wrote:
> Hello,
>
> This is the first version of the patch series extending V4L2 and media
> framework to support some advanced camera function, for example, to change
> the sensor when ISP is still streaming. A typical scenario is the wide-angle
> sensor and telephoto sensor switching in camera application. When the user
> is using the zooming UI, the application needs to switch the sensor from
> wide-angle sensor to telephoto sensor smoothly.
>
> To finish the function, we may need to modify the links of a pipeline and
> the format of pad and video device per request. Currently, the link,
> pad and video device format and selection settings are not involved in
> media request's design. Therefore, we try to extend the related interface
> to support the request-based operations. In the early version, we added
> request fd to the parameters of MEDIA_IOC_SETUP_LINK,
> VIDIOC_S_FMT, VIDIOC_SUBDEV_S_SELECTION, VIDIOC_SUBDEV_S_FMT.
> The driver uses media_request_get_by_fd() to retrieve the media request
> and save the pending change in it, so that we can apply the pending change
> in req_queue() callback then.
>
> Here is an example:
>
> int mtk_cam_vidioc_s_selection(struct file *file, void *fh,
> struct v4l2_selection *s)
> {
> struct mtk_cam_device *cam = video_drvdata(file);
> struct mtk_cam_video_device *node = file_to_mtk_cam_node(file);
> struct mtk_cam_request_stream_data *stream_data;
> struct mtk_cam_request *cam_req;
> struct media_request *req;
> s32 fd;
>
> fd = s->request_fd;
> if (fd < 0)
> return -EINVAL;
>
> req = media_request_get_by_fd(&cam->media_dev, fd);
>
> /* .... */
>
> cam_req = to_mtk_cam_req(req);
> stream_data = &cam_req->stream_data[node->uid.pipe_id];
> stream_data->vdev_selection_update |= (1 << node->desc.id);
> stream_data->vdev_selection[node->desc.id] = *s;
>
> /* .... */
>
> media_request_put(req);
>
> return 0;
> }
>
> I posted interface change to discuss first and would like some
> review comments.
>
> Thank you very much.

Just adding a request_fd in several places is the easy bit. The much
harder part is where to store that information, and even harder is an
outstanding issue with the request framework:

Currently the request framework is only used with decoder drivers, so
there are no subdev drivers involved. I suspect that there is a fair
amount of work to do to make it work well if part of the request configuration
is for subdev drivers.

Ideally I would like to see a proof-of-concept with the vimc driver.

I think getting this right is quite a lot of work. The public API part
is just a minor part of that since the public API was designed with support
for this in mind. It's the internal kernel support that is lacking.

If you want to pursue this (and that would be great!), then start with
vimc and initially just support controls in a request. The core problem
is likely to be how to keep track of the request data if it is spread
out between the bridge driver and subdev drivers, and that can be tested
with just supporting controls.

Adding support for formats and selection rectangles is, I think, much less
difficult and can be addressed later. Changing the topology in a request
is a separate issue as well, and I would suggest that you postpone that.
There is some low-level work going on that might make this easier in the
near future (1), we'll have to wait and see.

Regards,

Hans

(1): https://patchwork.linuxtv.org/project/linux-media/cover/[email protected]/

>
> media: v4l2-core: extend the v4l2 format to support request
> media: subdev: support which in v4l2_subdev_frame_interval
> media: v4l2-ctrl: Add ISP Camsys user control
> media: pixfmt: Add ISP Camsys formats
>
> drivers/media/mc/mc-device.c | 7 +-
> drivers/media/v4l2-core/v4l2-ioctl.c | 153 ++++++++++++++++++++++++++-
> include/media/media-entity.h | 3 +
> include/uapi/linux/media.h | 3 +-
> include/uapi/linux/v4l2-controls.h | 4 +
> include/uapi/linux/v4l2-subdev.h | 8 +-
> include/uapi/linux/videodev2.h | 109 ++++++++++++++++++-
> 7 files changed, 275 insertions(+), 12 deletions(-)
>
>

2021-10-11 13:31:53

by Hans Verkuil

[permalink] [raw]
Subject: Re: [RESENT PATCH V0 0/4] media: some framework interface extension for new feature of Mediatek Camsys driver

On 14/06/2021 12:56, Hans Verkuil wrote:
> Hi Louis,
>
> On 07/05/2021 09:46, Louis Kuo wrote:
>> Hello,
>>
>> This is the first version of the patch series extending V4L2 and media
>> framework to support some advanced camera function, for example, to change
>> the sensor when ISP is still streaming. A typical scenario is the wide-angle
>> sensor and telephoto sensor switching in camera application. When the user
>> is using the zooming UI, the application needs to switch the sensor from
>> wide-angle sensor to telephoto sensor smoothly.
>>
>> To finish the function, we may need to modify the links of a pipeline and
>> the format of pad and video device per request. Currently, the link,
>> pad and video device format and selection settings are not involved in
>> media request's design. Therefore, we try to extend the related interface
>> to support the request-based operations. In the early version, we added
>> request fd to the parameters of MEDIA_IOC_SETUP_LINK,
>> VIDIOC_S_FMT, VIDIOC_SUBDEV_S_SELECTION, VIDIOC_SUBDEV_S_FMT.
>> The driver uses media_request_get_by_fd() to retrieve the media request
>> and save the pending change in it, so that we can apply the pending change
>> in req_queue() callback then.
>>
>> Here is an example:
>>
>> int mtk_cam_vidioc_s_selection(struct file *file, void *fh,
>> struct v4l2_selection *s)
>> {
>> struct mtk_cam_device *cam = video_drvdata(file);
>> struct mtk_cam_video_device *node = file_to_mtk_cam_node(file);
>> struct mtk_cam_request_stream_data *stream_data;
>> struct mtk_cam_request *cam_req;
>> struct media_request *req;
>> s32 fd;
>>
>> fd = s->request_fd;
>> if (fd < 0)
>> return -EINVAL;
>>
>> req = media_request_get_by_fd(&cam->media_dev, fd);
>>
>> /* .... */
>>
>> cam_req = to_mtk_cam_req(req);
>> stream_data = &cam_req->stream_data[node->uid.pipe_id];
>> stream_data->vdev_selection_update |= (1 << node->desc.id);
>> stream_data->vdev_selection[node->desc.id] = *s;
>>
>> /* .... */
>>
>> media_request_put(req);
>>
>> return 0;
>> }
>>
>> I posted interface change to discuss first and would like some
>> review comments.
>>
>> Thank you very much.
>
> Just adding a request_fd in several places is the easy bit. The much
> harder part is where to store that information, and even harder is an
> outstanding issue with the request framework:
>
> Currently the request framework is only used with decoder drivers, so
> there are no subdev drivers involved. I suspect that there is a fair
> amount of work to do to make it work well if part of the request configuration
> is for subdev drivers.
>
> Ideally I would like to see a proof-of-concept with the vimc driver.
>
> I think getting this right is quite a lot of work. The public API part
> is just a minor part of that since the public API was designed with support
> for this in mind. It's the internal kernel support that is lacking.
>
> If you want to pursue this (and that would be great!), then start with
> vimc and initially just support controls in a request. The core problem
> is likely to be how to keep track of the request data if it is spread
> out between the bridge driver and subdev drivers, and that can be tested
> with just supporting controls.
>
> Adding support for formats and selection rectangles is, I think, much less
> difficult and can be addressed later. Changing the topology in a request
> is a separate issue as well, and I would suggest that you postpone that.
> There is some low-level work going on that might make this easier in the
> near future (1), we'll have to wait and see.

Just FYI: I have not heard anything about this since my reply, so I am marking
this series as RFC in patchwork.

Regards,

Hans

>
> Regards,
>
> Hans
>
> (1): https://patchwork.linuxtv.org/project/linux-media/cover/[email protected]/
>
>>
>> media: v4l2-core: extend the v4l2 format to support request
>> media: subdev: support which in v4l2_subdev_frame_interval
>> media: v4l2-ctrl: Add ISP Camsys user control
>> media: pixfmt: Add ISP Camsys formats
>>
>> drivers/media/mc/mc-device.c | 7 +-
>> drivers/media/v4l2-core/v4l2-ioctl.c | 153 ++++++++++++++++++++++++++-
>> include/media/media-entity.h | 3 +
>> include/uapi/linux/media.h | 3 +-
>> include/uapi/linux/v4l2-controls.h | 4 +
>> include/uapi/linux/v4l2-subdev.h | 8 +-
>> include/uapi/linux/videodev2.h | 109 ++++++++++++++++++-
>> 7 files changed, 275 insertions(+), 12 deletions(-)
>>
>>
>