From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Philippe De Muyter <phdm@macqel.be>
Cc: linux-media@vger.kernel.org, slongerbeam@gmail.com
Subject: Re: [PATCH v3 1/2] media: v4l2-subdev.h: allow V4L2_FRMIVAL_TYPE_CONTINUOUS & _STEPWISE
Date: Thu, 20 Sep 2018 17:11:50 +0300 [thread overview]
Message-ID: <1715501.OtfZWGH4Dz@avalon> (raw)
In-Reply-To: <1536685593-27512-2-git-send-email-phdm@macqel.be>
Hi Philippe,
Thank you for the patch.
On Tuesday, 11 September 2018 20:06:32 EEST Philippe De Muyter wrote:
> add V4L2_FRMIVAL_TYPE_CONTINUOUS and V4L2_FRMIVAL_TYPE_STEPWISE for
> subdev's frame intervals in addition to implicit existing
> V4L2_FRMIVAL_TYPE_DISCRETE type. This needs three new fields in the
> v4l2_subdev_frame_interval_enum struct :
> - type
> - max_interval
> - step_interval
>
> A helper function 'v4l2_fill_frmivalenum_from_subdev' is also added.
>
> Subdevs must fill the 'type' field. If they do not, the default
> value (0) is used which is equal to V4L2_SUBDEV_FRMIVAL_TYPE_DISCRETE.
>
> if type is set to V4L2_SUBDEV_FRMIVAL_TYPE_DISCRETE, or left untouched,
> only the 'interval' field must be filled, just as before.
>
> If type is set to V4L2_FRMIVAL_TYPE_CONTINUOUS, 'interval' must be set
> to the minimum frame interval (highest framerate), and 'max_interval'
> to the maximum frame interval.
>
> If type is set to V4L2_FRMIVAL_TYPE_STEPWISE, 'step_interval' must be
> set to the step between available intervals, in addition to 'interval'
> and 'max_interval' which must be set as for V4L2_FRMIVAL_TYPE_CONTINUOUS
Continuous is a special case of stepwise with the step set to 1. Should we
merge the two types ?
I'm curious, as there's nothing in this series, using the new types, what are
your use cases ?
> Old users which do not check the 'type' field will get the minimum frame
> interval (highest framrate) just like before.
>
> Callers who intend to check the 'type' field should zero it themselves,
> in case an old subdev driver does not do zero it.
>
> When filled correctly by the sensor driver, the new fields must be
> used as follows by the caller :
>
> struct v4l2_frmivalenum * fival;
> struct v4l2_subdev_frame_interval_enum fie;
>
> if (fie.type == V4L2_SUBDEV_FRMIVAL_TYPE_DISCRETE) {
> fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
> fival->discrete = fie.interval;
> } else if (fie.type == V4L2_SUBDEV_FRMIVAL_TYPE_CONTINUOUS) {
> fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
> fival->stepwise.min = fie.interval;
> fival->stepwise.max = fie.max_interval;
> } else {
> fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
> fival->stepwise.min = fie.interval;
> fival->stepwise.max = fie.max_interval;
> fival->stepwise.step = fie.step_interval;
> }
>
> Kernel users should use the new 'v4l2_fill_frmivalenum_from_subdev'
> helper function.
>
> Signed-off-by: Philippe De Muyter <phdm@macqel.be>
> ---
> .../uapi/v4l/vidioc-subdev-enum-frame-interval.rst | 69 ++++++++++++++++++-
> drivers/media/v4l2-core/v4l2-common.c | 33 +++++++++++
> include/media/v4l2-common.h | 12 ++++
> include/uapi/linux/v4l2-subdev.h | 22 ++++++-
> 4 files changed, 133 insertions(+), 3 deletions(-)
>
> diff --git
> a/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-interval.rst
> b/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-interval.rst index
> 1bfe386..e14fa14 100644
> --- a/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-interval.rst
> +++ b/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-interval.rst
> @@ -51,6 +51,41 @@ EINVAL error code if one of the input fields is invalid.
> All frame intervals are enumerable by beginning at index zero and
> incrementing by one until ``EINVAL`` is returned.
>
> +If the sub-device can work only with a fixed set of frame intervals, then
> +the driver must enumerate them with increasing indexes, by setting the
> +``type`` field to ``V4L2_SUBDEV_FRMIVAL_TYPE_DISCRETE`` and only filling
> +the ``interval`` field . If the sub-device can work with a continuous
> +range of frame intervals, then the driver must only return success for
> +index 0, set the ``type`` field to ``V4L2_SUBDEV_FRMIVAL_TYPE_CONTINUOUS``,
> +fill ``interval`` with the minimum interval and ``max_interval`` with
> +the maximum interval. If it is worth mentioning the step in the
> +continuous interval, the driver must set the ``type`` field to
> +``V4L2_SUBDEV_FRMIVAL_TYPE_STEPWISE`` and fill also the ``step_interval``
> +field with the step between the possible intervals.
> +
> +Callers are expected to use the returned information as follows:
> +
> +.. code-block:: c
> +
> + struct v4l2_frmivalenum *fival;
> + struct v4l2_subdev_frame_interval_enum fie;
> +
> + if (fie.type == V4L2_SUBDEV_FRMIVAL_TYPE_DISCRETE) {
> + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
> + fival->discrete = fie.interval;
> + } else if (fie.type == V4L2_SUBDEV_FRMIVAL_TYPE_CONTINUOUS) {
> + fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
> + fival->stepwise.min = fie.interval;
> + fival->stepwise.max = fie.max_interval;
> + } else {
> + fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
> + fival->stepwise.min = fie.interval;
> + fival->stepwise.max = fie.max_interval;
> + fival->stepwise.step = fie.step_interval;
> + }
> +
> +.. code-block:: c
> +
> Available frame intervals may depend on the current 'try' formats at
> other pads of the sub-device, as well as on the current active links.
> See :ref:`VIDIOC_SUBDEV_G_FMT` for more
> @@ -93,11 +128,43 @@ multiple pads of the same sub-device is not defined.
> - Frame intervals to be enumerated, from enum
>
> :ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
>
> * - __u32
> - - ``reserved``\ [8]
> + - ``type``
> + - Type of enumerated interval
> + :ref:`v4l2_subdev_frmival_type <v4l2-subdev-frmival-type>`.
> + * - struct :c:type:`v4l2_fract`
> + - ``max_interval``
> + - Maximum period, in seconds, between consecutive video frames, or 0.
> + * - struct :c:type:`v4l2_fract`
> + - ``step_interval``
> + - Frame interval step size, in seconds, or 0.
Having minimum and maximum values as fractions and a step as a fraction as
well will make the maths pretty fun... I think it was a mistake to go with
fractions in the first place, as it gives many ways to represent the same
value. It lead to gems such as https://elixir.bootlin.com/linux/latest/source/
drivers/media/usb/uvc/uvc_driver.c#L263 (which I'm both proud and ashamed of).
Instead of repeating the mistake, is there a chance we could fix it and
express intervals as an integer (in nanoseconds for instance, or possibly 10s
or 100s of nanoseconds) for these new types ? Ideally I'd move to the same
unit for the discrete type as well but we can't change the API there. We could
deprecate it though (given that I expect very few users of that subdev
userspace API) and add a new type for discrete intervals using integers.
Subdev drivers would then implement the new API only, with the conversion
performed in core code.
> + * - __u32
> + - ``reserved``\ [3]
> - Reserved for future extensions. Applications and drivers must set
> the array to zero.
>
>
> +
> +.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
> +
> +.. _v4l2-subdev-frmival-type:
> +
> +.. flat-table:: enum v4l2_subdev_format_whence
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 3 1 4
> +
> + * - V4L2_SUBDEV_FRMIVAL_TYPE_DISCRETE
> + - 0
> + - This frame interval is fixed
> + * - V4L2_SUBDEV_FRMIVAL_TYPE_CONTINUOUS
> + - 1
> + - Any frame interval between min and max is available
> + * - V4L2_SUBDEV_FRMIVAL_TYPE_STEPWISE
> + - 2
> + - Many frame intervals between min and max are available, with a
> + significant and constant step between them.
> +
> +
> Return Value
> ============
>
> diff --git a/drivers/media/v4l2-core/v4l2-common.c
> b/drivers/media/v4l2-core/v4l2-common.c index b062111..ec9b748 100644
> --- a/drivers/media/v4l2-core/v4l2-common.c
> +++ b/drivers/media/v4l2-core/v4l2-common.c
> @@ -445,3 +445,36 @@ int v4l2_s_parm_cap(struct video_device *vdev,
> return ret;
> }
> EXPORT_SYMBOL_GPL(v4l2_s_parm_cap);
> +
> +int v4l2_fill_frmivalenum_from_subdev(struct v4l2_subdev *sd, struct
> v4l2_frmivalenum *fival, int code) +{
> + struct v4l2_subdev_frame_interval_enum fie;
> + int ret;
> +
> + fie.index = fival->index;
> + fie.code = code;
> + fie.width = fival->width;
> + fie.height = fival->height;
> + fie.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> +
> + fie.type = V4L2_SUBDEV_FRMIVAL_TYPE_DISCRETE; /* for old subdev drivers */
> + ret = v4l2_subdev_call(sd, pad, enum_frame_interval, NULL, &fie); +
> + if (!ret) {
> + if (fie.type == V4L2_SUBDEV_FRMIVAL_TYPE_DISCRETE) {
> + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
> + fival->discrete = fie.interval;
> + } else if (fie.type == V4L2_SUBDEV_FRMIVAL_TYPE_CONTINUOUS) {
> + fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
> + fival->stepwise.min = fie.interval;
> + fival->stepwise.max = fie.max_interval;
> + } else {
> + fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
> + fival->stepwise.min = fie.interval;
> + fival->stepwise.max = fie.max_interval;
> + fival->stepwise.step = fie.step_interval;
> + }
> + }
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_fill_frmivalenum_from_subdev);
> diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
> index cdc87ec..3c62403 100644
> --- a/include/media/v4l2-common.h
> +++ b/include/media/v4l2-common.h
> @@ -384,4 +384,16 @@ int v4l2_g_parm_cap(struct video_device *vdev,
> int v4l2_s_parm_cap(struct video_device *vdev,
> struct v4l2_subdev *sd, struct v4l2_streamparm *a);
>
> +/**
> + * v4l2_fill_frmivalenum_from_subdev - helper for
> vidioc_enum_frameintervals + * calling the enum_frame_interval op of
> the given subdev.
> + *
> + * @sd: the sub-device pointer.
> + * @fival: the VIDIOC_ENUM_FRAMEINTERVALS argument.
> + * @code: the MEDIA_BUS_FMT_ code (not fival->pixel_format !)
> + */
> +int v4l2_fill_frmivalenum_from_subdev(struct v4l2_subdev *sd,
> + struct v4l2_frmivalenum *fival,
> + int code);
> +
> #endif /* V4L2_COMMON_H_ */
> diff --git a/include/uapi/linux/v4l2-subdev.h
> b/include/uapi/linux/v4l2-subdev.h index 03970ce..3faae35 100644
> --- a/include/uapi/linux/v4l2-subdev.h
> +++ b/include/uapi/linux/v4l2-subdev.h
> @@ -100,6 +100,16 @@ struct v4l2_subdev_frame_size_enum {
> };
>
> /**
> + * enum v4l2_subdev_frmival_type - Frame interval type
> + */
> +enum v4l2_subdev_frmival_type {
> + V4L2_SUBDEV_FRMIVAL_TYPE_DISCRETE = 0,
> + V4L2_SUBDEV_FRMIVAL_TYPE_CONTINUOUS = 1,
> + V4L2_SUBDEV_FRMIVAL_TYPE_STEPWISE = 2,
> +};
> +
> +
> +/**
> * struct v4l2_subdev_frame_interval - Pad-level frame rate
> * @pad: pad number, as reported by the media API
> * @interval: frame interval in seconds
> @@ -117,8 +127,13 @@ struct v4l2_subdev_frame_interval {
> * @code: format code (MEDIA_BUS_FMT_ definitions)
> * @width: frame width in pixels
> * @height: frame height in pixels
> - * @interval: frame interval in seconds
> + * @interval: minimum frame interval in seconds
> * @which: format type (from enum v4l2_subdev_format_whence)
> + * @type: frame interval type (from enum v4l2_subdev_frmival_type)
> + * @max_interval: maximum frame interval in seconds,
> + * if type != V4L2_SUBDEV_FRMIVAL_TYPE_DISCRETE
> + * @step_interval: step between frame intervals, in seconds,
> + * if type == V4L2_SUBDEV_FRMIVAL_TYPE_STEPWISE
> */
> struct v4l2_subdev_frame_interval_enum {
> __u32 index;
> @@ -128,7 +143,10 @@ struct v4l2_subdev_frame_interval_enum {
> __u32 height;
> struct v4l2_fract interval;
> __u32 which;
> - __u32 reserved[8];
> + __u32 type;
> + struct v4l2_fract max_interval;
> + struct v4l2_fract step_interval;
> + __u32 reserved[3];
> };
>
> /**
--
Regards,
Laurent Pinchart
next prev parent reply other threads:[~2018-09-20 19:55 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <linux-media@vger.kernel.org.slongerbeam@gmail.com>
2018-09-11 17:06 ` [PATCH v3 0/2] media: v4l2-subdev.h: allow V4L2_FRMIVAL_TYPE_CONTINUOUS & _STEPWISE Philippe De Muyter
2018-09-11 17:06 ` [PATCH v3 1/2] " Philippe De Muyter
2018-09-20 14:11 ` Laurent Pinchart [this message]
2018-09-20 15:15 ` Philippe De Muyter
2018-09-11 17:06 ` [PATCH v3 2/2] media: imx: capture: use 'v4l2_fill_frmivalenum_from_subdev' Philippe De Muyter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1715501.OtfZWGH4Dz@avalon \
--to=laurent.pinchart@ideasonboard.com \
--cc=linux-media@vger.kernel.org \
--cc=phdm@macqel.be \
--cc=slongerbeam@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox