요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. _control:
*************
User Controls
*************
Devices typically have a number of user-settable controls such as
brightness, saturation and so on, which would be presented to the user
on a graphical user interface. But, different devices will have
different controls available, and furthermore, the range of possible
values, and the default value will vary from device to device. The
control ioctls provide the information and a mechanism to create a nice
user interface for these controls that will work correctly with any
device.
All controls are accessed using an ID value. V4L2 defines several IDs
for specific purposes. Drivers can also implement their own custom
controls using ``V4L2_CID_PRIVATE_BASE`` [#f1]_ and higher values. The
pre-defined control IDs have the prefix ``V4L2_CID_``, and are listed in
:ref:`control-id`. The ID is used when querying the attributes of a
control, and when getting or setting the current value.
Generally applications should present controls to the user without
assumptions about their purpose. Each control comes with a name string
the user is supposed to understand. When the purpose is non-intuitive
the driver writer should provide a user manual, a user interface plug-in
or a driver specific panel application. Predefined IDs were introduced
to change a few controls programmatically, for example to mute a device
during a channel switch.
Drivers may enumerate different controls after switching the current
video input or output, tuner or modulator, or audio input or output.
Different in the sense of other bounds, another default and current
value, step size or other menu items. A control with a certain *custom*
ID can also change name and type.
If a control is not applicable to the current configuration of the
device (for example, it doesn't apply to the current video input)
drivers set the ``V4L2_CTRL_FLAG_INACTIVE`` flag.
Control values are stored globally, they do not change when switching
except to stay within the reported bounds. They also do not change e. g.
when the device is opened or closed, when the tuner radio frequency is
changed or generally never without application request.
V4L2 specifies an event mechanism to notify applications when controls
change value (see
:ref:`VIDIOC_SUBSCRIBE_EVENT`, event
``V4L2_EVENT_CTRL``), panel applications might want to make use of that
in order to always reflect the correct control value.
All controls use machine endianness.
.. _control-id:
Control IDs
===========
``V4L2_CID_BASE``
First predefined ID, equal to ``V4L2_CID_BRIGHTNESS``.
``V4L2_CID_USER_BASE``
Synonym of ``V4L2_CID_BASE``.
``V4L2_CID_BRIGHTNESS`` ``(integer)``
Picture brightness, or more precisely, the black level.
``V4L2_CID_CONTRAST`` ``(integer)``
Picture contrast or luma gain.
``V4L2_CID_SATURATION`` ``(integer)``
Picture color saturation or chroma gain.
``V4L2_CID_HUE`` ``(integer)``
Hue or color balance.
``V4L2_CID_AUDIO_VOLUME`` ``(integer)``
Overall audio volume. Note some drivers also provide an OSS or ALSA
mixer interface.
``V4L2_CID_AUDIO_BALANCE`` ``(integer)``
Audio stereo balance. Minimum corresponds to all the way left,
maximum to right.
``V4L2_CID_AUDIO_BASS`` ``(integer)``
Audio bass adjustment.
``V4L2_CID_AUDIO_TREBLE`` ``(integer)``
Audio treble adjustment.
``V4L2_CID_AUDIO_MUTE`` ``(boolean)``
Mute audio, i. e. set the volume to zero, however without affecting
``V4L2_CID_AUDIO_VOLUME``. Like ALSA drivers, V4L2 drivers must mute
at load time to avoid excessive noise. Actually the entire device
should be reset to a low power consumption state.
``V4L2_CID_AUDIO_LOUDNESS`` ``(boolean)``
Loudness mode (bass boost).
``V4L2_CID_BLACK_LEVEL`` ``(integer)``
Another name for brightness (not a synonym of
``V4L2_CID_BRIGHTNESS``). This control is deprecated and should not
be used in new drivers and applications.
``V4L2_CID_AUTO_WHITE_BALANCE`` ``(boolean)``
Automatic white balance (cameras).
``V4L2_CID_DO_WHITE_BALANCE`` ``(button)``
This is an action control. When set (the value is ignored), the
device will do a white balance and then hold the current setting.
Contrast this with the boolean ``V4L2_CID_AUTO_WHITE_BALANCE``,
which, when activated, keeps adjusting the white balance.
``V4L2_CID_RED_BALANCE`` ``(integer)``
Red chroma balance.
``V4L2_CID_BLUE_BALANCE`` ``(integer)``
Blue chroma balance.
``V4L2_CID_GAMMA`` ``(integer)``
Gamma adjust.
``V4L2_CID_WHITENESS`` ``(integer)``
Whiteness for grey-scale devices. This is a synonym for
``V4L2_CID_GAMMA``. This control is deprecated and should not be
used in new drivers and applications.
``V4L2_CID_EXPOSURE`` ``(integer)``
Exposure (cameras). [Unit?]
``V4L2_CID_AUTOGAIN`` ``(boolean)``
Automatic gain/exposure control.
``V4L2_CID_GAIN`` ``(integer)``
Gain control.
Primarily used to control gain on e.g. TV tuners but also on
webcams. Most devices control only digital gain with this control
but on some this could include analogue gain as well. Devices that
recognise the difference between digital and analogue gain use
controls ``V4L2_CID_DIGITAL_GAIN`` and ``V4L2_CID_ANALOGUE_GAIN``.
.. _v4l2-cid-hflip:
``V4L2_CID_HFLIP`` ``(boolean)``
Mirror the picture horizontally.
.. _v4l2-cid-vflip:
``V4L2_CID_VFLIP`` ``(boolean)``
Mirror the picture vertically.
.. _v4l2-power-line-frequency:
``V4L2_CID_POWER_LINE_FREQUENCY`` ``(enum)``
Enables a power line frequency filter to avoid flicker. Possible
values for ``enum v4l2_power_line_frequency`` are:
========================================== ==
``V4L2_CID_POWER_LINE_FREQUENCY_DISABLED`` 0
``V4L2_CID_POWER_LINE_FREQUENCY_50HZ`` 1
``V4L2_CID_POWER_LINE_FREQUENCY_60HZ`` 2
``V4L2_CID_POWER_LINE_FREQUENCY_AUTO`` 3
========================================== ==
``V4L2_CID_HUE_AUTO`` ``(boolean)``
Enables automatic hue control by the device. The effect of setting
``V4L2_CID_HUE`` while automatic hue control is enabled is
undefined, drivers should ignore such request.
``V4L2_CID_WHITE_BALANCE_TEMPERATURE`` ``(integer)``
This control specifies the white balance settings as a color
temperature in Kelvin. A driver should have a minimum of 2800
(incandescent) to 6500 (daylight). For more information about color
temperature see
`Wikipedia <http://en.wikipedia.org/wiki/Color_temperature>`__.
``V4L2_CID_SHARPNESS`` ``(integer)``
Adjusts the sharpness filters in a camera. The minimum value
disables the filters, higher values give a sharper picture.
``V4L2_CID_BACKLIGHT_COMPENSATION`` ``(integer)``
Adjusts the backlight compensation in a camera. The minimum value
disables backlight compensation.
``V4L2_CID_CHROMA_AGC`` ``(boolean)``
Chroma automatic gain control.
``V4L2_CID_CHROMA_GAIN`` ``(integer)``
Adjusts the Chroma gain control (for use when chroma AGC is
disabled).
``V4L2_CID_COLOR_KILLER`` ``(boolean)``
Enable the color killer (i. e. force a black & white image in case
of a weak video signal).
.. _v4l2-colorfx:
``V4L2_CID_COLORFX`` ``(enum)``
Selects a color effect. The following values are defined:
.. tabularcolumns:: |p{5.7cm}|p{11.8cm}|
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 11 24
* - ``V4L2_COLORFX_NONE``
- Color effect is disabled.
* - ``V4L2_COLORFX_ANTIQUE``
- An aging (old photo) effect.
* - ``V4L2_COLORFX_ART_FREEZE``
- Frost color effect.
* - ``V4L2_COLORFX_AQUA``
- Water color, cool tone.
* - ``V4L2_COLORFX_BW``
- Black and white.
* - ``V4L2_COLORFX_EMBOSS``
- Emboss, the highlights and shadows replace light/dark boundaries
and low contrast areas are set to a gray background.
* - ``V4L2_COLORFX_GRASS_GREEN``
- Grass green.
* - ``V4L2_COLORFX_NEGATIVE``
- Negative.
* - ``V4L2_COLORFX_SEPIA``
- Sepia tone.
* - ``V4L2_COLORFX_SKETCH``
- Sketch.
* - ``V4L2_COLORFX_SKIN_WHITEN``
- Skin whiten.
* - ``V4L2_COLORFX_SKY_BLUE``
- Sky blue.
* - ``V4L2_COLORFX_SOLARIZATION``
- Solarization, the image is partially reversed in tone, only color
values above or below a certain threshold are inverted.
* - ``V4L2_COLORFX_SILHOUETTE``
- Silhouette (outline).
* - ``V4L2_COLORFX_VIVID``
- Vivid colors.
* - ``V4L2_COLORFX_SET_CBCR``
- The Cb and Cr chroma components are replaced by fixed coefficients
determined by ``V4L2_CID_COLORFX_CBCR`` control.
* - ``V4L2_COLORFX_SET_RGB``
- The RGB components are replaced by the fixed RGB components determined
by ``V4L2_CID_COLORFX_RGB`` control.
``V4L2_CID_COLORFX_RGB`` ``(integer)``
Determines the Red, Green, and Blue coefficients for
``V4L2_COLORFX_SET_RGB`` color effect.
Bits [7:0] of the supplied 32 bit value are interpreted as Blue component,
bits [15:8] as Green component, bits [23:16] as Red component, and
bits [31:24] must be zero.
``V4L2_CID_COLORFX_CBCR`` ``(integer)``
Determines the Cb and Cr coefficients for ``V4L2_COLORFX_SET_CBCR``
color effect. Bits [7:0] of the supplied 32 bit value are
interpreted as Cr component, bits [15:8] as Cb component and bits
[31:16] must be zero.
``V4L2_CID_AUTOBRIGHTNESS`` ``(boolean)``
Enable Automatic Brightness.
``V4L2_CID_ROTATE`` ``(integer)``
Rotates the image by specified angle. Common angles are 90, 270 and
180. Rotating the image to 90 and 270 will reverse the height and
width of the display window. It is necessary to set the new height
and width of the picture using the
:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl according to the
rotation angle selected.
``V4L2_CID_BG_COLOR`` ``(integer)``
Sets the background color on the current output device. Background
color needs to be specified in the RGB24 format. The supplied 32 bit
value is interpreted as bits 0-7 Red color information, bits 8-15
Green color information, bits 16-23 Blue color information and bits
24-31 must be zero.
``V4L2_CID_ILLUMINATORS_1 V4L2_CID_ILLUMINATORS_2`` ``(boolean)``
Switch on or off the illuminator 1 or 2 of the device (usually a
microscope).
``V4L2_CID_MIN_BUFFERS_FOR_CAPTURE`` ``(integer)``
This is a read-only control that can be read by the application and
used as a hint to determine the number of CAPTURE buffers to pass to
REQBUFS. The value is the minimum number of CAPTURE buffers that is
necessary for hardware to work. This control is required for stateful
decoders.
``V4L2_CID_MIN_BUFFERS_FOR_OUTPUT`` ``(integer)``
This is a read-only control that can be read by the application and
used as a hint to determine the number of OUTPUT buffers to pass to
REQBUFS. The value is the minimum number of OUTPUT buffers that is
necessary for hardware to work. This control is required for stateful
encoders.
.. _v4l2-alpha-component:
``V4L2_CID_ALPHA_COMPONENT`` ``(integer)``
Sets the alpha color component. When a capture device (or capture
queue of a mem-to-mem device) produces a frame format that includes
an alpha component (e.g.
:ref:`packed RGB image formats <pixfmt-rgb>`) and the alpha value
is not defined by the device or the mem-to-mem input data this
control lets you select the alpha component value of all pixels.
When an output device (or output queue of a mem-to-mem device)
consumes a frame format that doesn't include an alpha component and
the device supports alpha channel processing this control lets you
set the alpha component value of all pixels for further processing
in the device.
``V4L2_CID_LASTP1``
End of the predefined control IDs (currently
``V4L2_CID_ALPHA_COMPONENT`` + 1).
``V4L2_CID_PRIVATE_BASE``
ID of the first custom (driver specific) control. Applications
depending on particular custom controls should check the driver name
and version, see :ref:`querycap`.
Applications can enumerate the available controls with the
:ref:`VIDIOC_QUERYCTRL` and
:ref:`VIDIOC_QUERYMENU <VIDIOC_QUERYCTRL>` ioctls, get and set a
control value with the :ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and
:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls. Drivers must implement
``VIDIOC_QUERYCTRL``, ``VIDIOC_G_CTRL`` and ``VIDIOC_S_CTRL`` when the
device has one or more controls, ``VIDIOC_QUERYMENU`` when it has one or
more menu type controls.
.. _enum_all_controls:
Example: Enumerating all controls
=================================
.. code-block:: c
struct v4l2_queryctrl queryctrl;
struct v4l2_querymenu querymenu;
static void enumerate_menu(__u32 id)
{
printf(" Menu items:\\n");
memset(&querymenu, 0, sizeof(querymenu));
querymenu.id = id;
for (querymenu.index = queryctrl.minimum;
querymenu.index <= queryctrl.maximum;
querymenu.index++) {
if (0 == ioctl(fd, VIDIOC_QUERYMENU, &querymenu)) {
printf(" %s\\n", querymenu.name);
}
}
}
memset(&queryctrl, 0, sizeof(queryctrl));
queryctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
while (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
if (!(queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
printf("Control %s\\n", queryctrl.name);
if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
enumerate_menu(queryctrl.id);
}
queryctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
}
if (errno != EINVAL) {
perror("VIDIOC_QUERYCTRL");
exit(EXIT_FAILURE);
}
Example: Enumerating all controls including compound controls
=============================================================
.. code-block:: c
struct v4l2_query_ext_ctrl query_ext_ctrl;
memset(&query_ext_ctrl, 0, sizeof(query_ext_ctrl));
query_ext_ctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
while (0 == ioctl(fd, VIDIOC_QUERY_EXT_CTRL, &query_ext_ctrl)) {
if (!(query_ext_ctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
printf("Control %s\\n", query_ext_ctrl.name);
if (query_ext_ctrl.type == V4L2_CTRL_TYPE_MENU)
enumerate_menu(query_ext_ctrl.id);
}
query_ext_ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
}
if (errno != EINVAL) {
perror("VIDIOC_QUERY_EXT_CTRL");
exit(EXIT_FAILURE);
}
Example: Enumerating all user controls (old style)
==================================================
.. code-block:: c
memset(&queryctrl, 0, sizeof(queryctrl));
for (queryctrl.id = V4L2_CID_BASE;
queryctrl.id < V4L2_CID_LASTP1;
queryctrl.id++) {
if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
continue;
printf("Control %s\\n", queryctrl.name);
if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
enumerate_menu(queryctrl.id);
} else {
if (errno == EINVAL)
continue;
perror("VIDIOC_QUERYCTRL");
exit(EXIT_FAILURE);
}
}
for (queryctrl.id = V4L2_CID_PRIVATE_BASE;;
queryctrl.id++) {
if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
continue;
printf("Control %s\\n", queryctrl.name);
if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
enumerate_menu(queryctrl.id);
} else {
if (errno == EINVAL)
break;
perror("VIDIOC_QUERYCTRL");
exit(EXIT_FAILURE);
}
}
Example: Changing controls
==========================
.. code-block:: c
struct v4l2_queryctrl queryctrl;
struct v4l2_control control;
memset(&queryctrl, 0, sizeof(queryctrl));
queryctrl.id = V4L2_CID_BRIGHTNESS;
if (-1 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
if (errno != EINVAL) {
perror("VIDIOC_QUERYCTRL");
exit(EXIT_FAILURE);
} else {
printf("V4L2_CID_BRIGHTNESS is not supported\n");
}
} else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
printf("V4L2_CID_BRIGHTNESS is not supported\n");
} else {
memset(&control, 0, sizeof (control));
control.id = V4L2_CID_BRIGHTNESS;
control.value = queryctrl.default_value;
if (-1 == ioctl(fd, VIDIOC_S_CTRL, &control)) {
perror("VIDIOC_S_CTRL");
exit(EXIT_FAILURE);
}
}
memset(&control, 0, sizeof(control));
control.id = V4L2_CID_CONTRAST;
if (0 == ioctl(fd, VIDIOC_G_CTRL, &control)) {
control.value += 1;
/* The driver may clamp the value or return ERANGE, ignored here */
if (-1 == ioctl(fd, VIDIOC_S_CTRL, &control)
&& errno != ERANGE) {
perror("VIDIOC_S_CTRL");
exit(EXIT_FAILURE);
}
/* Ignore if V4L2_CID_CONTRAST is unsupported */
} else if (errno != EINVAL) {
perror("VIDIOC_G_CTRL");
exit(EXIT_FAILURE);
}
control.id = V4L2_CID_AUDIO_MUTE;
control.value = 1; /* silence */
/* Errors ignored */
ioctl(fd, VIDIOC_S_CTRL, &control);
.. [#f1]
The use of ``V4L2_CID_PRIVATE_BASE`` is problematic because different
drivers may use the same ``V4L2_CID_PRIVATE_BASE`` ID for different
controls. This makes it hard to programmatically set such controls
since the meaning of the control with that ID is driver dependent. In
order to resolve this drivers use unique IDs and the
``V4L2_CID_PRIVATE_BASE`` IDs are mapped to those unique IDs by the
kernel. Consider these ``V4L2_CID_PRIVATE_BASE`` IDs as aliases to
the real IDs.
Many applications today still use the ``V4L2_CID_PRIVATE_BASE`` IDs
instead of using :ref:`VIDIOC_QUERYCTRL` with
the ``V4L2_CTRL_FLAG_NEXT_CTRL`` flag to enumerate all IDs, so
support for ``V4L2_CID_PRIVATE_BASE`` is still around.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
컨트롤 모델과 동적 상태
1-56V4L2 장치는 밝기와 채도처럼 사용자가 조절하는 여러 컨트롤을 제공합니다. 장치마다 지원 항목, 값 범위, 단계와 기본값이 다르므로 애플리케이션은 컨트롤 ioctl로 속성을 조회해 장치 독립적인 UI를 구성해야 합니다.
모든 컨트롤은 ID로 접근합니다. 표준 ID는 `V4L2_CID_` 접두사를 사용하고, 드라이버 고유 컨트롤은 `V4L2_CID_PRIVATE_BASE` 이상의 값을 사용할 수 있습니다. 같은 ID를 속성 조회와 현재값 읽기·쓰기에 사용합니다.
애플리케이션은 컨트롤의 목적을 추측하지 말고 드라이버가 제공하는 사용자용 이름을 표시하는 것이 원칙입니다. 직관적이지 않은 기능에는 드라이버 매뉴얼, UI 플러그인 또는 전용 패널 프로그램이 필요합니다. 표준 ID는 채널 전환 중 음소거처럼 일부 기능을 프로그램으로 제어하기 위해 정의됐습니다.
현재 비디오·오디오 입력이나 출력, 튜너 또는 모듈레이터를 바꾸면 열거되는 컨트롤의 범위, 기본값, 현재값, 단계와 메뉴가 달라질 수 있습니다. custom ID 컨트롤은 이름과 형식까지 바뀔 수 있습니다.
현재 구성에 적용되지 않는 컨트롤은 드라이버가 `V4L2_CTRL_FLAG_INACTIVE`로 표시합니다. 값은 장치 전체에 전역으로 저장되며 입력 전환 시 새 범위 안으로 맞춰지는 경우를 제외하면 열기·닫기나 튜너 주파수 변경만으로 임의 변경되지 않습니다.
값 변경은 `VIDIOC_SUBSCRIBE_EVENT`로 `V4L2_EVENT_CTRL` 이벤트를 구독해 알 수 있습니다. 패널 애플리케이션은 이를 사용해 실제 컨트롤 값을 계속 반영해야 합니다. 모든 컨트롤 데이터는 머신 엔디언을 사용합니다.
장치 구성과 이벤트에 맞춰 UI를 다시 동기화합니다.
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. _control:
*************
User Controls
*************
Devices typically have a number of user-settable controls such as
brightness, saturation and so on, which would be presented to the user
on a graphical user interface. But, different devices will have
different controls available, and furthermore, the range of possible
values, and the default value will vary from device to device. The
control ioctls provide the information and a mechanism to create a nice
user interface for these controls that will work correctly with any
device.
All controls are accessed using an ID value. V4L2 defines several IDs
for specific purposes. Drivers can also implement their own custom
controls using ``V4L2_CID_PRIVATE_BASE`` [#f1]_ and higher values. The
pre-defined control IDs have the prefix ``V4L2_CID_``, and are listed in
:ref:`control-id`. The ID is used when querying the attributes of a
control, and when getting or setting the current value.
Generally applications should present controls to the user without
assumptions about their purpose. Each control comes with a name string
the user is supposed to understand. When the purpose is non-intuitive
the driver writer should provide a user manual, a user interface plug-in
or a driver specific panel application. Predefined IDs were introduced
to change a few controls programmatically, for example to mute a device
during a channel switch.
Drivers may enumerate different controls after switching the current
video input or output, tuner or modulator, or audio input or output.
Different in the sense of other bounds, another default and current
value, step size or other menu items. A control with a certain *custom*
ID can also change name and type.
If a control is not applicable to the current configuration of the
device (for example, it doesn't apply to the current video input)
drivers set the ``V4L2_CTRL_FLAG_INACTIVE`` flag.
Control values are stored globally, they do not change when switching
except to stay within the reported bounds. They also do not change e. g.
when the device is opened or closed, when the tuner radio frequency is
changed or generally never without application request.
V4L2 specifies an event mechanism to notify applications when controls
change value (see
:ref:`VIDIOC_SUBSCRIBE_EVENT`, event
``V4L2_EVENT_CTRL``), panel applications might want to make use of that
in order to always reflect the correct control value.
All controls use machine endianness.
기본 영상·오디오 컨트롤 ID
57-145`V4L2_CID_BASE`는 첫 사전 정의 ID이며 `V4L2_CID_BRIGHTNESS`와 같습니다. `V4L2_CID_USER_BASE`는 그 동의어입니다.
영상, 오디오, 화이트 밸런스와 이득 관련 ID의 형식과 의미입니다.
`V4L2_CID_AUDIO_MUTE`는 `V4L2_CID_AUDIO_VOLUME`을 보존한 채 출력을 0으로 만듭니다. 과도한 소음을 막기 위해 ALSA와 마찬가지로 V4L2 드라이버도 로드 시 음소거해야 하며, 전체 장치는 저전력 상태로 초기화하는 것이 바람직합니다.
`DO_WHITE_BALANCE`는 설정값을 무시하고 한 번 동작하는 button 컨트롤인 반면 `AUTO_WHITE_BALANCE`는 활성화된 동안 계속 조정합니다. 폐기된 `BLACK_LEVEL`과 `WHITENESS`는 새 드라이버와 애플리케이션에서 사용하면 안 됩니다.
일반 `GAIN`은 주로 TV 튜너와 웹캠에서 쓰이며 대부분 디지털 이득만 조절하지만 일부 장치는 아날로그 이득까지 포함합니다. 두 종류를 구분하는 장치는 전용 DIGITAL_GAIN과 ANALOGUE_GAIN을 사용합니다.
.. _control-id:
Control IDs
===========
``V4L2_CID_BASE``
First predefined ID, equal to ``V4L2_CID_BRIGHTNESS``.
``V4L2_CID_USER_BASE``
Synonym of ``V4L2_CID_BASE``.
``V4L2_CID_BRIGHTNESS`` ``(integer)``
Picture brightness, or more precisely, the black level.
``V4L2_CID_CONTRAST`` ``(integer)``
Picture contrast or luma gain.
``V4L2_CID_SATURATION`` ``(integer)``
Picture color saturation or chroma gain.
``V4L2_CID_HUE`` ``(integer)``
Hue or color balance.
``V4L2_CID_AUDIO_VOLUME`` ``(integer)``
Overall audio volume. Note some drivers also provide an OSS or ALSA
mixer interface.
``V4L2_CID_AUDIO_BALANCE`` ``(integer)``
Audio stereo balance. Minimum corresponds to all the way left,
maximum to right.
``V4L2_CID_AUDIO_BASS`` ``(integer)``
Audio bass adjustment.
``V4L2_CID_AUDIO_TREBLE`` ``(integer)``
Audio treble adjustment.
``V4L2_CID_AUDIO_MUTE`` ``(boolean)``
Mute audio, i. e. set the volume to zero, however without affecting
``V4L2_CID_AUDIO_VOLUME``. Like ALSA drivers, V4L2 drivers must mute
at load time to avoid excessive noise. Actually the entire device
should be reset to a low power consumption state.
``V4L2_CID_AUDIO_LOUDNESS`` ``(boolean)``
Loudness mode (bass boost).
``V4L2_CID_BLACK_LEVEL`` ``(integer)``
Another name for brightness (not a synonym of
``V4L2_CID_BRIGHTNESS``). This control is deprecated and should not
be used in new drivers and applications.
``V4L2_CID_AUTO_WHITE_BALANCE`` ``(boolean)``
Automatic white balance (cameras).
``V4L2_CID_DO_WHITE_BALANCE`` ``(button)``
This is an action control. When set (the value is ignored), the
device will do a white balance and then hold the current setting.
Contrast this with the boolean ``V4L2_CID_AUTO_WHITE_BALANCE``,
which, when activated, keeps adjusting the white balance.
``V4L2_CID_RED_BALANCE`` ``(integer)``
Red chroma balance.
``V4L2_CID_BLUE_BALANCE`` ``(integer)``
Blue chroma balance.
``V4L2_CID_GAMMA`` ``(integer)``
Gamma adjust.
``V4L2_CID_WHITENESS`` ``(integer)``
Whiteness for grey-scale devices. This is a synonym for
``V4L2_CID_GAMMA``. This control is deprecated and should not be
used in new drivers and applications.
``V4L2_CID_EXPOSURE`` ``(integer)``
Exposure (cameras). [Unit?]
``V4L2_CID_AUTOGAIN`` ``(boolean)``
Automatic gain/exposure control.
``V4L2_CID_GAIN`` ``(integer)``
Gain control.
Primarily used to control gain on e.g. TV tuners but also on
webcams. Most devices control only digital gain with this control
but on some this could include analogue gain as well. Devices that
recognise the difference between digital and analogue gain use
controls ``V4L2_CID_DIGITAL_GAIN`` and ``V4L2_CID_ANALOGUE_GAIN``.
반전·전원 주파수·카메라 영상 컨트롤
146-199반전, 자동 조정과 색 신호 보정 ID입니다.
enum v4l2_power_line_frequency의 네 값입니다.
자동 hue 제어가 켜진 동안 `V4L2_CID_HUE`를 설정한 결과는 정의되지 않으며 드라이버는 이 요청을 무시해야 합니다.
화이트 밸런스 색온도는 Kelvin으로 표현하며 드라이버는 적어도 백열광 2800 K부터 주광 6500 K까지의 범위를 제공해야 합니다.
.. _v4l2-cid-hflip:
``V4L2_CID_HFLIP`` ``(boolean)``
Mirror the picture horizontally.
.. _v4l2-cid-vflip:
``V4L2_CID_VFLIP`` ``(boolean)``
Mirror the picture vertically.
.. _v4l2-power-line-frequency:
``V4L2_CID_POWER_LINE_FREQUENCY`` ``(enum)``
Enables a power line frequency filter to avoid flicker. Possible
values for ``enum v4l2_power_line_frequency`` are:
========================================== ==
``V4L2_CID_POWER_LINE_FREQUENCY_DISABLED`` 0
``V4L2_CID_POWER_LINE_FREQUENCY_50HZ`` 1
``V4L2_CID_POWER_LINE_FREQUENCY_60HZ`` 2
``V4L2_CID_POWER_LINE_FREQUENCY_AUTO`` 3
========================================== ==
``V4L2_CID_HUE_AUTO`` ``(boolean)``
Enables automatic hue control by the device. The effect of setting
``V4L2_CID_HUE`` while automatic hue control is enabled is
undefined, drivers should ignore such request.
``V4L2_CID_WHITE_BALANCE_TEMPERATURE`` ``(integer)``
This control specifies the white balance settings as a color
temperature in Kelvin. A driver should have a minimum of 2800
(incandescent) to 6500 (daylight). For more information about color
temperature see
`Wikipedia <http://en.wikipedia.org/wiki/Color_temperature>`__.
``V4L2_CID_SHARPNESS`` ``(integer)``
Adjusts the sharpness filters in a camera. The minimum value
disables the filters, higher values give a sharper picture.
``V4L2_CID_BACKLIGHT_COMPENSATION`` ``(integer)``
Adjusts the backlight compensation in a camera. The minimum value
disables backlight compensation.
``V4L2_CID_CHROMA_AGC`` ``(boolean)``
Chroma automatic gain control.
``V4L2_CID_CHROMA_GAIN`` ``(integer)``
Adjusts the Chroma gain control (for use when chroma AGC is
disabled).
``V4L2_CID_COLOR_KILLER`` ``(boolean)``
Enable the color killer (i. e. force a black & white image in case
of a weak video signal).
색 효과와 고정 성분
200-266`V4L2_CID_COLORFX`는 장치가 적용할 색 효과를 열거형으로 선택합니다. 고정 CbCr 또는 RGB 효과는 별도 컨트롤의 packed 32비트 값과 함께 사용합니다.
V4L2_COLORFX 열거형 17개 값의 의미입니다.
두 32비트 컨트롤은 성분 순서와 예약 비트가 다릅니다.
`SET_RGB`와 `SET_CBCR`를 선택하지 않은 경우 이 두 packed 성분 컨트롤은 해당 효과에 사용되지 않습니다. 예약 상위 비트는 반드시 0이어야 합니다.
.. _v4l2-colorfx:
``V4L2_CID_COLORFX`` ``(enum)``
Selects a color effect. The following values are defined:
.. tabularcolumns:: |p{5.7cm}|p{11.8cm}|
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 11 24
* - ``V4L2_COLORFX_NONE``
- Color effect is disabled.
* - ``V4L2_COLORFX_ANTIQUE``
- An aging (old photo) effect.
* - ``V4L2_COLORFX_ART_FREEZE``
- Frost color effect.
* - ``V4L2_COLORFX_AQUA``
- Water color, cool tone.
* - ``V4L2_COLORFX_BW``
- Black and white.
* - ``V4L2_COLORFX_EMBOSS``
- Emboss, the highlights and shadows replace light/dark boundaries
and low contrast areas are set to a gray background.
* - ``V4L2_COLORFX_GRASS_GREEN``
- Grass green.
* - ``V4L2_COLORFX_NEGATIVE``
- Negative.
* - ``V4L2_COLORFX_SEPIA``
- Sepia tone.
* - ``V4L2_COLORFX_SKETCH``
- Sketch.
* - ``V4L2_COLORFX_SKIN_WHITEN``
- Skin whiten.
* - ``V4L2_COLORFX_SKY_BLUE``
- Sky blue.
* - ``V4L2_COLORFX_SOLARIZATION``
- Solarization, the image is partially reversed in tone, only color
values above or below a certain threshold are inverted.
* - ``V4L2_COLORFX_SILHOUETTE``
- Silhouette (outline).
* - ``V4L2_COLORFX_VIVID``
- Vivid colors.
* - ``V4L2_COLORFX_SET_CBCR``
- The Cb and Cr chroma components are replaced by fixed coefficients
determined by ``V4L2_CID_COLORFX_CBCR`` control.
* - ``V4L2_COLORFX_SET_RGB``
- The RGB components are replaced by the fixed RGB components determined
by ``V4L2_CID_COLORFX_RGB`` control.
``V4L2_CID_COLORFX_RGB`` ``(integer)``
Determines the Red, Green, and Blue coefficients for
``V4L2_COLORFX_SET_RGB`` color effect.
Bits [7:0] of the supplied 32 bit value are interpreted as Blue component,
bits [15:8] as Green component, bits [23:16] as Red component, and
bits [31:24] must be zero.
``V4L2_CID_COLORFX_CBCR`` ``(integer)``
Determines the Cb and Cr coefficients for ``V4L2_COLORFX_SET_CBCR``
color effect. Bits [7:0] of the supplied 32 bit value are
interpreted as Cr component, bits [15:8] as Cb component and bits
[31:16] must be zero.
회전·배경·버퍼·알파와 ID 경계
267-326형식 배치와 코덱 큐 동작까지 영향을 주는 ID입니다.
90도 또는 270도 회전은 표시 창의 폭과 높이를 서로 바꿉니다. 선택한 각도에 맞춰 `VIDIOC_S_FMT`으로 새 폭과 높이를 반드시 설정해야 합니다.
배경색 packed 값은 [7:0] Red, [15:8] Green, [23:16] Blue이고 [31:24]는 0입니다. 앞 절의 `COLORFX_RGB`가 낮은 바이트부터 Blue, Green, Red인 것과 순서가 다릅니다.
최소 버퍼 컨트롤은 애플리케이션이 `REQBUFS`에 전달할 개수를 정하는 힌트입니다. CAPTURE 쪽은 stateful decoder, OUTPUT 쪽은 stateful encoder에서 필수입니다.
ALPHA_COMPONENT는 캡처 형식에 alpha가 있지만 장치나 mem-to-mem 입력이 값을 정하지 못할 때 출력할 모든 픽셀의 alpha를 선택합니다. 반대로 alpha 없는 출력 프레임을 소비하면서 장치가 alpha 처리를 지원할 때 내부 후처리용 alpha를 지정합니다.
custom 컨트롤에 의존하는 애플리케이션은 `querycap`으로 드라이버 이름과 버전을 확인해야 합니다.
``V4L2_CID_AUTOBRIGHTNESS`` ``(boolean)``
Enable Automatic Brightness.
``V4L2_CID_ROTATE`` ``(integer)``
Rotates the image by specified angle. Common angles are 90, 270 and
180. Rotating the image to 90 and 270 will reverse the height and
width of the display window. It is necessary to set the new height
and width of the picture using the
:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl according to the
rotation angle selected.
``V4L2_CID_BG_COLOR`` ``(integer)``
Sets the background color on the current output device. Background
color needs to be specified in the RGB24 format. The supplied 32 bit
value is interpreted as bits 0-7 Red color information, bits 8-15
Green color information, bits 16-23 Blue color information and bits
24-31 must be zero.
``V4L2_CID_ILLUMINATORS_1 V4L2_CID_ILLUMINATORS_2`` ``(boolean)``
Switch on or off the illuminator 1 or 2 of the device (usually a
microscope).
``V4L2_CID_MIN_BUFFERS_FOR_CAPTURE`` ``(integer)``
This is a read-only control that can be read by the application and
used as a hint to determine the number of CAPTURE buffers to pass to
REQBUFS. The value is the minimum number of CAPTURE buffers that is
necessary for hardware to work. This control is required for stateful
decoders.
``V4L2_CID_MIN_BUFFERS_FOR_OUTPUT`` ``(integer)``
This is a read-only control that can be read by the application and
used as a hint to determine the number of OUTPUT buffers to pass to
REQBUFS. The value is the minimum number of OUTPUT buffers that is
necessary for hardware to work. This control is required for stateful
encoders.
.. _v4l2-alpha-component:
``V4L2_CID_ALPHA_COMPONENT`` ``(integer)``
Sets the alpha color component. When a capture device (or capture
queue of a mem-to-mem device) produces a frame format that includes
an alpha component (e.g.
:ref:`packed RGB image formats <pixfmt-rgb>`) and the alpha value
is not defined by the device or the mem-to-mem input data this
control lets you select the alpha component value of all pixels.
When an output device (or output queue of a mem-to-mem device)
consumes a frame format that doesn't include an alpha component and
the device supports alpha channel processing this control lets you
set the alpha component value of all pixels for further processing
in the device.
``V4L2_CID_LASTP1``
End of the predefined control IDs (currently
``V4L2_CID_ALPHA_COMPONENT`` + 1).
``V4L2_CID_PRIVATE_BASE``
ID of the first custom (driver specific) control. Applications
depending on particular custom controls should check the driver name
and version, see :ref:`querycap`.
컨트롤 조회·열거·읽기·쓰기 ioctl
327-336애플리케이션은 `VIDIOC_QUERYCTRL`과 `VIDIOC_QUERYMENU`로 사용 가능한 컨트롤과 메뉴를 열거하고, `VIDIOC_G_CTRL`과 `VIDIOC_S_CTRL`로 현재값을 읽고 씁니다.
컨트롤이 하나 이상인 드라이버는 QUERYCTRL, G_CTRL, S_CTRL을 구현해야 합니다. 메뉴형 컨트롤이 하나 이상이면 QUERYMENU도 구현해야 합니다. 복합 컨트롤의 확장 속성 열거에는 `VIDIOC_QUERY_EXT_CTRL`을 사용합니다.
기본 및 확장 컨트롤 인터페이스의 핵심 요청입니다.
Applications can enumerate the available controls with the
:ref:`VIDIOC_QUERYCTRL` and
:ref:`VIDIOC_QUERYMENU <VIDIOC_QUERYCTRL>` ioctls, get and set a
control value with the :ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and
:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls. Drivers must implement
``VIDIOC_QUERYCTRL``, ``VIDIOC_G_CTRL`` and ``VIDIOC_S_CTRL`` when the
device has one or more controls, ``VIDIOC_QUERYMENU`` when it has one or
more menu type controls.
NEXT_CTRL로 모든 기본 컨트롤 열거
337-380첫 번째 예제는 `v4l2_queryctrl.id`를 `V4L2_CTRL_FLAG_NEXT_CTRL`로 시작합니다. QUERYCTRL이 반환한 ID에 같은 플래그를 OR하여 다음 컨트롤을 계속 요청합니다.
`V4L2_CTRL_FLAG_DISABLED`가 설정된 컨트롤은 건너뜁니다. 형식이 `V4L2_CTRL_TYPE_MENU`이면 minimum부터 maximum까지 QUERYMENU를 호출하고 성공한 메뉴 항목의 이름만 출력합니다.
모든 컨트롤을 지나면 QUERYCTRL이 `EINVAL`로 끝나는 것이 정상입니다. 다른 오류라면 진단을 출력하고 실패로 종료합니다.
ID 공간의 빈 구간을 직접 추측하지 않고 드라이버가 다음 ID를 반환하게 합니다.
.. _enum_all_controls:
Example: Enumerating all controls
=================================
.. code-block:: c
struct v4l2_queryctrl queryctrl;
struct v4l2_querymenu querymenu;
static void enumerate_menu(__u32 id)
{
printf(" Menu items:\\n");
memset(&querymenu, 0, sizeof(querymenu));
querymenu.id = id;
for (querymenu.index = queryctrl.minimum;
querymenu.index <= queryctrl.maximum;
querymenu.index++) {
if (0 == ioctl(fd, VIDIOC_QUERYMENU, &querymenu)) {
printf(" %s\\n", querymenu.name);
}
}
}
memset(&queryctrl, 0, sizeof(queryctrl));
queryctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
while (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
if (!(queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
printf("Control %s\\n", queryctrl.name);
if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
enumerate_menu(queryctrl.id);
}
queryctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
}
if (errno != EINVAL) {
perror("VIDIOC_QUERYCTRL");
exit(EXIT_FAILURE);
}
복합 컨트롤을 포함한 열거
381-405복합 컨트롤까지 포함하려면 `struct v4l2_query_ext_ctrl`과 `VIDIOC_QUERY_EXT_CTRL`을 사용합니다. 초기 ID에는 `V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND`를 함께 넣습니다.
반환된 컨트롤을 처리한 뒤 두 플래그를 다시 OR하여 다음 기본 또는 복합 컨트롤로 이동합니다. 종료 조건과 DISABLED·MENU 처리는 기본 열거 예제와 같습니다.
확장 QUERY 요청이 기본·복합 ID를 모두 순회합니다.
Example: Enumerating all controls including compound controls
=============================================================
.. code-block:: c
struct v4l2_query_ext_ctrl query_ext_ctrl;
memset(&query_ext_ctrl, 0, sizeof(query_ext_ctrl));
query_ext_ctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
while (0 == ioctl(fd, VIDIOC_QUERY_EXT_CTRL, &query_ext_ctrl)) {
if (!(query_ext_ctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
printf("Control %s\\n", query_ext_ctrl.name);
if (query_ext_ctrl.type == V4L2_CTRL_TYPE_MENU)
enumerate_menu(query_ext_ctrl.id);
}
query_ext_ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
}
if (errno != EINVAL) {
perror("VIDIOC_QUERY_EXT_CTRL");
exit(EXIT_FAILURE);
}
구식 사용자 컨트롤 열거
406-453구식 예제는 `V4L2_CID_BASE`부터 `V4L2_CID_LASTP1` 직전까지 모든 정수 ID를 QUERYCTRL로 시험합니다. `EINVAL`은 빈 ID로 보고 계속하며 다른 오류만 치명적으로 처리합니다.
그 다음 `V4L2_CID_PRIVATE_BASE`부터 ID를 증가시키며 custom 컨트롤을 조회하고 첫 `EINVAL`에서 끝냅니다. 성공한 DISABLED 컨트롤은 건너뛰고 MENU는 항목까지 열거합니다.
새 코드는 ID가 연속이라는 가정이 없는 NEXT_CTRL 방식을 사용해야 합니다. 구식 방식은 표준 범위와 private 범위를 별도 루프로 훑어야 하고 custom ID 빈 구간 처리에도 취약합니다.
새로운 NEXT_CTRL 방식이 권장되는 이유입니다.
Example: Enumerating all user controls (old style)
==================================================
.. code-block:: c
memset(&queryctrl, 0, sizeof(queryctrl));
for (queryctrl.id = V4L2_CID_BASE;
queryctrl.id < V4L2_CID_LASTP1;
queryctrl.id++) {
if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
continue;
printf("Control %s\\n", queryctrl.name);
if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
enumerate_menu(queryctrl.id);
} else {
if (errno == EINVAL)
continue;
perror("VIDIOC_QUERYCTRL");
exit(EXIT_FAILURE);
}
}
for (queryctrl.id = V4L2_CID_PRIVATE_BASE;;
queryctrl.id++) {
if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
continue;
printf("Control %s\\n", queryctrl.name);
if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
enumerate_menu(queryctrl.id);
} else {
if (errno == EINVAL)
break;
perror("VIDIOC_QUERYCTRL");
exit(EXIT_FAILURE);
}
}
컨트롤 값 변경 예제
454-509밝기 예제는 먼저 `V4L2_CID_BRIGHTNESS`를 QUERYCTRL로 조회합니다. `EINVAL` 또는 DISABLED이면 미지원으로 알리고, 지원되면 `struct v4l2_control`에 기본값을 넣어 S_CTRL로 설정합니다.
대비 예제는 G_CTRL로 현재값을 얻어 1 증가시킨 뒤 S_CTRL로 씁니다. 드라이버는 값을 범위에 맞춰 clamp하거나 `ERANGE`를 반환할 수 있으며 예제는 ERANGE를 무시합니다.
CONTRAST 자체가 미지원이라 G_CTRL이 `EINVAL`을 반환한 경우도 무시합니다. 그 밖의 G_CTRL 또는 S_CTRL 오류는 치명적으로 처리합니다.
마지막으로 `V4L2_CID_AUDIO_MUTE`에 값 1을 설정해 음소거하고, 이 호출의 오류는 의도적으로 무시합니다.
지원 여부와 범위를 확인한 뒤 값을 설정하는 패턴입니다.
Example: Changing controls
==========================
.. code-block:: c
struct v4l2_queryctrl queryctrl;
struct v4l2_control control;
memset(&queryctrl, 0, sizeof(queryctrl));
queryctrl.id = V4L2_CID_BRIGHTNESS;
if (-1 == ioctl(fd, VIDIOC_QUERYCTRL, &queryctrl)) {
if (errno != EINVAL) {
perror("VIDIOC_QUERYCTRL");
exit(EXIT_FAILURE);
} else {
printf("V4L2_CID_BRIGHTNESS is not supported\n");
}
} else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
printf("V4L2_CID_BRIGHTNESS is not supported\n");
} else {
memset(&control, 0, sizeof (control));
control.id = V4L2_CID_BRIGHTNESS;
control.value = queryctrl.default_value;
if (-1 == ioctl(fd, VIDIOC_S_CTRL, &control)) {
perror("VIDIOC_S_CTRL");
exit(EXIT_FAILURE);
}
}
memset(&control, 0, sizeof(control));
control.id = V4L2_CID_CONTRAST;
if (0 == ioctl(fd, VIDIOC_G_CTRL, &control)) {
control.value += 1;
/* The driver may clamp the value or return ERANGE, ignored here */
if (-1 == ioctl(fd, VIDIOC_S_CTRL, &control)
&& errno != ERANGE) {
perror("VIDIOC_S_CTRL");
exit(EXIT_FAILURE);
}
/* Ignore if V4L2_CID_CONTRAST is unsupported */
} else if (errno != EINVAL) {
perror("VIDIOC_G_CTRL");
exit(EXIT_FAILURE);
}
control.id = V4L2_CID_AUDIO_MUTE;
control.value = 1; /* silence */
/* Errors ignored */
ioctl(fd, VIDIOC_S_CTRL, &control);
PRIVATE_BASE의 별칭과 호환성
510-523`V4L2_CID_PRIVATE_BASE`는 여러 드라이버가 같은 숫자 ID를 서로 다른 의미로 사용할 수 있어 프로그램 방식 제어가 어렵습니다. ID의 의미가 드라이버에 종속되기 때문입니다.
이를 해결하기 위해 드라이버는 고유 ID를 사용하고 커널이 기존 PRIVATE_BASE ID를 실제 고유 ID로 매핑합니다. 따라서 PRIVATE_BASE 계열 ID는 실제 ID의 호환성 별칭으로 봐야 합니다.
오늘날에도 많은 애플리케이션이 `VIDIOC_QUERYCTRL`과 `V4L2_CTRL_FLAG_NEXT_CTRL`로 모든 ID를 열거하지 않고 PRIVATE_BASE ID를 직접 사용하므로 이 호환 지원이 남아 있습니다.
숫자 충돌을 고유 ID와 커널 별칭으로 완화합니다.
.. [#f1]
The use of ``V4L2_CID_PRIVATE_BASE`` is problematic because different
drivers may use the same ``V4L2_CID_PRIVATE_BASE`` ID for different
controls. This makes it hard to programmatically set such controls
since the meaning of the control with that ID is driver dependent. In
order to resolve this drivers use unique IDs and the
``V4L2_CID_PRIVATE_BASE`` IDs are mapped to those unique IDs by the
kernel. Consider these ``V4L2_CID_PRIVATE_BASE`` IDs as aliases to
the real IDs.
Many applications today still use the ``V4L2_CID_PRIVATE_BASE`` IDs
instead of using :ref:`VIDIOC_QUERYCTRL` with
the ``V4L2_CTRL_FLAG_NEXT_CTRL`` flag to enumerate all IDs, so
support for ``V4L2_CID_PRIVATE_BASE`` is still around.
요약·해설
control.rst:1-523장치마다 다른 컨트롤을 하드코딩하지 않고 속성 조회와 NEXT_CTRL 열거로 발견한 뒤, 이름·형식·범위·동적 상태를 반영해 UI와 제어 코드를 만드는 기준 문서입니다.