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

Linux 6.18.37 · Userspace API / Media / V4L

메모리 대 메모리 상태 유지형 비디오 인코더 인터페이스

상태 유지형 encoder의 format 협상, queue 동작, frame interval, drain과 reset 절차를 정의합니다.

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

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

1. 요약·해설

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

요약·해설

dev-encoder.rst:1-729

상태 유지형 encoder에서는 CAPTURE가 coded format을 지배하는 master queue이고 OUTPUT이 display-order raw frame을 공급합니다. 두 queue의 독립 동작, frame interval, LAST flag와 Reset 경계를 기준으로 안전하게 stream을 구성해야 합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
2
3 .. _encoder:
4
5 *************************************************
6 Memory-to-Memory Stateful Video Encoder Interface
7 *************************************************
8
9 A stateful video encoder takes raw video frames in display order and encodes
10 them into a bytestream. It generates complete chunks of the bytestream, including
11 all metadata, headers, etc. The resulting bytestream does not require any
12 further post-processing by the client.
13
14 Performing software stream processing, header generation etc. in the driver
15 in order to support this interface is strongly discouraged. In case such
16 operations are needed, use of the Stateless Video Encoder Interface (in
17 development) is strongly advised.
18
19 Conventions and Notations Used in This Document
20 ===============================================
21
22 1. The general V4L2 API rules apply if not specified in this document
23 otherwise.
24
25 2. The meaning of words "must", "may", "should", etc. is as per `RFC
26 2119 <https://tools.ietf.org/html/rfc2119>`_.
27
28 3. All steps not marked "optional" are required.
29
30 4. :c:func:`VIDIOC_G_EXT_CTRLS` and :c:func:`VIDIOC_S_EXT_CTRLS` may be used
31 interchangeably with :c:func:`VIDIOC_G_CTRL` and :c:func:`VIDIOC_S_CTRL`,
32 unless specified otherwise.
33
34 5. Single-planar API (see :ref:`planar-apis`) and applicable structures may be
35 used interchangeably with multi-planar API, unless specified otherwise,
36 depending on encoder capabilities and following the general V4L2 guidelines.
37
38 6. i = [a..b]: sequence of integers from a to b, inclusive, i.e. i =
39 [0..2]: i = 0, 1, 2.
40
41 7. Given an ``OUTPUT`` buffer A, then A' represents a buffer on the ``CAPTURE``
42 queue containing data that resulted from processing buffer A.
43
44 Glossary
45 ========
46
47 Refer to :ref:`decoder-glossary`.
48
49 State Machine
50 =============
51
52 .. kernel-render:: DOT
53 :alt: DOT digraph of encoder state machine
54 :caption: Encoder State Machine
55
56 digraph encoder_state_machine {
57 node [shape = doublecircle, label="Encoding"] Encoding;
58
59 node [shape = circle, label="Initialization"] Initialization;
60 node [shape = circle, label="Stopped"] Stopped;
61 node [shape = circle, label="Drain"] Drain;
62 node [shape = circle, label="Reset"] Reset;
63
64 node [shape = point]; qi
65 qi -> Initialization [ label = "open()" ];
66
67 Initialization -> Encoding [ label = "Both queues streaming" ];
68
69 Encoding -> Drain [ label = "V4L2_ENC_CMD_STOP" ];
70 Encoding -> Reset [ label = "VIDIOC_STREAMOFF(CAPTURE)" ];
71 Encoding -> Stopped [ label = "VIDIOC_STREAMOFF(OUTPUT)" ];
72 Encoding -> Encoding;
73
74 Drain -> Stopped [ label = "All CAPTURE\nbuffers dequeued\nor\nVIDIOC_STREAMOFF(OUTPUT)" ];
75 Drain -> Reset [ label = "VIDIOC_STREAMOFF(CAPTURE)" ];
76
77 Reset -> Encoding [ label = "VIDIOC_STREAMON(CAPTURE)" ];
78 Reset -> Initialization [ label = "VIDIOC_REQBUFS(OUTPUT, 0)" ];
79
80 Stopped -> Encoding [ label = "V4L2_ENC_CMD_START\nor\nVIDIOC_STREAMON(OUTPUT)" ];
81 Stopped -> Reset [ label = "VIDIOC_STREAMOFF(CAPTURE)" ];
82 }
83
84 Querying Capabilities
85 =====================
86
87 1. To enumerate the set of coded formats supported by the encoder, the
88 client may call :c:func:`VIDIOC_ENUM_FMT` on ``CAPTURE``.
89
90 * The full set of supported formats will be returned, regardless of the
91 format set on ``OUTPUT``.
92
93 2. To enumerate the set of supported raw formats, the client may call
94 :c:func:`VIDIOC_ENUM_FMT` on ``OUTPUT``.
95
96 * Only the formats supported for the format currently active on ``CAPTURE``
97 will be returned.
98
99 * In order to enumerate raw formats supported by a given coded format,
100 the client must first set that coded format on ``CAPTURE`` and then
101 enumerate the formats on ``OUTPUT``.
102
103 3. The client may use :c:func:`VIDIOC_ENUM_FRAMESIZES` to detect supported
104 resolutions for a given format, passing the desired pixel format in
105 :c:type:`v4l2_frmsizeenum` ``pixel_format``.
106
107 * Values returned by :c:func:`VIDIOC_ENUM_FRAMESIZES` for a coded pixel
108 format will include all possible coded resolutions supported by the
109 encoder for the given coded pixel format.
110
111 * Values returned by :c:func:`VIDIOC_ENUM_FRAMESIZES` for a raw pixel format
112 will include all possible frame buffer resolutions supported by the
113 encoder for the given raw pixel format and coded format currently set on
114 ``CAPTURE``.
115
116 4. The client may use :c:func:`VIDIOC_ENUM_FRAMEINTERVALS` to detect supported
117 frame intervals for a given format and resolution, passing the desired pixel
118 format in :c:type:`v4l2_frmivalenum` ``pixel_format`` and the resolution
119 in :c:type:`v4l2_frmivalenum` ``width`` and :c:type:`v4l2_frmivalenum`
120 ``height``.
121
122 * Values returned by :c:func:`VIDIOC_ENUM_FRAMEINTERVALS` for a coded pixel
123 format and coded resolution will include all possible frame intervals
124 supported by the encoder for the given coded pixel format and resolution.
125
126 * Values returned by :c:func:`VIDIOC_ENUM_FRAMEINTERVALS` for a raw pixel
127 format and resolution will include all possible frame intervals supported
128 by the encoder for the given raw pixel format and resolution and for the
129 coded format, coded resolution and coded frame interval currently set on
130 ``CAPTURE``.
131
132 * Support for :c:func:`VIDIOC_ENUM_FRAMEINTERVALS` is optional. If it is
133 not implemented, then there are no special restrictions other than the
134 limits of the codec itself.
135
136 5. Supported profiles and levels for the coded format currently set on
137 ``CAPTURE``, if applicable, may be queried using their respective controls
138 via :c:func:`VIDIOC_QUERYCTRL`.
139
140 6. Any additional encoder capabilities may be discovered by querying
141 their respective controls.
142
143 Initialization
144 ==============
145
146 1. Set the coded format on the ``CAPTURE`` queue via :c:func:`VIDIOC_S_FMT`.
147
148 * **Required fields:**
149
150 ``type``
151 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
152
153 ``pixelformat``
154 the coded format to be produced.
155
156 ``sizeimage``
157 desired size of ``CAPTURE`` buffers; the encoder may adjust it to
158 match hardware requirements.
159
160 ``width``, ``height``
161 ignored (read-only).
162
163 other fields
164 follow standard semantics.
165
166 * **Returned fields:**
167
168 ``sizeimage``
169 adjusted size of ``CAPTURE`` buffers.
170
171 ``width``, ``height``
172 the coded size selected by the encoder based on current state, e.g.
173 ``OUTPUT`` format, selection rectangles, etc. (read-only).
174
175 .. important::
176
177 Changing the ``CAPTURE`` format may change the currently set ``OUTPUT``
178 format. How the new ``OUTPUT`` format is determined is up to the encoder
179 and the client must ensure it matches its needs afterwards.
180
181 2. **Optional.** Enumerate supported ``OUTPUT`` formats (raw formats for
182 source) for the selected coded format via :c:func:`VIDIOC_ENUM_FMT`.
183
184 * **Required fields:**
185
186 ``type``
187 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
188
189 other fields
190 follow standard semantics.
191
192 * **Returned fields:**
193
194 ``pixelformat``
195 raw format supported for the coded format currently selected on
196 the ``CAPTURE`` queue.
197
198 other fields
199 follow standard semantics.
200
201 3. Set the raw source format on the ``OUTPUT`` queue via
202 :c:func:`VIDIOC_S_FMT`.
203
204 * **Required fields:**
205
206 ``type``
207 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
208
209 ``pixelformat``
210 raw format of the source.
211
212 ``width``, ``height``
213 source resolution.
214
215 other fields
216 follow standard semantics.
217
218 * **Returned fields:**
219
220 ``width``, ``height``
221 may be adjusted to match encoder minimums, maximums and alignment
222 requirements, as required by the currently selected formats, as
223 reported by :c:func:`VIDIOC_ENUM_FRAMESIZES`.
224
225 other fields
226 follow standard semantics.
227
228 * Setting the ``OUTPUT`` format will reset the selection rectangles to their
229 default values, based on the new resolution, as described in the next
230 step.
231
232 4. Set the raw frame interval on the ``OUTPUT`` queue via
233 :c:func:`VIDIOC_S_PARM`. This also sets the coded frame interval on the
234 ``CAPTURE`` queue to the same value.
235
236 * **Required fields:**
237
238 ``type``
239 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
240
241 ``parm.output``
242 set all fields except ``parm.output.timeperframe`` to 0.
243
244 ``parm.output.timeperframe``
245 the desired frame interval; the encoder may adjust it to
246 match hardware requirements.
247
248 * **Returned fields:**
249
250 ``parm.output.timeperframe``
251 the adjusted frame interval.
252
253 .. important::
254
255 Changing the ``OUTPUT`` frame interval *also* sets the framerate that
256 the encoder uses to encode the video. So setting the frame interval
257 to 1/24 (or 24 frames per second) will produce a coded video stream
258 that can be played back at that speed. The frame interval for the
259 ``OUTPUT`` queue is just a hint, the application may provide raw
260 frames at a different rate. It can be used by the driver to help
261 schedule multiple encoders running in parallel.
262
263 In the next step the ``CAPTURE`` frame interval can optionally be
264 changed to a different value. This is useful for off-line encoding
265 were the coded frame interval can be different from the rate at
266 which raw frames are supplied.
267
268 .. important::
269
270 ``timeperframe`` deals with *frames*, not fields. So for interlaced
271 formats this is the time per two fields, since a frame consists of
272 a top and a bottom field.
273
274 .. note::
275
276 It is due to historical reasons that changing the ``OUTPUT`` frame
277 interval also changes the coded frame interval on the ``CAPTURE``
278 queue. Ideally these would be independent settings, but that would
279 break the existing API.
280
281 5. **Optional** Set the coded frame interval on the ``CAPTURE`` queue via
282 :c:func:`VIDIOC_S_PARM`. This is only necessary if the coded frame
283 interval is different from the raw frame interval, which is typically
284 the case for off-line encoding. Support for this feature is signalled
285 by the :ref:`V4L2_FMT_FLAG_ENC_CAP_FRAME_INTERVAL <fmtdesc-flags>` format flag.
286
287 * **Required fields:**
288
289 ``type``
290 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
291
292 ``parm.capture``
293 set all fields except ``parm.capture.timeperframe`` to 0.
294
295 ``parm.capture.timeperframe``
296 the desired coded frame interval; the encoder may adjust it to
297 match hardware requirements.
298
299 * **Returned fields:**
300
301 ``parm.capture.timeperframe``
302 the adjusted frame interval.
303
304 .. important::
305
306 Changing the ``CAPTURE`` frame interval sets the framerate for the
307 coded video. It does *not* set the rate at which buffers arrive on the
308 ``CAPTURE`` queue, that depends on how fast the encoder is and how
309 fast raw frames are queued on the ``OUTPUT`` queue.
310
311 .. important::
312
313 ``timeperframe`` deals with *frames*, not fields. So for interlaced
314 formats this is the time per two fields, since a frame consists of
315 a top and a bottom field.
316
317 .. note::
318
319 Not all drivers support this functionality, in that case just set
320 the desired coded frame interval for the ``OUTPUT`` queue.
321
322 However, drivers that can schedule multiple encoders based on the
323 ``OUTPUT`` frame interval must support this optional feature.
324
325 6. **Optional.** Set the visible resolution for the stream metadata via
326 :c:func:`VIDIOC_S_SELECTION` on the ``OUTPUT`` queue if it is desired
327 to be different than the full OUTPUT resolution.
328
329 * **Required fields:**
330
331 ``type``
332 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
333
334 ``target``
335 set to ``V4L2_SEL_TGT_CROP``.
336
337 ``r.left``, ``r.top``, ``r.width``, ``r.height``
338 visible rectangle; this must fit within the `V4L2_SEL_TGT_CROP_BOUNDS`
339 rectangle and may be subject to adjustment to match codec and
340 hardware constraints.
341
342 * **Returned fields:**
343
344 ``r.left``, ``r.top``, ``r.width``, ``r.height``
345 visible rectangle adjusted by the encoder.
346
347 * The following selection targets are supported on ``OUTPUT``:
348
349 ``V4L2_SEL_TGT_CROP_BOUNDS``
350 equal to the full source frame, matching the active ``OUTPUT``
351 format.
352
353 ``V4L2_SEL_TGT_CROP_DEFAULT``
354 equal to ``V4L2_SEL_TGT_CROP_BOUNDS``.
355
356 ``V4L2_SEL_TGT_CROP``
357 rectangle within the source buffer to be encoded into the
358 ``CAPTURE`` stream; defaults to ``V4L2_SEL_TGT_CROP_DEFAULT``.
359
360 .. note::
361
362 A common use case for this selection target is encoding a source
363 video with a resolution that is not a multiple of a macroblock,
364 e.g. the common 1920x1080 resolution may require the source
365 buffers to be aligned to 1920x1088 for codecs with 16x16 macroblock
366 size. To avoid encoding the padding, the client needs to explicitly
367 configure this selection target to 1920x1080.
368
369 .. warning::
370
371 The encoder may adjust the crop/compose rectangles to the nearest
372 supported ones to meet codec and hardware requirements. The client needs
373 to check the adjusted rectangle returned by :c:func:`VIDIOC_S_SELECTION`.
374
375 7. Allocate buffers for both ``OUTPUT`` and ``CAPTURE`` via
376 :c:func:`VIDIOC_REQBUFS`. This may be performed in any order.
377
378 * **Required fields:**
379
380 ``count``
381 requested number of buffers to allocate; greater than zero.
382
383 ``type``
384 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT`` or
385 ``CAPTURE``.
386
387 other fields
388 follow standard semantics.
389
390 * **Returned fields:**
391
392 ``count``
393 actual number of buffers allocated.
394
395 .. warning::
396
397 The actual number of allocated buffers may differ from the ``count``
398 given. The client must check the updated value of ``count`` after the
399 call returns.
400
401 .. note::
402
403 To allocate more than the minimum number of OUTPUT buffers (for pipeline
404 depth), the client may query the ``V4L2_CID_MIN_BUFFERS_FOR_OUTPUT``
405 control to get the minimum number of buffers required, and pass the
406 obtained value plus the number of additional buffers needed in the
407 ``count`` field to :c:func:`VIDIOC_REQBUFS`.
408
409 Alternatively, :c:func:`VIDIOC_CREATE_BUFS` can be used to have more
410 control over buffer allocation.
411
412 * **Required fields:**
413
414 ``count``
415 requested number of buffers to allocate; greater than zero.
416
417 ``type``
418 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
419
420 other fields
421 follow standard semantics.
422
423 * **Returned fields:**
424
425 ``count``
426 adjusted to the number of allocated buffers.
427
428 8. Begin streaming on both ``OUTPUT`` and ``CAPTURE`` queues via
429 :c:func:`VIDIOC_STREAMON`. This may be performed in any order. The actual
430 encoding process starts when both queues start streaming.
431
432 .. note::
433
434 If the client stops the ``CAPTURE`` queue during the encode process and then
435 restarts it again, the encoder will begin generating a stream independent
436 from the stream generated before the stop. The exact constraints depend
437 on the coded format, but may include the following implications:
438
439 * encoded frames produced after the restart must not reference any
440 frames produced before the stop, e.g. no long term references for
441 H.264/HEVC,
442
443 * any headers that must be included in a standalone stream must be
444 produced again, e.g. SPS and PPS for H.264/HEVC.
445
446 Encoding
447 ========
448
449 This state is reached after the `Initialization` sequence finishes
450 successfully. In this state, the client queues and dequeues buffers to both
451 queues via :c:func:`VIDIOC_QBUF` and :c:func:`VIDIOC_DQBUF`, following the
452 standard semantics.
453
454 The content of encoded ``CAPTURE`` buffers depends on the active coded pixel
455 format and may be affected by codec-specific extended controls, as stated
456 in the documentation of each format.
457
458 Both queues operate independently, following standard behavior of V4L2 buffer
459 queues and memory-to-memory devices. In addition, the order of encoded frames
460 dequeued from the ``CAPTURE`` queue may differ from the order of queuing raw
461 frames to the ``OUTPUT`` queue, due to properties of the selected coded format,
462 e.g. frame reordering.
463
464 The client must not assume any direct relationship between ``CAPTURE`` and
465 ``OUTPUT`` buffers and any specific timing of buffers becoming
466 available to dequeue. Specifically:
467
468 * a buffer queued to ``OUTPUT`` may result in more than one buffer produced on
469 ``CAPTURE`` (for example, if returning an encoded frame allowed the encoder
470 to return a frame that preceded it in display, but succeeded it in the decode
471 order; however, there may be other reasons for this as well),
472
473 * a buffer queued to ``OUTPUT`` may result in a buffer being produced on
474 ``CAPTURE`` later into encode process, and/or after processing further
475 ``OUTPUT`` buffers, or be returned out of order, e.g. if display
476 reordering is used,
477
478 * buffers may become available on the ``CAPTURE`` queue without additional
479 buffers queued to ``OUTPUT`` (e.g. during drain or ``EOS``), because of the
480 ``OUTPUT`` buffers queued in the past whose encoding results are only
481 available at later time, due to specifics of the encoding process,
482
483 * buffers queued to ``OUTPUT`` may not become available to dequeue instantly
484 after being encoded into a corresponding ``CAPTURE`` buffer, e.g. if the
485 encoder needs to use the frame as a reference for encoding further frames.
486
487 .. note::
488
489 To allow matching encoded ``CAPTURE`` buffers with ``OUTPUT`` buffers they
490 originated from, the client can set the ``timestamp`` field of the
491 :c:type:`v4l2_buffer` struct when queuing an ``OUTPUT`` buffer. The
492 ``CAPTURE`` buffer(s), which resulted from encoding that ``OUTPUT`` buffer
493 will have their ``timestamp`` field set to the same value when dequeued.
494
495 In addition to the straightforward case of one ``OUTPUT`` buffer producing
496 one ``CAPTURE`` buffer, the following cases are defined:
497
498 * one ``OUTPUT`` buffer generates multiple ``CAPTURE`` buffers: the same
499 ``OUTPUT`` timestamp will be copied to multiple ``CAPTURE`` buffers,
500
501 * the encoding order differs from the presentation order (i.e. the
502 ``CAPTURE`` buffers are out-of-order compared to the ``OUTPUT`` buffers):
503 ``CAPTURE`` timestamps will not retain the order of ``OUTPUT`` timestamps.
504
505 .. note::
506
507 To let the client distinguish between frame types (keyframes, intermediate
508 frames; the exact list of types depends on the coded format), the
509 ``CAPTURE`` buffers will have corresponding flag bits set in their
510 :c:type:`v4l2_buffer` struct when dequeued. See the documentation of
511 :c:type:`v4l2_buffer` and each coded pixel format for exact list of flags
512 and their meanings.
513
514 Should an encoding error occur, it will be reported to the client with the level
515 of details depending on the encoder capabilities. Specifically:
516
517 * the ``CAPTURE`` buffer (if any) that contains the results of the failed encode
518 operation will be returned with the ``V4L2_BUF_FLAG_ERROR`` flag set,
519
520 * if the encoder is able to precisely report the ``OUTPUT`` buffer(s) that triggered
521 the error, such buffer(s) will be returned with the ``V4L2_BUF_FLAG_ERROR`` flag
522 set.
523
524 .. note::
525
526 If a ``CAPTURE`` buffer is too small then it is just returned with the
527 ``V4L2_BUF_FLAG_ERROR`` flag set. More work is needed to detect that this
528 error occurred because the buffer was too small, and to provide support to
529 free existing buffers that were too small.
530
531 In case of a fatal failure that does not allow the encoding to continue, any
532 further operations on corresponding encoder file handle will return the -EIO
533 error code. The client may close the file handle and open a new one, or
534 alternatively reinitialize the instance by stopping streaming on both queues,
535 releasing all buffers and performing the Initialization sequence again.
536
537 Encoding Parameter Changes
538 ==========================
539
540 The client is allowed to use :c:func:`VIDIOC_S_CTRL` to change encoder
541 parameters at any time. The availability of parameters is encoder-specific
542 and the client must query the encoder to find the set of available controls.
543
544 The ability to change each parameter during encoding is encoder-specific, as
545 per the standard semantics of the V4L2 control interface. The client may
546 attempt to set a control during encoding and if the operation fails with the
547 -EBUSY error code, the ``CAPTURE`` queue needs to be stopped for the
548 configuration change to be allowed. To do this, it may follow the `Drain`
549 sequence to avoid losing the already queued/encoded frames.
550
551 The timing of parameter updates is encoder-specific, as per the standard
552 semantics of the V4L2 control interface. If the client needs to apply the
553 parameters exactly at specific frame, using the Request API
554 (:ref:`media-request-api`) should be considered, if supported by the encoder.
555
556 Drain
557 =====
558
559 To ensure that all the queued ``OUTPUT`` buffers have been processed and the
560 related ``CAPTURE`` buffers are given to the client, the client must follow the
561 drain sequence described below. After the drain sequence ends, the client has
562 received all encoded frames for all ``OUTPUT`` buffers queued before the
563 sequence was started.
564
565 1. Begin the drain sequence by issuing :c:func:`VIDIOC_ENCODER_CMD`.
566
567 * **Required fields:**
568
569 ``cmd``
570 set to ``V4L2_ENC_CMD_STOP``.
571
572 ``flags``
573 set to 0.
574
575 ``pts``
576 set to 0.
577
578 .. warning::
579
580 The sequence can be only initiated if both ``OUTPUT`` and ``CAPTURE``
581 queues are streaming. For compatibility reasons, the call to
582 :c:func:`VIDIOC_ENCODER_CMD` will not fail even if any of the queues is
583 not streaming, but at the same time it will not initiate the `Drain`
584 sequence and so the steps described below would not be applicable.
585
586 2. Any ``OUTPUT`` buffers queued by the client before the
587 :c:func:`VIDIOC_ENCODER_CMD` was issued will be processed and encoded as
588 normal. The client must continue to handle both queues independently,
589 similarly to normal encode operation. This includes:
590
591 * queuing and dequeuing ``CAPTURE`` buffers, until a buffer marked with the
592 ``V4L2_BUF_FLAG_LAST`` flag is dequeued,
593
594 .. warning::
595
596 The last buffer may be empty (with :c:type:`v4l2_buffer`
597 ``bytesused`` = 0) and in that case it must be ignored by the client,
598 as it does not contain an encoded frame.
599
600 .. note::
601
602 Any attempt to dequeue more ``CAPTURE`` buffers beyond the buffer
603 marked with ``V4L2_BUF_FLAG_LAST`` will result in a -EPIPE error from
604 :c:func:`VIDIOC_DQBUF`.
605
606 * dequeuing processed ``OUTPUT`` buffers, until all the buffers queued
607 before the ``V4L2_ENC_CMD_STOP`` command are dequeued,
608
609 * dequeuing the ``V4L2_EVENT_EOS`` event, if the client subscribes to it.
610
611 .. note::
612
613 For backwards compatibility, the encoder will signal a ``V4L2_EVENT_EOS``
614 event when the last frame has been encoded and all frames are ready to be
615 dequeued. It is deprecated behavior and the client must not rely on it.
616 The ``V4L2_BUF_FLAG_LAST`` buffer flag should be used instead.
617
618 3. Once all ``OUTPUT`` buffers queued before the ``V4L2_ENC_CMD_STOP`` call are
619 dequeued and the last ``CAPTURE`` buffer is dequeued, the encoder is stopped
620 and it will accept, but not process any newly queued ``OUTPUT`` buffers
621 until the client issues any of the following operations:
622
623 * ``V4L2_ENC_CMD_START`` - the encoder will not be reset and will resume
624 operation normally, with all the state from before the drain,
625
626 * a pair of :c:func:`VIDIOC_STREAMOFF` and :c:func:`VIDIOC_STREAMON` on the
627 ``CAPTURE`` queue - the encoder will be reset (see the `Reset` sequence)
628 and then resume encoding,
629
630 * a pair of :c:func:`VIDIOC_STREAMOFF` and :c:func:`VIDIOC_STREAMON` on the
631 ``OUTPUT`` queue - the encoder will resume operation normally, however any
632 source frames queued to the ``OUTPUT`` queue between ``V4L2_ENC_CMD_STOP``
633 and :c:func:`VIDIOC_STREAMOFF` will be discarded.
634
635 .. note::
636
637 Once the drain sequence is initiated, the client needs to drive it to
638 completion, as described by the steps above, unless it aborts the process by
639 issuing :c:func:`VIDIOC_STREAMOFF` on any of the ``OUTPUT`` or ``CAPTURE``
640 queues. The client is not allowed to issue ``V4L2_ENC_CMD_START`` or
641 ``V4L2_ENC_CMD_STOP`` again while the drain sequence is in progress and they
642 will fail with -EBUSY error code if attempted.
643
644 For reference, handling of various corner cases is described below:
645
646 * In case of no buffer in the ``OUTPUT`` queue at the time the
647 ``V4L2_ENC_CMD_STOP`` command was issued, the drain sequence completes
648 immediately and the encoder returns an empty ``CAPTURE`` buffer with the
649 ``V4L2_BUF_FLAG_LAST`` flag set.
650
651 * In case of no buffer in the ``CAPTURE`` queue at the time the drain
652 sequence completes, the next time the client queues a ``CAPTURE`` buffer
653 it is returned at once as an empty buffer with the ``V4L2_BUF_FLAG_LAST``
654 flag set.
655
656 * If :c:func:`VIDIOC_STREAMOFF` is called on the ``CAPTURE`` queue in the
657 middle of the drain sequence, the drain sequence is canceled and all
658 ``CAPTURE`` buffers are implicitly returned to the client.
659
660 * If :c:func:`VIDIOC_STREAMOFF` is called on the ``OUTPUT`` queue in the
661 middle of the drain sequence, the drain sequence completes immediately and
662 next ``CAPTURE`` buffer will be returned empty with the
663 ``V4L2_BUF_FLAG_LAST`` flag set.
664
665 Although not mandatory, the availability of encoder commands may be queried
666 using :c:func:`VIDIOC_TRY_ENCODER_CMD`.
667
668 Reset
669 =====
670
671 The client may want to request the encoder to reinitialize the encoding, so
672 that the following stream data becomes independent from the stream data
673 generated before. Depending on the coded format, that may imply that:
674
675 * encoded frames produced after the restart must not reference any frames
676 produced before the stop, e.g. no long term references for H.264/HEVC,
677
678 * any headers that must be included in a standalone stream must be produced
679 again, e.g. SPS and PPS for H.264/HEVC.
680
681 This can be achieved by performing the reset sequence.
682
683 1. Perform the `Drain` sequence to ensure all the in-flight encoding finishes
684 and respective buffers are dequeued.
685
686 2. Stop streaming on the ``CAPTURE`` queue via :c:func:`VIDIOC_STREAMOFF`. This
687 will return all currently queued ``CAPTURE`` buffers to the client, without
688 valid frame data.
689
690 3. Start streaming on the ``CAPTURE`` queue via :c:func:`VIDIOC_STREAMON` and
691 continue with regular encoding sequence. The encoded frames produced into
692 ``CAPTURE`` buffers from now on will contain a standalone stream that can be
693 decoded without the need for frames encoded before the reset sequence,
694 starting at the first ``OUTPUT`` buffer queued after issuing the
695 `V4L2_ENC_CMD_STOP` of the `Drain` sequence.
696
697 This sequence may be also used to change encoding parameters for encoders
698 without the ability to change the parameters on the fly.
699
700 Commit Points
701 =============
702
703 Setting formats and allocating buffers triggers changes in the behavior of the
704 encoder.
705
706 1. Setting the format on the ``CAPTURE`` queue may change the set of formats
707 supported/advertised on the ``OUTPUT`` queue. In particular, it also means
708 that the ``OUTPUT`` format may be reset and the client must not rely on the
709 previously set format being preserved.
710
711 2. Enumerating formats on the ``OUTPUT`` queue always returns only formats
712 supported for the current ``CAPTURE`` format.
713
714 3. Setting the format on the ``OUTPUT`` queue does not change the list of
715 formats available on the ``CAPTURE`` queue. An attempt to set the ``OUTPUT``
716 format that is not supported for the currently selected ``CAPTURE`` format
717 will result in the encoder adjusting the requested ``OUTPUT`` format to a
718 supported one.
719
720 4. Enumerating formats on the ``CAPTURE`` queue always returns the full set of
721 supported coded formats, irrespective of the current ``OUTPUT`` format.
722
723 5. While buffers are allocated on any of the ``OUTPUT`` or ``CAPTURE`` queues,
724 the client must not change the format on the ``CAPTURE`` queue. Drivers will
725 return the -EBUSY error code for any such format change attempt.
726
727 To summarize, setting formats and allocation must always start with the
728 ``CAPTURE`` queue and the ``CAPTURE`` queue is the master that governs the
729 set of supported formats for the ``OUTPUT`` queue.
730

3. 한국어 전문 번역

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

상태 유지형 encoder와 문서 규칙

1-43

상태 유지형 비디오 encoder는 display order의 raw video frame을 받아 bytestream으로 encode합니다. metadata와 header를 포함한 완전한 bytestream chunk를 생성하므로 결과 stream에 client의 추가 후처리가 필요하지 않습니다.

이 인터페이스를 지원하려고 드라이버에서 software stream 처리나 header 생성을 수행하는 것은 강하게 권장되지 않습니다. 이런 작업이 필요하다면 개발 중인 Stateless Video Encoder Interface를 사용하는 것이 바람직합니다.

별도 규정이 없으면 일반 V4L2 API 규칙을 적용하고 must·may·should 등은 RFC 2119 의미를 따릅니다. optional 표시가 없는 모든 단계는 필수입니다.

별도 규정이 없으면 `VIDIOC_G_EXT_CTRLS`와 `VIDIOC_S_EXT_CTRLS`는 각각 `VIDIOC_G_CTRL`과 `VIDIOC_S_CTRL` 대신 사용할 수 있고 그 반대도 가능합니다.

Encoder 문서 표기
항목설명
single-planar / multi-planarencoder capability와 일반 지침에 따라 상호 교환 가능
i = [a..b]a부터 b까지 양 끝을 포함하는 정수열
OUTPUT Aclient가 공급하는 raw source frame buffer
CAPTURE A'OUTPUT A를 encode해 생긴 coded data buffer
필수 단계optional 표시가 없는 모든 단계

planar API와 buffer 대응을 포함한 공통 표기 규칙입니다.

.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later

.. _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와 encoder 상태 기계

44-83

encoder의 용어 정의는 `decoder-glossary`를 참조합니다. encoder에서는 `OUTPUT`이 raw source frame queue이고 `CAPTURE`가 encoded bytestream destination queue라는 점이 핵심입니다.

원문의 DOT 상태 기계는 Initialization, Encoding, Drain, Stopped, Reset으로 구성됩니다. 두 queue가 모두 streaming일 때 encode가 시작되고, 어느 queue를 STREAMOFF하는지에 따라 Stopped와 Reset이 갈립니다.

Encoder 주요 생명주기
open() -> Initialization두 queue streaming -> EncodingENC_CMD_STOP -> Drain모든 CAPTURE dequeue -> StoppedCAPTURE STREAMOFF -> ResetCAPTURE STREAMON -> EncodingENC_CMD_START 또는 OUTPUT STREAMON -> Encoding

초기화, 정상 encode, drain과 독립 stream reset의 흐름입니다.

Encoder 상태 전이
항목설명
Initialization -> EncodingOUTPUT과 CAPTURE 모두 streaming
Encoding -> DrainV4L2_ENC_CMD_STOP
Encoding -> ResetVIDIOC_STREAMOFF(CAPTURE)
Encoding -> StoppedVIDIOC_STREAMOFF(OUTPUT)
Drain -> Stopped모든 CAPTURE dequeue 또는 OUTPUT STREAMOFF
Drain -> ResetCAPTURE STREAMOFF
Reset -> EncodingCAPTURE STREAMON
Reset -> InitializationREQBUFS(OUTPUT, 0)
Stopped -> EncodingENC_CMD_START 또는 OUTPUT STREAMON
Stopped -> ResetCAPTURE STREAMOFF

DOT graph의 사건별 출발 상태와 도착 상태입니다.

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)" ];
   }

지원 format, 해상도와 frame interval 조회

84-142

encoder가 지원하는 coded format 전체는 `CAPTURE`에서 `VIDIOC_ENUM_FMT`를 호출해 열거합니다. 현재 `OUTPUT` format과 관계없이 지원 coded format 전체를 반환합니다.

지원 raw format은 `OUTPUT`의 `VIDIOC_ENUM_FMT`로 열거하며 현재 `CAPTURE`에 활성화된 coded format과 호환되는 항목만 반환합니다. 특정 coded format의 raw format을 확인하려면 먼저 CAPTURE에 coded format을 설정해야 합니다.

`VIDIOC_ENUM_FRAMESIZES`에 원하는 `struct v4l2_frmsizeenum.pixel_format`을 전달하면 해상도를 조회할 수 있습니다. coded pixel format에는 가능한 coded resolution 전체가, raw pixel format에는 현재 CAPTURE coded format과 조합할 수 있는 frame buffer resolution 전체가 포함됩니다.

`VIDIOC_ENUM_FRAMEINTERVALS`에는 `struct v4l2_frmivalenum`의 `pixel_format`, `width`, `height`를 전달합니다. coded format과 resolution에는 encoder가 지원하는 coded frame interval 전체가, raw format과 resolution에는 현재 CAPTURE의 coded format·resolution·frame interval과 함께 사용할 수 있는 interval이 반환됩니다.

FRAMEINTERVALS 구현은 선택 사항입니다. 구현하지 않았다면 codec 자체 한계 외의 특별한 interval 제한은 없습니다. 현재 CAPTURE coded format의 profile과 level은 각각의 control을 `VIDIOC_QUERYCTRL`로 조회하며, 추가 encoder capability도 해당 control을 조회해 발견합니다.

Encoder capability 조회 방향
항목설명
ENUM_FMT on CAPTUREOUTPUT과 무관한 전체 coded format
ENUM_FMT on OUTPUT현재 CAPTURE coded format이 지원하는 raw format
ENUM_FRAMESIZES coded해당 coded format의 모든 coded resolution
ENUM_FRAMESIZES raw현재 CAPTURE coded format과 조합 가능한 raw resolution
ENUM_FRAMEINTERVALSformat과 resolution별 지원 frame interval, 선택적 구현
QUERYCTRLprofile, level과 추가 encoder capability

CAPTURE가 coded master이고 OUTPUT이 raw source입니다.

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.

CAPTURE coded format과 OUTPUT raw format

143-230

초기화는 `CAPTURE` queue의 `VIDIOC_S_FMT`로 생성할 coded format을 설정하는 것부터 시작합니다. 필수 입력은 CAPTURE용 `type`, coded `pixelformat`, 원하는 CAPTURE buffer 크기 `sizeimage`입니다. 입력 width와 height는 무시되는 read-only 필드이고 나머지는 표준 의미를 따릅니다.

encoder는 하드웨어 요구에 맞춘 `sizeimage`와 현재 OUTPUT format, selection rectangle 등 상태를 바탕으로 선택한 coded `width`와 `height`를 반환합니다. CAPTURE format을 바꾸면 현재 OUTPUT format도 바뀔 수 있으므로 client는 결과가 요구에 맞는지 다시 확인해야 합니다.

선택적으로 `OUTPUT`의 `VIDIOC_ENUM_FMT`를 사용해 선택한 CAPTURE coded format이 지원하는 raw source format을 열거할 수 있습니다. 입력은 OUTPUT용 type이고 반환 `pixelformat`이 현재 coded format과 호환되는 raw format입니다.

그 다음 `VIDIOC_S_FMT(OUTPUT)`으로 raw source format을 설정합니다. 필수 입력은 OUTPUT용 type, source raw pixelformat, source resolution인 width와 height입니다. encoder는 현재 format 조합의 최소·최대·정렬 조건에 맞춰 width와 height를 조정할 수 있으며 이 범위는 `VIDIOC_ENUM_FRAMESIZES`로 보고됩니다.

OUTPUT format을 설정하면 새 resolution을 기준으로 selection rectangle이 다음 단계에서 설명하는 기본값으로 초기화됩니다.

초기 format 필드
항목설명
CAPTURE.typeCAPTURE용 V4L2_BUF_TYPE_*
CAPTURE.pixelformat생성할 coded format
CAPTURE.sizeimage원하는 coded buffer 크기, encoder가 조정 가능
CAPTURE.width/height 입력무시되는 read-only 필드
CAPTURE.width/height 반환현재 상태를 바탕으로 선택한 coded size
OUTPUT.pixelformatraw source format
OUTPUT.width/heightsource resolution, 하드웨어 제약에 따라 조정 가능

coded destination과 raw source queue의 S_FMT 역할입니다.

Encoder format 협상
S_FMT(CAPTURE)로 coded format 설정반환된 sizeimage와 coded size 확인선택적으로 ENUM_FMT(OUTPUT)으로 raw format 열거S_FMT(OUTPUT)으로 raw source format과 resolution 설정조정된 OUTPUT resolution 확인

master CAPTURE coded format을 먼저 선택합니다.

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.

raw와 coded frame interval

231-324

`VIDIOC_S_PARM(OUTPUT)`으로 raw frame interval을 설정합니다. OUTPUT용 `type`을 지정하고 `parm.output.timeperframe`을 제외한 `parm.output` 필드는 0으로 만들며, 원하는 timeperframe을 전달합니다. encoder는 하드웨어 요구에 맞춰 조정된 값을 반환합니다.

역사적 API 동작 때문에 OUTPUT frame interval을 바꾸면 CAPTURE의 coded frame interval도 같은 값으로 설정됩니다. 예를 들어 1/24를 주면 초당 24 frame으로 재생할 coded stream을 만듭니다. OUTPUT interval은 raw frame 공급률에 대한 hint이므로 애플리케이션은 다른 속도로 frame을 공급할 수 있고, driver는 병렬 encoder scheduling에 이 값을 사용할 수 있습니다.

offline encoding처럼 raw 공급률과 coded 재생률이 다르면 다음 단계에서 CAPTURE interval을 별도로 바꿀 수 있습니다. `timeperframe`은 field가 아니라 frame 기준이므로 interlaced format에서는 top과 bottom 두 field를 합친 한 frame의 시간입니다.

선택적인 `VIDIOC_S_PARM(CAPTURE)`는 `V4L2_FMT_FLAG_ENC_CAP_FRAME_INTERVAL`이 광고될 때 사용할 수 있습니다. CAPTURE용 type과 `parm.capture.timeperframe`만 설정하고 다른 parm.capture 필드는 0으로 만들며, 조정된 coded interval을 반환받습니다.

CAPTURE interval은 coded video의 framerate를 정하지만 CAPTURE buffer 도착 속도를 정하지는 않습니다. 실제 도착 속도는 encoder 성능과 OUTPUT raw frame queue 속도에 달려 있습니다. 이 기능을 지원하지 않는 driver는 원하는 coded interval을 OUTPUT에 설정하면 됩니다. 다만 OUTPUT interval로 여러 encoder를 scheduling할 수 있는 driver는 별도 CAPTURE interval 기능을 지원해야 합니다.

Frame interval 설정
항목설명
S_PARM(OUTPUT)raw frame interval hint를 설정하고 기본적으로 coded interval도 동일하게 변경
parm.output.timeperframe원하는 raw frame interval, 조정값 반환
S_PARM(CAPTURE)offline encoding 등에 쓰는 선택적 coded frame interval
V4L2_FMT_FLAG_ENC_CAP_FRAME_INTERVAL독립 CAPTURE interval 지원 표시
parm.capture.timeperframecoded video 재생률, buffer 도착률과는 다름
Interlacedtimeperframe은 두 field로 구성된 한 frame의 시간

raw 공급 hint와 coded 재생률의 관계입니다.

Frame interval 결정
S_PARM(OUTPUT)으로 raw interval 설정같은 값이 CAPTURE coded interval에 반영실시간 encode이면 그대로 사용offline encode이고 flag 지원 시 S_PARM(CAPTURE)반환된 조정 interval 확인

일반 실시간 encode와 offline encode를 구분합니다.


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.

visible resolution과 crop

325-374

visible resolution이 전체 OUTPUT resolution과 달라야 한다면 선택적으로 `VIDIOC_S_SELECTION(OUTPUT)`을 사용합니다. OUTPUT용 type, `target = V4L2_SEL_TGT_CROP`, 원하는 `r.left`, `r.top`, `r.width`, `r.height`를 전달합니다.

visible rectangle은 `V4L2_SEL_TGT_CROP_BOUNDS` 안에 들어가야 하며 codec과 하드웨어 제약에 따라 조정될 수 있습니다. encoder가 반환한 rectangle을 client가 반드시 확인해야 합니다.

OUTPUT selection target
항목설명
V4L2_SEL_TGT_CROP_BOUNDS활성 OUTPUT format과 일치하는 전체 source frame
V4L2_SEL_TGT_CROP_DEFAULTCROP_BOUNDS와 동일한 기본 영역
V4L2_SEL_TGT_CROPCAPTURE stream으로 encode할 source buffer 내부 rectangle

raw source buffer 중 encode할 visible 영역을 정의합니다.

대표적인 용도는 source resolution이 macroblock 배수가 아닐 때 padding을 제외하는 것입니다. 16x16 macroblock codec에서 일반적인 1920x1080 영상은 source buffer를 1920x1088로 정렬해야 할 수 있으므로, client가 CROP target을 1920x1080으로 명시해 아래 8줄의 padding이 encode되지 않게 합니다.

정렬된 source의 visible crop
OUTPUT format 1920x1088CROP_BOUNDS 1920x1088S_SELECTION CROP 1920x1080 요청encoder의 조정 rectangle 확인CAPTURE stream에는 visible 1920x1080만 encode

frame buffer 정렬과 실제 영상 크기를 분리합니다.

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`.

Buffer 할당과 streaming 시작

375-445

`VIDIOC_REQBUFS`로 OUTPUT과 CAPTURE 양쪽 buffer를 할당하며 순서는 상관없습니다. 요청 `count`는 0보다 커야 하고 `type`은 해당 queue에 맞아야 하며 나머지는 표준 의미를 따릅니다. 실제 할당 수는 요청과 다를 수 있으므로 반환 count를 확인합니다.

pipeline depth를 위해 최소 수보다 많은 OUTPUT buffer를 원하면 `V4L2_CID_MIN_BUFFERS_FOR_OUTPUT` control로 최소 수를 조회하고 필요한 추가 수를 더해 REQBUFS count로 전달합니다.

더 세밀한 할당에는 `VIDIOC_CREATE_BUFS`를 사용할 수 있습니다. 원문이 명시한 필수 입력은 0보다 큰 count, OUTPUT용 type, 그 밖의 표준 필드이며 조정된 실제 count를 반환합니다.

두 queue 모두에 `VIDIOC_STREAMON`을 호출하며 순서는 상관없습니다. 실제 encode는 OUTPUT과 CAPTURE가 모두 streaming을 시작했을 때 진행됩니다.

encode 중 CAPTURE를 멈췄다가 다시 시작하면 이전 stream과 독립된 새 stream을 생성해야 합니다. coded format별 세부 조건은 다르지만 H.264/HEVC의 long-term reference처럼 정지 전 frame을 참조해서는 안 되고, 독립 stream에 필요한 SPS와 PPS 같은 header를 다시 생성해야 합니다.

Buffer와 streaming 준비
항목설명
REQBUFSOUTPUT/CAPTURE 어느 순서로든 count > 0 할당
반환 count요청과 다를 수 있으므로 확인
V4L2_CID_MIN_BUFFERS_FOR_OUTPUTencode에 필요한 최소 OUTPUT buffer 수
CREATE_BUFS더 세밀한 OUTPUT buffer 할당
STREAMON두 queue 모두 시작되어야 실제 encoding 시작

두 queue의 할당 및 시작 규칙입니다.

CAPTURE 재시작의 독립 stream
STREAMOFF(CAPTURE)정지 전 reference 관계 종료STREAMON(CAPTURE)SPS/PPS 등 standalone header 재생성정지 전 frame을 참조하지 않는 encoded frame 생성

중단 전 stream에 의존하지 않는 새 coded stream을 만듭니다.

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 queue와 오류 처리

446-536

Initialization을 성공적으로 마치면 Encoding 상태에 도달합니다. client는 표준 의미에 따라 `VIDIOC_QBUF`와 `VIDIOC_DQBUF`로 두 queue의 buffer를 넣고 빼며, encoded CAPTURE 내용은 coded pixel format과 codec별 extended control의 영향을 받습니다.

두 queue는 독립적이고 frame reordering 때문에 CAPTURE의 encoded frame 순서가 OUTPUT raw frame queue 순서와 다를 수 있습니다. client는 queue 사이의 직접적인 1:1 관계나 특정 dequeue 시점을 가정해서는 안 됩니다.

OUTPUT과 CAPTURE의 비동기 관계
항목설명
1 OUTPUT -> 여러 CAPTUREdecode order상 앞선 frame까지 반환 가능
지연 또는 순서 변경후속 OUTPUT 처리 뒤 CAPTURE 생성 또는 display reorder
추가 OUTPUT 없이 CAPTURE과거 source 결과가 drain/EOS 중 뒤늦게 준비
OUTPUT dequeue 지연후속 encode의 reference로 raw frame이 계속 필요

raw source와 coded 결과 사이에 허용되는 동작입니다.

origin을 맞추려면 OUTPUT을 queue할 때 `struct v4l2_buffer.timestamp`를 설정합니다. 해당 OUTPUT에서 나온 CAPTURE buffer는 dequeue할 때 같은 timestamp를 갖습니다. 하나의 OUTPUT이 여러 CAPTURE를 만들면 모두 같은 값이 복사되고, encode order와 presentation order가 다르면 CAPTURE timestamp 순서는 OUTPUT 순서를 보존하지 않습니다.

client가 keyframe과 intermediate frame 등 frame type을 구분할 수 있도록 CAPTURE의 `struct v4l2_buffer`에는 coded format에 맞는 flag bit가 설정됩니다. 정확한 종류와 의미는 v4l2_buffer 및 각 coded pixel format 문서를 따릅니다.

encode 오류가 나면 실패 결과를 담은 CAPTURE buffer가 있다면 `V4L2_BUF_FLAG_ERROR`로 반환됩니다. encoder가 오류를 유발한 OUTPUT buffer를 정확히 식별할 수 있으면 그 buffer에도 같은 flag를 설정합니다. CAPTURE buffer가 너무 작아도 ERROR flag만 설정해 반환되며, 작은 크기가 원인임을 별도로 감지하고 기존 buffer를 해제하는 지원은 아직 추가 작업이 필요합니다.

encode를 계속할 수 없는 치명적 failure 뒤에는 해당 file handle의 후속 작업이 `-EIO`를 반환합니다. handle을 닫고 다시 열거나, 두 queue를 정지하고 모든 buffer를 해제한 뒤 Initialization을 다시 수행해 instance를 재초기화할 수 있습니다.

Timestamp origin 추적
QBUF(OUTPUT)에 timestamp 설정encoder가 raw frame 처리결과 CAPTURE buffer에 timestamp 복사DQBUF(CAPTURE)에서 origin 확인

raw source와 encoded 결과의 비동기 대응을 기록합니다.

Encoding 오류 신호
항목설명
CAPTURE ERROR실패한 encode 결과 또는 너무 작은 coded buffer
OUTPUT ERRORencoder가 오류 유발 raw source를 식별
-EIO계속할 수 없는 failure, handle 재생성 또는 완전 재초기화

복구 가능한 buffer 오류와 치명적 instance 오류입니다.

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 변경

537-555

client는 언제든 `VIDIOC_S_CTRL`로 encoder parameter 변경을 시도할 수 있습니다. 제공되는 parameter 집합과 encode 중 변경 가능 여부는 encoder별로 다르므로 control을 조회해야 합니다.

encode 중 control 설정이 `-EBUSY`로 실패하면 configuration 변경을 허용하기 위해 CAPTURE queue를 정지해야 합니다. 이미 queue되거나 encode된 frame을 잃지 않으려면 먼저 Drain sequence를 수행할 수 있습니다.

parameter가 실제 적용되는 시점도 encoder별 V4L2 control 표준 의미를 따릅니다. 특정 frame에 정확히 적용해야 하고 encoder가 지원한다면 Request API를 고려해야 합니다.

Encoder parameter 변경
사용 가능한 control 조회VIDIOC_S_CTRL로 변경 시도성공하면 encoder가 정한 시점에 적용-EBUSY이면 Drain 후 CAPTURE 정지특정 frame 적용은 Request API 고려

on-the-fly 지원 여부와 정확한 적용 시점에 따른 선택입니다.

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과 정지 후 재개

556-667

Drain은 이미 queue한 모든 OUTPUT을 처리하고 관련 encoded CAPTURE를 전부 client에 전달하는 절차입니다. 완료되면 시작 전에 넣은 모든 raw frame의 encoded 결과를 받은 상태가 됩니다.

`VIDIOC_ENCODER_CMD`에 `cmd = V4L2_ENC_CMD_STOP`, `flags = 0`, `pts = 0`을 주어 시작합니다. OUTPUT과 CAPTURE가 모두 streaming일 때만 실제 drain이 시작됩니다. 호환성 때문에 queue가 정지 상태여도 ioctl 자체는 실패하지 않지만 이후 단계는 적용되지 않습니다.

STOP 전에 queue한 OUTPUT은 정상 encode하고 두 queue를 계속 독립 처리합니다. CAPTURE는 `V4L2_BUF_FLAG_LAST`가 붙은 buffer까지 queue/dequeue하고, `bytesused = 0`인 빈 LAST는 frame이 없으므로 무시합니다. LAST 뒤 DQBUF는 `-EPIPE`입니다.

STOP 전 OUTPUT도 모두 dequeue해야 합니다. 마지막 frame 준비 시 구형 호환성용 `V4L2_EVENT_EOS`가 발생할 수 있지만 deprecated이므로 의존하지 말고 LAST flag를 사용합니다.

기존 OUTPUT과 마지막 CAPTURE를 모두 dequeue하면 encoder는 멈추며 새 OUTPUT을 받아도 처리하지 않습니다. `V4L2_ENC_CMD_START`는 state를 보존해 정상 재개합니다. CAPTURE STREAMOFF/ON은 Reset 뒤 encode를 재개합니다. OUTPUT STREAMOFF/ON은 정상 재개하지만 STOP과 STREAMOFF 사이에 queue한 source frame을 버립니다.

drain을 시작하면 어느 queue든 STREAMOFF해 중단하지 않는 한 끝까지 수행해야 합니다. 진행 중 START나 STOP을 다시 호출하면 `-EBUSY`입니다. encoder command 지원 여부는 선택적으로 `VIDIOC_TRY_ENCODER_CMD`로 조회할 수 있습니다.

Drain 시작 필드
항목설명
cmdV4L2_ENC_CMD_STOP
flags0
pts0
전제OUTPUT과 CAPTURE 모두 streaming

V4L2_ENC_CMD_STOP 요청의 필수 값입니다.

Encoder Drain
ENCODER_CMD(STOP)기존 OUTPUT 정상 encodeCAPTURE LAST buffer dequeueSTOP 전 OUTPUT 모두 dequeuedeprecated EOS event는 보조 신호로만 처리encoder Stopped

STOP 이전 frame을 모두 encode하고 정지합니다.

Drain 뒤 재개
항목설명
V4L2_ENC_CMD_STARTencoder state를 유지하고 정상 재개
CAPTURE STREAMOFF/ONReset한 뒤 독립 stream으로 재개
OUTPUT STREAMOFF/ON정상 재개하되 STOP 뒤 queue한 source 폐기

선택한 동작에 따른 state와 buffer 처리 차이입니다.

Drain corner case
항목설명
STOP 시 OUTPUT 없음즉시 완료하고 빈 CAPTURE LAST 반환
완료 시 CAPTURE 없음다음 CAPTURE QBUF를 즉시 빈 LAST로 반환
중간 CAPTURE STREAMOFFdrain 취소, 모든 CAPTURE를 암묵적으로 반환
중간 OUTPUT STREAMOFFdrain 즉시 완료, 다음 CAPTURE를 빈 LAST로 반환

buffer 부재 또는 중간 STREAMOFF 때의 LAST 처리입니다.

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`.

독립 stream을 위한 Reset

668-699

client는 이후 coded data가 이전 stream과 독립적이 되도록 encoder 재초기화를 요청할 수 있습니다. format에 따라 재시작 뒤 frame은 정지 전 frame을 참조하지 않아야 하고, H.264/HEVC의 SPS와 PPS처럼 standalone stream에 필요한 header를 다시 만들어야 합니다.

먼저 Drain을 수행해 in-flight encoding을 끝내고 관련 buffer를 모두 dequeue합니다. 그 다음 `VIDIOC_STREAMOFF(CAPTURE)`로 streaming을 멈추면 현재 queue된 CAPTURE buffer가 유효 frame data 없이 client에 반환됩니다.

`VIDIOC_STREAMON(CAPTURE)`으로 다시 시작하면 Drain의 `V4L2_ENC_CMD_STOP` 뒤 처음 queue한 OUTPUT부터, reset 전 encoded frame 없이 decode할 수 있는 standalone stream이 CAPTURE에 생성됩니다.

on-the-fly parameter 변경을 지원하지 않는 encoder에서는 이 Reset sequence를 encoding parameter 변경에도 사용할 수 있습니다.

Reset sequence
Drain으로 in-flight frame 완료STREAMOFF(CAPTURE)queue된 CAPTURE buffer를 유효 data 없이 반환STREAMON(CAPTURE)새 header와 독립 reference chain 생성

정지 전 stream 의존성을 끊고 새 standalone stream을 시작합니다.

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.

CAPTURE master와 format commit point

700-729

format 설정과 buffer 할당은 encoder 동작을 바꾸는 commit point입니다. CAPTURE format을 설정하면 OUTPUT이 광고하는 raw format 집합과 현재 OUTPUT format이 바뀔 수 있으므로 이전 설정 보존을 기대해서는 안 됩니다.

OUTPUT ENUM_FMT는 항상 현재 CAPTURE coded format이 지원하는 raw format만 반환합니다. OUTPUT format 설정은 CAPTURE 목록을 바꾸지 않으며, 현재 CAPTURE와 호환되지 않는 OUTPUT format을 요청하면 encoder가 지원 format으로 조정합니다.

CAPTURE ENUM_FMT는 현재 OUTPUT과 관계없이 전체 coded format을 반환합니다. 어느 queue든 buffer가 할당된 동안 CAPTURE format을 바꿀 수 없으며 driver는 `-EBUSY`를 반환합니다. 따라서 format 설정과 할당은 언제나 master인 CAPTURE queue에서 시작해야 합니다.

Encoder format commit 규칙
항목설명
CAPTURE S_FMTOUTPUT 지원 목록과 현재 OUTPUT format을 바꿀 수 있음
OUTPUT ENUM_FMT현재 CAPTURE format이 지원하는 raw 항목만 반환
OUTPUT S_FMTCAPTURE 목록은 불변, 비호환 요청은 지원 format으로 조정
CAPTURE ENUM_FMT현재 OUTPUT과 무관한 전체 coded format 반환
Buffer 할당 중 CAPTURE S_FMT허용되지 않으며 -EBUSY

CAPTURE가 OUTPUT 지원 집합을 지배하는 다섯 가지 규칙입니다.

Encoder commit 순서
CAPTURE coded format 설정호환 OUTPUT raw format 열거OUTPUT raw format과 selection 설정두 queue buffer 할당할당 중에는 CAPTURE format 변경 금지

master queue인 CAPTURE에서 format 협상을 시작합니다.

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.