← Documents Documentation/userspace-api/media/v4l/vidioc-qbuf.rst GitHub 원문 ↗

Linux 6.18.37 · 사용자 공간 API

VIDIOC_QBUF·VIDIOC_DQBUF ioctl

MMAP·USERPTR·DMABUF buffer를 queue/dequeue하고 request API, 잠금 수명, nonblocking 동작과 복구 가능한 오류를 처리하는 방법을 설명합니다.

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

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

1. 요약·해설

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

요약·해설

vidioc-qbuf.rst:1-197

Memory 방식별 필드와 소유권 전환을 지키고 직접 큐잉과 request 큐잉을 섞지 않는 것이 핵심입니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 .. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
2 .. c:namespace:: V4L
3
4 .. _VIDIOC_QBUF:
5
6 *******************************
7 ioctl VIDIOC_QBUF, VIDIOC_DQBUF
8 *******************************
9
10 Name
11 ====
12
13 VIDIOC_QBUF - VIDIOC_DQBUF - Exchange a buffer with the driver
14
15 Synopsis
16 ========
17
18 .. c:macro:: VIDIOC_QBUF
19
20 ``int ioctl(int fd, VIDIOC_QBUF, struct v4l2_buffer *argp)``
21
22 .. c:macro:: VIDIOC_DQBUF
23
24 ``int ioctl(int fd, VIDIOC_DQBUF, struct v4l2_buffer *argp)``
25
26 Arguments
27 =========
28
29 ``fd``
30 File descriptor returned by :c:func:`open()`.
31
32 ``argp``
33 Pointer to struct :c:type:`v4l2_buffer`.
34
35 Description
36 ===========
37
38 Applications call the ``VIDIOC_QBUF`` ioctl to enqueue an empty
39 (capturing) or filled (output) buffer in the driver's incoming queue.
40 The semantics depend on the selected I/O method.
41
42 To enqueue a buffer applications set the ``type`` field of a struct
43 :c:type:`v4l2_buffer` to the same buffer type as was
44 previously used with struct :c:type:`v4l2_format` ``type``
45 and struct :c:type:`v4l2_requestbuffers` ``type``.
46 Applications must also set the ``index`` field. Valid index numbers
47 range from zero to the number of buffers allocated with
48 :ref:`VIDIOC_REQBUFS` (struct
49 :c:type:`v4l2_requestbuffers` ``count``) minus
50 one. The contents of the struct :c:type:`v4l2_buffer` returned
51 by a :ref:`VIDIOC_QUERYBUF` ioctl will do as well.
52 When the buffer is intended for output (``type`` is
53 ``V4L2_BUF_TYPE_VIDEO_OUTPUT``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``,
54 or ``V4L2_BUF_TYPE_VBI_OUTPUT``) applications must also initialize the
55 ``bytesused``, ``field`` and ``timestamp`` fields, see :ref:`buffer`
56 for details. Applications must also set ``flags`` to 0. The
57 ``reserved2`` and ``reserved`` fields must be set to 0. When using the
58 :ref:`multi-planar API <planar-apis>`, the ``m.planes`` field must
59 contain a userspace pointer to a filled-in array of struct
60 :c:type:`v4l2_plane` and the ``length`` field must be set
61 to the number of elements in that array.
62
63 To enqueue a :ref:`memory mapped <mmap>` buffer applications set the
64 ``memory`` field to ``V4L2_MEMORY_MMAP``. When ``VIDIOC_QBUF`` is called
65 with a pointer to this structure the driver sets the
66 ``V4L2_BUF_FLAG_MAPPED`` and ``V4L2_BUF_FLAG_QUEUED`` flags and clears
67 the ``V4L2_BUF_FLAG_DONE`` flag in the ``flags`` field, or it returns an
68 ``EINVAL`` error code.
69
70 To enqueue a :ref:`user pointer <userp>` buffer applications set the
71 ``memory`` field to ``V4L2_MEMORY_USERPTR``, the ``m.userptr`` field to
72 the address of the buffer and ``length`` to its size. When the
73 multi-planar API is used, ``m.userptr`` and ``length`` members of the
74 passed array of struct :c:type:`v4l2_plane` have to be used
75 instead. When ``VIDIOC_QBUF`` is called with a pointer to this structure
76 the driver sets the ``V4L2_BUF_FLAG_QUEUED`` flag and clears the
77 ``V4L2_BUF_FLAG_MAPPED`` and ``V4L2_BUF_FLAG_DONE`` flags in the
78 ``flags`` field, or it returns an error code. This ioctl locks the
79 memory pages of the buffer in physical memory, they cannot be swapped
80 out to disk. Buffers remain locked until dequeued, until the
81 :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` or
82 :ref:`VIDIOC_REQBUFS` ioctl is called, or until the
83 device is closed.
84
85 To enqueue a :ref:`DMABUF <dmabuf>` buffer applications set the
86 ``memory`` field to ``V4L2_MEMORY_DMABUF`` and the ``m.fd`` field to a
87 file descriptor associated with a DMABUF buffer. When the multi-planar
88 API is used the ``m.fd`` fields of the passed array of struct
89 :c:type:`v4l2_plane` have to be used instead. When
90 ``VIDIOC_QBUF`` is called with a pointer to this structure the driver
91 sets the ``V4L2_BUF_FLAG_QUEUED`` flag and clears the
92 ``V4L2_BUF_FLAG_MAPPED`` and ``V4L2_BUF_FLAG_DONE`` flags in the
93 ``flags`` field, or it returns an error code. This ioctl locks the
94 buffer. Locking a buffer means passing it to a driver for a hardware
95 access (usually DMA). If an application accesses (reads/writes) a locked
96 buffer then the result is undefined. Buffers remain locked until
97 dequeued, until the :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` or
98 :ref:`VIDIOC_REQBUFS` ioctl is called, or until the
99 device is closed.
100
101 The ``request_fd`` field can be used with the ``VIDIOC_QBUF`` ioctl to specify
102 the file descriptor of a :ref:`request <media-request-api>`, if requests are
103 in use. Setting it means that the buffer will not be passed to the driver
104 until the request itself is queued. Also, the driver will apply any
105 settings associated with the request for this buffer. This field will
106 be ignored unless the ``V4L2_BUF_FLAG_REQUEST_FD`` flag is set.
107 If the device does not support requests, then ``EBADR`` will be returned.
108 If requests are supported but an invalid request file descriptor is given,
109 then ``EINVAL`` will be returned.
110
111 .. caution::
112 It is not allowed to mix queuing requests with queuing buffers directly.
113 ``EBUSY`` will be returned if the first buffer was queued directly and
114 then the application tries to queue a request, or vice versa. After
115 closing the file descriptor, calling
116 :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` or calling :ref:`VIDIOC_REQBUFS`
117 the check for this will be reset.
118
119 For :ref:`memory-to-memory devices <mem2mem>` you can specify the
120 ``request_fd`` only for output buffers, not for capture buffers. Attempting
121 to specify this for a capture buffer will result in an ``EBADR`` error.
122
123 Applications call the ``VIDIOC_DQBUF`` ioctl to dequeue a filled
124 (capturing) or displayed (output) buffer from the driver's outgoing
125 queue. They just set the ``type``, ``memory`` and ``reserved`` fields of
126 a struct :c:type:`v4l2_buffer` as above, when
127 ``VIDIOC_DQBUF`` is called with a pointer to this structure the driver
128 fills all remaining fields or returns an error code. The driver may also
129 set ``V4L2_BUF_FLAG_ERROR`` in the ``flags`` field. It indicates a
130 non-critical (recoverable) streaming error. In such case the application
131 may continue as normal, but should be aware that data in the dequeued
132 buffer might be corrupted. When using the multi-planar API, the planes
133 array must be passed in as well.
134
135 If the application sets the ``memory`` field to ``V4L2_MEMORY_DMABUF`` to
136 dequeue a :ref:`DMABUF <dmabuf>` buffer, the driver fills the ``m.fd`` field
137 with a file descriptor numerically the same as the one given to ``VIDIOC_QBUF``
138 when the buffer was enqueued. No new file descriptor is created at dequeue time
139 and the value is only for the application convenience. When the multi-planar
140 API is used the ``m.fd`` fields of the passed array of struct
141 :c:type:`v4l2_plane` are filled instead.
142
143 By default ``VIDIOC_DQBUF`` blocks when no buffer is in the outgoing
144 queue. When the ``O_NONBLOCK`` flag was given to the
145 :c:func:`open()` function, ``VIDIOC_DQBUF`` returns
146 immediately with an ``EAGAIN`` error code when no buffer is available.
147
148 The struct :c:type:`v4l2_buffer` structure is specified in
149 :ref:`buffer`.
150
151 Return Value
152 ============
153
154 On success 0 is returned, on error -1 and the ``errno`` variable is set
155 appropriately. The generic error codes are described at the
156 :ref:`Generic Error Codes <gen-errors>` chapter.
157
158 EAGAIN
159 Non-blocking I/O has been selected using ``O_NONBLOCK`` and no
160 buffer was in the outgoing queue.
161
162 EINVAL
163 The buffer ``type`` is not supported, or the ``index`` is out of
164 bounds, or no buffers have been allocated yet, or the ``userptr`` or
165 ``length`` are invalid, or the ``V4L2_BUF_FLAG_REQUEST_FD`` flag was
166 set but the given ``request_fd`` was invalid, or ``m.fd`` was
167 an invalid DMABUF file descriptor.
168
169 EIO
170 ``VIDIOC_DQBUF`` failed due to an internal error. Can also indicate
171 temporary problems like signal loss.
172
173 .. note::
174
175 The driver might dequeue an (empty) buffer despite returning
176 an error, or even stop capturing. Reusing such buffer may be unsafe
177 though and its details (e.g. ``index``) may not be returned either.
178 It is recommended that drivers indicate recoverable errors by setting
179 the ``V4L2_BUF_FLAG_ERROR`` and returning 0 instead. In that case the
180 application should be able to safely reuse the buffer and continue
181 streaming.
182
183 EPIPE
184 ``VIDIOC_DQBUF`` returns this on an empty capture queue for mem2mem
185 codecs if a buffer with the ``V4L2_BUF_FLAG_LAST`` was already
186 dequeued and no new buffers are expected to become available.
187
188 EBADR
189 The ``V4L2_BUF_FLAG_REQUEST_FD`` flag was set but the device does not
190 support requests for the given buffer type, or
191 the ``V4L2_BUF_FLAG_REQUEST_FD`` flag was not set but the device requires
192 that the buffer is part of a request.
193
194 EBUSY
195 The first buffer was queued via a request, but the application now tries
196 to queue it directly, or vice versa (it is not permitted to mix the two
197 APIs).
198

3. 한국어 전문 번역

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

목적, 호출 형식과 인자

1-34

`VIDIOC_QBUF`는 capture용 빈 buffer 또는 output용으로 채운 buffer를 드라이버의 incoming queue에 넣고, `VIDIOC_DQBUF`는 처리된 capture/output buffer를 outgoing queue에서 꺼냅니다. 둘 다 `struct v4l2_buffer *argp`를 사용합니다.

.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. c:namespace:: V4L

.. _VIDIOC_QBUF:

*******************************
ioctl VIDIOC_QBUF, VIDIOC_DQBUF
*******************************

Name
====

VIDIOC_QBUF - VIDIOC_DQBUF - Exchange a buffer with the driver

Synopsis
========

.. c:macro:: VIDIOC_QBUF

``int ioctl(int fd, VIDIOC_QBUF, struct v4l2_buffer *argp)``

.. c:macro:: VIDIOC_DQBUF

``int ioctl(int fd, VIDIOC_DQBUF, struct v4l2_buffer *argp)``

Arguments
=========

``fd``
    File descriptor returned by :c:func:`open()`.

``argp``
    Pointer to struct :c:type:`v4l2_buffer`.

공통 enqueue 필드

35-62

`type`은 이전에 `v4l2_format.type`과 `v4l2_requestbuffers.type`에 사용한 buffer type과 같아야 합니다. `index`는 0부터 `VIDIOC_REQBUFS`가 할당한 `count - 1`까지이며, `VIDIOC_QUERYBUF` 결과 구조체를 그대로 바탕으로 사용할 수 있습니다.

QBUF 공통 입력
필드요구사항
`type`FORMAT·REQBUFS에서 사용한 것과 동일한 buffer type
`index`0 이상, 할당한 buffer 수 미만
`flags`0으로 초기화
`reserved2`, `reserved`0으로 초기화
`m.planes`multi-planar API에서는 채운 `v4l2_plane` 배열의 사용자 공간 포인터
`length`multi-planar API에서는 plane 배열 원소 수

모든 memory 방식에 공통으로 준비할 필드입니다.

Output type인 `V4L2_BUF_TYPE_VIDEO_OUTPUT`, `V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE`, `V4L2_BUF_TYPE_VBI_OUTPUT`에서는 `bytesused`, `field`, `timestamp`도 초기화해야 합니다.

Description
===========

Applications call the ``VIDIOC_QBUF`` ioctl to enqueue an empty
(capturing) or filled (output) buffer in the driver's incoming queue.
The semantics depend on the selected I/O method.

To enqueue a buffer applications set the ``type`` field of a struct
:c:type:`v4l2_buffer` to the same buffer type as was
previously used with struct :c:type:`v4l2_format` ``type``
and struct :c:type:`v4l2_requestbuffers` ``type``.
Applications must also set the ``index`` field. Valid index numbers
range from zero to the number of buffers allocated with
:ref:`VIDIOC_REQBUFS` (struct
:c:type:`v4l2_requestbuffers` ``count``) minus
one. The contents of the struct :c:type:`v4l2_buffer` returned
by a :ref:`VIDIOC_QUERYBUF` ioctl will do as well.
When the buffer is intended for output (``type`` is
``V4L2_BUF_TYPE_VIDEO_OUTPUT``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``,
or ``V4L2_BUF_TYPE_VBI_OUTPUT``) applications must also initialize the
``bytesused``, ``field`` and ``timestamp`` fields, see :ref:`buffer`
for details. Applications must also set ``flags`` to 0. The
``reserved2`` and ``reserved`` fields must be set to 0. When using the
:ref:`multi-planar API <planar-apis>`, the ``m.planes`` field must
contain a userspace pointer to a filled-in array of struct
:c:type:`v4l2_plane` and the ``length`` field must be set
to the number of elements in that array.

Memory-mapped buffer 큐잉

63-69

MMAP buffer는 `memory = V4L2_MEMORY_MMAP`으로 지정합니다. 성공하면 드라이버가 `V4L2_BUF_FLAG_MAPPED`와 `V4L2_BUF_FLAG_QUEUED`를 설정하고 `V4L2_BUF_FLAG_DONE`을 지웁니다. 입력이 유효하지 않으면 `EINVAL`입니다.

To enqueue a :ref:`memory mapped <mmap>` buffer applications set the
``memory`` field to ``V4L2_MEMORY_MMAP``. When ``VIDIOC_QBUF`` is called
with a pointer to this structure the driver sets the
``V4L2_BUF_FLAG_MAPPED`` and ``V4L2_BUF_FLAG_QUEUED`` flags and clears
the ``V4L2_BUF_FLAG_DONE`` flag in the ``flags`` field, or it returns an
``EINVAL`` error code.

User pointer buffer 큐잉

70-84

USERPTR 방식은 `memory = V4L2_MEMORY_USERPTR`, `m.userptr = buffer 주소`, `length = buffer 크기`로 설정합니다. Multi-planar API에서는 각 `v4l2_plane`의 `m.userptr`와 `length`를 사용합니다.

성공 시 `QUEUED`를 설정하고 `MAPPED`와 `DONE`을 지웁니다. 호출은 buffer의 memory page를 물리 메모리에 고정해 swap-out을 막습니다.

Page lock은 buffer가 dequeue되거나 `VIDIOC_STREAMOFF`·`VIDIOC_REQBUFS`를 호출하거나 장치를 닫을 때까지 유지됩니다.

To enqueue a :ref:`user pointer <userp>` buffer applications set the
``memory`` field to ``V4L2_MEMORY_USERPTR``, the ``m.userptr`` field to
the address of the buffer and ``length`` to its size. When the
multi-planar API is used, ``m.userptr`` and ``length`` members of the
passed array of struct :c:type:`v4l2_plane` have to be used
instead. When ``VIDIOC_QBUF`` is called with a pointer to this structure
the driver sets the ``V4L2_BUF_FLAG_QUEUED`` flag and clears the
``V4L2_BUF_FLAG_MAPPED`` and ``V4L2_BUF_FLAG_DONE`` flags in the
``flags`` field, or it returns an error code. This ioctl locks the
memory pages of the buffer in physical memory, they cannot be swapped
out to disk. Buffers remain locked until dequeued, until the
:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` or
:ref:`VIDIOC_REQBUFS` ioctl is called, or until the
device is closed.

DMABUF 큐잉과 잠금

85-100

DMABUF 방식은 `memory = V4L2_MEMORY_DMABUF`과 해당 DMABUF의 file descriptor인 `m.fd`를 설정합니다. Multi-planar API에서는 각 plane의 `m.fd`를 사용합니다.

성공 시 `QUEUED`를 설정하고 `MAPPED`와 `DONE`을 지웁니다. 잠금은 보통 DMA인 하드웨어 접근을 위해 buffer를 드라이버에 넘긴다는 뜻이며, 잠긴 buffer를 애플리케이션이 읽거나 쓰면 결과가 정의되지 않습니다.

DMABUF lock도 dequeue, `STREAMOFF`, `REQBUFS`, 장치 close 중 하나가 일어날 때까지 유지됩니다.

To enqueue a :ref:`DMABUF <dmabuf>` buffer applications set the
``memory`` field to ``V4L2_MEMORY_DMABUF`` and the ``m.fd`` field to a
file descriptor associated with a DMABUF buffer. When the multi-planar
API is used the ``m.fd`` fields of the passed array of struct
:c:type:`v4l2_plane` have to be used instead. When
``VIDIOC_QBUF`` is called with a pointer to this structure the driver
sets the ``V4L2_BUF_FLAG_QUEUED`` flag and clears the
``V4L2_BUF_FLAG_MAPPED`` and ``V4L2_BUF_FLAG_DONE`` flags in the
``flags`` field, or it returns an error code. This ioctl locks the
buffer. Locking a buffer means passing it to a driver for a hardware
access (usually DMA). If an application accesses (reads/writes) a locked
buffer then the result is undefined. Buffers remain locked until
dequeued, until the :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` or
:ref:`VIDIOC_REQBUFS` ioctl is called, or until the
device is closed.

Media request와 큐잉 규칙

101-122

Request API를 사용할 때 `request_fd`에 request file descriptor를 넣고 `V4L2_BUF_FLAG_REQUEST_FD`를 설정할 수 있습니다. Buffer는 request 자체가 queue될 때까지 드라이버로 전달되지 않으며, request에 연결된 설정이 이 buffer에 적용됩니다.

`REQUEST_FD` flag가 없으면 `request_fd`는 무시됩니다. 장치가 request를 지원하지 않으면 `EBADR`, 지원하지만 descriptor가 잘못되면 `EINVAL`입니다.

Request 큐잉 제약
상황결과
첫 buffer는 직접 큐잉, 다음은 request 큐잉 또는 그 반대`EBUSY`
fd close, `STREAMOFF`, `REQBUFS` 호출혼용 검사 상태 재설정
mem2mem output buffer에 `request_fd`허용
mem2mem capture buffer에 `request_fd``EBADR`

직접 큐잉과 request 큐잉은 한 streaming 세션에서 섞을 수 없습니다.

The ``request_fd`` field can be used with the ``VIDIOC_QBUF`` ioctl to specify
the file descriptor of a :ref:`request <media-request-api>`, if requests are
in use. Setting it means that the buffer will not be passed to the driver
until the request itself is queued. Also, the driver will apply any
settings associated with the request for this buffer. This field will
be ignored unless the ``V4L2_BUF_FLAG_REQUEST_FD`` flag is set.
If the device does not support requests, then ``EBADR`` will be returned.
If requests are supported but an invalid request file descriptor is given,
then ``EINVAL`` will be returned.

.. caution::
   It is not allowed to mix queuing requests with queuing buffers directly.
   ``EBUSY`` will be returned if the first buffer was queued directly and
   then the application tries to queue a request, or vice versa. After
   closing the file descriptor, calling
   :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` or calling :ref:`VIDIOC_REQBUFS`
   the check for this will be reset.

   For :ref:`memory-to-memory devices <mem2mem>` you can specify the
   ``request_fd`` only for output buffers, not for capture buffers. Attempting
   to specify this for a capture buffer will result in an ``EBADR`` error.

Buffer dequeue와 오류 표시

123-150

DQBUF 호출자는 `type`, `memory`, `reserved`를 준비하고, multi-planar API라면 plane 배열도 전달합니다. 드라이버는 나머지 필드를 채워 outgoing queue의 처리된 buffer를 반환합니다.

드라이버가 `V4L2_BUF_FLAG_ERROR`를 설정하면 복구 가능한 비치명적 streaming 오류입니다. 애플리케이션은 계속 진행할 수 있지만 dequeued buffer의 데이터가 손상됐을 수 있음을 고려해야 합니다.

DMABUF를 dequeue하면 `m.fd`에는 QBUF 때 전달한 것과 숫자가 같은 descriptor가 기록됩니다. 새 descriptor를 만들지 않으며 편의를 위한 값입니다. Multi-planar에서는 각 plane의 `m.fd`가 채워집니다.

기본적으로 outgoing queue가 비면 DQBUF가 block합니다. 장치를 `O_NONBLOCK`으로 열었다면 즉시 `EAGAIN`을 반환합니다. 구조체 필드 정의는 `buffer` 절을 따릅니다.

Applications call the ``VIDIOC_DQBUF`` ioctl to dequeue a filled
(capturing) or displayed (output) buffer from the driver's outgoing
queue. They just set the ``type``, ``memory`` and ``reserved`` fields of
a struct :c:type:`v4l2_buffer` as above, when
``VIDIOC_DQBUF`` is called with a pointer to this structure the driver
fills all remaining fields or returns an error code. The driver may also
set ``V4L2_BUF_FLAG_ERROR`` in the ``flags`` field. It indicates a
non-critical (recoverable) streaming error. In such case the application
may continue as normal, but should be aware that data in the dequeued
buffer might be corrupted. When using the multi-planar API, the planes
array must be passed in as well.

If the application sets the ``memory`` field to ``V4L2_MEMORY_DMABUF`` to
dequeue a :ref:`DMABUF <dmabuf>` buffer, the driver fills the ``m.fd`` field
with a file descriptor numerically the same as the one given to ``VIDIOC_QBUF``
when the buffer was enqueued. No new file descriptor is created at dequeue time
and the value is only for the application convenience. When the multi-planar
API is used the ``m.fd`` fields of the passed array of struct
:c:type:`v4l2_plane` are filled instead.

By default ``VIDIOC_DQBUF`` blocks when no buffer is in the outgoing
queue. When the ``O_NONBLOCK`` flag was given to the
:c:func:`open()` function, ``VIDIOC_DQBUF`` returns
immediately with an ``EAGAIN`` error code when no buffer is available.

The struct :c:type:`v4l2_buffer` structure is specified in
:ref:`buffer`.

반환값과 오류

151-197

성공하면 0, 오류이면 -1을 반환하고 `errno`를 설정합니다.

QBUF·DQBUF 오류
errno조건
`EAGAIN``O_NONBLOCK`이며 outgoing queue에 buffer가 없음
`EINVAL`지원하지 않는 type, 잘못된 index/userptr/length/request_fd/DMABUF fd, 또는 미할당 buffer
`EIO`DQBUF 내부 오류 또는 신호 손실 같은 일시적 문제
`EPIPE`mem2mem codec에서 `LAST` buffer를 이미 꺼냈고 새 buffer가 예상되지 않는 빈 capture queue
`EBADR`buffer type이 request를 지원하지 않는데 `REQUEST_FD`를 설정했거나, request가 필수인데 설정하지 않음
`EBUSY`request 큐잉과 직접 큐잉을 혼용함

큐 상태, buffer 설명자, request 방식에 따른 전용 오류입니다.

`EIO`를 반환하면서 드라이버가 빈 buffer를 dequeue하거나 capture를 중지할 수도 있어 그 buffer를 재사용하는 것은 안전하지 않을 수 있고 `index` 같은 세부 정보도 없을 수 있습니다.

복구 가능한 오류는 드라이버가 `V4L2_BUF_FLAG_ERROR`를 설정하고 0을 반환하는 방식이 권장됩니다. 이 경우 애플리케이션은 buffer를 안전하게 재사용하고 streaming을 계속할 수 있어야 합니다.

Return Value
============

On success 0 is returned, on error -1 and the ``errno`` variable is set
appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.

EAGAIN
    Non-blocking I/O has been selected using ``O_NONBLOCK`` and no
    buffer was in the outgoing queue.

EINVAL
    The buffer ``type`` is not supported, or the ``index`` is out of
    bounds, or no buffers have been allocated yet, or the ``userptr`` or
    ``length`` are invalid, or the ``V4L2_BUF_FLAG_REQUEST_FD`` flag was
    set but the given ``request_fd`` was invalid, or ``m.fd`` was
    an invalid DMABUF file descriptor.

EIO
    ``VIDIOC_DQBUF`` failed due to an internal error. Can also indicate
    temporary problems like signal loss.

    .. note::

       The driver might dequeue an (empty) buffer despite returning
       an error, or even stop capturing. Reusing such buffer may be unsafe
       though and its details (e.g. ``index``) may not be returned either.
       It is recommended that drivers indicate recoverable errors by setting
       the ``V4L2_BUF_FLAG_ERROR`` and returning 0 instead. In that case the
       application should be able to safely reuse the buffer and continue
       streaming.

EPIPE
    ``VIDIOC_DQBUF`` returns this on an empty capture queue for mem2mem
    codecs if a buffer with the ``V4L2_BUF_FLAG_LAST`` was already
    dequeued and no new buffers are expected to become available.

EBADR
    The ``V4L2_BUF_FLAG_REQUEST_FD`` flag was set but the device does not
    support requests for the given buffer type, or
    the ``V4L2_BUF_FLAG_REQUEST_FD`` flag was not set but the device requires
    that the buffer is part of a request.

EBUSY
    The first buffer was queued via a request, but the application now tries
    to queue it directly, or vice versa (it is not permitted to mix the two
    APIs).