요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. _osd:
******************************
Video Output Overlay Interface
******************************
**Also known as On-Screen Display (OSD)**
Some video output devices can overlay a framebuffer image onto the
outgoing video signal. Applications can set up such an overlay using
this interface, which borrows structures and ioctls of the
:ref:`Video Overlay <overlay>` interface.
The OSD function is accessible through the same character special file
as the :ref:`Video Output <capture>` function.
.. note::
The default function of such a ``/dev/video`` device is video
capturing or output. The OSD function is only available after calling
the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
Querying Capabilities
=====================
Devices supporting the *Video Output Overlay* interface set the
``V4L2_CAP_VIDEO_OUTPUT_OVERLAY`` flag in the ``capabilities`` field of
struct :c:type:`v4l2_capability` returned by the
:ref:`VIDIOC_QUERYCAP` ioctl.
Framebuffer
===========
Contrary to the *Video Overlay* interface the framebuffer is normally
implemented on the TV card and not the graphics card. On Linux it is
accessible as a framebuffer device (``/dev/fbN``). Given a V4L2 device,
applications can find the corresponding framebuffer device by calling
the :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` ioctl. It returns, amongst
other information, the physical address of the framebuffer in the
``base`` field of struct :c:type:`v4l2_framebuffer`.
The framebuffer device ioctl ``FBIOGET_FSCREENINFO`` returns the same
address in the ``smem_start`` field of struct
:c:type:`fb_fix_screeninfo`. The ``FBIOGET_FSCREENINFO``
ioctl and struct :c:type:`fb_fix_screeninfo` are defined in
the ``linux/fb.h`` header file.
The width and height of the framebuffer depends on the current video
standard. A V4L2 driver may reject attempts to change the video standard
(or any other ioctl which would imply a framebuffer size change) with an
``EBUSY`` error code until all applications closed the framebuffer device.
Example: Finding a framebuffer device for OSD
---------------------------------------------
.. code-block:: c
#include <linux/fb.h>
struct v4l2_framebuffer fbuf;
unsigned int i;
int fb_fd;
if (-1 == ioctl(fd, VIDIOC_G_FBUF, &fbuf)) {
perror("VIDIOC_G_FBUF");
exit(EXIT_FAILURE);
}
for (i = 0; i < 30; i++) {
char dev_name[16];
struct fb_fix_screeninfo si;
snprintf(dev_name, sizeof(dev_name), "/dev/fb%u", i);
fb_fd = open(dev_name, O_RDWR);
if (-1 == fb_fd) {
switch (errno) {
case ENOENT: /* no such file */
case ENXIO: /* no driver */
continue;
default:
perror("open");
exit(EXIT_FAILURE);
}
}
if (0 == ioctl(fb_fd, FBIOGET_FSCREENINFO, &si)) {
if (si.smem_start == (unsigned long)fbuf.base)
break;
} else {
/* Apparently not a framebuffer device. */
}
close(fb_fd);
fb_fd = -1;
}
/* fb_fd is the file descriptor of the framebuffer device
for the video output overlay, or -1 if no device was found. */
Overlay Window and Scaling
==========================
The overlay is controlled by source and target rectangles. The source
rectangle selects a subsection of the framebuffer image to be overlaid,
the target rectangle an area in the outgoing video signal where the
image will appear. Drivers may or may not support scaling, and arbitrary
sizes and positions of these rectangles. Further drivers may support any
(or none) of the clipping/blending methods defined for the
:ref:`Video Overlay <overlay>` interface.
A struct :c:type:`v4l2_window` defines the size of the
source rectangle, its position in the framebuffer and the
clipping/blending method to be used for the overlay. To get the current
parameters applications set the ``type`` field of a struct
:c:type:`v4l2_format` to
``V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY`` and call the
:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl. The driver fills the
struct :c:type:`v4l2_window` substructure named ``win``. It is not
possible to retrieve a previously programmed clipping list or bitmap.
To program the source rectangle applications set the ``type`` field of a
struct :c:type:`v4l2_format` to
``V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY``, initialize the ``win``
substructure and call the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
The driver adjusts the parameters against hardware limits and returns
the actual parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does. Like :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`,
the :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl can be used to learn
about driver capabilities without actually changing driver state. Unlike
:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` this also works after the overlay has been enabled.
A struct :c:type:`v4l2_crop` defines the size and position
of the target rectangle. The scaling factor of the overlay is implied by
the width and height given in struct :c:type:`v4l2_window`
and struct :c:type:`v4l2_crop`. The cropping API applies to
*Video Output* and *Video Output Overlay* devices in the same way as to
*Video Capture* and *Video Overlay* devices, merely reversing the
direction of the data flow. For more information see :ref:`crop`.
Enabling Overlay
================
There is no V4L2 ioctl to enable or disable the overlay, however the
framebuffer interface of the driver may support the ``FBIOBLANK`` ioctl.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
OSD 기능과 capability
1-34Video Output Overlay는 On-Screen Display, 즉 OSD라고도 합니다. 일부 video output 장치는 framebuffer 영상을 outgoing video signal 위에 겹칠 수 있으며, 이 인터페이스는 Video Overlay의 구조체와 ioctl을 빌려 OSD를 구성합니다.
OSD는 Video Output 기능과 같은 character special file을 통해 접근합니다. `/dev/video` 장치의 기본 기능은 video capture 또는 output이며, OSD 기능은 `VIDIOC_S_FMT`를 호출한 뒤에만 사용할 수 있습니다.
Video Output Overlay를 지원하는 장치는 `VIDIOC_QUERYCAP`이 반환하는 `struct v4l2_capability.capabilities`에 `V4L2_CAP_VIDEO_OUTPUT_OVERLAY`를 설정합니다.
같은 video node에서 output과 overlay 기능을 구분합니다.
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
.. _osd:
******************************
Video Output Overlay Interface
******************************
**Also known as On-Screen Display (OSD)**
Some video output devices can overlay a framebuffer image onto the
outgoing video signal. Applications can set up such an overlay using
this interface, which borrows structures and ioctls of the
:ref:`Video Overlay <overlay>` interface.
The OSD function is accessible through the same character special file
as the :ref:`Video Output <capture>` function.
.. note::
The default function of such a ``/dev/video`` device is video
capturing or output. The OSD function is only available after calling
the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
Querying Capabilities
=====================
Devices supporting the *Video Output Overlay* interface set the
``V4L2_CAP_VIDEO_OUTPUT_OVERLAY`` flag in the ``capabilities`` field of
struct :c:type:`v4l2_capability` returned by the
:ref:`VIDIOC_QUERYCAP` ioctl.
Framebuffer 장치 식별과 크기 제약
35-55Video Overlay와 달리 OSD framebuffer는 보통 graphics card가 아니라 TV card에 구현됩니다. Linux에서는 `/dev/fbN` framebuffer device로 접근합니다.
주어진 V4L2 장치에 대응하는 framebuffer를 찾으려면 `VIDIOC_G_FBUF`를 호출합니다. 반환된 `struct v4l2_framebuffer.base`에는 framebuffer의 physical address가 들어 있습니다.
framebuffer 장치의 `FBIOGET_FSCREENINFO`는 같은 주소를 `struct fb_fix_screeninfo.smem_start`에 반환합니다. ioctl과 구조체 정의는 `linux/fb.h`에 있습니다.
framebuffer 폭과 높이는 현재 video standard에 따라 달라집니다. 모든 애플리케이션이 framebuffer 장치를 닫을 때까지 V4L2 driver는 framebuffer 크기를 바꿀 수 있는 video standard 변경이나 다른 ioctl을 `EBUSY`로 거부할 수 있습니다.
두 API가 보고하는 같은 physical address를 비교합니다.
V4L2와 fbdev 구조체의 대응 address입니다.
Framebuffer
===========
Contrary to the *Video Overlay* interface the framebuffer is normally
implemented on the TV card and not the graphics card. On Linux it is
accessible as a framebuffer device (``/dev/fbN``). Given a V4L2 device,
applications can find the corresponding framebuffer device by calling
the :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` ioctl. It returns, amongst
other information, the physical address of the framebuffer in the
``base`` field of struct :c:type:`v4l2_framebuffer`.
The framebuffer device ioctl ``FBIOGET_FSCREENINFO`` returns the same
address in the ``smem_start`` field of struct
:c:type:`fb_fix_screeninfo`. The ``FBIOGET_FSCREENINFO``
ioctl and struct :c:type:`fb_fix_screeninfo` are defined in
the ``linux/fb.h`` header file.
The width and height of the framebuffer depends on the current video
standard. A V4L2 driver may reject attempts to change the video standard
(or any other ioctl which would imply a framebuffer size change) with an
``EBUSY`` error code until all applications closed the framebuffer device.
OSD framebuffer 검색 예제
56-105예제는 먼저 `VIDIOC_G_FBUF`로 OSD framebuffer의 base address를 얻은 뒤 `/dev/fb0`부터 `/dev/fb29`까지 순서대로 엽니다.
`open()`이 `ENOENT` 또는 `ENXIO`로 실패하면 파일이나 driver가 없는 것으로 보고 다음 번호로 넘어갑니다. 그 밖의 오류는 치명적으로 처리합니다.
열린 descriptor에 `FBIOGET_FSCREENINFO`를 호출하고 `si.smem_start`가 `fbuf.base`와 같으면 검색을 끝냅니다. 같지 않거나 framebuffer ioctl이 실패하면 descriptor를 닫고 다음 장치를 검사합니다.
반복이 끝났을 때 `fb_fd`는 Video Output Overlay에 대응하는 framebuffer descriptor이며, 장치를 찾지 못했다면 -1입니다.
0부터 29까지 address가 일치하는 framebuffer를 찾습니다.
framebuffer 후보를 열고 검사할 때의 분기입니다.
Example: Finding a framebuffer device for OSD
---------------------------------------------
.. code-block:: c
#include <linux/fb.h>
struct v4l2_framebuffer fbuf;
unsigned int i;
int fb_fd;
if (-1 == ioctl(fd, VIDIOC_G_FBUF, &fbuf)) {
perror("VIDIOC_G_FBUF");
exit(EXIT_FAILURE);
}
for (i = 0; i < 30; i++) {
char dev_name[16];
struct fb_fix_screeninfo si;
snprintf(dev_name, sizeof(dev_name), "/dev/fb%u", i);
fb_fd = open(dev_name, O_RDWR);
if (-1 == fb_fd) {
switch (errno) {
case ENOENT: /* no such file */
case ENXIO: /* no driver */
continue;
default:
perror("open");
exit(EXIT_FAILURE);
}
}
if (0 == ioctl(fb_fd, FBIOGET_FSCREENINFO, &si)) {
if (si.smem_start == (unsigned long)fbuf.base)
break;
} else {
/* Apparently not a framebuffer device. */
}
close(fb_fd);
fb_fd = -1;
}
/* fb_fd is the file descriptor of the framebuffer device
for the video output overlay, or -1 if no device was found. */
Source/target rectangle과 scaling
106-145overlay는 source와 target rectangle으로 제어합니다. source rectangle은 겹칠 framebuffer 영상의 일부를 선택하고, target rectangle은 outgoing video signal에서 영상이 나타날 영역을 정합니다.
driver는 scaling, 임의 rectangle 크기와 위치, Video Overlay에 정의된 clipping 또는 blending 방식 중 일부나 전부를 지원할 수도 있고 전혀 지원하지 않을 수도 있습니다.
`struct v4l2_window`은 source rectangle의 크기와 framebuffer 내 위치, overlay에 쓸 clipping/blending 방식을 정의합니다. 현재 값을 얻으려면 `struct v4l2_format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY`로 설정하고 `VIDIOC_G_FMT`를 호출하며, driver가 `fmt.win`을 채웁니다. 이전에 program한 clipping list나 bitmap은 다시 가져올 수 없습니다.
source rectangle을 program하려면 같은 type으로 `win`을 초기화해 `VIDIOC_S_FMT`를 호출합니다. driver는 하드웨어 한계에 맞춰 조정한 실제값을 반환합니다. `VIDIOC_TRY_FMT`는 state를 바꾸지 않고 capability를 시험하며 overlay가 이미 enabled인 뒤에도 사용할 수 있습니다.
`struct v4l2_crop`은 target rectangle의 크기와 위치를 정의합니다. overlay scaling factor는 `v4l2_window`와 `v4l2_crop`의 폭·높이 관계로 결정됩니다. cropping API는 data flow 방향만 반대로 하여 Video Output/Output Overlay에도 Capture/Overlay와 같은 방식으로 적용됩니다.
framebuffer source에서 video signal target으로의 배치를 정의합니다.
framebuffer 일부를 outgoing signal 영역으로 변환합니다.
Overlay Window and Scaling
==========================
The overlay is controlled by source and target rectangles. The source
rectangle selects a subsection of the framebuffer image to be overlaid,
the target rectangle an area in the outgoing video signal where the
image will appear. Drivers may or may not support scaling, and arbitrary
sizes and positions of these rectangles. Further drivers may support any
(or none) of the clipping/blending methods defined for the
:ref:`Video Overlay <overlay>` interface.
A struct :c:type:`v4l2_window` defines the size of the
source rectangle, its position in the framebuffer and the
clipping/blending method to be used for the overlay. To get the current
parameters applications set the ``type`` field of a struct
:c:type:`v4l2_format` to
``V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY`` and call the
:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` ioctl. The driver fills the
struct :c:type:`v4l2_window` substructure named ``win``. It is not
possible to retrieve a previously programmed clipping list or bitmap.
To program the source rectangle applications set the ``type`` field of a
struct :c:type:`v4l2_format` to
``V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY``, initialize the ``win``
substructure and call the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl.
The driver adjusts the parameters against hardware limits and returns
the actual parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does. Like :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`,
the :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl can be used to learn
about driver capabilities without actually changing driver state. Unlike
:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` this also works after the overlay has been enabled.
A struct :c:type:`v4l2_crop` defines the size and position
of the target rectangle. The scaling factor of the overlay is implied by
the width and height given in struct :c:type:`v4l2_window`
and struct :c:type:`v4l2_crop`. The cropping API applies to
*Video Output* and *Video Output Overlay* devices in the same way as to
*Video Capture* and *Video Overlay* devices, merely reversing the
direction of the data flow. For more information see :ref:`crop`.
Overlay enable과 FBIOBLANK
146-150overlay를 enable하거나 disable하는 V4L2 ioctl은 없습니다. 다만 driver의 framebuffer interface가 `FBIOBLANK` ioctl을 지원해 표시를 blank하거나 다시 켤 수 있습니다.
V4L2와 framebuffer API의 역할 차이입니다.
Enabling Overlay
================
There is no V4L2 ioctl to enable or disable the overlay, however the
framebuffer interface of the driver may support the ``FBIOBLANK`` ioctl.
요약·해설
dev-osd.rst:1-150OSD는 TV card의 framebuffer 일부를 outgoing signal 영역에 배치합니다. V4L2와 fbdev가 보고하는 physical address를 맞추고 source/target rectangle으로 scaling을 구성합니다.