| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730 |
- .. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
- .. c:namespace:: V4L
- .. _encoder:
- *************************************************
- Memory-to-Memory Stateful Video Encoder Interface
- *************************************************
- A stateful video encoder takes raw video frames in display order and encodes
- them into a bytestream. It generates complete chunks of the bytestream, including
- all metadata, headers, etc. The resulting bytestream does not require any
- further post-processing by the client.
- Performing software stream processing, header generation etc. in the driver
- in order to support this interface is strongly discouraged. In case such
- operations are needed, use of the Stateless Video Encoder Interface (in
- development) is strongly advised.
- Conventions and Notations Used in This Document
- ===============================================
- 1. The general V4L2 API rules apply if not specified in this document
- otherwise.
- 2. The meaning of words "must", "may", "should", etc. is as per `RFC
- 2119 <https://tools.ietf.org/html/rfc2119>`_.
- 3. All steps not marked "optional" are required.
- 4. :c:func:`VIDIOC_G_EXT_CTRLS` and :c:func:`VIDIOC_S_EXT_CTRLS` may be used
- interchangeably with :c:func:`VIDIOC_G_CTRL` and :c:func:`VIDIOC_S_CTRL`,
- unless specified otherwise.
- 5. Single-planar API (see :ref:`planar-apis`) and applicable structures may be
- used interchangeably with multi-planar API, unless specified otherwise,
- depending on encoder capabilities and following the general V4L2 guidelines.
- 6. i = [a..b]: sequence of integers from a to b, inclusive, i.e. i =
- [0..2]: i = 0, 1, 2.
- 7. Given an ``OUTPUT`` buffer A, then A' represents a buffer on the ``CAPTURE``
- queue containing data that resulted from processing buffer A.
- Glossary
- ========
- Refer to :ref:`decoder-glossary`.
- State Machine
- =============
- .. kernel-render:: DOT
- :alt: DOT digraph of encoder state machine
- :caption: Encoder State Machine
- digraph encoder_state_machine {
- node [shape = doublecircle, label="Encoding"] Encoding;
- node [shape = circle, label="Initialization"] Initialization;
- node [shape = circle, label="Stopped"] Stopped;
- node [shape = circle, label="Drain"] Drain;
- node [shape = circle, label="Reset"] Reset;
- node [shape = point]; qi
- qi -> Initialization [ label = "open()" ];
- Initialization -> Encoding [ label = "Both queues streaming" ];
- Encoding -> Drain [ label = "V4L2_ENC_CMD_STOP" ];
- Encoding -> Reset [ label = "VIDIOC_STREAMOFF(CAPTURE)" ];
- Encoding -> Stopped [ label = "VIDIOC_STREAMOFF(OUTPUT)" ];
- Encoding -> Encoding;
- Drain -> Stopped [ label = "All CAPTURE\nbuffers dequeued\nor\nVIDIOC_STREAMOFF(OUTPUT)" ];
- Drain -> Reset [ label = "VIDIOC_STREAMOFF(CAPTURE)" ];
- Reset -> Encoding [ label = "VIDIOC_STREAMON(CAPTURE)" ];
- Reset -> Initialization [ label = "VIDIOC_REQBUFS(OUTPUT, 0)" ];
- Stopped -> Encoding [ label = "V4L2_ENC_CMD_START\nor\nVIDIOC_STREAMON(OUTPUT)" ];
- Stopped -> Reset [ label = "VIDIOC_STREAMOFF(CAPTURE)" ];
- }
- Querying Capabilities
- =====================
- 1. To enumerate the set of coded formats supported by the encoder, the
- client may call :c:func:`VIDIOC_ENUM_FMT` on ``CAPTURE``.
- * The full set of supported formats will be returned, regardless of the
- format set on ``OUTPUT``.
- 2. To enumerate the set of supported raw formats, the client may call
- :c:func:`VIDIOC_ENUM_FMT` on ``OUTPUT``.
- * Only the formats supported for the format currently active on ``CAPTURE``
- will be returned.
- * In order to enumerate raw formats supported by a given coded format,
- the client must first set that coded format on ``CAPTURE`` and then
- enumerate the formats on ``OUTPUT``.
- 3. The client may use :c:func:`VIDIOC_ENUM_FRAMESIZES` to detect supported
- resolutions for a given format, passing the desired pixel format in
- :c:type:`v4l2_frmsizeenum` ``pixel_format``.
- * Values returned by :c:func:`VIDIOC_ENUM_FRAMESIZES` for a coded pixel
- format will include all possible coded resolutions supported by the
- encoder for the given coded pixel format.
- * Values returned by :c:func:`VIDIOC_ENUM_FRAMESIZES` for a raw pixel format
- will include all possible frame buffer resolutions supported by the
- encoder for the given raw pixel format and coded format currently set on
- ``CAPTURE``.
- 4. The client may use :c:func:`VIDIOC_ENUM_FRAMEINTERVALS` to detect supported
- frame intervals for a given format and resolution, passing the desired pixel
- format in :c:type:`v4l2_frmivalenum` ``pixel_format`` and the resolution
- in :c:type:`v4l2_frmivalenum` ``width`` and :c:type:`v4l2_frmivalenum`
- ``height``.
- * Values returned by :c:func:`VIDIOC_ENUM_FRAMEINTERVALS` for a coded pixel
- format and coded resolution will include all possible frame intervals
- supported by the encoder for the given coded pixel format and resolution.
- * Values returned by :c:func:`VIDIOC_ENUM_FRAMEINTERVALS` for a raw pixel
- format and resolution will include all possible frame intervals supported
- by the encoder for the given raw pixel format and resolution and for the
- coded format, coded resolution and coded frame interval currently set on
- ``CAPTURE``.
- * Support for :c:func:`VIDIOC_ENUM_FRAMEINTERVALS` is optional. If it is
- not implemented, then there are no special restrictions other than the
- limits of the codec itself.
- 5. Supported profiles and levels for the coded format currently set on
- ``CAPTURE``, if applicable, may be queried using their respective controls
- via :c:func:`VIDIOC_QUERYCTRL`.
- 6. Any additional encoder capabilities may be discovered by querying
- their respective controls.
- Initialization
- ==============
- 1. Set the coded format on the ``CAPTURE`` queue via :c:func:`VIDIOC_S_FMT`.
- * **Required fields:**
- ``type``
- a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
- ``pixelformat``
- the coded format to be produced.
- ``sizeimage``
- desired size of ``CAPTURE`` buffers; the encoder may adjust it to
- match hardware requirements.
- ``width``, ``height``
- ignored (read-only).
- other fields
- follow standard semantics.
- * **Returned fields:**
- ``sizeimage``
- adjusted size of ``CAPTURE`` buffers.
- ``width``, ``height``
- the coded size selected by the encoder based on current state, e.g.
- ``OUTPUT`` format, selection rectangles, etc. (read-only).
- .. important::
- Changing the ``CAPTURE`` format may change the currently set ``OUTPUT``
- format. How the new ``OUTPUT`` format is determined is up to the encoder
- and the client must ensure it matches its needs afterwards.
- 2. **Optional.** Enumerate supported ``OUTPUT`` formats (raw formats for
- source) for the selected coded format via :c:func:`VIDIOC_ENUM_FMT`.
- * **Required fields:**
- ``type``
- a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
- other fields
- follow standard semantics.
- * **Returned fields:**
- ``pixelformat``
- raw format supported for the coded format currently selected on
- the ``CAPTURE`` queue.
- other fields
- follow standard semantics.
- 3. Set the raw source format on the ``OUTPUT`` queue via
- :c:func:`VIDIOC_S_FMT`.
- * **Required fields:**
- ``type``
- a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
- ``pixelformat``
- raw format of the source.
- ``width``, ``height``
- source resolution.
- other fields
- follow standard semantics.
- * **Returned fields:**
- ``width``, ``height``
- may be adjusted to match encoder minimums, maximums and alignment
- requirements, as required by the currently selected formats, as
- reported by :c:func:`VIDIOC_ENUM_FRAMESIZES`.
- other fields
- follow standard semantics.
- * Setting the ``OUTPUT`` format will reset the selection rectangles to their
- default values, based on the new resolution, as described in the next
- step.
- 4. Set the raw frame interval on the ``OUTPUT`` queue via
- :c:func:`VIDIOC_S_PARM`. This also sets the coded frame interval on the
- ``CAPTURE`` queue to the same value.
- * **Required fields:**
- ``type``
- a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
- ``parm.output``
- set all fields except ``parm.output.timeperframe`` to 0.
- ``parm.output.timeperframe``
- the desired frame interval; the encoder may adjust it to
- match hardware requirements.
- * **Returned fields:**
- ``parm.output.timeperframe``
- the adjusted frame interval.
- .. important::
- Changing the ``OUTPUT`` frame interval *also* sets the framerate that
- the encoder uses to encode the video. So setting the frame interval
- to 1/24 (or 24 frames per second) will produce a coded video stream
- that can be played back at that speed. The frame interval for the
- ``OUTPUT`` queue is just a hint, the application may provide raw
- frames at a different rate. It can be used by the driver to help
- schedule multiple encoders running in parallel.
- In the next step the ``CAPTURE`` frame interval can optionally be
- changed to a different value. This is useful for off-line encoding
- were the coded frame interval can be different from the rate at
- which raw frames are supplied.
- .. important::
- ``timeperframe`` deals with *frames*, not fields. So for interlaced
- formats this is the time per two fields, since a frame consists of
- a top and a bottom field.
- .. note::
- It is due to historical reasons that changing the ``OUTPUT`` frame
- interval also changes the coded frame interval on the ``CAPTURE``
- queue. Ideally these would be independent settings, but that would
- break the existing API.
- 5. **Optional** Set the coded frame interval on the ``CAPTURE`` queue via
- :c:func:`VIDIOC_S_PARM`. This is only necessary if the coded frame
- interval is different from the raw frame interval, which is typically
- the case for off-line encoding. Support for this feature is signalled
- by the :ref:`V4L2_FMT_FLAG_ENC_CAP_FRAME_INTERVAL <fmtdesc-flags>` format flag.
- * **Required fields:**
- ``type``
- a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
- ``parm.capture``
- set all fields except ``parm.capture.timeperframe`` to 0.
- ``parm.capture.timeperframe``
- the desired coded frame interval; the encoder may adjust it to
- match hardware requirements.
- * **Returned fields:**
- ``parm.capture.timeperframe``
- the adjusted frame interval.
- .. important::
- Changing the ``CAPTURE`` frame interval sets the framerate for the
- coded video. It does *not* set the rate at which buffers arrive on the
- ``CAPTURE`` queue, that depends on how fast the encoder is and how
- fast raw frames are queued on the ``OUTPUT`` queue.
- .. important::
- ``timeperframe`` deals with *frames*, not fields. So for interlaced
- formats this is the time per two fields, since a frame consists of
- a top and a bottom field.
- .. note::
- Not all drivers support this functionality, in that case just set
- the desired coded frame interval for the ``OUTPUT`` queue.
- However, drivers that can schedule multiple encoders based on the
- ``OUTPUT`` frame interval must support this optional feature.
- 6. **Optional.** Set the visible resolution for the stream metadata via
- :c:func:`VIDIOC_S_SELECTION` on the ``OUTPUT`` queue if it is desired
- to be different than the full OUTPUT resolution.
- * **Required fields:**
- ``type``
- a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
- ``target``
- set to ``V4L2_SEL_TGT_CROP``.
- ``r.left``, ``r.top``, ``r.width``, ``r.height``
- visible rectangle; this must fit within the `V4L2_SEL_TGT_CROP_BOUNDS`
- rectangle and may be subject to adjustment to match codec and
- hardware constraints.
- * **Returned fields:**
- ``r.left``, ``r.top``, ``r.width``, ``r.height``
- visible rectangle adjusted by the encoder.
- * The following selection targets are supported on ``OUTPUT``:
- ``V4L2_SEL_TGT_CROP_BOUNDS``
- equal to the full source frame, matching the active ``OUTPUT``
- format.
- ``V4L2_SEL_TGT_CROP_DEFAULT``
- equal to ``V4L2_SEL_TGT_CROP_BOUNDS``.
- ``V4L2_SEL_TGT_CROP``
- rectangle within the source buffer to be encoded into the
- ``CAPTURE`` stream; defaults to ``V4L2_SEL_TGT_CROP_DEFAULT``.
- .. note::
- A common use case for this selection target is encoding a source
- video with a resolution that is not a multiple of a macroblock,
- e.g. the common 1920x1080 resolution may require the source
- buffers to be aligned to 1920x1088 for codecs with 16x16 macroblock
- size. To avoid encoding the padding, the client needs to explicitly
- configure this selection target to 1920x1080.
- .. warning::
- The encoder may adjust the crop/compose rectangles to the nearest
- supported ones to meet codec and hardware requirements. The client needs
- to check the adjusted rectangle returned by :c:func:`VIDIOC_S_SELECTION`.
- 7. Allocate buffers for both ``OUTPUT`` and ``CAPTURE`` via
- :c:func:`VIDIOC_REQBUFS`. This may be performed in any order.
- * **Required fields:**
- ``count``
- requested number of buffers to allocate; greater than zero.
- ``type``
- a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT`` or
- ``CAPTURE``.
- other fields
- follow standard semantics.
- * **Returned fields:**
- ``count``
- actual number of buffers allocated.
- .. warning::
- The actual number of allocated buffers may differ from the ``count``
- given. The client must check the updated value of ``count`` after the
- call returns.
- .. note::
- To allocate more than the minimum number of OUTPUT buffers (for pipeline
- depth), the client may query the ``V4L2_CID_MIN_BUFFERS_FOR_OUTPUT``
- control to get the minimum number of buffers required, and pass the
- obtained value plus the number of additional buffers needed in the
- ``count`` field to :c:func:`VIDIOC_REQBUFS`.
- Alternatively, :c:func:`VIDIOC_CREATE_BUFS` can be used to have more
- control over buffer allocation.
- * **Required fields:**
- ``count``
- requested number of buffers to allocate; greater than zero.
- ``type``
- a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
- other fields
- follow standard semantics.
- * **Returned fields:**
- ``count``
- adjusted to the number of allocated buffers.
- 8. Begin streaming on both ``OUTPUT`` and ``CAPTURE`` queues via
- :c:func:`VIDIOC_STREAMON`. This may be performed in any order. The actual
- encoding process starts when both queues start streaming.
- .. note::
- If the client stops the ``CAPTURE`` queue during the encode process and then
- restarts it again, the encoder will begin generating a stream independent
- from the stream generated before the stop. The exact constraints depend
- on the coded format, but may include the following implications:
- * encoded frames produced after the restart must not reference any
- frames produced before the stop, e.g. no long term references for
- H.264/HEVC,
- * any headers that must be included in a standalone stream must be
- produced again, e.g. SPS and PPS for H.264/HEVC.
- Encoding
- ========
- This state is reached after the `Initialization` sequence finishes
- successfully. In this state, the client queues and dequeues buffers to both
- queues via :c:func:`VIDIOC_QBUF` and :c:func:`VIDIOC_DQBUF`, following the
- standard semantics.
- The content of encoded ``CAPTURE`` buffers depends on the active coded pixel
- format and may be affected by codec-specific extended controls, as stated
- in the documentation of each format.
- Both queues operate independently, following standard behavior of V4L2 buffer
- queues and memory-to-memory devices. In addition, the order of encoded frames
- dequeued from the ``CAPTURE`` queue may differ from the order of queuing raw
- frames to the ``OUTPUT`` queue, due to properties of the selected coded format,
- e.g. frame reordering.
- The client must not assume any direct relationship between ``CAPTURE`` and
- ``OUTPUT`` buffers and any specific timing of buffers becoming
- available to dequeue. Specifically:
- * a buffer queued to ``OUTPUT`` may result in more than one buffer produced on
- ``CAPTURE`` (for example, if returning an encoded frame allowed the encoder
- to return a frame that preceded it in display, but succeeded it in the decode
- order; however, there may be other reasons for this as well),
- * a buffer queued to ``OUTPUT`` may result in a buffer being produced on
- ``CAPTURE`` later into encode process, and/or after processing further
- ``OUTPUT`` buffers, or be returned out of order, e.g. if display
- reordering is used,
- * buffers may become available on the ``CAPTURE`` queue without additional
- buffers queued to ``OUTPUT`` (e.g. during drain or ``EOS``), because of the
- ``OUTPUT`` buffers queued in the past whose encoding results are only
- available at later time, due to specifics of the encoding process,
- * buffers queued to ``OUTPUT`` may not become available to dequeue instantly
- after being encoded into a corresponding ``CAPTURE`` buffer, e.g. if the
- encoder needs to use the frame as a reference for encoding further frames.
- .. note::
- To allow matching encoded ``CAPTURE`` buffers with ``OUTPUT`` buffers they
- originated from, the client can set the ``timestamp`` field of the
- :c:type:`v4l2_buffer` struct when queuing an ``OUTPUT`` buffer. The
- ``CAPTURE`` buffer(s), which resulted from encoding that ``OUTPUT`` buffer
- will have their ``timestamp`` field set to the same value when dequeued.
- In addition to the straightforward case of one ``OUTPUT`` buffer producing
- one ``CAPTURE`` buffer, the following cases are defined:
- * one ``OUTPUT`` buffer generates multiple ``CAPTURE`` buffers: the same
- ``OUTPUT`` timestamp will be copied to multiple ``CAPTURE`` buffers,
- * the encoding order differs from the presentation order (i.e. the
- ``CAPTURE`` buffers are out-of-order compared to the ``OUTPUT`` buffers):
- ``CAPTURE`` timestamps will not retain the order of ``OUTPUT`` timestamps.
- .. note::
- To let the client distinguish between frame types (keyframes, intermediate
- frames; the exact list of types depends on the coded format), the
- ``CAPTURE`` buffers will have corresponding flag bits set in their
- :c:type:`v4l2_buffer` struct when dequeued. See the documentation of
- :c:type:`v4l2_buffer` and each coded pixel format for exact list of flags
- and their meanings.
- Should an encoding error occur, it will be reported to the client with the level
- of details depending on the encoder capabilities. Specifically:
- * the ``CAPTURE`` buffer (if any) that contains the results of the failed encode
- operation will be returned with the ``V4L2_BUF_FLAG_ERROR`` flag set,
- * if the encoder is able to precisely report the ``OUTPUT`` buffer(s) that triggered
- the error, such buffer(s) will be returned with the ``V4L2_BUF_FLAG_ERROR`` flag
- set.
- .. note::
- If a ``CAPTURE`` buffer is too small then it is just returned with the
- ``V4L2_BUF_FLAG_ERROR`` flag set. More work is needed to detect that this
- error occurred because the buffer was too small, and to provide support to
- free existing buffers that were too small.
- In case of a fatal failure that does not allow the encoding to continue, any
- further operations on corresponding encoder file handle will return the -EIO
- error code. The client may close the file handle and open a new one, or
- alternatively reinitialize the instance by stopping streaming on both queues,
- releasing all buffers and performing the Initialization sequence again.
- Encoding Parameter Changes
- ==========================
- The client is allowed to use :c:func:`VIDIOC_S_CTRL` to change encoder
- parameters at any time. The availability of parameters is encoder-specific
- and the client must query the encoder to find the set of available controls.
- The ability to change each parameter during encoding is encoder-specific, as
- per the standard semantics of the V4L2 control interface. The client may
- attempt to set a control during encoding and if the operation fails with the
- -EBUSY error code, the ``CAPTURE`` queue needs to be stopped for the
- configuration change to be allowed. To do this, it may follow the `Drain`
- sequence to avoid losing the already queued/encoded frames.
- The timing of parameter updates is encoder-specific, as per the standard
- semantics of the V4L2 control interface. If the client needs to apply the
- parameters exactly at specific frame, using the Request API
- (:ref:`media-request-api`) should be considered, if supported by the encoder.
- Drain
- =====
- To ensure that all the queued ``OUTPUT`` buffers have been processed and the
- related ``CAPTURE`` buffers are given to the client, the client must follow the
- drain sequence described below. After the drain sequence ends, the client has
- received all encoded frames for all ``OUTPUT`` buffers queued before the
- sequence was started.
- 1. Begin the drain sequence by issuing :c:func:`VIDIOC_ENCODER_CMD`.
- * **Required fields:**
- ``cmd``
- set to ``V4L2_ENC_CMD_STOP``.
- ``flags``
- set to 0.
- ``pts``
- set to 0.
- .. warning::
- The sequence can be only initiated if both ``OUTPUT`` and ``CAPTURE``
- queues are streaming. For compatibility reasons, the call to
- :c:func:`VIDIOC_ENCODER_CMD` will not fail even if any of the queues is
- not streaming, but at the same time it will not initiate the `Drain`
- sequence and so the steps described below would not be applicable.
- 2. Any ``OUTPUT`` buffers queued by the client before the
- :c:func:`VIDIOC_ENCODER_CMD` was issued will be processed and encoded as
- normal. The client must continue to handle both queues independently,
- similarly to normal encode operation. This includes:
- * queuing and dequeuing ``CAPTURE`` buffers, until a buffer marked with the
- ``V4L2_BUF_FLAG_LAST`` flag is dequeued,
- .. warning::
- The last buffer may be empty (with :c:type:`v4l2_buffer`
- ``bytesused`` = 0) and in that case it must be ignored by the client,
- as it does not contain an encoded frame.
- .. note::
- Any attempt to dequeue more ``CAPTURE`` buffers beyond the buffer
- marked with ``V4L2_BUF_FLAG_LAST`` will result in a -EPIPE error from
- :c:func:`VIDIOC_DQBUF`.
- * dequeuing processed ``OUTPUT`` buffers, until all the buffers queued
- before the ``V4L2_ENC_CMD_STOP`` command are dequeued,
- * dequeuing the ``V4L2_EVENT_EOS`` event, if the client subscribes to it.
- .. note::
- For backwards compatibility, the encoder will signal a ``V4L2_EVENT_EOS``
- event when the last frame has been encoded and all frames are ready to be
- dequeued. It is deprecated behavior and the client must not rely on it.
- The ``V4L2_BUF_FLAG_LAST`` buffer flag should be used instead.
- 3. Once all ``OUTPUT`` buffers queued before the ``V4L2_ENC_CMD_STOP`` call are
- dequeued and the last ``CAPTURE`` buffer is dequeued, the encoder is stopped
- and it will accept, but not process any newly queued ``OUTPUT`` buffers
- until the client issues any of the following operations:
- * ``V4L2_ENC_CMD_START`` - the encoder will not be reset and will resume
- operation normally, with all the state from before the drain,
- * a pair of :c:func:`VIDIOC_STREAMOFF` and :c:func:`VIDIOC_STREAMON` on the
- ``CAPTURE`` queue - the encoder will be reset (see the `Reset` sequence)
- and then resume encoding,
- * a pair of :c:func:`VIDIOC_STREAMOFF` and :c:func:`VIDIOC_STREAMON` on the
- ``OUTPUT`` queue - the encoder will resume operation normally, however any
- source frames queued to the ``OUTPUT`` queue between ``V4L2_ENC_CMD_STOP``
- and :c:func:`VIDIOC_STREAMOFF` will be discarded.
- .. note::
- Once the drain sequence is initiated, the client needs to drive it to
- completion, as described by the steps above, unless it aborts the process by
- issuing :c:func:`VIDIOC_STREAMOFF` on any of the ``OUTPUT`` or ``CAPTURE``
- queues. The client is not allowed to issue ``V4L2_ENC_CMD_START`` or
- ``V4L2_ENC_CMD_STOP`` again while the drain sequence is in progress and they
- will fail with -EBUSY error code if attempted.
- For reference, handling of various corner cases is described below:
- * In case of no buffer in the ``OUTPUT`` queue at the time the
- ``V4L2_ENC_CMD_STOP`` command was issued, the drain sequence completes
- immediately and the encoder returns an empty ``CAPTURE`` buffer with the
- ``V4L2_BUF_FLAG_LAST`` flag set.
- * In case of no buffer in the ``CAPTURE`` queue at the time the drain
- sequence completes, the next time the client queues a ``CAPTURE`` buffer
- it is returned at once as an empty buffer with the ``V4L2_BUF_FLAG_LAST``
- flag set.
- * If :c:func:`VIDIOC_STREAMOFF` is called on the ``CAPTURE`` queue in the
- middle of the drain sequence, the drain sequence is canceled and all
- ``CAPTURE`` buffers are implicitly returned to the client.
- * If :c:func:`VIDIOC_STREAMOFF` is called on the ``OUTPUT`` queue in the
- middle of the drain sequence, the drain sequence completes immediately and
- next ``CAPTURE`` buffer will be returned empty with the
- ``V4L2_BUF_FLAG_LAST`` flag set.
- Although not mandatory, the availability of encoder commands may be queried
- using :c:func:`VIDIOC_TRY_ENCODER_CMD`.
- Reset
- =====
- The client may want to request the encoder to reinitialize the encoding, so
- that the following stream data becomes independent from the stream data
- generated before. Depending on the coded format, that may imply that:
- * encoded frames produced after the restart must not reference any frames
- produced before the stop, e.g. no long term references for H.264/HEVC,
- * any headers that must be included in a standalone stream must be produced
- again, e.g. SPS and PPS for H.264/HEVC.
- This can be achieved by performing the reset sequence.
- 1. Perform the `Drain` sequence to ensure all the in-flight encoding finishes
- and respective buffers are dequeued.
- 2. Stop streaming on the ``CAPTURE`` queue via :c:func:`VIDIOC_STREAMOFF`. This
- will return all currently queued ``CAPTURE`` buffers to the client, without
- valid frame data.
- 3. Start streaming on the ``CAPTURE`` queue via :c:func:`VIDIOC_STREAMON` and
- continue with regular encoding sequence. The encoded frames produced into
- ``CAPTURE`` buffers from now on will contain a standalone stream that can be
- decoded without the need for frames encoded before the reset sequence,
- starting at the first ``OUTPUT`` buffer queued after issuing the
- `V4L2_ENC_CMD_STOP` of the `Drain` sequence.
- This sequence may be also used to change encoding parameters for encoders
- without the ability to change the parameters on the fly.
- Commit Points
- =============
- Setting formats and allocating buffers triggers changes in the behavior of the
- encoder.
- 1. Setting the format on the ``CAPTURE`` queue may change the set of formats
- supported/advertised on the ``OUTPUT`` queue. In particular, it also means
- that the ``OUTPUT`` format may be reset and the client must not rely on the
- previously set format being preserved.
- 2. Enumerating formats on the ``OUTPUT`` queue always returns only formats
- supported for the current ``CAPTURE`` format.
- 3. Setting the format on the ``OUTPUT`` queue does not change the list of
- formats available on the ``CAPTURE`` queue. An attempt to set the ``OUTPUT``
- format that is not supported for the currently selected ``CAPTURE`` format
- will result in the encoder adjusting the requested ``OUTPUT`` format to a
- supported one.
- 4. Enumerating formats on the ``CAPTURE`` queue always returns the full set of
- supported coded formats, irrespective of the current ``OUTPUT`` format.
- 5. While buffers are allocated on any of the ``OUTPUT`` or ``CAPTURE`` queues,
- the client must not change the format on the ``CAPTURE`` queue. Drivers will
- return the -EBUSY error code for any such format change attempt.
- To summarize, setting formats and allocation must always start with the
- ``CAPTURE`` queue and the ``CAPTURE`` queue is the master that governs the
- set of supported formats for the ``OUTPUT`` queue.
|