From cbb6a7f52b148dea0fed434b629aedddf7804d14 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Mon, 21 May 2018 04:54:54 -0400 Subject: media: Documentation: v4l: document request API Document the request API for V4L2 devices, and amend the documentation of system calls influenced by it. Signed-off-by: Alexandre Courbot Signed-off-by: Hans Verkuil Reviewed-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- .../media/uapi/mediactl/media-controller.rst | 1 + Documentation/media/uapi/mediactl/media-funcs.rst | 6 + .../uapi/mediactl/media-ioc-request-alloc.rst | 65 ++++++ .../uapi/mediactl/media-request-ioc-queue.rst | 82 +++++++ .../uapi/mediactl/media-request-ioc-reinit.rst | 51 +++++ Documentation/media/uapi/mediactl/request-api.rst | 245 +++++++++++++++++++++ .../media/uapi/mediactl/request-func-close.rst | 48 ++++ .../media/uapi/mediactl/request-func-ioctl.rst | 67 ++++++ .../media/uapi/mediactl/request-func-poll.rst | 77 +++++++ 9 files changed, 642 insertions(+) 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 (limited to 'Documentation/media/uapi/mediactl') 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() `. + +``argp`` + Pointer to an integer. + + +Description +=========== + +If the media device supports :ref:`requests `, 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 `, +:ref:`VIDIOC_G_EXT_CTRLS `, +:ref:`VIDIOC_S_EXT_CTRLS ` and +:ref:`VIDIOC_TRY_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 ` 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() ` 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 ` 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 `, 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 ` 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 ` 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 `, 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() ` 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 ` 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 ` is called or the device is + :ref:`closed `. 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() ` 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 ` with the request file +descriptor. Calling :ref:`ioctl 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() ` 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 `, 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 `: + +.. 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 `. +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 + + +.. 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() ` 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 + + +.. 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() ` 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 ` 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 + + +.. 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() ` function applications can wait +for a request to complete. + +On success :c: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() ` 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. -- cgit v1.2.1 From b4ae675d3f4f31b7810b58895e643177be8fc010 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 4 Aug 2018 05:48:36 -0400 Subject: media: mediactl/*.rst: document argp The documentation of the Media Controller API ioctls is missing a description of the argp ioctl argument. Add this. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/mediactl/media-ioc-device-info.rst | 1 + Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst | 1 + Documentation/media/uapi/mediactl/media-ioc-enum-links.rst | 1 + Documentation/media/uapi/mediactl/media-ioc-g-topology.rst | 1 + Documentation/media/uapi/mediactl/media-ioc-setup-link.rst | 1 + 5 files changed, 5 insertions(+) (limited to 'Documentation/media/uapi/mediactl') diff --git a/Documentation/media/uapi/mediactl/media-ioc-device-info.rst b/Documentation/media/uapi/mediactl/media-ioc-device-info.rst index 649cb3d9e058..c6f224e404b7 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-device-info.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-device-info.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`media_device_info`. Description diff --git a/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst b/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst index fc2e39c070c9..02738640e34e 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`media_entity_desc`. Description diff --git a/Documentation/media/uapi/mediactl/media-ioc-enum-links.rst b/Documentation/media/uapi/mediactl/media-ioc-enum-links.rst index f158c134e9b0..b89aaae373df 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-enum-links.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-enum-links.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`media_links_enum`. Description diff --git a/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst b/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst index bac128c7eda9..4e1c59238371 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`media_v2_topology`. Description diff --git a/Documentation/media/uapi/mediactl/media-ioc-setup-link.rst b/Documentation/media/uapi/mediactl/media-ioc-setup-link.rst index ae5194940100..e345e7dc9ad7 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-setup-link.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-setup-link.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`media_link_desc`. Description -- cgit v1.2.1 From 15cd442e79e2a60a725ee5501e4ffb537698c802 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 1 Sep 2018 07:29:14 -0400 Subject: media: media-request: EPERM -> EACCES/EBUSY If requests are not supported by the driver, then return EACCES, not EPERM. If you attempt to mix queueing buffers directly and using requests, then EBUSY is returned instead of EPERM: once a specific queueing mode has been chosen the queue is 'busy' if you attempt the other mode (i.e. direct queueing vs via a request). Signed-off-by: Hans Verkuil Reviewed-by: Tomasz Figa Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/mediactl/media-request-ioc-queue.rst | 9 ++++----- Documentation/media/uapi/mediactl/request-api.rst | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'Documentation/media/uapi/mediactl') diff --git a/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst b/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst index d4f8119e0643..dbf635ae9b2b 100644 --- a/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst +++ b/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst @@ -49,7 +49,7 @@ 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 +(without a request). ``EBUSY`` 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 @@ -63,10 +63,9 @@ appropriately. The generic error codes are described at the :ref:`Generic Error Codes ` 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. + The request was already queued or 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 diff --git a/Documentation/media/uapi/mediactl/request-api.rst b/Documentation/media/uapi/mediactl/request-api.rst index 0b9da58b01e3..aeb8d00934a4 100644 --- a/Documentation/media/uapi/mediactl/request-api.rst +++ b/Documentation/media/uapi/mediactl/request-api.rst @@ -64,7 +64,7 @@ request cannot be modified anymore. .. caution:: For :ref:`memory-to-memory devices ` 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. + to a request will result in an ``EACCES`` error. If the request contains parameters for multiple entities, individual drivers may synchronize so the requested pipeline's topology is applied before the buffers @@ -77,7 +77,7 @@ perfect atomicity may not be possible due to hardware limitations. whichever method is used first locks this in place until :ref:`VIDIOC_STREAMOFF ` is called or the device is :ref:`closed `. Attempts to directly queue a buffer when earlier - a buffer was queued via a request or vice versa will result in an ``EPERM`` + a buffer was queued via a request or vice versa will result in an ``EBUSY`` error. Controls can still be set without a request and are applied immediately, -- cgit v1.2.1 From d4215edbd4b170b207b0e5a1d8ae42fb49f5c470 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 28 Aug 2018 05:11:04 -0400 Subject: media: media-request: update documentation Various clarifications and readability improvements based on Laurent Pinchart's review of the documentation. Signed-off-by: Hans Verkuil Reviewed-by: Tomasz Figa Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../uapi/mediactl/media-ioc-request-alloc.rst | 3 +- .../uapi/mediactl/media-request-ioc-queue.rst | 7 +-- Documentation/media/uapi/mediactl/request-api.rst | 51 ++++++++++++---------- .../media/uapi/mediactl/request-func-close.rst | 1 + .../media/uapi/mediactl/request-func-poll.rst | 2 +- 5 files changed, 35 insertions(+), 29 deletions(-) (limited to 'Documentation/media/uapi/mediactl') diff --git a/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst b/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst index 34434e2b3918..0f8b31874002 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-request-alloc.rst @@ -52,7 +52,8 @@ for the request to complete. The request will remain allocated until all the file descriptors associated with it are closed by :ref:`close() ` and the driver no -longer uses the request internally. +longer uses the request internally. See also +:ref:`here ` for more information. Return Value ============ diff --git a/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst b/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst index dbf635ae9b2b..6dd2d7fea714 100644 --- a/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst +++ b/Documentation/media/uapi/mediactl/media-request-ioc-queue.rst @@ -40,9 +40,6 @@ 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 @@ -68,8 +65,8 @@ EBUSY 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. + to have at least one buffer. This can also be returned if some required + configuration is missing in the request. ENOMEM Out of memory when allocating internal data structures for this request. diff --git a/Documentation/media/uapi/mediactl/request-api.rst b/Documentation/media/uapi/mediactl/request-api.rst index aeb8d00934a4..5f4a23029c48 100644 --- a/Documentation/media/uapi/mediactl/request-api.rst +++ b/Documentation/media/uapi/mediactl/request-api.rst @@ -12,6 +12,9 @@ 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. +While the initial use-case was V4L2, it can be extended to other subsystems +as well, as long as they use the media controller. + 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 @@ -20,19 +23,23 @@ 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. +controller topology + configuration for each media entity) to be associated with +specific buffers. This allows user-space to schedule several tasks ("requests") +with different configurations in advance, knowing that the configuration will be +applied when needed to get the expected result. Configuration 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. +The Request API extends the Media Controller API and cooperates with +subsystem-specific APIs to support request usage. At the Media Controller +level, requests are allocated from the supporting Media Controller device +node. Their life cycle is then managed through the request file descriptors in +an opaque way. Configuration data, buffer handles and processing results +stored in requests are accessed through subsystem-specific APIs extended for +request support, such as V4L2 APIs that take an explicit ``request_fd`` +parameter. Request Allocation ------------------ @@ -47,29 +54,27 @@ 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. +support this. Configurations 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 +Once the configuration 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. +A queued request cannot be modified anymore. .. caution:: For :ref:`memory-to-memory devices ` 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 ``EACCES`` 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. +If the request contains configurations 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:: @@ -96,14 +101,16 @@ 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 +A completed request contains the state of the device after the request was +executed. User-space can query that state by calling :ref:`ioctl VIDIOC_G_EXT_CTRLS ` with the request file descriptor. Calling :ref:`ioctl 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. +.. _media-request-life-time: + Recycling and Destruction ------------------------- diff --git a/Documentation/media/uapi/mediactl/request-func-close.rst b/Documentation/media/uapi/mediactl/request-func-close.rst index b5c78683840b..098d7f2b9548 100644 --- a/Documentation/media/uapi/mediactl/request-func-close.rst +++ b/Documentation/media/uapi/mediactl/request-func-close.rst @@ -36,6 +36,7 @@ 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. +See :ref:`here ` for more information. Return Value diff --git a/Documentation/media/uapi/mediactl/request-func-poll.rst b/Documentation/media/uapi/mediactl/request-func-poll.rst index 70cc9d406a9f..85191254f381 100644 --- a/Documentation/media/uapi/mediactl/request-func-poll.rst +++ b/Documentation/media/uapi/mediactl/request-func-poll.rst @@ -50,7 +50,7 @@ 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 +Attempting to poll for a request that is not yet queued will set the ``POLLERR`` flag in ``revents``. -- cgit v1.2.1