요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=======================
Linux UVC Gadget Driver
=======================
Overview
--------
The UVC Gadget driver is a driver for hardware on the *device* side of a USB
connection. It is intended to run on a Linux system that has USB device-side
hardware such as boards with an OTG port.
On the device system, once the driver is bound it appears as a V4L2 device with
the output capability.
On the host side (once connected via USB cable), a device running the UVC Gadget
driver *and controlled by an appropriate userspace program* should appear as a UVC
specification compliant camera, and function appropriately with any program
designed to handle them. The userspace program running on the device system can
queue image buffers from a variety of sources to be transmitted via the USB
connection. Typically this would mean forwarding the buffers from a camera sensor
peripheral, but the source of the buffer is entirely dependent on the userspace
companion program.
Configuring the device kernel
-----------------------------
The Kconfig options USB_CONFIGFS, USB_LIBCOMPOSITE, USB_CONFIGFS_F_UVC and
USB_F_UVC must be selected to enable support for the UVC gadget.
Configuring the gadget through configfs
---------------------------------------
The UVC Gadget expects to be configured through configfs using the UVC function.
This allows a significant degree of flexibility, as many of a UVC device's
settings can be controlled this way.
Not all of the available attributes are described here. For a complete enumeration
see Documentation/ABI/testing/configfs-usb-gadget-uvc
Assumptions
~~~~~~~~~~~
This section assumes that you have mounted configfs at `/sys/kernel/config` and
created a gadget as `/sys/kernel/config/usb_gadget/g1`.
The UVC Function
~~~~~~~~~~~~~~~~
The first step is to create the UVC function:
.. code-block:: bash
# These variables will be assumed throughout the rest of the document
CONFIGFS="/sys/kernel/config"
GADGET="$CONFIGFS/usb_gadget/g1"
FUNCTION="$GADGET/functions/uvc.0"
mkdir -p $FUNCTION
Formats and Frames
~~~~~~~~~~~~~~~~~~
You must configure the gadget by telling it which formats you support, as well
as the frame sizes and frame intervals that are supported for each format. In
the current implementation there is no way for the gadget to refuse to set a
format that the host instructs it to set, so it is important that this step is
completed *accurately* to ensure that the host never asks for a format that
can't be provided.
Formats are created under the streaming/uncompressed and streaming/mjpeg configfs
groups, with the framesizes created under the formats in the following
structure:
::
uvc.0 +
|
+ streaming +
|
+ mjpeg +
| |
| + mjpeg +
| |
| + 720p
| |
| + 1080p
|
+ uncompressed +
|
+ yuyv +
|
+ 720p
|
+ 1080p
Each frame can then be configured with a width and height, plus the maximum
buffer size required to store a single frame, and finally with the supported
frame intervals for that format and framesize. Width and height are enumerated in
units of pixels, frame interval in units of 100ns. To create the structure
above with 2, 15 and 100 fps frameintervals for each framesize for example you
might do:
.. code-block:: bash
create_frame() {
# Example usage:
# create_frame <width> <height> <group> <format name>
WIDTH=$1
HEIGHT=$2
FORMAT=$3
NAME=$4
wdir=$FUNCTION/streaming/$FORMAT/$NAME/${HEIGHT}p
mkdir -p $wdir
echo $WIDTH > $wdir/wWidth
echo $HEIGHT > $wdir/wHeight
echo $(( $WIDTH * $HEIGHT * 2 )) > $wdir/dwMaxVideoFrameBufferSize
cat <<EOF > $wdir/dwFrameInterval
666666
100000
5000000
EOF
}
create_frame 1280 720 mjpeg mjpeg
create_frame 1920 1080 mjpeg mjpeg
create_frame 1280 720 uncompressed yuyv
create_frame 1920 1080 uncompressed yuyv
The only uncompressed format currently supported is YUYV, which is detailed at
Documentation/userspace-api/media/v4l/pixfmt-packed-yuv.rst.
Color Matching Descriptors
~~~~~~~~~~~~~~~~~~~~~~~~~~
It's possible to specify some colometry information for each format you create.
This step is optional, and default information will be included if this step is
skipped; those default values follow those defined in the Color Matching Descriptor
section of the UVC specification.
To create a Color Matching Descriptor, create a configfs item and set its three
attributes to your desired settings and then link to it from the format you wish
it to be associated with:
.. code-block:: bash
# Create a new Color Matching Descriptor
mkdir $FUNCTION/streaming/color_matching/yuyv
pushd $FUNCTION/streaming/color_matching/yuyv
echo 1 > bColorPrimaries
echo 1 > bTransferCharacteristics
echo 4 > bMatrixCoefficients
popd
# Create a symlink to the Color Matching Descriptor from the format's config item
ln -s $FUNCTION/streaming/color_matching/yuyv $FUNCTION/streaming/uncompressed/yuyv
For details about the valid values, consult the UVC specification. Note that a
default color matching descriptor exists and is used by any format which does
not have a link to a different Color Matching Descriptor. It's possible to
change the attribute settings for the default descriptor, so bear in mind that if
you do that you are altering the defaults for any format that does not link to
a different one.
Header linking
~~~~~~~~~~~~~~
The UVC specification requires that Format and Frame descriptors be preceded by
Headers detailing things such as the number and cumulative size of the different
Format descriptors that follow. This and similar operations are achieved in
configfs by linking between the configfs item representing the header and the
config items representing those other descriptors, in this manner:
.. code-block:: bash
mkdir $FUNCTION/streaming/header/h
# This section links the format descriptors and their associated frames
# to the header
cd $FUNCTION/streaming/header/h
ln -s ../../uncompressed/yuyv
ln -s ../../mjpeg/mjpeg
# This section ensures that the header will be transmitted for each
# speed's set of descriptors. If support for a particular speed is not
# needed then it can be skipped here.
cd ../../class/fs
ln -s ../../header/h
cd ../../class/hs
ln -s ../../header/h
cd ../../class/ss
ln -s ../../header/h
cd ../../../control
mkdir header/h
ln -s header/h class/fs
ln -s header/h class/ss
Extension Unit Support
~~~~~~~~~~~~~~~~~~~~~~
A UVC Extension Unit (XU) basically provides a distinct unit to which control set
and get requests can be addressed. The meaning of those control requests is
entirely implementation dependent, but may be used to control settings outside
of the UVC specification (for example enabling or disabling video effects). An
XU can be inserted into the UVC unit chain or left free-hanging.
Configuring an extension unit involves creating an entry in the appropriate
directory and setting its attributes appropriately, like so:
.. code-block:: bash
mkdir $FUNCTION/control/extensions/xu.0
pushd $FUNCTION/control/extensions/xu.0
# Set the bUnitID of the Processing Unit as the source for this
# Extension Unit
echo 2 > baSourceID
# Set this XU as the source of the default output terminal. This inserts
# the XU into the UVC chain between the PU and OT such that the final
# chain is IT > PU > XU.0 > OT
cat bUnitID > ../../terminal/output/default/baSourceID
# Flag some controls as being available for use. The bmControl field is
# a bitmap with each bit denoting the availability of a particular
# control. For example to flag the 0th, 2nd and 3rd controls available:
echo 0x0d > bmControls
# Set the GUID; this is a vendor-specific code identifying the XU.
echo -e -n "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" > guidExtensionCode
popd
The bmControls attribute and the baSourceID attribute are multi-value attributes.
This means that you may write multiple newline separated values to them. For
example to flag the 1st, 2nd, 9th and 10th controls as being available you would
need to write two values to bmControls, like so:
.. code-block:: bash
cat << EOF > bmControls
0x03
0x03
EOF
The multi-value nature of the baSourceID attribute belies the fact that XUs can
be multiple-input, though note that this currently has no significant effect.
The bControlSize attribute reflects the size of the bmControls attribute, and
similarly bNrInPins reflects the size of the baSourceID attributes. Both
attributes are automatically increased / decreased as you set bmControls and
baSourceID. It is also possible to manually increase or decrease bControlSize
which has the effect of truncating entries to the new size, or padding entries
out with 0x00, for example:
::
$ cat bmControls
0x03
0x05
$ cat bControlSize
2
$ echo 1 > bControlSize
$ cat bmControls
0x03
$ echo 2 > bControlSize
$ cat bmControls
0x03
0x00
bNrInPins and baSourceID function in the same way.
Configuring Supported Controls for Camera Terminal and Processing Unit
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Camera Terminal and Processing Units in the UVC chain also have bmControls
attributes which function similarly to the same field in an Extension Unit.
Unlike XUs however, the meaning of the bitflag for these units is defined in
the UVC specification; you should consult the "Camera Terminal Descriptor" and
"Processing Unit Descriptor" sections for an enumeration of the flags.
.. code-block:: bash
# Set the Processing Unit's bmControls, flagging Brightness, Contrast
# and Hue as available controls:
echo 0x05 > $FUNCTION/control/processing/default/bmControls
# Set the Camera Terminal's bmControls, flagging Focus Absolute and
# Focus Relative as available controls:
echo 0x60 > $FUNCTION/control/terminal/camera/default/bmControls
If you do not set these fields then by default the Auto-Exposure Mode control
for the Camera Terminal and the Brightness control for the Processing Unit will
be flagged as available; if they are not supported you should set the field to
0x00.
Note that the size of the bmControls field for a Camera Terminal or Processing
Unit is fixed by the UVC specification, and so the bControlSize attribute is
read-only here.
Custom Strings Support
~~~~~~~~~~~~~~~~~~~~~~
String descriptors that provide a textual description for various parts of a
USB device can be defined in the usual place within USB configfs, and may then
be linked to from the UVC function root or from Extension Unit directories to
assign those strings as descriptors:
.. code-block:: bash
# Create a string descriptor in us-EN and link to it from the function
# root. The name of the link is significant here, as it declares this
# descriptor to be intended for the Interface Association Descriptor.
# Other significant link names at function root are vs0_desc and vs1_desc
# For the VideoStreaming Interface 0/1 Descriptors.
mkdir -p $GADGET/strings/0x409/iad_desc
echo -n "Interface Associaton Descriptor" > $GADGET/strings/0x409/iad_desc/s
ln -s $GADGET/strings/0x409/iad_desc $FUNCTION/iad_desc
# Because the link to a String Descriptor from an Extension Unit clearly
# associates the two, the name of this link is not significant and may
# be set freely.
mkdir -p $GADGET/strings/0x409/xu.0
echo -n "A Very Useful Extension Unit" > $GADGET/strings/0x409/xu.0/s
ln -s $GADGET/strings/0x409/xu.0 $FUNCTION/control/extensions/xu.0
The interrupt endpoint
~~~~~~~~~~~~~~~~~~~~~~
The VideoControl interface has an optional interrupt endpoint which is by default
disabled. This is intended to support delayed response control set requests for
UVC (which should respond through the interrupt endpoint rather than tying up
endpoint 0). At present support for sending data through this endpoint is missing
and so it is left disabled to avoid confusion. If you wish to enable it you can
do so through the configfs attribute:
.. code-block:: bash
echo 1 > $FUNCTION/control/enable_interrupt_ep
Bandwidth configuration
~~~~~~~~~~~~~~~~~~~~~~~
There are three attributes which control the bandwidth of the USB connection.
These live in the function root and can be set within limits:
.. code-block:: bash
# streaming_interval sets bInterval. Values range from 1..255
echo 1 > $FUNCTION/streaming_interval
# streaming_maxpacket sets wMaxPacketSize. Valid values are 1024/2048/3072
echo 3072 > $FUNCTION/streaming_maxpacket
# streaming_maxburst sets bMaxBurst. Valid values are 1..15
echo 1 > $FUNCTION/streaming_maxburst
The values passed here will be clamped to valid values according to the UVC
specification (which depend on the speed of the USB connection). To understand
how the settings influence bandwidth you should consult the UVC specifications,
but a rule of thumb is that increasing the streaming_maxpacket setting will
improve bandwidth (and thus the maximum possible framerate), whilst the same is
true for streaming_maxburst provided the USB connection is running at SuperSpeed.
Increasing streaming_interval will reduce bandwidth and framerate.
The userspace application
-------------------------
By itself, the UVC Gadget driver cannot do anything particularly interesting. It
must be paired with a userspace program that responds to UVC control requests and
fills buffers to be queued to the V4L2 device that the driver creates. How those
things are achieved is implementation dependent and beyond the scope of this
document, but a reference application can be found at https://gitlab.freedesktop.org/camera/uvc-gadget
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
개요
1-22UVC Gadget 드라이버는 USB 연결의 장치 측 하드웨어를 위한 드라이버입니다. OTG 포트가 있는 보드처럼 USB device-side 하드웨어를 갖춘 Linux 시스템에서 실행하도록 설계되었습니다.
드라이버가 장치 시스템에 바인딩되면 출력 기능을 가진 V4L2 장치로 나타납니다.
USB 케이블로 연결한 호스트에서는 UVC Gadget 드라이버와 적절한 사용자 공간 프로그램이 함께 동작할 때 UVC 규격 준수 카메라로 보여야 하며, UVC 카메라를 처리하는 프로그램에서 정상적으로 사용할 수 있어야 합니다.
장치 측 사용자 공간 프로그램은 여러 소스의 이미지 버퍼를 큐에 넣어 USB로 전송할 수 있습니다. 보통 카메라 센서 주변장치의 버퍼를 전달하지만, 실제 버퍼 소스는 전적으로 함께 실행되는 사용자 공간 프로그램이 결정합니다.
장치 측 이미지 소스가 사용자 공간과 V4L2 출력 장치를 거쳐 호스트의 UVC 응용 프로그램으로 전달됩니다.
=======================
Linux UVC Gadget Driver
=======================
Overview
--------
The UVC Gadget driver is a driver for hardware on the *device* side of a USB
connection. It is intended to run on a Linux system that has USB device-side
hardware such as boards with an OTG port.
On the device system, once the driver is bound it appears as a V4L2 device with
the output capability.
On the host side (once connected via USB cable), a device running the UVC Gadget
driver *and controlled by an appropriate userspace program* should appear as a UVC
specification compliant camera, and function appropriately with any program
designed to handle them. The userspace program running on the device system can
queue image buffers from a variety of sources to be transmitted via the USB
connection. Typically this would mean forwarding the buffers from a camera sensor
peripheral, but the source of the buffer is entirely dependent on the userspace
companion program.
장치 커널과 configfs 준비
23-41UVC gadget 지원을 활성화하려면 Kconfig에서 `USB_CONFIGFS`, `USB_LIBCOMPOSITE`, `USB_CONFIGFS_F_UVC`, `USB_F_UVC`를 선택해야 합니다.
UVC Gadget은 configfs의 UVC function을 통해 구성합니다. 이 방식은 UVC 장치의 많은 설정을 configfs 속성으로 제어할 수 있어 구성 유연성이 높습니다.
이 문서는 사용 가능한 모든 속성을 열거하지 않습니다. 전체 목록은 `Documentation/ABI/testing/configfs-usb-gadget-uvc`를 참조해야 합니다.
이후 절차는 configfs가 `/sys/kernel/config`에 마운트되어 있고 gadget이 `/sys/kernel/config/usb_gadget/g1`에 생성되어 있다고 가정합니다.
UVC function을 만들기 전에 필요한 Kconfig 선택과 configfs 경로입니다.
Configuring the device kernel
-----------------------------
The Kconfig options USB_CONFIGFS, USB_LIBCOMPOSITE, USB_CONFIGFS_F_UVC and
USB_F_UVC must be selected to enable support for the UVC gadget.
Configuring the gadget through configfs
---------------------------------------
The UVC Gadget expects to be configured through configfs using the UVC function.
This allows a significant degree of flexibility, as many of a UVC device's
settings can be controlled this way.
Not all of the available attributes are described here. For a complete enumeration
see Documentation/ABI/testing/configfs-usb-gadget-uvc
Assumptions
~~~~~~~~~~~
This section assumes that you have mounted configfs at `/sys/kernel/config` and
created a gadget as `/sys/kernel/config/usb_gadget/g1`.
UVC function 생성
42-55첫 단계는 gadget 아래에 UVC function을 만드는 것입니다. 문서의 나머지 명령은 `CONFIGFS`, `GADGET`, `FUNCTION` 셸 변수를 공통으로 사용합니다.
`FUNCTION`은 `$GADGET/functions/uvc.0`을 가리키며, `mkdir -p $FUNCTION`으로 function 디렉터리를 생성합니다.
공통 변수에서 실제 UVC function 디렉터리까지 이어지는 경로입니다.
The UVC Function
~~~~~~~~~~~~~~~~
The first step is to create the UVC function:
.. code-block:: bash
# These variables will be assumed throughout the rest of the document
CONFIGFS="/sys/kernel/config"
GADGET="$CONFIGFS/usb_gadget/g1"
FUNCTION="$GADGET/functions/uvc.0"
mkdir -p $FUNCTION
형식과 프레임
56-130gadget에는 지원할 형식과 각 형식에서 지원하는 프레임 크기 및 프레임 간격을 정확히 알려야 합니다.
현재 구현은 호스트가 지정한 형식 설정을 gadget이 거부할 방법이 없습니다. 따라서 실제로 제공할 수 없는 형식을 호스트가 요청하지 않도록 이 구성을 정확하게 완료하는 것이 중요합니다.
형식은 configfs의 `streaming/uncompressed`와 `streaming/mjpeg` 그룹 아래에 만들고, 각 형식 아래에 프레임 크기 항목을 생성합니다. 예제 계층에는 MJPEG와 YUYV 각각에 720p 및 1080p가 있습니다.
각 프레임에는 픽셀 단위의 `wWidth`, `wHeight`, 한 프레임을 담는 데 필요한 최대 버퍼 크기 `dwMaxVideoFrameBufferSize`, 100ns 단위의 지원 프레임 간격 `dwFrameInterval`을 설정합니다. 예제의 666666, 100000, 5000000은 각각 약 15, 100, 2fps에 해당합니다.
현재 지원되는 비압축 형식은 YUYV뿐이며 자세한 내용은 `Documentation/userspace-api/media/v4l/pixfmt-packed-yuv.rst`에 있습니다.
원문의 ASCII 트리를 동일한 configfs 경로별 흐름으로 다시 구성했습니다.
프레임 항목에 기록하는 크기와 간격 속성입니다.
Formats and Frames
~~~~~~~~~~~~~~~~~~
You must configure the gadget by telling it which formats you support, as well
as the frame sizes and frame intervals that are supported for each format. In
the current implementation there is no way for the gadget to refuse to set a
format that the host instructs it to set, so it is important that this step is
completed *accurately* to ensure that the host never asks for a format that
can't be provided.
Formats are created under the streaming/uncompressed and streaming/mjpeg configfs
groups, with the framesizes created under the formats in the following
structure:
::
uvc.0 +
|
+ streaming +
|
+ mjpeg +
| |
| + mjpeg +
| |
| + 720p
| |
| + 1080p
|
+ uncompressed +
|
+ yuyv +
|
+ 720p
|
+ 1080p
Each frame can then be configured with a width and height, plus the maximum
buffer size required to store a single frame, and finally with the supported
frame intervals for that format and framesize. Width and height are enumerated in
units of pixels, frame interval in units of 100ns. To create the structure
above with 2, 15 and 100 fps frameintervals for each framesize for example you
might do:
.. code-block:: bash
create_frame() {
# Example usage:
# create_frame <width> <height> <group> <format name>
WIDTH=$1
HEIGHT=$2
FORMAT=$3
NAME=$4
wdir=$FUNCTION/streaming/$FORMAT/$NAME/${HEIGHT}p
mkdir -p $wdir
echo $WIDTH > $wdir/wWidth
echo $HEIGHT > $wdir/wHeight
echo $(( $WIDTH * $HEIGHT * 2 )) > $wdir/dwMaxVideoFrameBufferSize
cat <<EOF > $wdir/dwFrameInterval
666666
100000
5000000
EOF
}
create_frame 1280 720 mjpeg mjpeg
create_frame 1920 1080 mjpeg mjpeg
create_frame 1280 720 uncompressed yuyv
create_frame 1920 1080 uncompressed yuyv
The only uncompressed format currently supported is YUYV, which is detailed at
Documentation/userspace-api/media/v4l/pixfmt-packed-yuv.rst.
색 일치 descriptor
131-165각 형식에 색도 정보를 지정할 수 있습니다. 이 단계는 선택 사항이며 생략하면 UVC 규격의 Color Matching Descriptor 절에 정의된 기본 정보가 포함됩니다.
Color Matching Descriptor를 만들려면 `streaming/color_matching` 아래에 configfs 항목을 생성하고 `bColorPrimaries`, `bTransferCharacteristics`, `bMatrixCoefficients` 세 속성을 원하는 값으로 설정합니다.
그 다음 해당 색 정보를 사용할 형식의 config 항목에서 Color Matching Descriptor로 심볼릭 링크를 만듭니다. 예제는 `color_matching/yuyv`를 `streaming/uncompressed/yuyv`에 연결합니다.
유효한 값은 UVC 규격을 확인해야 합니다. 별도 descriptor 링크가 없는 형식은 기본 color matching descriptor를 사용하며, 기본 descriptor의 속성을 바꾸면 별도 링크가 없는 모든 형식의 기본값이 함께 달라집니다.
형식에 연결하는 색 정보의 세 configfs 속성입니다.
Color Matching Descriptors
~~~~~~~~~~~~~~~~~~~~~~~~~~
It's possible to specify some colometry information for each format you create.
This step is optional, and default information will be included if this step is
skipped; those default values follow those defined in the Color Matching Descriptor
section of the UVC specification.
To create a Color Matching Descriptor, create a configfs item and set its three
attributes to your desired settings and then link to it from the format you wish
it to be associated with:
.. code-block:: bash
# Create a new Color Matching Descriptor
mkdir $FUNCTION/streaming/color_matching/yuyv
pushd $FUNCTION/streaming/color_matching/yuyv
echo 1 > bColorPrimaries
echo 1 > bTransferCharacteristics
echo 4 > bMatrixCoefficients
popd
# Create a symlink to the Color Matching Descriptor from the format's config item
ln -s $FUNCTION/streaming/color_matching/yuyv $FUNCTION/streaming/uncompressed/yuyv
For details about the valid values, consult the UVC specification. Note that a
default color matching descriptor exists and is used by any format which does
not have a link to a different Color Matching Descriptor. It's possible to
change the attribute settings for the default descriptor, so bear in mind that if
you do that you are altering the defaults for any format that does not link to
a different one.
Header 연결
166-199UVC 규격은 Format 및 Frame descriptor 앞에 뒤따르는 Format descriptor의 개수와 누적 크기 등을 기록한 Header가 오도록 요구합니다.
configfs에서는 header를 나타내는 항목과 다른 descriptor 항목 사이에 링크를 만들어 이 관계를 표현합니다.
예제는 `streaming/header/h`를 만들고 `uncompressed/yuyv`와 `mjpeg/mjpeg`를 이 header에 연결합니다.
그 뒤 header를 `class/fs`, `class/hs`, `class/ss`에 각각 연결하여 각 USB 속도의 descriptor 집합에 전송되게 합니다. 필요하지 않은 속도는 생략할 수 있고, control 쪽에도 `header/h`를 만든 뒤 `class/fs`와 `class/ss`에 연결합니다.
Format과 Frame descriptor가 Header에 묶이고 각 속도별 descriptor class로 노출되는 관계입니다.
Header linking
~~~~~~~~~~~~~~
The UVC specification requires that Format and Frame descriptors be preceded by
Headers detailing things such as the number and cumulative size of the different
Format descriptors that follow. This and similar operations are achieved in
configfs by linking between the configfs item representing the header and the
config items representing those other descriptors, in this manner:
.. code-block:: bash
mkdir $FUNCTION/streaming/header/h
# This section links the format descriptors and their associated frames
# to the header
cd $FUNCTION/streaming/header/h
ln -s ../../uncompressed/yuyv
ln -s ../../mjpeg/mjpeg
# This section ensures that the header will be transmitted for each
# speed's set of descriptors. If support for a particular speed is not
# needed then it can be skipped here.
cd ../../class/fs
ln -s ../../header/h
cd ../../class/hs
ln -s ../../header/h
cd ../../class/ss
ln -s ../../header/h
cd ../../../control
mkdir header/h
ln -s header/h class/fs
ln -s header/h class/ss
Extension Unit 지원
200-235UVC Extension Unit(XU)은 control set/get 요청을 보낼 수 있는 독립된 unit을 제공합니다.
그 control 요청의 의미는 전적으로 구현에 따라 달라지며, 영상 효과 활성화처럼 UVC 규격 밖의 설정을 제어하는 데 사용할 수 있습니다. XU는 UVC unit chain에 삽입하거나 어느 체인에도 연결하지 않은 상태로 둘 수 있습니다.
예제는 `$FUNCTION/control/extensions/xu.0`을 만들고 Processing Unit의 `bUnitID` 값 2를 `baSourceID`에 써서 XU의 소스로 지정합니다.
XU의 `bUnitID`를 기본 output terminal의 `baSourceID`에 기록하면 체인이 `IT > PU > XU.0 > OT`가 됩니다. `bmControls`는 각 비트가 control 하나의 사용 가능 여부를 나타내며, `0x0d`는 0, 2, 3번 control을 사용 가능하게 표시합니다.
`guidExtensionCode`에는 XU를 식별하는 vendor-specific GUID를 16바이트 값으로 설정합니다.
XU를 Processing Unit과 Output Terminal 사이에 넣은 최종 UVC unit chain입니다.
XU의 입력, control bitmap, 식별자를 구성하는 속성입니다.
Extension Unit Support
~~~~~~~~~~~~~~~~~~~~~~
A UVC Extension Unit (XU) basically provides a distinct unit to which control set
and get requests can be addressed. The meaning of those control requests is
entirely implementation dependent, but may be used to control settings outside
of the UVC specification (for example enabling or disabling video effects). An
XU can be inserted into the UVC unit chain or left free-hanging.
Configuring an extension unit involves creating an entry in the appropriate
directory and setting its attributes appropriately, like so:
.. code-block:: bash
mkdir $FUNCTION/control/extensions/xu.0
pushd $FUNCTION/control/extensions/xu.0
# Set the bUnitID of the Processing Unit as the source for this
# Extension Unit
echo 2 > baSourceID
# Set this XU as the source of the default output terminal. This inserts
# the XU into the UVC chain between the PU and OT such that the final
# chain is IT > PU > XU.0 > OT
cat bUnitID > ../../terminal/output/default/baSourceID
# Flag some controls as being available for use. The bmControl field is
# a bitmap with each bit denoting the availability of a particular
# control. For example to flag the 0th, 2nd and 3rd controls available:
echo 0x0d > bmControls
# Set the GUID; this is a vendor-specific code identifying the XU.
echo -e -n "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" > guidExtensionCode
popd
XU 다중 값 속성과 크기
236-277`bmControls`와 `baSourceID`는 여러 값을 갖는 속성이므로 줄바꿈으로 구분한 값을 여러 개 쓸 수 있습니다.
예를 들어 1, 2, 9, 10번 control을 사용 가능하게 하려면 `bmControls`에 `0x03`을 두 줄로 기록합니다. 첫 바이트와 둘째 바이트에서 각각 하위 두 비트를 설정하는 방식입니다.
`baSourceID`가 다중 값이라는 것은 XU가 여러 입력을 가질 수 있음을 뜻하지만, 현재는 여러 입력을 지정해도 유의미한 효과가 없습니다.
`bControlSize`는 `bmControls`의 크기를, `bNrInPins`는 `baSourceID`의 크기를 반영합니다. `bmControls`와 `baSourceID`를 설정하면 대응하는 크기 속성이 자동으로 증가하거나 감소합니다.
`bControlSize`를 수동으로 줄이면 새 크기에 맞게 항목이 잘리고, 늘리면 `0x00`으로 채워집니다. `bNrInPins`와 `baSourceID`도 같은 방식으로 동작합니다.
값 목록과 그 길이를 반영하는 UVC XU 속성입니다.
The bmControls attribute and the baSourceID attribute are multi-value attributes.
This means that you may write multiple newline separated values to them. For
example to flag the 1st, 2nd, 9th and 10th controls as being available you would
need to write two values to bmControls, like so:
.. code-block:: bash
cat << EOF > bmControls
0x03
0x03
EOF
The multi-value nature of the baSourceID attribute belies the fact that XUs can
be multiple-input, though note that this currently has no significant effect.
The bControlSize attribute reflects the size of the bmControls attribute, and
similarly bNrInPins reflects the size of the baSourceID attributes. Both
attributes are automatically increased / decreased as you set bmControls and
baSourceID. It is also possible to manually increase or decrease bControlSize
which has the effect of truncating entries to the new size, or padding entries
out with 0x00, for example:
::
$ cat bmControls
0x03
0x05
$ cat bControlSize
2
$ echo 1 > bControlSize
$ cat bmControls
0x03
$ echo 2 > bControlSize
$ cat bmControls
0x03
0x00
bNrInPins and baSourceID function in the same way.
Camera Terminal과 Processing Unit control
278-305UVC chain의 Camera Terminal과 Processing Unit에도 Extension Unit의 필드와 비슷하게 동작하는 `bmControls`가 있습니다.
XU와 달리 이 두 unit의 bit flag 의미는 UVC 규격이 정의합니다. 전체 flag 목록은 규격의 Camera Terminal Descriptor 및 Processing Unit Descriptor 절을 확인해야 합니다.
예제에서 Processing Unit의 `0x05`는 Brightness, Contrast, Hue control을 사용 가능하게 표시하고, Camera Terminal의 `0x60`은 Focus Absolute와 Focus Relative를 표시합니다.
값을 설정하지 않으면 기본적으로 Camera Terminal의 Auto-Exposure Mode와 Processing Unit의 Brightness가 사용 가능한 것으로 표시됩니다. 지원하지 않으면 해당 필드를 `0x00`으로 설정해야 합니다. 이 unit들의 `bmControls` 크기는 UVC 규격으로 고정되므로 여기서 `bControlSize`는 읽기 전용입니다.
예제 bitmap, 기본 control, 크기 제약을 구분합니다.
Configuring Supported Controls for Camera Terminal and Processing Unit
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Camera Terminal and Processing Units in the UVC chain also have bmControls
attributes which function similarly to the same field in an Extension Unit.
Unlike XUs however, the meaning of the bitflag for these units is defined in
the UVC specification; you should consult the "Camera Terminal Descriptor" and
"Processing Unit Descriptor" sections for an enumeration of the flags.
.. code-block:: bash
# Set the Processing Unit's bmControls, flagging Brightness, Contrast
# and Hue as available controls:
echo 0x05 > $FUNCTION/control/processing/default/bmControls
# Set the Camera Terminal's bmControls, flagging Focus Absolute and
# Focus Relative as available controls:
echo 0x60 > $FUNCTION/control/terminal/camera/default/bmControls
If you do not set these fields then by default the Auto-Exposure Mode control
for the Camera Terminal and the Brightness control for the Processing Unit will
be flagged as available; if they are not supported you should set the field to
0x00.
Note that the size of the bmControls field for a Camera Terminal or Processing
Unit is fixed by the UVC specification, and so the bControlSize attribute is
read-only here.
사용자 정의 문자열 지원
306-333USB 장치의 여러 부분을 설명하는 String Descriptor는 일반적인 USB configfs 위치에 정의한 뒤 UVC function root 또는 Extension Unit 디렉터리에서 링크하여 descriptor로 지정할 수 있습니다.
예제는 영어(미국) 언어 ID `0x409` 아래에 `iad_desc` 문자열을 만들고 function root의 `$FUNCTION/iad_desc`로 연결합니다.
function root에서는 링크 이름에 의미가 있습니다. `iad_desc`는 Interface Association Descriptor용이며, `vs0_desc`와 `vs1_desc`는 각각 VideoStreaming Interface 0/1 Descriptor용입니다.
Extension Unit에서 String Descriptor로 연결한 링크는 위치만으로 어느 XU와 연결되는지 명확하므로 링크 이름을 자유롭게 정할 수 있습니다.
링크 위치에 따라 이름의 의미와 제약이 달라집니다.
Custom Strings Support
~~~~~~~~~~~~~~~~~~~~~~
String descriptors that provide a textual description for various parts of a
USB device can be defined in the usual place within USB configfs, and may then
be linked to from the UVC function root or from Extension Unit directories to
assign those strings as descriptors:
.. code-block:: bash
# Create a string descriptor in us-EN and link to it from the function
# root. The name of the link is significant here, as it declares this
# descriptor to be intended for the Interface Association Descriptor.
# Other significant link names at function root are vs0_desc and vs1_desc
# For the VideoStreaming Interface 0/1 Descriptors.
mkdir -p $GADGET/strings/0x409/iad_desc
echo -n "Interface Associaton Descriptor" > $GADGET/strings/0x409/iad_desc/s
ln -s $GADGET/strings/0x409/iad_desc $FUNCTION/iad_desc
# Because the link to a String Descriptor from an Extension Unit clearly
# associates the two, the name of this link is not significant and may
# be set freely.
mkdir -p $GADGET/strings/0x409/xu.0
echo -n "A Very Useful Extension Unit" > $GADGET/strings/0x409/xu.0/s
ln -s $GADGET/strings/0x409/xu.0 $FUNCTION/control/extensions/xu.0
Interrupt endpoint
334-347VideoControl interface에는 선택적인 interrupt endpoint가 있지만 기본값은 비활성화입니다.
이 endpoint는 지연 응답 control set 요청을 지원하기 위한 것입니다. 이런 요청은 endpoint 0을 계속 점유하는 대신 interrupt endpoint를 통해 응답해야 합니다.
현재는 이 endpoint로 데이터를 보내는 기능이 구현되어 있지 않아 혼동을 피하려고 비활성화되어 있습니다. 필요하면 `$FUNCTION/control/enable_interrupt_ep`에 1을 써서 활성화할 수 있습니다.
지원이 완성되면 지연 control set 응답이 endpoint 0 대신 선택적 interrupt endpoint를 사용합니다.
The interrupt endpoint
~~~~~~~~~~~~~~~~~~~~~~
The VideoControl interface has an optional interrupt endpoint which is by default
disabled. This is intended to support delayed response control set requests for
UVC (which should respond through the interrupt endpoint rather than tying up
endpoint 0). At present support for sending data through this endpoint is missing
and so it is left disabled to avoid confusion. If you wish to enable it you can
do so through the configfs attribute:
.. code-block:: bash
echo 1 > $FUNCTION/control/enable_interrupt_ep
대역폭 구성
348-373USB 연결의 대역폭은 function root에 있는 세 속성 `streaming_interval`, `streaming_maxpacket`, `streaming_maxburst`로 제어합니다.
`streaming_interval`은 `bInterval`을 설정하며 범위는 1부터 255입니다. `streaming_maxpacket`은 `wMaxPacketSize`를 설정하며 유효 값은 1024, 2048, 3072입니다.
`streaming_maxburst`는 `bMaxBurst`를 설정하며 유효 범위는 1부터 15입니다.
입력값은 USB 연결 속도에 따라 달라지는 UVC 규격의 유효 범위로 제한됩니다. 설정이 대역폭에 미치는 정확한 영향은 UVC 규격을 확인해야 합니다.
일반적으로 `streaming_maxpacket`을 늘리면 대역폭과 가능한 최대 frame rate가 높아집니다. SuperSpeed 연결에서는 `streaming_maxburst`를 늘려도 같은 효과가 있고, `streaming_interval`을 늘리면 대역폭과 frame rate가 낮아집니다.
각 configfs 속성이 설정하는 USB 필드, 범위, 일반적인 효과입니다.
Bandwidth configuration
~~~~~~~~~~~~~~~~~~~~~~~
There are three attributes which control the bandwidth of the USB connection.
These live in the function root and can be set within limits:
.. code-block:: bash
# streaming_interval sets bInterval. Values range from 1..255
echo 1 > $FUNCTION/streaming_interval
# streaming_maxpacket sets wMaxPacketSize. Valid values are 1024/2048/3072
echo 3072 > $FUNCTION/streaming_maxpacket
# streaming_maxburst sets bMaxBurst. Valid values are 1..15
echo 1 > $FUNCTION/streaming_maxburst
The values passed here will be clamped to valid values according to the UVC
specification (which depend on the speed of the USB connection). To understand
how the settings influence bandwidth you should consult the UVC specifications,
but a rule of thumb is that increasing the streaming_maxpacket setting will
improve bandwidth (and thus the maximum possible framerate), whilst the same is
true for streaming_maxburst provided the USB connection is running at SuperSpeed.
Increasing streaming_interval will reduce bandwidth and framerate.
사용자 공간 응용 프로그램
374-380UVC Gadget 드라이버만으로는 실질적인 동작을 수행할 수 없습니다.
드라이버가 만드는 V4L2 장치에 큐잉할 버퍼를 채우고 UVC control 요청에 응답하는 사용자 공간 프로그램과 반드시 함께 사용해야 합니다.
구체적인 구현 방식은 구현에 따라 달라지며 이 문서의 범위를 벗어납니다. 참조 구현은 `https://gitlab.freedesktop.org/camera/uvc-gadget`에서 확인할 수 있습니다.
사용자 공간 프로그램이 control 요청 처리와 영상 버퍼 공급을 맡아 UVC gadget을 완성합니다.
The userspace application
-------------------------
By itself, the UVC Gadget driver cannot do anything particularly interesting. It
must be paired with a userspace program that responds to UVC control requests and
fills buffers to be queued to the V4L2 device that the driver creates. How those
things are achieved is implementation dependent and beyond the scope of this
document, but a reference application can be found at https://gitlab.freedesktop.org/camera/uvc-gadget
요약·해설
gadget_uvc.rst:1-380UVC Gadget은 device-side USB 하드웨어를 V4L2 출력 장치로 제공하고, 호스트에는 UVC 카메라로 노출합니다. 다만 control 요청 처리와 영상 버퍼 공급은 사용자 공간 동반 프로그램이 맡아야 하므로 드라이버만 로드해서는 영상 장치로 완성되지 않습니다.
configfs에서는 실제 제공 가능한 format, frame size, 100ns 단위 frame interval을 정확히 선언해야 합니다. 현재 gadget은 호스트가 선택한 format을 거부할 수 없으므로 과장된 descriptor 구성은 런타임 실패로 이어질 수 있습니다.
색 일치 descriptor, streaming/control header 링크, Extension Unit과 `bmControls`, 문자열 descriptor, interrupt endpoint, `streaming_interval`·`streaming_maxpacket`·`streaming_maxburst`가 주요 구성 지점입니다. 특히 bitmap 크기와 USB 속도별 대역폭 제한은 UVC 규격과 함께 검토해야 합니다.