← Documents Documentation/userspace-api/media/v4l/dev-stateless-decoder.rst GitHub 원문 ↗

Linux 6.18.37 · Userspace API / Media / V4L

Memory-to-memory Stateless Video Decoder 인터페이스

Stateless decoder의 request API, queue 초기화, frame/reference buffer 수명과 상태 전환 절차를 설명합니다.

Source pathDocumentation/userspace-api/media/v4l/dev-stateless-decoder.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

dev-stateless-decoder.rst:1-424

Stateless decoder에서는 client가 encoded unit, parsed header, reference state를 media request 하나에 묶습니다. OUTPUT buffer는 request에 연결하지만 CAPTURE buffer는 독립 queue이며, timestamp가 frame과 reference의 identity 역할을 합니다.

Client는 decoded reference buffer의 재사용 시점과 resolution change를 직접 관리합니다. Multi-request frame의 held CAPTURE는 FLUSH로 회수하고, 해상도 변경 때 CAPTURE layout만 해제·재구성합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 .. _stateless_decoder:
4
5 **************************************************
6 Memory-to-memory Stateless Video Decoder Interface
7 **************************************************
8
9 A stateless decoder is a decoder that works without retaining any kind of state
10 between processed frames. This means that each frame is decoded independently
11 of any previous and future frames, and that the client is responsible for
12 maintaining the decoding state and providing it to the decoder with each
13 decoding request. This is in contrast to the stateful video decoder interface,
14 where the hardware and driver maintain the decoding state and all the client
15 has to do is to provide the raw encoded stream and dequeue decoded frames in
16 display order.
17
18 This section describes how user-space ("the client") is expected to communicate
19 with stateless decoders in order to successfully decode an encoded stream.
20 Compared to stateful codecs, the decoder/client sequence is simpler, but the
21 cost of this simplicity is extra complexity in the client which is responsible
22 for maintaining a consistent decoding state.
23
24 Stateless decoders make use of the :ref:`media-request-api`. A stateless
25 decoder must expose the ``V4L2_BUF_CAP_SUPPORTS_REQUESTS`` capability on its
26 ``OUTPUT`` queue when :c:func:`VIDIOC_REQBUFS` or :c:func:`VIDIOC_CREATE_BUFS`
27 are invoked.
28
29 Depending on the encoded formats supported by the decoder, a single decoded
30 frame may be the result of several decode requests (for instance, H.264 streams
31 with multiple slices per frame). Decoders that support such formats must also
32 expose the ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF`` capability on their
33 ``OUTPUT`` queue.
34
35 Querying capabilities
36 =====================
37
38 1. To enumerate the set of coded formats supported by the decoder, the client
39 calls :c:func:`VIDIOC_ENUM_FMT` on the ``OUTPUT`` queue.
40
41 * The driver must always return the full set of supported ``OUTPUT`` formats,
42 irrespective of the format currently set on the ``CAPTURE`` queue.
43
44 * Simultaneously, the driver must restrain the set of values returned by
45 codec-specific capability controls (such as H.264 profiles) to the set
46 actually supported by the hardware.
47
48 2. To enumerate the set of supported raw formats, the client calls
49 :c:func:`VIDIOC_ENUM_FMT` on the ``CAPTURE`` queue.
50
51 * The driver must return only the formats supported for the format currently
52 active on the ``OUTPUT`` queue.
53
54 * Depending on the currently set ``OUTPUT`` format, the set of supported raw
55 formats may depend on the value of some codec-dependent controls.
56 The client is responsible for making sure that these controls are set
57 before querying the ``CAPTURE`` queue. Failure to do so will result in the
58 default values for these controls being used, and a returned set of formats
59 that may not be usable for the media the client is trying to decode.
60
61 3. The client may use :c:func:`VIDIOC_ENUM_FRAMESIZES` to detect supported
62 resolutions for a given format, passing desired pixel format in
63 :c:type:`v4l2_frmsizeenum`'s ``pixel_format``.
64
65 4. Supported profiles and levels for the current ``OUTPUT`` format, if
66 applicable, may be queried using their respective controls via
67 :c:func:`VIDIOC_QUERYCTRL`.
68
69 Initialization
70 ==============
71
72 1. Set the coded format on the ``OUTPUT`` queue via :c:func:`VIDIOC_S_FMT`.
73
74 * **Required fields:**
75
76 ``type``
77 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
78
79 ``pixelformat``
80 a coded pixel format.
81
82 ``width``, ``height``
83 coded width and height parsed from the stream.
84
85 other fields
86 follow standard semantics.
87
88 .. note::
89
90 Changing the ``OUTPUT`` format may change the currently set ``CAPTURE``
91 format. The driver will derive a new ``CAPTURE`` format from the
92 ``OUTPUT`` format being set, including resolution, colorimetry
93 parameters, etc. If the client needs a specific ``CAPTURE`` format,
94 it must adjust it afterwards.
95
96 2. Call :c:func:`VIDIOC_S_EXT_CTRLS` to set all the controls (parsed headers,
97 etc.) required by the ``OUTPUT`` format to enumerate the ``CAPTURE`` formats.
98
99 3. Call :c:func:`VIDIOC_G_FMT` for ``CAPTURE`` queue to get the format for the
100 destination buffers parsed/decoded from the bytestream.
101
102 * **Required fields:**
103
104 ``type``
105 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
106
107 * **Returned fields:**
108
109 ``width``, ``height``
110 frame buffer resolution for the decoded frames.
111
112 ``pixelformat``
113 pixel format for decoded frames.
114
115 ``num_planes`` (for _MPLANE ``type`` only)
116 number of planes for pixelformat.
117
118 ``sizeimage``, ``bytesperline``
119 as per standard semantics; matching frame buffer format.
120
121 .. note::
122
123 The value of ``pixelformat`` may be any pixel format supported for the
124 ``OUTPUT`` format, based on the hardware capabilities. It is suggested
125 that the driver chooses the preferred/optimal format for the current
126 configuration. For example, a YUV format may be preferred over an RGB
127 format, if an additional conversion step would be required for RGB.
128
129 4. *[optional]* Enumerate ``CAPTURE`` formats via :c:func:`VIDIOC_ENUM_FMT` on
130 the ``CAPTURE`` queue. The client may use this ioctl to discover which
131 alternative raw formats are supported for the current ``OUTPUT`` format and
132 select one of them via :c:func:`VIDIOC_S_FMT`.
133
134 .. note::
135
136 The driver will return only formats supported for the currently selected
137 ``OUTPUT`` format and currently set controls, even if more formats may be
138 supported by the decoder in general.
139
140 For example, a decoder may support YUV and RGB formats for
141 resolutions 1920x1088 and lower, but only YUV for higher resolutions (due
142 to hardware limitations). After setting a resolution of 1920x1088 or lower
143 as the ``OUTPUT`` format, :c:func:`VIDIOC_ENUM_FMT` may return a set of
144 YUV and RGB pixel formats, but after setting a resolution higher than
145 1920x1088, the driver will not return RGB pixel formats, since they are
146 unsupported for this resolution.
147
148 5. *[optional]* Choose a different ``CAPTURE`` format than suggested via
149 :c:func:`VIDIOC_S_FMT` on ``CAPTURE`` queue. It is possible for the client to
150 choose a different format than selected/suggested by the driver in
151 :c:func:`VIDIOC_G_FMT`.
152
153 * **Required fields:**
154
155 ``type``
156 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
157
158 ``pixelformat``
159 a raw pixel format.
160
161 ``width``, ``height``
162 frame buffer resolution of the decoded stream; typically unchanged from
163 what was returned with :c:func:`VIDIOC_G_FMT`, but it may be different
164 if the hardware supports composition and/or scaling.
165
166 After performing this step, the client must perform step 3 again in order
167 to obtain up-to-date information about the buffers size and layout.
168
169 6. Allocate source (bytestream) buffers via :c:func:`VIDIOC_REQBUFS` on
170 ``OUTPUT`` queue.
171
172 * **Required fields:**
173
174 ``count``
175 requested number of buffers to allocate; greater than zero.
176
177 ``type``
178 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
179
180 ``memory``
181 follows standard semantics.
182
183 * **Returned fields:**
184
185 ``count``
186 actual number of buffers allocated.
187
188 * If required, the driver will adjust ``count`` to be equal or bigger to the
189 minimum of required number of ``OUTPUT`` buffers for the given format and
190 requested count. The client must check this value after the ioctl returns
191 to get the actual number of buffers allocated.
192
193 7. Allocate destination (raw format) buffers via :c:func:`VIDIOC_REQBUFS` on the
194 ``CAPTURE`` queue.
195
196 * **Required fields:**
197
198 ``count``
199 requested number of buffers to allocate; greater than zero. The client
200 is responsible for deducing the minimum number of buffers required
201 for the stream to be properly decoded (taking e.g. reference frames
202 into account) and pass an equal or bigger number.
203
204 ``type``
205 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
206
207 ``memory``
208 follows standard semantics. ``V4L2_MEMORY_USERPTR`` is not supported
209 for ``CAPTURE`` buffers.
210
211 * **Returned fields:**
212
213 ``count``
214 adjusted to allocated number of buffers, in case the codec requires
215 more buffers than requested.
216
217 * The driver must adjust count to the minimum of required number of
218 ``CAPTURE`` buffers for the current format, stream configuration and
219 requested count. The client must check this value after the ioctl
220 returns to get the number of buffers allocated.
221
222 8. Allocate requests (likely one per ``OUTPUT`` buffer) via
223 :c:func:`MEDIA_IOC_REQUEST_ALLOC` on the media device.
224
225 9. Start streaming on both ``OUTPUT`` and ``CAPTURE`` queues via
226 :c:func:`VIDIOC_STREAMON`.
227
228 Decoding
229 ========
230
231 For each frame, the client is responsible for submitting at least one request to
232 which the following is attached:
233
234 * The amount of encoded data expected by the codec for its current
235 configuration, as a buffer submitted to the ``OUTPUT`` queue. Typically, this
236 corresponds to one frame worth of encoded data, but some formats may allow (or
237 require) different amounts per unit.
238 * All the metadata needed to decode the submitted encoded data, in the form of
239 controls relevant to the format being decoded.
240
241 The amount of data and contents of the source ``OUTPUT`` buffer, as well as the
242 controls that must be set on the request, depend on the active coded pixel
243 format and might be affected by codec-specific extended controls, as stated in
244 documentation of each format.
245
246 If there is a possibility that the decoded frame will require one or more
247 decode requests after the current one in order to be produced, then the client
248 must set the ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag on the ``OUTPUT``
249 buffer. This will result in the (potentially partially) decoded ``CAPTURE``
250 buffer not being made available for dequeueing, and reused for the next decode
251 request if the timestamp of the next ``OUTPUT`` buffer has not changed.
252
253 A typical frame would thus be decoded using the following sequence:
254
255 1. Queue an ``OUTPUT`` buffer containing one unit of encoded bytestream data for
256 the decoding request, using :c:func:`VIDIOC_QBUF`.
257
258 * **Required fields:**
259
260 ``index``
261 index of the buffer being queued.
262
263 ``type``
264 type of the buffer.
265
266 ``bytesused``
267 number of bytes taken by the encoded data frame in the buffer.
268
269 ``flags``
270 the ``V4L2_BUF_FLAG_REQUEST_FD`` flag must be set. Additionally, if
271 we are not sure that the current decode request is the last one needed
272 to produce a fully decoded frame, then
273 ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` must also be set.
274
275 ``request_fd``
276 must be set to the file descriptor of the decoding request.
277
278 ``timestamp``
279 must be set to a unique value per frame. This value will be propagated
280 into the decoded frame's buffer and can also be used to use this frame
281 as the reference of another. If using multiple decode requests per
282 frame, then the timestamps of all the ``OUTPUT`` buffers for a given
283 frame must be identical. If the timestamp changes, then the currently
284 held ``CAPTURE`` buffer will be made available for dequeuing and the
285 current request will work on a new ``CAPTURE`` buffer.
286
287 2. Set the codec-specific controls for the decoding request, using
288 :c:func:`VIDIOC_S_EXT_CTRLS`.
289
290 * **Required fields:**
291
292 ``which``
293 must be ``V4L2_CTRL_WHICH_REQUEST_VAL``.
294
295 ``request_fd``
296 must be set to the file descriptor of the decoding request.
297
298 other fields
299 other fields are set as usual when setting controls. The ``controls``
300 array must contain all the codec-specific controls required to decode
301 a frame.
302
303 .. note::
304
305 It is possible to specify the controls in different invocations of
306 :c:func:`VIDIOC_S_EXT_CTRLS`, or to overwrite a previously set control, as
307 long as ``request_fd`` and ``which`` are properly set. The controls state
308 at the moment of request submission is the one that will be considered.
309
310 .. note::
311
312 The order in which steps 1 and 2 take place is interchangeable.
313
314 3. Submit the request by invoking :c:func:`MEDIA_REQUEST_IOC_QUEUE` on the
315 request FD.
316
317 If the request is submitted without an ``OUTPUT`` buffer, or if some of the
318 required controls are missing from the request, then
319 :c:func:`MEDIA_REQUEST_IOC_QUEUE` will return ``-ENOENT``. If more than one
320 ``OUTPUT`` buffer is queued, then it will return ``-EINVAL``.
321 :c:func:`MEDIA_REQUEST_IOC_QUEUE` returning non-zero means that no
322 ``CAPTURE`` buffer will be produced for this request.
323
324 ``CAPTURE`` buffers must not be part of the request, and are queued
325 independently. They are returned in decode order (i.e. the same order as coded
326 frames were submitted to the ``OUTPUT`` queue).
327
328 Runtime decoding errors are signaled by the dequeued ``CAPTURE`` buffers
329 carrying the ``V4L2_BUF_FLAG_ERROR`` flag. If a decoded reference frame has an
330 error, then all following decoded frames that refer to it also have the
331 ``V4L2_BUF_FLAG_ERROR`` flag set, although the decoder will still try to
332 produce (likely corrupted) frames.
333
334 Buffer management while decoding
335 ================================
336 Contrary to stateful decoders, a stateless decoder does not perform any kind of
337 buffer management: it only guarantees that dequeued ``CAPTURE`` buffers can be
338 used by the client for as long as they are not queued again. "Used" here
339 encompasses using the buffer for compositing or display.
340
341 A dequeued capture buffer can also be used as the reference frame of another
342 buffer.
343
344 A frame is specified as reference by converting its timestamp into nanoseconds,
345 and storing it into the relevant member of a codec-dependent control structure.
346 The :c:func:`v4l2_timeval_to_ns` function must be used to perform that
347 conversion. The timestamp of a frame can be used to reference it as soon as all
348 its units of encoded data are successfully submitted to the ``OUTPUT`` queue.
349
350 A decoded buffer containing a reference frame must not be reused as a decoding
351 target until all the frames referencing it have been decoded. The safest way to
352 achieve this is to refrain from queueing a reference buffer until all the
353 decoded frames referencing it have been dequeued. However, if the driver can
354 guarantee that buffers queued to the ``CAPTURE`` queue are processed in queued
355 order, then user-space can take advantage of this guarantee and queue a
356 reference buffer when the following conditions are met:
357
358 1. All the requests for frames affected by the reference frame have been
359 queued, and
360
361 2. A sufficient number of ``CAPTURE`` buffers to cover all the decoded
362 referencing frames have been queued.
363
364 When queuing a decoding request, the driver will increase the reference count of
365 all the resources associated with reference frames. This means that the client
366 can e.g. close the DMABUF file descriptors of reference frame buffers if it
367 won't need them afterwards.
368
369 Seeking
370 =======
371 In order to seek, the client just needs to submit requests using input buffers
372 corresponding to the new stream position. It must however be aware that
373 resolution may have changed and follow the dynamic resolution change sequence in
374 that case. Also depending on the codec used, picture parameters (e.g. SPS/PPS
375 for H.264) may have changed and the client is responsible for making sure that a
376 valid state is sent to the decoder.
377
378 The client is then free to ignore any returned ``CAPTURE`` buffer that comes
379 from the pre-seek position.
380
381 Pausing
382 =======
383
384 In order to pause, the client can just cease queuing buffers onto the ``OUTPUT``
385 queue. Without source bytestream data, there is no data to process and the codec
386 will remain idle.
387
388 Dynamic resolution change
389 =========================
390
391 If the client detects a resolution change in the stream, it will need to perform
392 the initialization sequence again with the new resolution:
393
394 1. If the last submitted request resulted in a ``CAPTURE`` buffer being
395 held by the use of the ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag, then the
396 last frame is not available on the ``CAPTURE`` queue. In this case, a
397 ``V4L2_DEC_CMD_FLUSH`` command shall be sent. This will make the driver
398 dequeue the held ``CAPTURE`` buffer.
399
400 2. Wait until all submitted requests have completed and dequeue the
401 corresponding output buffers.
402
403 3. Call :c:func:`VIDIOC_STREAMOFF` on both the ``OUTPUT`` and ``CAPTURE``
404 queues.
405
406 4. Free all ``CAPTURE`` buffers by calling :c:func:`VIDIOC_REQBUFS` on the
407 ``CAPTURE`` queue with a buffer count of zero.
408
409 5. Perform the initialization sequence again (minus the allocation of
410 ``OUTPUT`` buffers), with the new resolution set on the ``OUTPUT`` queue.
411 Note that due to resolution constraints, a different format may need to be
412 picked on the ``CAPTURE`` queue.
413
414 Drain
415 =====
416
417 If the last submitted request resulted in a ``CAPTURE`` buffer being
418 held by the use of the ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag, then the
419 last frame is not available on the ``CAPTURE`` queue. In this case, a
420 ``V4L2_DEC_CMD_FLUSH`` command shall be sent. This will make the driver
421 dequeue the held ``CAPTURE`` buffer.
422
423 After that, in order to drain the stream on a stateless decoder, the client
424 just needs to wait until all the submitted requests are completed.
425

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Stateless decoder와 request API

1-34

Stateless decoder는 처리한 frame 사이에 decoding state를 보관하지 않습니다. 각 frame을 이전·이후 frame과 독립적으로 decode하며, client가 decoding state를 유지하고 매 decode request에 필요한 상태를 모두 제공해야 합니다.

Stateful decoder에서는 hardware와 driver가 state를 유지하므로 client는 encoded stream을 넣고 display order로 decoded frame을 꺼내면 됩니다. Stateless 방식은 decoder/client 순서가 단순한 대신 일관된 state 유지와 reference 관리 복잡성이 user space로 이동합니다.

Stateless decoder는 media request API를 사용합니다. `VIDIOC_REQBUFS` 또는 `VIDIOC_CREATE_BUFS`로 `OUTPUT` queue를 조회할 때 `V4L2_BUF_CAP_SUPPORTS_REQUESTS` capability를 반드시 노출해야 합니다.

H.264 multi-slice처럼 decoded frame 하나가 여러 decode request의 결과가 될 수 있는 format을 지원하면 `OUTPUT` queue에 `V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF`도 노출해야 합니다.

Stateful과 stateless
항목설명
StatefulDriver/hardware가 state와 frame 순서를 관리
StatelessClient가 header, reference, decode state를 request마다 제공
OUTPUTEncoded bytestream와 request 연결
CAPTUREDecoded raw frame을 독립적으로 queue/dequeue

Decoding state의 소유권과 client 책임이 다릅니다.

Request 기반 frame decode
Client가 stream header와 reference state parsingOUTPUT buffer에 encoded unit 준비Codec-specific controls를 request에 연결MEDIA_REQUEST_IOC_QUEUE로 request 제출Driver가 독립적으로 frame decodeCAPTURE queue에서 decoded frame dequeue

한 frame의 encoded data와 metadata를 하나의 request로 묶습니다.

.. SPDX-License-Identifier: GPL-2.0

.. _stateless_decoder:

**************************************************
Memory-to-memory Stateless Video Decoder Interface
**************************************************

A stateless decoder is a decoder that works without retaining any kind of state
between processed frames. This means that each frame is decoded independently
of any previous and future frames, and that the client is responsible for
maintaining the decoding state and providing it to the decoder with each
decoding request. This is in contrast to the stateful video decoder interface,
where the hardware and driver maintain the decoding state and all the client
has to do is to provide the raw encoded stream and dequeue decoded frames in
display order.

This section describes how user-space ("the client") is expected to communicate
with stateless decoders in order to successfully decode an encoded stream.
Compared to stateful codecs, the decoder/client sequence is simpler, but the
cost of this simplicity is extra complexity in the client which is responsible
for maintaining a consistent decoding state.

Stateless decoders make use of the :ref:`media-request-api`. A stateless
decoder must expose the ``V4L2_BUF_CAP_SUPPORTS_REQUESTS`` capability on its
``OUTPUT`` queue when :c:func:`VIDIOC_REQBUFS` or :c:func:`VIDIOC_CREATE_BUFS`
are invoked.

Depending on the encoded formats supported by the decoder, a single decoded
frame may be the result of several decode requests (for instance, H.264 streams
with multiple slices per frame). Decoders that support such formats must also
expose the ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF`` capability on their
``OUTPUT`` queue.

Coded/raw format과 profile 조회

35-68

지원 coded format은 `OUTPUT` queue에서 `VIDIOC_ENUM_FMT`로 열거합니다. Driver는 현재 `CAPTURE` format과 관계없이 지원하는 OUTPUT format 전체를 반환해야 하고, H.264 profile 같은 codec-specific capability control은 hardware가 실제 지원하는 값으로 제한해야 합니다.

지원 raw format은 `CAPTURE` queue에서 `VIDIOC_ENUM_FMT`로 열거합니다. 이 결과는 현재 활성 `OUTPUT` format에 맞는 항목만 포함하며 codec-dependent control 값에 따라 달라질 수 있습니다.

Client는 CAPTURE format을 열거하기 전에 필요한 codec control을 설정해야 합니다. 설정하지 않으면 default control 값으로 계산한 raw format 목록이 반환되어 실제 media를 decode하는 데 쓸 수 없을 수 있습니다.

특정 format의 지원 resolution은 원하는 `pixel_format`을 `struct v4l2_frmsizeenum`에 넣고 `VIDIOC_ENUM_FRAMESIZES`로 조회합니다. 현재 OUTPUT format의 profile과 level은 각각의 control을 `VIDIOC_QUERYCTRL`로 조회할 수 있습니다.

Capability 탐색 순서
OUTPUT에서 VIDIOC_ENUM_FMT로 coded format 열거Codec profile/level control capability 조회필요한 codec-dependent control 설정CAPTURE에서 VIDIOC_ENUM_FMT로 raw format 열거VIDIOC_ENUM_FRAMESIZES로 resolution 범위 확인

OUTPUT format을 먼저 정해야 CAPTURE 후보가 의미를 갖습니다.

Format 열거 의존성
항목설명
OUTPUT ENUM_FMT현재 CAPTURE와 무관한 전체 coded format
Codec controlsHardware가 실제 지원하는 profile/level로 제한
CAPTURE ENUM_FMT현재 OUTPUT과 control에 호환되는 raw format만
Control 미설정Default 값 기준의 부적합한 format 목록 가능

Queue별 반환 범위와 선행 조건입니다.

Querying capabilities
=====================

1. To enumerate the set of coded formats supported by the decoder, the client
   calls :c:func:`VIDIOC_ENUM_FMT` on the ``OUTPUT`` queue.

   * The driver must always return the full set of supported ``OUTPUT`` formats,
     irrespective of the format currently set on the ``CAPTURE`` queue.

   * Simultaneously, the driver must restrain the set of values returned by
     codec-specific capability controls (such as H.264 profiles) to the set
     actually supported by the hardware.

2. To enumerate the set of supported raw formats, the client calls
   :c:func:`VIDIOC_ENUM_FMT` on the ``CAPTURE`` queue.

   * The driver must return only the formats supported for the format currently
     active on the ``OUTPUT`` queue.

   * Depending on the currently set ``OUTPUT`` format, the set of supported raw
     formats may depend on the value of some codec-dependent controls.
     The client is responsible for making sure that these controls are set
     before querying the ``CAPTURE`` queue. Failure to do so will result in the
     default values for these controls being used, and a returned set of formats
     that may not be usable for the media the client is trying to decode.

3. The client may use :c:func:`VIDIOC_ENUM_FRAMESIZES` to detect supported
   resolutions for a given format, passing desired pixel format in
   :c:type:`v4l2_frmsizeenum`'s ``pixel_format``.

4. Supported profiles and levels for the current ``OUTPUT`` format, if
   applicable, may be queried using their respective controls via
   :c:func:`VIDIOC_QUERYCTRL`.

초기화 1~3: OUTPUT과 기본 CAPTURE

69-128

첫 단계는 `VIDIOC_S_FMT`로 `OUTPUT` queue의 coded format을 설정하는 것입니다. 적절한 OUTPUT `type`, coded `pixelformat`, stream에서 parsing한 coded `width`와 `height`가 필수이며 나머지 필드는 표준 의미를 따릅니다.

OUTPUT format을 바꾸면 현재 CAPTURE format도 바뀔 수 있습니다. Driver는 새 OUTPUT format에서 decoded resolution과 colorimetry 등을 도출해 CAPTURE format을 갱신하므로, client가 특정 raw format을 원하면 그 뒤에 조정해야 합니다.

두 번째 단계에서는 `VIDIOC_S_EXT_CTRLS`로 CAPTURE format 열거에 필요한 parsed header 등 OUTPUT codec의 모든 control을 설정합니다.

세 번째 단계는 CAPTURE queue에 `VIDIOC_G_FMT`를 호출해 decoded destination buffer format을 얻는 것입니다. 필수 입력은 CAPTURE `type`이고, driver는 decoded frame의 `width`, `height`, `pixelformat`, multiplanar이면 `num_planes`, 표준 의미의 `sizeimage`와 `bytesperline`을 반환합니다.

반환 pixelformat은 현재 OUTPUT에서 hardware가 지원하는 어느 raw format이든 될 수 있습니다. Driver는 추가 RGB conversion이 필요한 상황에서 YUV를 고르는 것처럼 현재 구성에 최적인 format을 선택하는 것이 권장됩니다.

초기화 1~3
OUTPUT S_FMT: coded pixelformat + width + heightDriver가 기본 CAPTURE resolution/colorimetry 도출S_EXT_CTRLS로 parsed header와 codec controls 설정CAPTURE G_FMT로 raw pixelformat 조회num_planes, sizeimage, bytesperline 확인

Coded stream 정보에서 기본 raw destination layout을 도출합니다.

CAPTURE G_FMT 반환
항목설명
width / heightDecoded frame buffer resolution
pixelformatDriver가 선호하는 지원 raw format
num_planesMPLANE type의 plane 수
sizeimage각 buffer/plane에 필요한 image byte 수
bytesperlineRaw frame의 line stride

Decoded buffer를 할당하는 데 필요한 layout입니다.

Initialization
==============

1. Set the coded format on the ``OUTPUT`` queue via :c:func:`VIDIOC_S_FMT`.

   * **Required fields:**

     ``type``
         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.

     ``pixelformat``
         a coded pixel format.

     ``width``, ``height``
         coded width and height parsed from the stream.

     other fields
         follow standard semantics.

   .. note::

      Changing the ``OUTPUT`` format may change the currently set ``CAPTURE``
      format. The driver will derive a new ``CAPTURE`` format from the
      ``OUTPUT`` format being set, including resolution, colorimetry
      parameters, etc. If the client needs a specific ``CAPTURE`` format,
      it must adjust it afterwards.

2. Call :c:func:`VIDIOC_S_EXT_CTRLS` to set all the controls (parsed headers,
   etc.) required by the ``OUTPUT`` format to enumerate the ``CAPTURE`` formats.

3. Call :c:func:`VIDIOC_G_FMT` for ``CAPTURE`` queue to get the format for the
   destination buffers parsed/decoded from the bytestream.

   * **Required fields:**

     ``type``
         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.

   * **Returned fields:**

     ``width``, ``height``
         frame buffer resolution for the decoded frames.

     ``pixelformat``
         pixel format for decoded frames.

     ``num_planes`` (for _MPLANE ``type`` only)
         number of planes for pixelformat.

     ``sizeimage``, ``bytesperline``
         as per standard semantics; matching frame buffer format.

   .. note::

      The value of ``pixelformat`` may be any pixel format supported for the
      ``OUTPUT`` format, based on the hardware capabilities. It is suggested
      that the driver chooses the preferred/optimal format for the current
      configuration. For example, a YUV format may be preferred over an RGB
      format, if an additional conversion step would be required for RGB.

초기화 4~5: CAPTURE format 선택

129-168

선택 단계로 CAPTURE queue에서 `VIDIOC_ENUM_FMT`를 호출하면 현재 OUTPUT format과 control에 지원되는 대안 raw format을 찾을 수 있습니다. Decoder 전체가 지원하는 모든 format이 아니라 현재 구성에서 가능한 subset만 반환합니다.

예를 들어 hardware가 1920x1088 이하에서 YUV와 RGB를 지원하고 그보다 큰 resolution에서는 YUV만 지원한다면, 작은 OUTPUT 크기에서는 두 종류를 열거하지만 큰 크기에서는 RGB를 반환하지 않습니다.

Client는 CAPTURE `type`, 원하는 raw `pixelformat`, decoded frame buffer `width`와 `height`를 `VIDIOC_S_FMT`로 설정할 수 있습니다. 보통 G_FMT 크기를 유지하지만 hardware composition이나 scaling을 지원하면 다른 크기를 고를 수 있습니다.

CAPTURE S_FMT 뒤에는 buffer 크기와 layout이 달라졌을 수 있으므로 반드시 초기화 3단계의 CAPTURE `VIDIOC_G_FMT`를 다시 호출해 최신 정보를 얻어야 합니다.

대안 CAPTURE 선택
현재 OUTPUT와 controls 확정CAPTURE VIDIOC_ENUM_FMT로 호환 raw format 열거원하는 pixelformat와 frame buffer 크기 선택CAPTURE VIDIOC_S_FMT 적용CAPTURE VIDIOC_G_FMT 재호출갱신된 sizeimage와 bytesperline 확인

현재 coded configuration 안에서 raw output을 바꿉니다.

Resolution별 raw format 예
항목설명
1920x1088 이하YUV와 RGB 가능
1920x1088 초과YUV만 가능
Composition/scaling 지원Decoded stream과 다른 CAPTURE 크기 가능
S_FMT 이후G_FMT로 실제 layout을 다시 조회

Hardware 제한이 CAPTURE 목록을 바꿀 수 있습니다.

4. *[optional]* Enumerate ``CAPTURE`` formats via :c:func:`VIDIOC_ENUM_FMT` on
   the ``CAPTURE`` queue. The client may use this ioctl to discover which
   alternative raw formats are supported for the current ``OUTPUT`` format and
   select one of them via :c:func:`VIDIOC_S_FMT`.

   .. note::

      The driver will return only formats supported for the currently selected
      ``OUTPUT`` format and currently set controls, even if more formats may be
      supported by the decoder in general.

      For example, a decoder may support YUV and RGB formats for
      resolutions 1920x1088 and lower, but only YUV for higher resolutions (due
      to hardware limitations). After setting a resolution of 1920x1088 or lower
      as the ``OUTPUT`` format, :c:func:`VIDIOC_ENUM_FMT` may return a set of
      YUV and RGB pixel formats, but after setting a resolution higher than
      1920x1088, the driver will not return RGB pixel formats, since they are
      unsupported for this resolution.

5. *[optional]* Choose a different ``CAPTURE`` format than suggested via
   :c:func:`VIDIOC_S_FMT` on ``CAPTURE`` queue. It is possible for the client to
   choose a different format than selected/suggested by the driver in
   :c:func:`VIDIOC_G_FMT`.

    * **Required fields:**

      ``type``
          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.

      ``pixelformat``
          a raw pixel format.

      ``width``, ``height``
         frame buffer resolution of the decoded stream; typically unchanged from
         what was returned with :c:func:`VIDIOC_G_FMT`, but it may be different
         if the hardware supports composition and/or scaling.

   After performing this step, the client must perform step 3 again in order
   to obtain up-to-date information about the buffers size and layout.

초기화 6~9: Buffer, request와 streaming

169-227

여섯 번째 단계는 OUTPUT queue에 `VIDIOC_REQBUFS`를 호출해 source bytestream buffer를 할당하는 것입니다. `count`는 0보다 큰 요청 수, `type`은 OUTPUT 종류, `memory`는 표준 의미를 사용합니다. Driver는 format에 필요한 최소 수와 요청 수를 고려해 실제 `count`를 같거나 더 크게 조정할 수 있으므로 반환값을 확인합니다.

일곱 번째 단계는 CAPTURE queue의 decoded destination buffer 할당입니다. Client는 reference frame 등을 고려해 stream decode에 필요한 최소 수를 계산하고 그 이상을 요청해야 합니다. `V4L2_MEMORY_USERPTR`는 CAPTURE buffer에서 지원되지 않습니다.

Driver는 현재 format과 stream configuration, 요청 수를 바탕으로 필요한 최소 CAPTURE count로 조정하고 실제 할당 수를 반환합니다. Client는 OUTPUT과 CAPTURE 모두 요청값이 그대로 적용된다고 가정하면 안 됩니다.

여덟 번째 단계에서 media device의 `MEDIA_IOC_REQUEST_ALLOC`으로 request를 할당합니다. 일반적으로 OUTPUT buffer마다 request 하나를 준비합니다. 마지막 아홉 번째 단계에서 `VIDIOC_STREAMON`으로 OUTPUT과 CAPTURE queue를 모두 시작합니다.

Queue별 buffer 할당
항목설명
OUTPUTEncoded bytestream source buffer
OUTPUT countDriver minimum과 client 요청을 반영해 조정
CAPTUREDecoded raw/reference destination buffer
CAPTURE countClient가 reference 수를 계산하고 driver가 minimum 보정
CAPTURE USERPTRV4L2_MEMORY_USERPTR 미지원

Source와 destination의 책임과 memory 제한입니다.

초기화 6~9
OUTPUT VIDIOC_REQBUFS 호출반환 OUTPUT count 확인Reference를 고려한 CAPTURE count 계산CAPTURE VIDIOC_REQBUFS 호출반환 CAPTURE count 확인MEDIA_IOC_REQUEST_ALLOC로 request pool 준비OUTPUT VIDIOC_STREAMONCAPTURE VIDIOC_STREAMON

두 queue와 media request를 준비한 뒤 streaming을 시작합니다.

6. Allocate source (bytestream) buffers via :c:func:`VIDIOC_REQBUFS` on
   ``OUTPUT`` queue.

    * **Required fields:**

      ``count``
          requested number of buffers to allocate; greater than zero.

      ``type``
          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.

      ``memory``
          follows standard semantics.

    * **Returned fields:**

      ``count``
          actual number of buffers allocated.

    * If required, the driver will adjust ``count`` to be equal or bigger to the
      minimum of required number of ``OUTPUT`` buffers for the given format and
      requested count. The client must check this value after the ioctl returns
      to get the actual number of buffers allocated.

7. Allocate destination (raw format) buffers via :c:func:`VIDIOC_REQBUFS` on the
   ``CAPTURE`` queue.

    * **Required fields:**

      ``count``
          requested number of buffers to allocate; greater than zero. The client
          is responsible for deducing the minimum number of buffers required
          for the stream to be properly decoded (taking e.g. reference frames
          into account) and pass an equal or bigger number.

      ``type``
          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.

      ``memory``
          follows standard semantics. ``V4L2_MEMORY_USERPTR`` is not supported
          for ``CAPTURE`` buffers.

    * **Returned fields:**

      ``count``
          adjusted to allocated number of buffers, in case the codec requires
          more buffers than requested.

    * The driver must adjust count to the minimum of required number of
      ``CAPTURE`` buffers for the current format, stream configuration and
      requested count. The client must check this value after the ioctl
      returns to get the number of buffers allocated.

8. Allocate requests (likely one per ``OUTPUT`` buffer) via
    :c:func:`MEDIA_IOC_REQUEST_ALLOC` on the media device.

9. Start streaming on both ``OUTPUT`` and ``CAPTURE`` queues via
    :c:func:`VIDIOC_STREAMON`.

Frame request와 HOLD_CAPTURE_BUF

228-252

각 frame마다 client는 적어도 하나의 request를 제출합니다. Request에는 현재 codec configuration이 요구하는 양의 encoded data를 담은 OUTPUT buffer와 그 data를 decode하는 데 필요한 codec-specific metadata control 전체가 연결됩니다.

대개 OUTPUT data 한 단위는 frame 하나지만 codec에 따라 다른 크기를 허용하거나 요구합니다. 정확한 buffer 내용과 request control 집합은 활성 coded pixelformat 및 codec-specific extended control 문서를 따릅니다.

현재 request 뒤에 같은 decoded frame을 완성할 추가 request가 올 수 있다면 OUTPUT buffer에 `V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`를 설정해야 합니다. 그러면 부분 decode된 CAPTURE buffer를 dequeue하지 않고 다음 request에서 재사용합니다. 다음 OUTPUT timestamp가 바뀌면 held buffer를 dequeue 가능 상태로 만들고 새 CAPTURE buffer를 사용합니다.

Decode request 구성
항목설명
OUTPUT bufferCodec이 현재 단위에서 기대하는 encoded data
Request controlsHeader, reference와 codec-specific metadata 전체
HOLD flag같은 frame의 추가 request가 필요할 수 있을 때 설정
Timestamp같은 frame request는 동일, 다음 frame은 고유 값

Encoded unit과 모든 frame metadata를 함께 제출합니다.

Multi-request frame
첫 slice OUTPUT에 HOLD_CAPTURE_BUF 설정부분 decoded CAPTURE buffer를 driver가 보유같은 timestamp의 다음 slice request 제출마지막 unit에서 HOLD 조건 종료완성된 CAPTURE buffer를 dequeue 가능 상태로 전환

같은 timestamp로 partial CAPTURE buffer를 이어서 사용합니다.

Decoding
========

For each frame, the client is responsible for submitting at least one request to
which the following is attached:

* The amount of encoded data expected by the codec for its current
  configuration, as a buffer submitted to the ``OUTPUT`` queue. Typically, this
  corresponds to one frame worth of encoded data, but some formats may allow (or
  require) different amounts per unit.
* All the metadata needed to decode the submitted encoded data, in the form of
  controls relevant to the format being decoded.

The amount of data and contents of the source ``OUTPUT`` buffer, as well as the
controls that must be set on the request, depend on the active coded pixel
format and might be affected by codec-specific extended controls, as stated in
documentation of each format.

If there is a possibility that the decoded frame will require one or more
decode requests after the current one in order to be produced, then the client
must set the ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag on the ``OUTPUT``
buffer. This will result in the (potentially partially) decoded ``CAPTURE``
buffer not being made available for dequeueing, and reused for the next decode
request if the timestamp of the next ``OUTPUT`` buffer has not changed.

OUTPUT·control 연결과 request 제출

253-326

첫 단계는 `VIDIOC_QBUF`로 request의 encoded data 단위를 담은 OUTPUT buffer 하나를 queue하는 것입니다. `index`, OUTPUT `type`, 실제 encoded byte 수인 `bytesused`가 필요합니다.

`flags`에는 `V4L2_BUF_FLAG_REQUEST_FD`를 반드시 설정하고 마지막 decode request인지 확실하지 않으면 `V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`도 설정합니다. `request_fd`는 해당 decoding request descriptor입니다.

`timestamp`는 frame마다 고유하며 decoded CAPTURE buffer로 전파되고 다른 frame이 reference할 때도 사용됩니다. 한 frame에 여러 request가 있으면 모든 OUTPUT buffer timestamp가 같아야 합니다. Timestamp가 바뀌면 held CAPTURE buffer를 dequeue하고 새 buffer에서 현재 request를 처리합니다.

두 번째 단계는 `VIDIOC_S_EXT_CTRLS`입니다. `which`를 `V4L2_CTRL_WHICH_REQUEST_VAL`, `request_fd`를 같은 request descriptor로 설정하고 frame decode에 필요한 codec control 전체를 연결합니다. 여러 번 호출하거나 기존 값을 덮어쓸 수 있으며 request 제출 순간의 최종 control state를 사용합니다.

OUTPUT buffer queue와 control 설정의 순서는 서로 바꿀 수 있습니다. 세 번째 단계에서 request FD에 `MEDIA_REQUEST_IOC_QUEUE`를 호출해 제출합니다.

OUTPUT buffer가 없거나 필수 control이 빠지면 `-ENOENT`, OUTPUT buffer가 둘 이상이면 `-EINVAL`입니다. Non-zero 반환은 해당 request에서 CAPTURE buffer가 생성되지 않는다는 뜻입니다.

CAPTURE buffer는 request에 포함하지 않고 독립적으로 queue합니다. 반환 순서는 display order가 아니라 OUTPUT에 coded frame을 제출한 decode order입니다.

OUTPUT QBUF 필드
항목설명
index / typeQueue할 OUTPUT buffer 식별
bytesusedEncoded frame/unit의 실제 byte 수
REQUEST_FDV4L2_BUF_FLAG_REQUEST_FD 필수
HOLD_CAPTURE_BUF같은 frame에 후속 request가 필요할 때
request_fdDecoding request file descriptor
timestampFrame identity와 reference key

Request와 encoded frame identity를 연결합니다.

MEDIA_REQUEST_IOC_QUEUE 오류
항목설명
-ENOENTOUTPUT buffer 없음 또는 필수 control 누락
-EINVAL한 request에 OUTPUT buffer가 둘 이상
Non-zero해당 request의 CAPTURE buffer 미생성

제출 검증에 실패하면 output frame이 생성되지 않습니다.

Frame request 3단계
VIDIOC_QBUF로 OUTPUT buffer 하나 연결VIDIOC_S_EXT_CTRLS로 codec controls 연결두 단계의 순서는 교환 가능MEDIA_REQUEST_IOC_QUEUE 호출CAPTURE buffer는 request 밖에서 독립 queueDecode order로 CAPTURE dequeue

Buffer와 metadata를 묶어 atomic decode 작업으로 제출합니다.

A typical frame would thus be decoded using the following sequence:

1. Queue an ``OUTPUT`` buffer containing one unit of encoded bytestream data for
   the decoding request, using :c:func:`VIDIOC_QBUF`.

    * **Required fields:**

      ``index``
          index of the buffer being queued.

      ``type``
          type of the buffer.

      ``bytesused``
          number of bytes taken by the encoded data frame in the buffer.

      ``flags``
          the ``V4L2_BUF_FLAG_REQUEST_FD`` flag must be set. Additionally, if
          we are not sure that the current decode request is the last one needed
          to produce a fully decoded frame, then
          ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` must also be set.

      ``request_fd``
          must be set to the file descriptor of the decoding request.

      ``timestamp``
          must be set to a unique value per frame. This value will be propagated
          into the decoded frame's buffer and can also be used to use this frame
          as the reference of another. If using multiple decode requests per
          frame, then the timestamps of all the ``OUTPUT`` buffers for a given
          frame must be identical. If the timestamp changes, then the currently
          held ``CAPTURE`` buffer will be made available for dequeuing and the
          current request will work on a new ``CAPTURE`` buffer.

2. Set the codec-specific controls for the decoding request, using
   :c:func:`VIDIOC_S_EXT_CTRLS`.

    * **Required fields:**

      ``which``
          must be ``V4L2_CTRL_WHICH_REQUEST_VAL``.

      ``request_fd``
          must be set to the file descriptor of the decoding request.

      other fields
          other fields are set as usual when setting controls. The ``controls``
          array must contain all the codec-specific controls required to decode
          a frame.

   .. note::

      It is possible to specify the controls in different invocations of
      :c:func:`VIDIOC_S_EXT_CTRLS`, or to overwrite a previously set control, as
      long as ``request_fd`` and ``which`` are properly set. The controls state
      at the moment of request submission is the one that will be considered.

   .. note::

      The order in which steps 1 and 2 take place is interchangeable.

3. Submit the request by invoking :c:func:`MEDIA_REQUEST_IOC_QUEUE` on the
   request FD.

    If the request is submitted without an ``OUTPUT`` buffer, or if some of the
    required controls are missing from the request, then
    :c:func:`MEDIA_REQUEST_IOC_QUEUE` will return ``-ENOENT``. If more than one
    ``OUTPUT`` buffer is queued, then it will return ``-EINVAL``.
    :c:func:`MEDIA_REQUEST_IOC_QUEUE` returning non-zero means that no
    ``CAPTURE`` buffer will be produced for this request.

``CAPTURE`` buffers must not be part of the request, and are queued
independently. They are returned in decode order (i.e. the same order as coded
frames were submitted to the ``OUTPUT`` queue).

오류 전파와 reference buffer 수명

327-368

Runtime decode 오류는 dequeue된 CAPTURE buffer의 `V4L2_BUF_FLAG_ERROR`로 알립니다. 오류가 있는 decoded reference frame을 뒤 frame이 참조하면 그 frame에도 ERROR flag를 설정하지만 decoder는 손상 가능성이 있는 frame 생성을 계속 시도합니다.

Stateless decoder는 buffer 관리를 수행하지 않습니다. Dequeue한 CAPTURE buffer는 다시 queue하기 전까지 client가 compositing, display 또는 다른 frame의 reference로 사용할 수 있음을 보장할 뿐입니다.

Frame을 reference로 지정할 때 timestamp를 nanosecond로 변환해 codec-dependent control의 관련 멤버에 저장합니다. 반드시 `v4l2_timeval_to_ns`를 사용합니다. Frame의 encoded data unit이 모두 OUTPUT에 성공적으로 제출되면 그 timestamp로 즉시 reference할 수 있습니다.

Reference frame을 담은 decoded buffer는 이를 참조하는 frame이 모두 decode될 때까지 새 decode target으로 재사용하면 안 됩니다. 가장 안전한 방법은 모든 referencing frame을 dequeue할 때까지 reference buffer를 queue하지 않는 것입니다.

Driver가 CAPTURE buffer를 queue 순서대로 처리한다고 보장한다면 더 일찍 재queue할 수 있습니다. Reference의 영향을 받는 모든 frame request가 queue되었고, 그 referencing frame 전체를 수용할 만큼 CAPTURE buffer가 뒤에 queue된 두 조건을 모두 충족해야 합니다.

Decode request를 queue할 때 driver는 reference frame 관련 resource의 reference count를 증가시킵니다. 따라서 client는 이후 필요하지 않은 reference buffer의 DMABUF file descriptor를 닫아도 request가 resource 수명을 유지합니다.

Reference buffer 재사용
항목설명
기본모든 referencing frame dequeue 전에는 reference buffer 재queue 금지
조건 1Reference 영향권의 모든 frame request가 이미 queue됨
조건 2모든 referencing frame을 덮을 충분한 CAPTURE buffer가 queue됨
전제Driver가 CAPTURE를 queue order로 처리한다고 보장

안전한 기본 규칙과 queue-order 최적화 조건입니다.

Reference frame 수명
Encoded unit 전체를 OUTPUT에 제출v4l2_timeval_to_ns로 timestamp 변환Codec control에서 reference 지정Driver가 request queue 시 resource refcount 증가Client가 필요 없는 DMABUF FD를 닫을 수 있음Referencing frame 완료 뒤 buffer를 decode target으로 재queue

Timestamp identity와 buffer ownership을 분리합니다.

Decode 오류 전파
항목설명
현재 frame 오류CAPTURE에 V4L2_BUF_FLAG_ERROR
오류 reference 사용뒤 frame에도 ERROR flag 전파
Decoder 동작가능하면 손상된 결과라도 계속 생성 시도

Reference chain의 손상을 flag로 전달합니다.


Runtime decoding errors are signaled by the dequeued ``CAPTURE`` buffers
carrying the ``V4L2_BUF_FLAG_ERROR`` flag. If a decoded reference frame has an
error, then all following decoded frames that refer to it also have the
``V4L2_BUF_FLAG_ERROR`` flag set, although the decoder will still try to
produce (likely corrupted) frames.

Buffer management while decoding
================================
Contrary to stateful decoders, a stateless decoder does not perform any kind of
buffer management: it only guarantees that dequeued ``CAPTURE`` buffers can be
used by the client for as long as they are not queued again. "Used" here
encompasses using the buffer for compositing or display.

A dequeued capture buffer can also be used as the reference frame of another
buffer.

A frame is specified as reference by converting its timestamp into nanoseconds,
and storing it into the relevant member of a codec-dependent control structure.
The :c:func:`v4l2_timeval_to_ns` function must be used to perform that
conversion. The timestamp of a frame can be used to reference it as soon as all
its units of encoded data are successfully submitted to the ``OUTPUT`` queue.

A decoded buffer containing a reference frame must not be reused as a decoding
target until all the frames referencing it have been decoded. The safest way to
achieve this is to refrain from queueing a reference buffer until all the
decoded frames referencing it have been dequeued. However, if the driver can
guarantee that buffers queued to the ``CAPTURE`` queue are processed in queued
order, then user-space can take advantage of this guarantee and queue a
reference buffer when the following conditions are met:

1. All the requests for frames affected by the reference frame have been
   queued, and

2. A sufficient number of ``CAPTURE`` buffers to cover all the decoded
   referencing frames have been queued.

When queuing a decoding request, the driver will increase the reference count of
all the resources associated with reference frames. This means that the client
can e.g. close the DMABUF file descriptors of reference frame buffers if it
won't need them afterwards.

Seeking과 pausing

369-387

Seek하려면 새 stream 위치의 input buffer를 사용해 request를 제출하면 됩니다. 다만 새 위치에서 resolution이 달라졌다면 dynamic resolution change 절차를 수행해야 합니다.

Codec에 따라 H.264 SPS/PPS 같은 picture parameter도 달라질 수 있으므로 client가 새 위치에 유효한 state를 decoder에 제공해야 합니다. Seek 전 위치에서 늦게 반환되는 CAPTURE buffer는 무시할 수 있습니다.

Pause는 OUTPUT queue에 buffer를 더 queue하지 않는 것으로 충분합니다. Source bytestream data가 없으면 처리할 작업이 없어 codec이 idle 상태로 유지됩니다.

Seek 처리
새 stream 위치로 parser 이동Resolution과 SPS/PPS 등 picture parameter 확인필요하면 dynamic resolution change 수행새 위치의 OUTPUT request 제출Seek 이전 CAPTURE 반환은 무시 가능

새 위치의 state를 다시 구성해 request 흐름을 이어갑니다.

Pause와 seek
항목설명
PauseOUTPUT queue 공급 중단
ResumeOUTPUT request queue 재개
Seek새 위치의 buffer와 완전한 codec state 제출

Stateless decoder에는 별도 pause state 명령이 필요하지 않습니다.

Seeking
=======
In order to seek, the client just needs to submit requests using input buffers
corresponding to the new stream position. It must however be aware that
resolution may have changed and follow the dynamic resolution change sequence in
that case. Also depending on the codec used, picture parameters (e.g. SPS/PPS
for H.264) may have changed and the client is responsible for making sure that a
valid state is sent to the decoder.

The client is then free to ignore any returned ``CAPTURE`` buffer that comes
from the pre-seek position.

Pausing
=======

In order to pause, the client can just cease queuing buffers onto the ``OUTPUT``
queue. Without source bytestream data, there is no data to process and the codec
will remain idle.

Dynamic resolution change

388-413

Client가 stream에서 resolution change를 발견하면 새 크기로 초기화 절차를 다시 수행합니다. 마지막 request가 `V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`로 CAPTURE buffer를 보유 중이면 `V4L2_DEC_CMD_FLUSH`를 보내 held buffer를 dequeue하게 합니다.

제출한 모든 request가 완료될 때까지 기다리고 대응 OUTPUT buffer를 dequeue합니다. 그 다음 OUTPUT과 CAPTURE 모두 `VIDIOC_STREAMOFF`를 호출합니다.

CAPTURE queue에 `count = 0`인 `VIDIOC_REQBUFS`를 호출해 모든 destination buffer를 해제합니다. OUTPUT buffer 할당 단계만 제외하고 새 resolution으로 초기화 절차를 반복합니다. Resolution 제약 때문에 CAPTURE pixelformat도 바꿔야 할 수 있습니다.

해상도 변경 5단계
Held CAPTURE가 있으면 V4L2_DEC_CMD_FLUSH모든 request 완료와 OUTPUT dequeue 대기OUTPUT과 CAPTURE에 VIDIOC_STREAMOFFCAPTURE REQBUFS count=0으로 buffer 해제새 OUTPUT resolution으로 초기화 반복필요하면 다른 CAPTURE format 선택기존 OUTPUT buffer는 재할당하지 않음

Held frame을 회수하고 CAPTURE layout을 새로 만듭니다.

재초기화 범위
항목설명
OUTPUT buffers기존 할당 유지
CAPTURE buffers전부 해제 후 새 layout으로 재할당
OUTPUT format새 coded resolution 설정
CAPTURE format새 resolution 제약에 맞춰 재선택 가능

유지하는 resource와 다시 만드는 resource를 구분합니다.

Dynamic resolution change
=========================

If the client detects a resolution change in the stream, it will need to perform
the initialization sequence again with the new resolution:

1. If the last submitted request resulted in a ``CAPTURE`` buffer being
   held by the use of the ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag, then the
   last frame is not available on the ``CAPTURE`` queue. In this case, a
   ``V4L2_DEC_CMD_FLUSH`` command shall be sent. This will make the driver
   dequeue the held ``CAPTURE`` buffer.

2. Wait until all submitted requests have completed and dequeue the
   corresponding output buffers.

3. Call :c:func:`VIDIOC_STREAMOFF` on both the ``OUTPUT`` and ``CAPTURE``
   queues.

4. Free all ``CAPTURE`` buffers by calling :c:func:`VIDIOC_REQBUFS` on the
   ``CAPTURE`` queue with a buffer count of zero.

5. Perform the initialization sequence again (minus the allocation of
   ``OUTPUT`` buffers), with the new resolution set on the ``OUTPUT`` queue.
   Note that due to resolution constraints, a different format may need to be
   picked on the ``CAPTURE`` queue.

Drain과 held CAPTURE 회수

414-424

마지막 request가 `V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`로 CAPTURE buffer를 보유해 마지막 frame을 아직 dequeue할 수 없다면 `V4L2_DEC_CMD_FLUSH`를 보냅니다. Driver는 held CAPTURE buffer를 dequeue 가능 상태로 만듭니다.

그 뒤 stateless decoder의 drain은 제출한 모든 request가 완료될 때까지 기다리는 것으로 끝납니다. Stateful decoder처럼 별도의 내부 decode state를 비우는 복잡한 절차는 없습니다.

Stateless drain
마지막 OUTPUT request 상태 확인Held CAPTURE가 있으면 V4L2_DEC_CMD_FLUSHHeld CAPTURE buffer dequeue제출된 모든 request 완료 대기남은 CAPTURE buffer dequeue

마지막 held frame만 명시적으로 release합니다.

Drain 조건
항목설명
Held buffer 있음FLUSH 후 request 완료 대기
Held buffer 없음바로 모든 request 완료 대기

Held buffer 여부에 따른 마지막 처리입니다.

Drain
=====

If the last submitted request resulted in a ``CAPTURE`` buffer being
held by the use of the ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag, then the
last frame is not available on the ``CAPTURE`` queue. In this case, a
``V4L2_DEC_CMD_FLUSH`` command shall be sent. This will make the driver
dequeue the held ``CAPTURE`` buffer.

After that, in order to drain the stream on a stateless decoder, the client
just needs to wait until all the submitted requests are completed.