요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. _standard:
***************
Video Standards
***************
Video devices typically support one or more different video standards or
variations of standards. Each video input and output may support another
set of standards. This set is reported by the ``std`` field of struct
:c:type:`v4l2_input` and struct
:c:type:`v4l2_output` returned by the
:ref:`VIDIOC_ENUMINPUT` and
:ref:`VIDIOC_ENUMOUTPUT` ioctls, respectively.
V4L2 defines one bit for each analog video standard currently in use
worldwide, and sets aside bits for driver defined standards, e. g.
hybrid standards to watch NTSC video tapes on PAL TVs and vice versa.
Applications can use the predefined bits to select a particular
standard, although presenting the user a menu of supported standards is
preferred. To enumerate and query the attributes of the supported
standards applications use the :ref:`VIDIOC_ENUMSTD`
ioctl.
Many of the defined standards are actually just variations of a few
major standards. The hardware may in fact not distinguish between them,
or do so internal and switch automatically. Therefore enumerated
standards also contain sets of one or more standard bits.
Assume a hypothetic tuner capable of demodulating B/PAL, G/PAL and I/PAL
signals. The first enumerated standard is a set of B and G/PAL, switched
automatically depending on the selected radio frequency in UHF or VHF
band. Enumeration gives a "PAL-B/G" or "PAL-I" choice. Similar a
Composite input may collapse standards, enumerating "PAL-B/G/H/I",
"NTSC-M" and "SECAM-D/K". [#f1]_
To query and select the standard used by the current video input or
output applications call the :ref:`VIDIOC_G_STD <VIDIOC_G_STD>` and
:ref:`VIDIOC_S_STD <VIDIOC_G_STD>` ioctl, respectively. The
*received* standard can be sensed with the
:ref:`VIDIOC_QUERYSTD` ioctl.
.. note::
The parameter of all these ioctls is a pointer to a
:ref:`v4l2_std_id <v4l2-std-id>` type (a standard set), *not* an
index into the standard enumeration. Drivers must implement all video
standard ioctls when the device has one or more video inputs or outputs.
Special rules apply to devices such as USB cameras where the notion of
video standards makes little sense. More generally for any capture or
output device which is:
- incapable of capturing fields or frames at the nominal rate of the
video standard, or
- that does not support the video standard formats at all.
Here the driver shall set the ``std`` field of struct
:c:type:`v4l2_input` and struct
:c:type:`v4l2_output` to zero and the :ref:`VIDIOC_G_STD <VIDIOC_G_STD>`,
:ref:`VIDIOC_S_STD <VIDIOC_G_STD>`, :ref:`VIDIOC_QUERYSTD` and :ref:`VIDIOC_ENUMSTD` ioctls
shall return the ``ENOTTY`` error code or the ``EINVAL`` error code.
Applications can make use of the :ref:`input-capabilities` and
:ref:`output-capabilities` flags to determine whether the video
standard ioctls can be used with the given input or output.
Example: Information about the current video standard
=====================================================
.. code-block:: c
v4l2_std_id std_id;
struct v4l2_standard standard;
if (-1 == ioctl(fd, VIDIOC_G_STD, &std_id)) {
/* Note when VIDIOC_ENUMSTD always returns ENOTTY this
is no video device or it falls under the USB exception,
and VIDIOC_G_STD returning ENOTTY is no error. */
perror("VIDIOC_G_STD");
exit(EXIT_FAILURE);
}
memset(&standard, 0, sizeof(standard));
standard.index = 0;
while (0 == ioctl(fd, VIDIOC_ENUMSTD, &standard)) {
if (standard.id & std_id) {
printf("Current video standard: %s\\n", standard.name);
exit(EXIT_SUCCESS);
}
standard.index++;
}
/* EINVAL indicates the end of the enumeration, which cannot be
empty unless this device falls under the USB exception. */
if (errno == EINVAL || standard.index == 0) {
perror("VIDIOC_ENUMSTD");
exit(EXIT_FAILURE);
}
Example: Listing the video standards supported by the current input
===================================================================
.. code-block:: c
struct v4l2_input input;
struct v4l2_standard standard;
memset(&input, 0, sizeof(input));
if (-1 == ioctl(fd, VIDIOC_G_INPUT, &input.index)) {
perror("VIDIOC_G_INPUT");
exit(EXIT_FAILURE);
}
if (-1 == ioctl(fd, VIDIOC_ENUMINPUT, &input)) {
perror("VIDIOC_ENUM_INPUT");
exit(EXIT_FAILURE);
}
printf("Current input %s supports:\\n", input.name);
memset(&standard, 0, sizeof(standard));
standard.index = 0;
while (0 == ioctl(fd, VIDIOC_ENUMSTD, &standard)) {
if (standard.id & input.std)
printf("%s\\n", standard.name);
standard.index++;
}
/* EINVAL indicates the end of the enumeration, which cannot be
empty unless this device falls under the USB exception. */
if (errno != EINVAL || standard.index == 0) {
perror("VIDIOC_ENUMSTD");
exit(EXIT_FAILURE);
}
Example: Selecting a new video standard
=======================================
.. code-block:: c
struct v4l2_input input;
v4l2_std_id std_id;
memset(&input, 0, sizeof(input));
if (-1 == ioctl(fd, VIDIOC_G_INPUT, &input.index)) {
perror("VIDIOC_G_INPUT");
exit(EXIT_FAILURE);
}
if (-1 == ioctl(fd, VIDIOC_ENUMINPUT, &input)) {
perror("VIDIOC_ENUM_INPUT");
exit(EXIT_FAILURE);
}
if (0 == (input.std & V4L2_STD_PAL_BG)) {
fprintf(stderr, "Oops. B/G PAL is not supported.\\n");
exit(EXIT_FAILURE);
}
/* Note this is also supposed to work when only B
or G/PAL is supported. */
std_id = V4L2_STD_PAL_BG;
if (-1 == ioctl(fd, VIDIOC_S_STD, &std_id)) {
perror("VIDIOC_S_STD");
exit(EXIT_FAILURE);
}
.. [#f1]
Some users are already confused by technical terms PAL, NTSC and
SECAM. There is no point asking them to distinguish between B, G, D,
or K when the software or hardware can do that automatically.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
표준 집합의 열거와 선택
1-49비디오 장치는 보통 하나 이상의 비디오 표준 또는 그 변형을 지원하며, 입력과 출력마다 지원 집합이 다를 수 있습니다. `VIDIOC_ENUMINPUT`과 `VIDIOC_ENUMOUTPUT`이 돌려주는 `v4l2_input.std` 및 `v4l2_output.std` 필드가 해당 집합을 나타냅니다.
V4L2는 세계에서 사용되는 각 아날로그 비디오 표준에 비트를 하나씩 정의하고, PAL TV에서 NTSC 비디오테이프를 보는 혼합 표준처럼 드라이버가 정의하는 표준에도 비트를 남겨 둡니다. 응용 프로그램은 미리 정의된 비트를 직접 선택할 수 있지만, 일반적으로는 `VIDIOC_ENUMSTD`로 지원 표준과 속성을 열거해 사용자에게 메뉴로 제시하는 편이 좋습니다.
많은 표준은 몇 가지 주요 표준의 변형입니다. 하드웨어가 변형을 구분하지 않거나 내부에서 자동 전환할 수 있으므로, 열거된 항목 하나가 여러 표준 비트의 집합일 수 있습니다. 예를 들어 B/PAL과 G/PAL을 주파수 대역에 따라 자동 전환하는 튜너는 이를 하나의 PAL-B/G 항목으로 열거할 수 있습니다.
현재 입력 또는 출력에 적용되는 표준을 조회하고 설정하는 호출입니다.
이 ioctl들의 인수는 표준 열거 인덱스가 아니라 표준 집합을 담는 `v4l2_std_id` 포인터입니다. 장치에 하나 이상의 비디오 입력이나 출력이 있으면 드라이버는 모든 비디오 표준 ioctl을 구현해야 합니다.
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. _standard:
***************
Video Standards
***************
Video devices typically support one or more different video standards or
variations of standards. Each video input and output may support another
set of standards. This set is reported by the ``std`` field of struct
:c:type:`v4l2_input` and struct
:c:type:`v4l2_output` returned by the
:ref:`VIDIOC_ENUMINPUT` and
:ref:`VIDIOC_ENUMOUTPUT` ioctls, respectively.
V4L2 defines one bit for each analog video standard currently in use
worldwide, and sets aside bits for driver defined standards, e. g.
hybrid standards to watch NTSC video tapes on PAL TVs and vice versa.
Applications can use the predefined bits to select a particular
standard, although presenting the user a menu of supported standards is
preferred. To enumerate and query the attributes of the supported
standards applications use the :ref:`VIDIOC_ENUMSTD`
ioctl.
Many of the defined standards are actually just variations of a few
major standards. The hardware may in fact not distinguish between them,
or do so internal and switch automatically. Therefore enumerated
standards also contain sets of one or more standard bits.
Assume a hypothetic tuner capable of demodulating B/PAL, G/PAL and I/PAL
signals. The first enumerated standard is a set of B and G/PAL, switched
automatically depending on the selected radio frequency in UHF or VHF
band. Enumeration gives a "PAL-B/G" or "PAL-I" choice. Similar a
Composite input may collapse standards, enumerating "PAL-B/G/H/I",
"NTSC-M" and "SECAM-D/K". [#f1]_
To query and select the standard used by the current video input or
output applications call the :ref:`VIDIOC_G_STD <VIDIOC_G_STD>` and
:ref:`VIDIOC_S_STD <VIDIOC_G_STD>` ioctl, respectively. The
*received* standard can be sensed with the
:ref:`VIDIOC_QUERYSTD` ioctl.
.. note::
The parameter of all these ioctls is a pointer to a
:ref:`v4l2_std_id <v4l2-std-id>` type (a standard set), *not* an
index into the standard enumeration. Drivers must implement all video
standard ioctls when the device has one or more video inputs or outputs.
표준 개념이 적용되지 않는 장치
50-68USB 카메라처럼 비디오 표준 개념이 의미가 없거나, 표준의 명목 필드·프레임 속도로 캡처할 수 없거나, 표준 형식 자체를 지원하지 않는 장치에는 특별 규칙이 적용됩니다.
이 경우 드라이버는 `v4l2_input.std`와 `v4l2_output.std`를 0으로 설정하고 `VIDIOC_G_STD`, `VIDIOC_S_STD`, `VIDIOC_QUERYSTD`, `VIDIOC_ENUMSTD`에서 `ENOTTY` 또는 `EINVAL`을 반환해야 합니다. 응용 프로그램은 입력 및 출력 capability 플래그를 확인해 표준 ioctl 사용 가능 여부를 판별할 수 있습니다.
Special rules apply to devices such as USB cameras where the notion of
video standards makes little sense. More generally for any capture or
output device which is:
- incapable of capturing fields or frames at the nominal rate of the
video standard, or
- that does not support the video standard formats at all.
Here the driver shall set the ``std`` field of struct
:c:type:`v4l2_input` and struct
:c:type:`v4l2_output` to zero and the :ref:`VIDIOC_G_STD <VIDIOC_G_STD>`,
:ref:`VIDIOC_S_STD <VIDIOC_G_STD>`, :ref:`VIDIOC_QUERYSTD` and :ref:`VIDIOC_ENUMSTD` ioctls
shall return the ``ENOTTY`` error code or the ``EINVAL`` error code.
Applications can make use of the :ref:`input-capabilities` and
:ref:`output-capabilities` flags to determine whether the video
standard ioctls can be used with the given input or output.
현재 비디오 표준 확인 예제
69-106먼저 `VIDIOC_G_STD`로 현재 표준 비트 집합을 얻고, `VIDIOC_ENUMSTD`로 표준을 순회하면서 `standard.id & std_id`가 참인 항목을 찾습니다. `VIDIOC_ENUMSTD`가 항상 `ENOTTY`를 반환하는 USB 예외 장치에서는 `VIDIOC_G_STD`의 `ENOTTY`도 오류로 취급하지 않아야 합니다.
열거 중 `EINVAL`은 목록의 끝을 뜻합니다. 다만 하나도 열거하지 못했다면 장치가 USB 예외에 해당하지 않는 한 오류입니다.
v4l2_std_id std_id;
struct v4l2_standard standard;
ioctl(fd, VIDIOC_G_STD, &std_id);
standard.index = 0;
while (0 == ioctl(fd, VIDIOC_ENUMSTD, &standard)) {
if (standard.id & std_id)
printf("Current video standard: %s\n", standard.name);
standard.index++;
}
Example: Information about the current video standard
=====================================================
.. code-block:: c
v4l2_std_id std_id;
struct v4l2_standard standard;
if (-1 == ioctl(fd, VIDIOC_G_STD, &std_id)) {
/* Note when VIDIOC_ENUMSTD always returns ENOTTY this
is no video device or it falls under the USB exception,
and VIDIOC_G_STD returning ENOTTY is no error. */
perror("VIDIOC_G_STD");
exit(EXIT_FAILURE);
}
memset(&standard, 0, sizeof(standard));
standard.index = 0;
while (0 == ioctl(fd, VIDIOC_ENUMSTD, &standard)) {
if (standard.id & std_id) {
printf("Current video standard: %s\\n", standard.name);
exit(EXIT_SUCCESS);
}
standard.index++;
}
/* EINVAL indicates the end of the enumeration, which cannot be
empty unless this device falls under the USB exception. */
if (errno == EINVAL || standard.index == 0) {
perror("VIDIOC_ENUMSTD");
exit(EXIT_FAILURE);
}
현재 입력이 지원하는 표준 열거
107-146`VIDIOC_G_INPUT`으로 현재 입력 인덱스를 얻고 `VIDIOC_ENUMINPUT`으로 입력 정보를 조회합니다. 그런 다음 모든 표준을 열거하면서 `standard.id & input.std`가 참인 항목만 출력하면 현재 입력이 지원하는 표준 목록을 얻을 수 있습니다.
정상적인 열거 종료 조건은 `errno == EINVAL`이고 적어도 한 항목이 있어야 합니다. 다른 오류이거나 목록이 비어 있으면 예외 장치가 아닌 한 실패로 처리합니다.
ioctl(fd, VIDIOC_G_INPUT, &input.index);
ioctl(fd, VIDIOC_ENUMINPUT, &input);
standard.index = 0;
while (0 == ioctl(fd, VIDIOC_ENUMSTD, &standard)) {
if (standard.id & input.std)
printf("%s\n", standard.name);
standard.index++;
}
Example: Listing the video standards supported by the current input
===================================================================
.. code-block:: c
struct v4l2_input input;
struct v4l2_standard standard;
memset(&input, 0, sizeof(input));
if (-1 == ioctl(fd, VIDIOC_G_INPUT, &input.index)) {
perror("VIDIOC_G_INPUT");
exit(EXIT_FAILURE);
}
if (-1 == ioctl(fd, VIDIOC_ENUMINPUT, &input)) {
perror("VIDIOC_ENUM_INPUT");
exit(EXIT_FAILURE);
}
printf("Current input %s supports:\\n", input.name);
memset(&standard, 0, sizeof(standard));
standard.index = 0;
while (0 == ioctl(fd, VIDIOC_ENUMSTD, &standard)) {
if (standard.id & input.std)
printf("%s\\n", standard.name);
standard.index++;
}
/* EINVAL indicates the end of the enumeration, which cannot be
empty unless this device falls under the USB exception. */
if (errno != EINVAL || standard.index == 0) {
perror("VIDIOC_ENUMSTD");
exit(EXIT_FAILURE);
}
새 비디오 표준 선택
147-185현재 입력 정보를 얻은 뒤 `input.std & V4L2_STD_PAL_BG`를 검사해 B/G PAL 지원 여부를 확인합니다. 지원된다면 `v4l2_std_id`에 `V4L2_STD_PAL_BG`를 넣고 `VIDIOC_S_STD`를 호출합니다. B 또는 G/PAL 중 하나만 지원하는 경우에도 이 호출이 동작해야 합니다.
if (0 == (input.std & V4L2_STD_PAL_BG)) {
fprintf(stderr, "B/G PAL is not supported.\n");
exit(EXIT_FAILURE);
}
std_id = V4L2_STD_PAL_BG;
ioctl(fd, VIDIOC_S_STD, &std_id);
소프트웨어나 하드웨어가 B, G, D, K 같은 변형을 자동으로 구분할 수 있다면 사용자에게 그 기술적 차이를 직접 선택하게 할 필요는 없습니다. PAL, NTSC, SECAM이라는 상위 구분만으로도 이미 복잡할 수 있기 때문입니다.
Example: Selecting a new video standard
=======================================
.. code-block:: c
struct v4l2_input input;
v4l2_std_id std_id;
memset(&input, 0, sizeof(input));
if (-1 == ioctl(fd, VIDIOC_G_INPUT, &input.index)) {
perror("VIDIOC_G_INPUT");
exit(EXIT_FAILURE);
}
if (-1 == ioctl(fd, VIDIOC_ENUMINPUT, &input)) {
perror("VIDIOC_ENUM_INPUT");
exit(EXIT_FAILURE);
}
if (0 == (input.std & V4L2_STD_PAL_BG)) {
fprintf(stderr, "Oops. B/G PAL is not supported.\\n");
exit(EXIT_FAILURE);
}
/* Note this is also supposed to work when only B
or G/PAL is supported. */
std_id = V4L2_STD_PAL_BG;
if (-1 == ioctl(fd, VIDIOC_S_STD, &std_id)) {
perror("VIDIOC_S_STD");
exit(EXIT_FAILURE);
}
.. [#f1]
Some users are already confused by technical terms PAL, NTSC and
SECAM. There is no point asking them to distinguish between B, G, D,
or K when the software or hardware can do that automatically.
요약·해설
standard.rst:1-185아날로그 비디오 표준 집합을 열거·조회·선택하는 ioctl과 예외 규칙을 설명합니다.