Re: [PATCHv18 01/35] Documentation: v4l: document request API

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

 



Em Tue, 14 Aug 2018 16:20:13 +0200
Hans Verkuil <hverkuil@xxxxxxxxx> escreveu:

> From: Alexandre Courbot <acourbot@xxxxxxxxxxxx>
> 
> Document the request API for V4L2 devices, and amend the documentation
> of system calls influenced by it.

Looks ok to me. Just a minor nitpick (see below).

Mental note: we'll need to push the no-invariant-sections upstream before
merging this there. 

With that:

Reviewed-by: Mauro Carvalho Chehab <mchehab+samsung@xxxxxxxxxx>

> 
> Signed-off-by: Alexandre Courbot <acourbot@xxxxxxxxxxxx>
> Signed-off-by: Hans Verkuil <hans.verkuil@xxxxxxxxx>
> ---
>  .../media/uapi/mediactl/media-controller.rst  |   1 +
>  .../media/uapi/mediactl/media-funcs.rst       |   6 +
>  .../uapi/mediactl/media-ioc-request-alloc.rst |  65 +++++
>  .../uapi/mediactl/media-request-ioc-queue.rst |  82 ++++++
>  .../mediactl/media-request-ioc-reinit.rst     |  51 ++++
>  .../media/uapi/mediactl/request-api.rst       | 245 ++++++++++++++++++
>  .../uapi/mediactl/request-func-close.rst      |  48 ++++
>  .../uapi/mediactl/request-func-ioctl.rst      |  67 +++++
>  .../media/uapi/mediactl/request-func-poll.rst |  77 ++++++
>  Documentation/media/uapi/v4l/buffer.rst       |  21 +-
>  .../media/uapi/v4l/vidioc-g-ext-ctrls.rst     |  53 +++-
>  Documentation/media/uapi/v4l/vidioc-qbuf.rst  |  32 ++-
>  .../media/videodev2.h.rst.exceptions          |   1 +
>  13 files changed, 739 insertions(+), 10 deletions(-)
>  create mode 100644 Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst
>  create mode 100644 Documentation/media/uapi/mediactl/media-request-ioc-queue.rst
>  create mode 100644 Documentation/media/uapi/mediactl/media-request-ioc-reinit.rst
>  create mode 100644 Documentation/media/uapi/mediactl/request-api.rst
>  create mode 100644 Documentation/media/uapi/mediactl/request-func-close.rst
>  create mode 100644 Documentation/media/uapi/mediactl/request-func-ioctl.rst
>  create mode 100644 Documentation/media/uapi/mediactl/request-func-poll.rst
> 
> diff --git a/Documentation/media/uapi/mediactl/media-controller.rst b/Documentation/media/uapi/mediactl/media-controller.rst
> index 0eea4f9a07d5..66aff38cd499 100644
> --- a/Documentation/media/uapi/mediactl/media-controller.rst
> +++ b/Documentation/media/uapi/mediactl/media-controller.rst
> @@ -21,6 +21,7 @@ Part IV - Media Controller API
>      media-controller-intro
>      media-controller-model
>      media-types
> +    request-api
>      media-funcs
>      media-header
>  
> diff --git a/Documentation/media/uapi/mediactl/media-funcs.rst b/Documentation/media/uapi/mediactl/media-funcs.rst
> index 076856501cdb..260f9dcadcde 100644
> --- a/Documentation/media/uapi/mediactl/media-funcs.rst
> +++ b/Documentation/media/uapi/mediactl/media-funcs.rst
> @@ -16,3 +16,9 @@ Function Reference
>      media-ioc-enum-entities
>      media-ioc-enum-links
>      media-ioc-setup-link
> +    media-ioc-request-alloc
> +    request-func-close
> +    request-func-ioctl
> +    request-func-poll
> +    media-request-ioc-queue
> +    media-request-ioc-reinit
> diff --git a/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst b/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst
> new file mode 100644
> index 000000000000..34434e2b3918
> --- /dev/null
> +++ b/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst
> @@ -0,0 +1,65 @@
> +.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
> +
> +.. _media_ioc_request_alloc:
> +
> +*****************************
> +ioctl MEDIA_IOC_REQUEST_ALLOC
> +*****************************
> +
> +Name
> +====
> +
> +MEDIA_IOC_REQUEST_ALLOC - Allocate a request
> +
> +
> +Synopsis
> +========
> +
> +.. c:function:: int ioctl( int fd, MEDIA_IOC_REQUEST_ALLOC, int *argp )
> +    :name: MEDIA_IOC_REQUEST_ALLOC
> +
> +
> +Arguments
> +=========
> +
> +``fd``
> +    File descriptor returned by :ref:`open() <media-func-open>`.
> +
> +``argp``
> +    Pointer to an integer.

Nitpick: I would name it as ``request_fd``.

> +
> +
> +Description
> +===========
> +
> +If the media device supports :ref:`requests <media-request-api>`, then
> +this ioctl can be used to allocate a request. If it is not supported, then
> +``errno`` is set to ``ENOTTY``. A request is accessed through a file descriptor
> +that is returned in ``*argp``.
> +
> +If the request was successfully allocated, then the request file descriptor
> +can be passed to the :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`,
> +:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`,
> +:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` and
> +:ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctls.
> +
> +In addition, the request can be queued by calling
> +:ref:`MEDIA_REQUEST_IOC_QUEUE` and re-initialized by calling
> +:ref:`MEDIA_REQUEST_IOC_REINIT`.
> +
> +Finally, the file descriptor can be :ref:`polled <request-func-poll>` to wait
> +for the request to complete.
> +
> +The request will remain allocated until all the file descriptors associated
> +with it are closed by :ref:`close() <request-func-close>` and the driver no
> +longer uses the request internally.
> +
> +Return Value
> +============
> +
> +On success 0 is returned, on error -1 and the ``errno`` variable is set
> +appropriately. The generic error codes are described at the
> +:ref:`Generic Error Codes <gen-errors>` chapter.
> +
> +ENOTTY
> +    The driver has no support for requests.
> diff --git a/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst b/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst
> new file mode 100644
> index 000000000000..d4f8119e0643
> --- /dev/null
> +++ b/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst
> @@ -0,0 +1,82 @@
> +.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
> +
> +.. _media_request_ioc_queue:
> +
> +*****************************
> +ioctl MEDIA_REQUEST_IOC_QUEUE
> +*****************************
> +
> +Name
> +====
> +
> +MEDIA_REQUEST_IOC_QUEUE - Queue a request
> +
> +
> +Synopsis
> +========
> +
> +.. c:function:: int ioctl( int request_fd, MEDIA_REQUEST_IOC_QUEUE )
> +    :name: MEDIA_REQUEST_IOC_QUEUE
> +
> +
> +Arguments
> +=========
> +
> +``request_fd``
> +    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
> +
> +
> +Description
> +===========
> +
> +If the media device supports :ref:`requests <media-request-api>`, then
> +this request ioctl can be used to queue a previously allocated request.
> +
> +If the request was successfully queued, then the file descriptor can be
> +:ref:`polled <request-func-poll>` to wait for the request to complete.
> +
> +If the request was already queued before, then ``EBUSY`` is returned.
> +Other errors can be returned if the contents of the request contained
> +invalid or inconsistent data, see the next section for a list of
> +common error codes. On error both the request and driver state are unchanged.
> +
> +Typically if you get an error here, then that means that the application
> +did something wrong and you have to fix the application.
> +
> +Once a request is queued, then the driver is required to gracefully handle
> +errors that occur when the request is applied to the hardware. The
> +exception is the ``EIO`` error which signals a fatal error that requires
> +the application to stop streaming to reset the hardware state.
> +
> +It is not allowed to mix queuing requests with queuing buffers directly
> +(without a request). ``EPERM`` will be returned if the first buffer was
> +queued directly and you next try to queue a request, or vice versa.
> +
> +A request must contain at least one buffer, otherwise this ioctl will
> +return an ``ENOENT`` error.
> +
> +Return Value
> +============
> +
> +On success 0 is returned, on error -1 and the ``errno`` variable is set
> +appropriately. The generic error codes are described at the
> +:ref:`Generic Error Codes <gen-errors>` chapter.
> +
> +EBUSY
> +    The request was already queued.
> +EPERM
> +    The application queued the first buffer directly, but later attempted
> +    to use a request. It is not permitted to mix the two APIs.
> +ENOENT
> +    The request did not contain any buffers. All requests are required
> +    to have at least one buffer. This can also be returned if required
> +    controls are missing.
> +ENOMEM
> +    Out of memory when allocating internal data structures for this
> +    request.
> +EINVAL
> +    The request has invalid data.
> +EIO
> +    The hardware is in a bad state. To recover, the application needs to
> +    stop streaming to reset the hardware state and then try to restart
> +    streaming.
> diff --git a/Documentation/media/uapi/mediactl/media-request-ioc-reinit.rst b/Documentation/media/uapi/mediactl/media-request-ioc-reinit.rst
> new file mode 100644
> index 000000000000..febe888494c8
> --- /dev/null
> +++ b/Documentation/media/uapi/mediactl/media-request-ioc-reinit.rst
> @@ -0,0 +1,51 @@
> +.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
> +
> +.. _media_request_ioc_reinit:
> +
> +******************************
> +ioctl MEDIA_REQUEST_IOC_REINIT
> +******************************
> +
> +Name
> +====
> +
> +MEDIA_REQUEST_IOC_REINIT - Re-initialize a request
> +
> +
> +Synopsis
> +========
> +
> +.. c:function:: int ioctl( int request_fd, MEDIA_REQUEST_IOC_REINIT )
> +    :name: MEDIA_REQUEST_IOC_REINIT
> +
> +
> +Arguments
> +=========
> +
> +``request_fd``
> +    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
> +
> +Description
> +===========
> +
> +If the media device supports :ref:`requests <media-request-api>`, then
> +this request ioctl can be used to re-initialize a previously allocated
> +request.
> +
> +Re-initializing a request will clear any existing data from the request.
> +This avoids having to :ref:`close() <request-func-close>` a completed
> +request and allocate a new request. Instead the completed request can just
> +be re-initialized and it is ready to be used again.
> +
> +A request can only be re-initialized if it either has not been queued
> +yet, or if it was queued and completed. Otherwise it will set ``errno``
> +to ``EBUSY``. No other error codes can be returned.
> +
> +Return Value
> +============
> +
> +On success 0 is returned, on error -1 and the ``errno`` variable is set
> +appropriately.
> +
> +EBUSY
> +    The request is queued but not yet completed.
> diff --git a/Documentation/media/uapi/mediactl/request-api.rst b/Documentation/media/uapi/mediactl/request-api.rst
> new file mode 100644
> index 000000000000..0b9da58b01e3
> --- /dev/null
> +++ b/Documentation/media/uapi/mediactl/request-api.rst
> @@ -0,0 +1,245 @@
> +.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
> +
> +.. _media-request-api:
> +
> +Request API
> +===========
> +
> +The Request API has been designed to allow V4L2 to deal with requirements of
> +modern devices (stateless codecs, complex camera pipelines, ...) and APIs
> +(Android Codec v2). One such requirement is the ability for devices belonging to
> +the same pipeline to reconfigure and collaborate closely on a per-frame basis.
> +Another is support of stateless codecs, which require controls to be applied
> +to specific frames (aka 'per-frame controls') in order to be used efficiently.
> +
> +Supporting these features without the Request API is not always possible and if
> +it is, it is terribly inefficient: user-space would have to flush all activity
> +on the media pipeline, reconfigure it for the next frame, queue the buffers to
> +be processed with that configuration, and wait until they are all available for
> +dequeuing before considering the next frame. This defeats the purpose of having
> +buffer queues since in practice only one buffer would be queued at a time.
> +
> +The Request API allows a specific configuration of the pipeline (media
> +controller topology + controls for each media entity) to be associated with
> +specific buffers. The parameters are applied by each participating device as
> +buffers associated to a request flow in. This allows user-space to schedule
> +several tasks ("requests") with different parameters in advance, knowing that
> +the parameters will be applied when needed to get the expected result. Control
> +values at the time of request completion are also available for reading.
> +
> +Usage
> +=====
> +
> +The Request API is used on top of standard media controller and V4L2 calls,
> +which are augmented with an extra ``request_fd`` parameter. Requests themselves
> +are allocated from the supporting media controller node.
> +
> +Request Allocation
> +------------------
> +
> +User-space allocates requests using :ref:`MEDIA_IOC_REQUEST_ALLOC`
> +for the media device node. This returns a file descriptor representing the
> +request. Typically, several such requests will be allocated.
> +
> +Request Preparation
> +-------------------
> +
> +Standard V4L2 ioctls can then receive a request file descriptor to express the
> +fact that the ioctl is part of said request, and is not to be applied
> +immediately. See :ref:`MEDIA_IOC_REQUEST_ALLOC` for a list of ioctls that
> +support this. Controls set with a ``request_fd`` parameter are stored instead
> +of being immediately applied, and buffers queued to a request do not enter the
> +regular buffer queue until the request itself is queued.
> +
> +Request Submission
> +------------------
> +
> +Once the parameters and buffers of the request are specified, it can be
> +queued by calling :ref:`MEDIA_REQUEST_IOC_QUEUE` on the request file descriptor.
> +A request must contain at least one buffer, otherwise ``ENOENT`` is returned.
> +This will make the buffers associated to the request available to their driver,
> +which can then apply the associated controls as buffers are processed. A queued
> +request cannot be modified anymore.
> +
> +.. caution::
> +   For :ref:`memory-to-memory devices <codec>` you can use requests only for
> +   output buffers, not for capture buffers. Attempting to add a capture buffer
> +   to a request will result in an ``EPERM`` error.
> +
> +If the request contains parameters for multiple entities, individual drivers may
> +synchronize so the requested pipeline's topology is applied before the buffers
> +are processed. Media controller drivers do a best effort implementation since
> +perfect atomicity may not be possible due to hardware limitations.
> +
> +.. caution::
> +
> +   It is not allowed to mix queuing requests with directly queuing buffers:
> +   whichever method is used first locks this in place until
> +   :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` is called or the device is
> +   :ref:`closed <func-close>`. Attempts to directly queue a buffer when earlier
> +   a buffer was queued via a request or vice versa will result in an ``EPERM``
> +   error.
> +
> +Controls can still be set without a request and are applied immediately,
> +regardless of whether a request is in use or not.
> +
> +.. caution::
> +
> +   Setting the same control through a request and also directly can lead to
> +   undefined behavior!
> +
> +User-space can :ref:`poll() <request-func-poll>` a request file descriptor in
> +order to wait until the request completes. A request is considered complete
> +once all its associated buffers are available for dequeuing and all the
> +associated controls have been updated with the values at the time of completion.
> +Note that user-space does not need to wait for the request to complete to
> +dequeue its buffers: buffers that are available halfway through a request can
> +be dequeued independently of the request's state.
> +
> +A completed request contains the state of the request at the time of the
> +request completion. User-space can query that state by calling
> +:ref:`ioctl VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` with the request file
> +descriptor. Calling :ref:`ioctl VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` for a
> +request that has been queued but not yet completed will return ``EBUSY``
> +since the control values might be changed at any time by the driver while the
> +request is in flight.
> +
> +Recycling and Destruction
> +-------------------------
> +
> +Finally, a completed request can either be discarded or be reused. Calling
> +:ref:`close() <request-func-close>` on a request file descriptor will make
> +that file descriptor unusable and the request will be freed once it is no
> +longer in use by the kernel. That is, if the request is queued and then the
> +file descriptor is closed, then it won't be freed until the driver completed
> +the request.
> +
> +The :ref:`MEDIA_REQUEST_IOC_REINIT` will clear a request's state and make it
> +available again. No state is retained by this operation: the request is as
> +if it had just been allocated.
> +
> +Example for a Codec Device
> +--------------------------
> +
> +For use-cases such as :ref:`codecs <codec>`, the request API can be used
> +to associate specific controls to
> +be applied by the driver for the OUTPUT buffer, allowing user-space
> +to queue many such buffers in advance. It can also take advantage of requests'
> +ability to capture the state of controls when the request completes to read back
> +information that may be subject to change.
> +
> +Put into code, after obtaining a request, user-space can assign controls and one
> +OUTPUT buffer to it:
> +
> +.. code-block:: c
> +
> +	struct v4l2_buffer buf;
> +	struct v4l2_ext_controls ctrls;
> +	int req_fd;
> +	...
> +	if (ioctl(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd))
> +		return errno;
> +	...
> +	ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
> +	ctrls.request_fd = req_fd;
> +	if (ioctl(codec_fd, VIDIOC_S_EXT_CTRLS, &ctrls))
> +		return errno;
> +	...
> +	buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
> +	buf.flags |= V4L2_BUF_FLAG_REQUEST_FD;
> +	buf.request_fd = req_fd;
> +	if (ioctl(codec_fd, VIDIOC_QBUF, &buf))
> +		return errno;
> +
> +Note that it is not allowed to use the Request API for CAPTURE buffers
> +since there are no per-frame settings to report there.
> +
> +Once the request is fully prepared, it can be queued to the driver:
> +
> +.. code-block:: c
> +
> +	if (ioctl(req_fd, MEDIA_REQUEST_IOC_QUEUE))
> +		return errno;
> +
> +User-space can then either wait for the request to complete by calling poll() on
> +its file descriptor, or start dequeuing CAPTURE buffers. Most likely, it will
> +want to get CAPTURE buffers as soon as possible and this can be done using a
> +regular :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`:
> +
> +.. code-block:: c
> +
> +	struct v4l2_buffer buf;
> +
> +	memset(&buf, 0, sizeof(buf));
> +	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> +	if (ioctl(codec_fd, VIDIOC_DQBUF, &buf))
> +		return errno;
> +
> +Note that this example assumes for simplicity that for every OUTPUT buffer
> +there will be one CAPTURE buffer, but this does not have to be the case.
> +
> +We can then, after ensuring that the request is completed via polling the
> +request file descriptor, query control values at the time of its completion via
> +a call to :ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`.
> +This is particularly useful for volatile controls for which we want to
> +query values as soon as the capture buffer is produced.
> +
> +.. code-block:: c
> +
> +	struct pollfd pfd = { .events = POLLPRI, .fd = req_fd };
> +	poll(&pfd, 1, -1);
> +	...
> +	ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
> +	ctrls.request_fd = req_fd;
> +	if (ioctl(codec_fd, VIDIOC_G_EXT_CTRLS, &ctrls))
> +		return errno;
> +
> +Once we don't need the request anymore, we can either recycle it for reuse with
> +:ref:`MEDIA_REQUEST_IOC_REINIT`...
> +
> +.. code-block:: c
> +
> +	if (ioctl(req_fd, MEDIA_REQUEST_IOC_REINIT))
> +		return errno;
> +
> +... or close its file descriptor to completely dispose of it.
> +
> +.. code-block:: c
> +
> +	close(req_fd);
> +
> +Example for a Simple Capture Device
> +-----------------------------------
> +
> +With a simple capture device, requests can be used to specify controls to apply
> +for a given CAPTURE buffer.
> +
> +.. code-block:: c
> +
> +	struct v4l2_buffer buf;
> +	struct v4l2_ext_controls ctrls;
> +	int req_fd;
> +	...
> +	if (ioctl(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd))
> +		return errno;
> +	...
> +	ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
> +	ctrls.request_fd = req_fd;
> +	if (ioctl(camera_fd, VIDIOC_S_EXT_CTRLS, &ctrls))
> +		return errno;
> +	...
> +	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> +	buf.flags |= V4L2_BUF_FLAG_REQUEST_FD;
> +	buf.request_fd = req_fd;
> +	if (ioctl(camera_fd, VIDIOC_QBUF, &buf))
> +		return errno;
> +
> +Once the request is fully prepared, it can be queued to the driver:
> +
> +.. code-block:: c
> +
> +	if (ioctl(req_fd, MEDIA_REQUEST_IOC_QUEUE))
> +		return errno;
> +
> +User-space can then dequeue buffers, wait for the request completion, query
> +controls and recycle the request as in the M2M example above.
> diff --git a/Documentation/media/uapi/mediactl/request-func-close.rst b/Documentation/media/uapi/mediactl/request-func-close.rst
> new file mode 100644
> index 000000000000..b5c78683840b
> --- /dev/null
> +++ b/Documentation/media/uapi/mediactl/request-func-close.rst
> @@ -0,0 +1,48 @@
> +.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
> +
> +.. _request-func-close:
> +
> +***************
> +request close()
> +***************
> +
> +Name
> +====
> +
> +request-close - Close a request file descriptor
> +
> +
> +Synopsis
> +========
> +
> +.. code-block:: c
> +
> +    #include <unistd.h>
> +
> +
> +.. c:function:: int close( int fd )
> +    :name: req-close
> +
> +Arguments
> +=========
> +
> +``fd``
> +    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
> +
> +
> +Description
> +===========
> +
> +Closes the request file descriptor. Resources associated with the request
> +are freed once all file descriptors associated with the request are closed
> +and the driver has completed the request.
> +
> +
> +Return Value
> +============
> +
> +:ref:`close() <request-func-close>` returns 0 on success. On error, -1 is
> +returned, and ``errno`` is set appropriately. Possible error codes are:
> +
> +EBADF
> +    ``fd`` is not a valid open file descriptor.
> diff --git a/Documentation/media/uapi/mediactl/request-func-ioctl.rst b/Documentation/media/uapi/mediactl/request-func-ioctl.rst
> new file mode 100644
> index 000000000000..ff7b072a6999
> --- /dev/null
> +++ b/Documentation/media/uapi/mediactl/request-func-ioctl.rst
> @@ -0,0 +1,67 @@
> +.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
> +
> +.. _request-func-ioctl:
> +
> +***************
> +request ioctl()
> +***************
> +
> +Name
> +====
> +
> +request-ioctl - Control a request file descriptor
> +
> +
> +Synopsis
> +========
> +
> +.. code-block:: c
> +
> +    #include <sys/ioctl.h>
> +
> +
> +.. c:function:: int ioctl( int fd, int cmd, void *argp )
> +    :name: req-ioctl
> +
> +Arguments
> +=========
> +
> +``fd``
> +    File descriptor returned by :ref:`MEDIA_IOC_REQUEST_ALLOC`.
> +
> +``cmd``
> +    The request ioctl command code as defined in the media.h header file, for
> +    example :ref:`MEDIA_REQUEST_IOC_QUEUE`.
> +
> +``argp``
> +    Pointer to a request-specific structure.
> +
> +
> +Description
> +===========
> +
> +The :ref:`ioctl() <request-func-ioctl>` function manipulates request
> +parameters. The argument ``fd`` must be an open file descriptor.
> +
> +The ioctl ``cmd`` code specifies the request function to be called. It
> +has encoded in it whether the argument is an input, output or read/write
> +parameter, and the size of the argument ``argp`` in bytes.
> +
> +Macros and structures definitions specifying request ioctl commands and
> +their parameters are located in the media.h header file. All request ioctl
> +commands, their respective function and parameters are specified in
> +:ref:`media-user-func`.
> +
> +
> +Return Value
> +============
> +
> +On success 0 is returned, on error -1 and the ``errno`` variable is set
> +appropriately. The generic error codes are described at the
> +:ref:`Generic Error Codes <gen-errors>` chapter.
> +
> +Command-specific error codes are listed in the individual command
> +descriptions.
> +
> +When an ioctl that takes an output or read/write parameter fails, the
> +parameter remains unmodified.
> diff --git a/Documentation/media/uapi/mediactl/request-func-poll.rst b/Documentation/media/uapi/mediactl/request-func-poll.rst
> new file mode 100644
> index 000000000000..70cc9d406a9f
> --- /dev/null
> +++ b/Documentation/media/uapi/mediactl/request-func-poll.rst
> @@ -0,0 +1,77 @@
> +.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
> +
> +.. _request-func-poll:
> +
> +**************
> +request poll()
> +**************
> +
> +Name
> +====
> +
> +request-poll - Wait for some event on a file descriptor
> +
> +
> +Synopsis
> +========
> +
> +.. code-block:: c
> +
> +    #include <sys/poll.h>
> +
> +
> +.. c:function:: int poll( struct pollfd *ufds, unsigned int nfds, int timeout )
> +   :name: request-poll
> +
> +Arguments
> +=========
> +
> +``ufds``
> +   List of file descriptor events to be watched
> +
> +``nfds``
> +   Number of file descriptor events at the \*ufds array
> +
> +``timeout``
> +   Timeout to wait for events
> +
> +
> +Description
> +===========
> +
> +With the :c:func:`poll() <request-func-poll>` function applications can wait
> +for a request to complete.
> +
> +On success :c:func:`poll() <request-func-poll>` returns the number of file
> +descriptors that have been selected (that is, file descriptors for which the
> +``revents`` field of the respective struct :c:type:`pollfd`
> +is non-zero). Request file descriptor set the ``POLLPRI`` flag in ``revents``
> +when the request was completed.  When the function times out it returns
> +a value of zero, on failure it returns -1 and the ``errno`` variable is
> +set appropriately.
> +
> +Attempting to poll for a request that is completed or not yet queued will
> +set the ``POLLERR`` flag in ``revents``.
> +
> +
> +Return Value
> +============
> +
> +On success, :c:func:`poll() <request-func-poll>` returns the number of
> +structures which have non-zero ``revents`` fields, or zero if the call
> +timed out. On error -1 is returned, and the ``errno`` variable is set
> +appropriately:
> +
> +``EBADF``
> +    One or more of the ``ufds`` members specify an invalid file
> +    descriptor.
> +
> +``EFAULT``
> +    ``ufds`` references an inaccessible memory area.
> +
> +``EINTR``
> +    The call was interrupted by a signal.
> +
> +``EINVAL``
> +    The ``nfds`` value exceeds the ``RLIMIT_NOFILE`` value. Use
> +    ``getrlimit()`` to obtain this value.
> diff --git a/Documentation/media/uapi/v4l/buffer.rst b/Documentation/media/uapi/v4l/buffer.rst
> index e2c85ddc990b..dd0065a95ea0 100644
> --- a/Documentation/media/uapi/v4l/buffer.rst
> +++ b/Documentation/media/uapi/v4l/buffer.rst
> @@ -306,10 +306,15 @@ struct v4l2_buffer
>        - A place holder for future extensions. Drivers and applications
>  	must set this to 0.
>      * - __u32
> -      - ``reserved``
> +      - ``request_fd``
>        -
> -      - A place holder for future extensions. Drivers and applications
> -	must set this to 0.
> +      - The file descriptor of the request to queue the buffer to. If specified
> +        and flag ``V4L2_BUF_FLAG_REQUEST_FD`` is set, then the buffer will be
> +	queued to that request. This is set by the user when calling
> +	:ref:`ioctl VIDIOC_QBUF <VIDIOC_QBUF>` and ignored by other ioctls.
> +	If the device does not support requests, then ``EPERM`` will be returned.
> +	If requests are supported but an invalid request FD is given, then
> +	``ENOENT`` will be returned.
>  
>  
>  
> @@ -514,6 +519,11 @@ Buffer Flags
>  	streaming may continue as normal and the buffer may be reused
>  	normally. Drivers set this flag when the ``VIDIOC_DQBUF`` ioctl is
>  	called.
> +    * .. _`V4L2-BUF-FLAG-IN-REQUEST`:
> +
> +      - ``V4L2_BUF_FLAG_IN_REQUEST``
> +      - 0x00000080
> +      - This buffer is part of a request that hasn't been queued yet.
>      * .. _`V4L2-BUF-FLAG-KEYFRAME`:
>  
>        - ``V4L2_BUF_FLAG_KEYFRAME``
> @@ -589,6 +599,11 @@ Buffer Flags
>  	the format. Any Any subsequent call to the
>  	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl will not block anymore,
>  	but return an ``EPIPE`` error code.
> +    * .. _`V4L2-BUF-FLAG-REQUEST-FD`:
> +
> +      - ``V4L2_BUF_FLAG_REQUEST_FD``
> +      - 0x00800000
> +      - The ``request_fd`` field contains a valid file descriptor.
>      * .. _`V4L2-BUF-FLAG-TIMESTAMP-MASK`:
>  
>        - ``V4L2_BUF_FLAG_TIMESTAMP_MASK``
> diff --git a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst
> index 2011c2b2ee67..771fd1161277 100644
> --- a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst
> +++ b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst
> @@ -95,6 +95,26 @@ appropriate. In the first case the new value is set in struct
>  is inappropriate (e.g. the given menu index is not supported by the menu
>  control), then this will also result in an ``EINVAL`` error code error.
>  
> +If ``request_fd`` is set to a not-yet-queued :ref:`request <media-request-api>`
> +file descriptor and ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL``,
> +then the controls are not applied immediately when calling
> +:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`, but instead are applied by
> +the driver for the buffer associated with the same request.
> +If the device does not support requests, then ``EPERM`` will be returned.
> +If requests are supported but an invalid request FD is given, then
> +``ENOENT`` will be returned.
> +
> +An attempt to call :ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` for a
> +request that has already been queued will result in an ``EBUSY`` error.
> +
> +If ``request_fd`` is specified and ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL``
> +during a call to :ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`, then the
> +returned values will be the values currently set for the request (or the
> +hardware value if none is set) if the request has not yet been queued, or the
> +values of the controls at the time of request completion if it has already
> +completed. Attempting to get controls while the request has been queued but
> +not yet completed will result in an ``EBUSY`` error.
> +
>  The driver will only set/get these controls if all control values are
>  correct. This prevents the situation where only some of the controls
>  were set/get. Only low-level errors (e. g. a failed i2c command) can
> @@ -209,13 +229,17 @@ still cause this situation.
>        - ``which``
>        - Which value of the control to get/set/try.
>  	``V4L2_CTRL_WHICH_CUR_VAL`` will return the current value of the
> -	control and ``V4L2_CTRL_WHICH_DEF_VAL`` will return the default
> -	value of the control.
> +	control, ``V4L2_CTRL_WHICH_DEF_VAL`` will return the default
> +	value of the control and ``V4L2_CTRL_WHICH_REQUEST_VAL`` indicates that
> +	these controls have to be retrieved from a request or tried/set for
> +	a request. In the latter case the ``request_fd`` field contains the
> +	file descriptor of the request that should be used. If the device
> +	does not support requests, then ``EPERM`` will be returned.
>  
>  	.. note::
>  
> -	   You can only get the default value of the control,
> -	   you cannot set or try it.
> +	   When using ``V4L2_CTRL_WHICH_DEF_VAL`` note that You can only
> +	   get the default value of the control, you cannot set or try it.
>  
>  	For backwards compatibility you can also use a control class here
>  	(see :ref:`ctrl-class`). In that case all controls have to
> @@ -272,8 +296,15 @@ still cause this situation.
>  	then you can call :ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` to try to discover the
>  	actual control that failed the validation step. Unfortunately,
>  	there is no ``TRY`` equivalent for :ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`.
> +    * - __s32
> +      - ``request_fd``
> +      - File descriptor of the request to be used by this operation. Only
> +	valid if ``which`` is set to ``V4L2_CTRL_WHICH_REQUEST_VAL``.
> +	If the device does not support requests, then ``EPERM`` will be returned.
> +	If requests are supported but an invalid request FD is given, then
> +	``ENOENT`` will be returned.
>      * - __u32
> -      - ``reserved``\ [2]
> +      - ``reserved``\ [1]
>        - Reserved for future extensions.
>  
>  	Drivers and applications must set the array to zero.
> @@ -362,7 +393,9 @@ ERANGE
>  EBUSY
>      The control is temporarily not changeable, possibly because another
>      applications took over control of the device function this control
> -    belongs to.
> +    belongs to, or (if the ``which`` field was set to
> +    ``V4L2_CTRL_WHICH_REQUEST_VAL``) the request was queued but not yet
> +    completed.
>  
>  ENOSPC
>      The space reserved for the control's payload is insufficient. The
> @@ -372,3 +405,11 @@ ENOSPC
>  EACCES
>      Attempt to try or set a read-only control or to get a write-only
>      control.
> +
> +EPERM
> +    The ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` but the
> +    device does not support requests.
> +
> +ENOENT
> +    The ``which`` field was set to ``V4L2_CTRL_WHICH_REQUEST_VAL`` but the
> +    the given ``request_fd`` was invalid.
> diff --git a/Documentation/media/uapi/v4l/vidioc-qbuf.rst b/Documentation/media/uapi/v4l/vidioc-qbuf.rst
> index 9e448a4aa3aa..0e415f2551b2 100644
> --- a/Documentation/media/uapi/v4l/vidioc-qbuf.rst
> +++ b/Documentation/media/uapi/v4l/vidioc-qbuf.rst
> @@ -65,7 +65,7 @@ To enqueue a :ref:`memory mapped <mmap>` buffer applications set the
>  with a pointer to this structure the driver sets the
>  ``V4L2_BUF_FLAG_MAPPED`` and ``V4L2_BUF_FLAG_QUEUED`` flags and clears
>  the ``V4L2_BUF_FLAG_DONE`` flag in the ``flags`` field, or it returns an
> -EINVAL error code.
> +``EINVAL`` error code.
>  
>  To enqueue a :ref:`user pointer <userp>` buffer applications set the
>  ``memory`` field to ``V4L2_MEMORY_USERPTR``, the ``m.userptr`` field to
> @@ -98,6 +98,25 @@ dequeued, until the :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` or
>  :ref:`VIDIOC_REQBUFS` ioctl is called, or until the
>  device is closed.
>  
> +The ``request_fd`` field can be used with the ``VIDIOC_QBUF`` ioctl to specify
> +the file descriptor of a :ref:`request <media-request-api>`, if requests are
> +in use. Setting it means that the buffer will not be passed to the driver
> +until the request itself is queued. Also, the driver will apply any
> +settings associated with the request for this buffer. This field will
> +be ignored unless the ``V4L2_BUF_FLAG_REQUEST_FD`` flag is set.
> +If the device does not support requests, then ``EPERM`` will be returned.
> +If requests are supported but an invalid request FD is given, then
> +``ENOENT`` will be returned.
> +
> +.. caution::
> +   It is not allowed to mix queuing requests with queuing buffers directly.
> +   ``EPERM`` will be returned if the first buffer was queued directly and
> +   then the application tries to queue a request, or vice versa.
> +
> +   For :ref:`memory-to-memory devices <codec>` you can specify the
> +   ``request_fd`` only for output buffers, not for capture buffers. Attempting
> +   to specify this for a capture buffer will result in an ``EPERM`` error.
> +
>  Applications call the ``VIDIOC_DQBUF`` ioctl to dequeue a filled
>  (capturing) or displayed (output) buffer from the driver's outgoing
>  queue. They just set the ``type``, ``memory`` and ``reserved`` fields of
> @@ -153,3 +172,14 @@ EPIPE
>      ``VIDIOC_DQBUF`` returns this on an empty capture queue for mem2mem
>      codecs if a buffer with the ``V4L2_BUF_FLAG_LAST`` was already
>      dequeued and no new buffers are expected to become available.
> +
> +EPERM
> +    The ``V4L2_BUF_FLAG_REQUEST_FD`` flag was set but the device does not
> +    support requests. Or the first buffer was queued via a request, but
> +    the application now tries to queue it directly, or vice versa (it is
> +    not permitted to mix the two APIs). Or an attempt is made to queue a
> +    CAPTURE buffer to a request for a :ref:`memory-to-memory device <codec>`.
> +
> +ENOENT
> +    The ``V4L2_BUF_FLAG_REQUEST_FD`` flag was set but the the given
> +    ``request_fd`` was invalid.
> diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions
> index ca9f0edc579e..99256a2c003e 100644
> --- a/Documentation/media/videodev2.h.rst.exceptions
> +++ b/Documentation/media/videodev2.h.rst.exceptions
> @@ -514,6 +514,7 @@ ignore define V4L2_CTRL_DRIVER_PRIV
>  ignore define V4L2_CTRL_MAX_DIMS
>  ignore define V4L2_CTRL_WHICH_CUR_VAL
>  ignore define V4L2_CTRL_WHICH_DEF_VAL
> +ignore define V4L2_CTRL_WHICH_REQUEST_VAL
>  ignore define V4L2_OUT_CAP_CUSTOM_TIMINGS
>  ignore define V4L2_CID_MAX_CTRLS
>  



Thanks,
Mauro



[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