← Documents Documentation/userspace-api/media/drivers/cx2341x-uapi.rst GitHub 원문 ↗

Linux 6.18.37 · Userspace API / Media / Drivers

cx2341x driver

cx23415/6의 16×16 tiled NV12와 embedded IVTV VBI packet format을 설명합니다.

Source pathDocumentation/userspace-api/media/drivers/cx2341x-uapi.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

요약·해설

cx2341x-uapi.rst:1-177

raw YUV는 Y 16×16, UV 16×8 macroblock을 block-major 순서로 전달합니다. 문서의 C 예제는 이를 raster Y·U·V plane으로 풀고, 뒤 절은 0xBD MPEG stream 안의 compact IVTV VBI record를 정의합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 The cx2341x driver
4 ==================
5
6 Non-compressed file format
7 --------------------------
8
9 The cx23416 can produce (and the cx23415 can also read) raw YUV output. The
10 format of a YUV frame is 16x16 linear tiled NV12 (V4L2_PIX_FMT_NV12_16L16).
11
12 The format is YUV 4:2:0 which uses 1 Y byte per pixel and 1 U and V byte per
13 four pixels.
14
15 The data is encoded as two macroblock planes, the first containing the Y
16 values, the second containing UV macroblocks.
17
18 The Y plane is divided into blocks of 16x16 pixels from left to right
19 and from top to bottom. Each block is transmitted in turn, line-by-line.
20
21 So the first 16 bytes are the first line of the top-left block, the
22 second 16 bytes are the second line of the top-left block, etc. After
23 transmitting this block the first line of the block on the right to the
24 first block is transmitted, etc.
25
26 The UV plane is divided into blocks of 16x8 UV values going from left
27 to right, top to bottom. Each block is transmitted in turn, line-by-line.
28
29 So the first 16 bytes are the first line of the top-left block and
30 contain 8 UV value pairs (16 bytes in total). The second 16 bytes are the
31 second line of 8 UV pairs of the top-left block, etc. After transmitting
32 this block the first line of the block on the right to the first block is
33 transmitted, etc.
34
35 The code below is given as an example on how to convert V4L2_PIX_FMT_NV12_16L16
36 to separate Y, U and V planes. This code assumes frames of 720x576 (PAL) pixels.
37
38 The width of a frame is always 720 pixels, regardless of the actual specified
39 width.
40
41 If the height is not a multiple of 32 lines, then the captured video is
42 missing macroblocks at the end and is unusable. So the height must be a
43 multiple of 32.
44
45 Raw format c example
46 ~~~~~~~~~~~~~~~~~~~~
47
48 .. code-block:: c
49
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53
54 static unsigned char frame[576*720*3/2];
55 static unsigned char framey[576*720];
56 static unsigned char frameu[576*720 / 4];
57 static unsigned char framev[576*720 / 4];
58
59 static void de_macro_y(unsigned char* dst, unsigned char *src, int dstride, int w, int h)
60 {
61 unsigned int y, x, i;
62
63 // descramble Y plane
64 // dstride = 720 = w
65 // The Y plane is divided into blocks of 16x16 pixels
66 // Each block in transmitted in turn, line-by-line.
67 for (y = 0; y < h; y += 16) {
68 for (x = 0; x < w; x += 16) {
69 for (i = 0; i < 16; i++) {
70 memcpy(dst + x + (y + i) * dstride, src, 16);
71 src += 16;
72 }
73 }
74 }
75 }
76
77 static void de_macro_uv(unsigned char *dstu, unsigned char *dstv, unsigned char *src, int dstride, int w, int h)
78 {
79 unsigned int y, x, i;
80
81 // descramble U/V plane
82 // dstride = 720 / 2 = w
83 // The U/V values are interlaced (UVUV...).
84 // Again, the UV plane is divided into blocks of 16x16 UV values.
85 // Each block in transmitted in turn, line-by-line.
86 for (y = 0; y < h; y += 16) {
87 for (x = 0; x < w; x += 8) {
88 for (i = 0; i < 16; i++) {
89 int idx = x + (y + i) * dstride;
90
91 dstu[idx+0] = src[0]; dstv[idx+0] = src[1];
92 dstu[idx+1] = src[2]; dstv[idx+1] = src[3];
93 dstu[idx+2] = src[4]; dstv[idx+2] = src[5];
94 dstu[idx+3] = src[6]; dstv[idx+3] = src[7];
95 dstu[idx+4] = src[8]; dstv[idx+4] = src[9];
96 dstu[idx+5] = src[10]; dstv[idx+5] = src[11];
97 dstu[idx+6] = src[12]; dstv[idx+6] = src[13];
98 dstu[idx+7] = src[14]; dstv[idx+7] = src[15];
99 src += 16;
100 }
101 }
102 }
103 }
104
105 /*************************************************************************/
106 int main(int argc, char **argv)
107 {
108 FILE *fin;
109 int i;
110
111 if (argc == 1) fin = stdin;
112 else fin = fopen(argv[1], "r");
113
114 if (fin == NULL) {
115 fprintf(stderr, "cannot open input\n");
116 exit(-1);
117 }
118 while (fread(frame, sizeof(frame), 1, fin) == 1) {
119 de_macro_y(framey, frame, 720, 720, 576);
120 de_macro_uv(frameu, framev, frame + 720 * 576, 720 / 2, 720 / 2, 576 / 2);
121 fwrite(framey, sizeof(framey), 1, stdout);
122 fwrite(framev, sizeof(framev), 1, stdout);
123 fwrite(frameu, sizeof(frameu), 1, stdout);
124 }
125 fclose(fin);
126 return 0;
127 }
128
129
130 Format of embedded V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data
131 ---------------------------------------------------------
132
133 Author: Hans Verkuil <hverkuil@kernel.org>
134
135
136 This section describes the V4L2_MPEG_STREAM_VBI_FMT_IVTV format of the VBI data
137 embedded in an MPEG-2 program stream. This format is in part dictated by some
138 hardware limitations of the ivtv driver (the driver for the Conexant cx23415/6
139 chips), in particular a maximum size for the VBI data. Anything longer is cut
140 off when the MPEG stream is played back through the cx23415.
141
142 The advantage of this format is it is very compact and that all VBI data for
143 all lines can be stored while still fitting within the maximum allowed size.
144
145 The stream ID of the VBI data is 0xBD. The maximum size of the embedded data is
146 4 + 43 * 36, which is 4 bytes for a header and 2 * 18 VBI lines with a 1 byte
147 header and a 42 bytes payload each. Anything beyond this limit is cut off by
148 the cx23415/6 firmware. Besides the data for the VBI lines we also need 36 bits
149 for a bitmask determining which lines are captured and 4 bytes for a magic cookie,
150 signifying that this data package contains V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data.
151 If all lines are used, then there is no longer room for the bitmask. To solve this
152 two different magic numbers were introduced:
153
154 'itv0': After this magic number two unsigned longs follow. Bits 0-17 of the first
155 unsigned long denote which lines of the first field are captured. Bits 18-31 of
156 the first unsigned long and bits 0-3 of the second unsigned long are used for the
157 second field.
158
159 'ITV0': This magic number assumes all VBI lines are captured, i.e. it implicitly
160 implies that the bitmasks are 0xffffffff and 0xf.
161
162 After these magic cookies (and the 8 byte bitmask in case of cookie 'itv0') the
163 captured VBI lines start:
164
165 For each line the least significant 4 bits of the first byte contain the data type.
166 Possible values are shown in the table below. The payload is in the following 42
167 bytes.
168
169 Here is the list of possible data types:
170
171 .. code-block:: c
172
173 #define IVTV_SLICED_TYPE_TELETEXT 0x1 // Teletext (uses lines 6-22 for PAL)
174 #define IVTV_SLICED_TYPE_CC 0x4 // Closed Captions (line 21 NTSC)
175 #define IVTV_SLICED_TYPE_WSS 0x5 // Wide Screen Signal (line 23 PAL)
176 #define IVTV_SLICED_TYPE_VPS 0x7 // Video Programming System (PAL) (line 16)
177
178

3. 한국어 전문 번역

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

16×16 tiled NV12 raw format

1-44

cx23416은 raw YUV output을 생성하고 cx23415는 이를 읽을 수도 있습니다. frame format은 `V4L2_PIX_FMT_NV12_16L16`, 즉 16×16 linear tiled NV12입니다.

YUV 4:2:0이므로 pixel마다 Y byte 하나를 사용하고 네 pixel마다 U byte 하나와 V byte 하나를 사용합니다.

data는 두 macroblock plane으로 인코딩됩니다. 첫 plane은 Y 값, 둘째 plane은 UV macroblock을 담습니다.

Y plane은 16×16 pixel block으로 나누어 왼쪽에서 오른쪽, 위에서 아래 순서로 진행합니다. 각 block 안에서는 line-by-line으로 송신하므로 처음 16 byte가 좌상단 block의 첫 line, 다음 16 byte가 둘째 line입니다. block을 마치면 오른쪽 block의 첫 line부터 이어집니다.

UV plane은 16×8개의 UV 값 block으로 나누고 같은 좌→우, 상→하, block 내부 line-by-line 순서를 사용합니다. 첫 16 byte에는 좌상단 block 첫 line의 UV pair 8개가 들어갑니다.

예제는 720×576 PAL frame의 `V4L2_PIX_FMT_NV12_16L16`을 분리된 Y, U, V plane으로 변환합니다. 실제 지정 width와 관계없이 frame width는 항상 720 pixel입니다.

height가 32 line의 배수가 아니면 마지막 macroblock이 빠져 capture video를 사용할 수 없으므로 height는 반드시 32의 배수여야 합니다.

NV12_16L16 plane layout
PlaneBlock전송 순서
Y plane16×16 pixels16-byte line × 16, block 좌→우·상→하
UV plane16×8 UV values8 UV pair의 16-byte line, block 좌→우·상→하

Y와 interleaved UV plane의 tile 크기와 순서를 구분합니다.

Tiled frame 해석
Frame 앞부분에서 Y macroblock plane 읽기16×16 block을 좌→우·상→하로 배치Frame 뒤쪽 UV macroblock plane 읽기interleaved UV pair를 U와 V로 분리720×height Y·U·V plane 완성

두 macroblock plane을 raster plane으로 풀어냅니다.

.. SPDX-License-Identifier: GPL-2.0

The cx2341x driver
==================

Non-compressed file format
--------------------------

The cx23416 can produce (and the cx23415 can also read) raw YUV output. The
format of a YUV frame is 16x16 linear tiled NV12 (V4L2_PIX_FMT_NV12_16L16).

The format is YUV 4:2:0 which uses 1 Y byte per pixel and 1 U and V byte per
four pixels.

The data is encoded as two macroblock planes, the first containing the Y
values, the second containing UV macroblocks.

The Y plane is divided into blocks of 16x16 pixels from left to right
and from top to bottom. Each block is transmitted in turn, line-by-line.

So the first 16 bytes are the first line of the top-left block, the
second 16 bytes are the second line of the top-left block, etc. After
transmitting this block the first line of the block on the right to the
first block is transmitted, etc.

The UV plane is divided into blocks of 16x8 UV values going from left
to right, top to bottom. Each block is transmitted in turn, line-by-line.

So the first 16 bytes are the first line of the top-left block and
contain 8 UV value pairs (16 bytes in total). The second 16 bytes are the
second line of 8 UV pairs of the top-left block, etc. After transmitting
this block the first line of the block on the right to the first block is
transmitted, etc.

The code below is given as an example on how to convert V4L2_PIX_FMT_NV12_16L16
to separate Y, U and V planes. This code assumes frames of 720x576 (PAL) pixels.

The width of a frame is always 720 pixels, regardless of the actual specified
width.

If the height is not a multiple of 32 lines, then the captured video is
missing macroblocks at the end and is unusable. So the height must be a
multiple of 32.

Raw format C 변환 예제

45-128

C 예제는 input frame, Y plane, quarter-size U와 V plane용 static buffer를 선언합니다. PAL 크기 720×576과 YUV 4:2:0의 3/2 byte 비율을 그대로 사용합니다.

`de_macro_y()`는 y와 x를 16씩 증가시키며 각 16×16 Y block의 16개 line을 destination stride 위치에 `memcpy()`합니다. source pointer는 line마다 16 byte 전진합니다.

`de_macro_uv()`는 UV가 `UVUV...`로 interlace됐다고 보고 각 16-byte source line의 짝수 byte를 U, 홀수 byte를 V destination에 복사합니다. x는 UV sample 8개씩, y는 16 line씩 진행합니다.

`main()`은 argument가 없으면 stdin, 있으면 첫 argument file을 열고 frame 크기만큼 반복해서 읽습니다. Y plane은 frame 시작에서, UV plane은 `frame + 720 * 576`에서 해제합니다.

변환 결과는 `framey`, `framev`, `frameu` 순서로 stdout에 씁니다. 즉 코드의 실제 output plane 순서는 Y, V, U입니다.

예제 buffer
Buffer크기역할
frame576*720*3/2Tiled NV12 input
framey576*720Raster Y output
frameu576*720/4Raster U output
framev576*720/4Raster V output

고정 PAL frame에서 각 plane의 크기를 계산합니다.

C example 실행
stdin 또는 file open한 tiled frame freadde_macro_y 호출de_macro_uv 호출Y, V, U 순서로 fwrite다음 frame 반복 후 fclose

input frame마다 두 plane을 풀고 세 output plane을 기록합니다.

Raw format c example
~~~~~~~~~~~~~~~~~~~~

.. code-block:: c

	#include <stdio.h>
	#include <stdlib.h>
	#include <string.h>

	static unsigned char frame[576*720*3/2];
	static unsigned char framey[576*720];
	static unsigned char frameu[576*720 / 4];
	static unsigned char framev[576*720 / 4];

	static void de_macro_y(unsigned char* dst, unsigned char *src, int dstride, int w, int h)
	{
	unsigned int y, x, i;

	// descramble Y plane
	// dstride = 720 = w
	// The Y plane is divided into blocks of 16x16 pixels
	// Each block in transmitted in turn, line-by-line.
	for (y = 0; y < h; y += 16) {
		for (x = 0; x < w; x += 16) {
		for (i = 0; i < 16; i++) {
			memcpy(dst + x + (y + i) * dstride, src, 16);
			src += 16;
		}
		}
	}
	}

	static void de_macro_uv(unsigned char *dstu, unsigned char *dstv, unsigned char *src, int dstride, int w, int h)
	{
	unsigned int y, x, i;

	// descramble U/V plane
	// dstride = 720 / 2 = w
	// The U/V values are interlaced (UVUV...).
	// Again, the UV plane is divided into blocks of 16x16 UV values.
	// Each block in transmitted in turn, line-by-line.
	for (y = 0; y < h; y += 16) {
		for (x = 0; x < w; x += 8) {
		for (i = 0; i < 16; i++) {
			int idx = x + (y + i) * dstride;

			dstu[idx+0] = src[0];  dstv[idx+0] = src[1];
			dstu[idx+1] = src[2];  dstv[idx+1] = src[3];
			dstu[idx+2] = src[4];  dstv[idx+2] = src[5];
			dstu[idx+3] = src[6];  dstv[idx+3] = src[7];
			dstu[idx+4] = src[8];  dstv[idx+4] = src[9];
			dstu[idx+5] = src[10]; dstv[idx+5] = src[11];
			dstu[idx+6] = src[12]; dstv[idx+6] = src[13];
			dstu[idx+7] = src[14]; dstv[idx+7] = src[15];
			src += 16;
		}
		}
	}
	}

	/*************************************************************************/
	int main(int argc, char **argv)
	{
	FILE *fin;
	int i;

	if (argc == 1) fin = stdin;
	else fin = fopen(argv[1], "r");

	if (fin == NULL) {
		fprintf(stderr, "cannot open input\n");
		exit(-1);
	}
	while (fread(frame, sizeof(frame), 1, fin) == 1) {
		de_macro_y(framey, frame, 720, 720, 576);
		de_macro_uv(frameu, framev, frame + 720 * 576, 720 / 2, 720 / 2, 576 / 2);
		fwrite(framey, sizeof(framey), 1, stdout);
		fwrite(framev, sizeof(framev), 1, stdout);
		fwrite(frameu, sizeof(frameu), 1, stdout);
	}
	fclose(fin);
	return 0;
	}

Embedded IVTV VBI format

129-153

이 절은 MPEG-2 program stream에 embedded된 VBI data의 `V4L2_MPEG_STREAM_VBI_FMT_IVTV` format을 설명합니다. 저자는 Hans Verkuil입니다.

format은 cx23415/6용 ivtv driver의 hardware 제약, 특히 VBI data 최대 크기의 영향을 받습니다. cx23415로 MPEG stream을 재생할 때 한도를 넘는 data는 잘립니다.

장점은 매우 compact하여 모든 line의 VBI data를 최대 허용 크기 안에 저장할 수 있다는 점입니다.

VBI stream ID는 `0xBD`이고 embedded data 최대 크기는 `4 + 43 * 36`입니다. 4-byte header 뒤에 두 field 각각 18개, 총 36개 VBI line이 오며 line마다 1-byte header와 42-byte payload를 사용합니다.

firmware는 이 한도를 넘는 부분을 자릅니다. line data 외에도 captured line을 나타내는 36-bit bitmask와 IVTV VBI package임을 표시하는 4-byte magic cookie가 필요합니다.

모든 line을 사용하면 bitmask 공간이 없어 이를 해결하려고 서로 다른 두 magic number를 도입했습니다.

IVTV embedded VBI 예산
항목설명
Stream ID0xBD
Package header4 bytes
VBI lines2 fields × 18 lines
Per-line record1-byte header + 42-byte payload = 43 bytes
Maximum4 + 43 * 36 bytes

header와 36개 line record가 firmware 최대 크기를 채웁니다.

VBI package 구성
0xBD stream 선택4-byte magic cookie 기록필요 시 captured-line bitmask 기록각 line의 1-byte type header 기록각 line의 42-byte payload 기록firmware 최대 크기를 넘는 부분 절단

compact line record와 magic cookie로 format을 식별합니다.


Format of embedded V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data
---------------------------------------------------------

Author: Hans Verkuil <hverkuil@kernel.org>


This section describes the V4L2_MPEG_STREAM_VBI_FMT_IVTV format of the VBI data
embedded in an MPEG-2 program stream. This format is in part dictated by some
hardware limitations of the ivtv driver (the driver for the Conexant cx23415/6
chips), in particular a maximum size for the VBI data. Anything longer is cut
off when the MPEG stream is played back through the cx23415.

The advantage of this format is it is very compact and that all VBI data for
all lines can be stored while still fitting within the maximum allowed size.

The stream ID of the VBI data is 0xBD. The maximum size of the embedded data is
4 + 43 * 36, which is 4 bytes for a header and 2 * 18 VBI lines with a 1 byte
header and a 42 bytes payload each. Anything beyond this limit is cut off by
the cx23415/6 firmware. Besides the data for the VBI lines we also need 36 bits
for a bitmask determining which lines are captured and 4 bytes for a magic cookie,
signifying that this data package contains V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data.
If all lines are used, then there is no longer room for the bitmask. To solve this
two different magic numbers were introduced:

Magic cookie, bitmask와 line record

154-168

소문자 `'itv0'` cookie 뒤에는 unsigned long 두 개가 옵니다. 첫 값의 bit 0–17은 first field의 captured line, bit 18–31과 둘째 값의 bit 0–3은 second field line을 나타냅니다.

대문자 `'ITV0'` cookie는 모든 VBI line을 capture한다고 가정하므로 bitmask `0xffffffff`와 `0xf`를 암묵적으로 의미합니다.

cookie와, 소문자 cookie인 경우의 8-byte bitmask 뒤에 captured VBI line record가 시작됩니다. 각 line 첫 byte의 least significant 4 bit가 data type이고 이어지는 42 byte가 payload입니다.

IVTV magic cookie
CookieBitmask의미
itv08-byte bitmask 포함field 1: bits 0–17; field 2: bits 18–31 + next bits 0–3
ITV0bitmask 생략암묵적으로 0xffffffff, 0xf

모든 line capture 여부에 따라 bitmask를 명시하거나 생략합니다.

VBI line record
항목설명
Type첫 byte bits 0–3
Payload다음 42 bytes

첫 byte 하위 nibble 뒤에 고정 payload가 옵니다.

'itv0': After this magic number two unsigned longs follow. Bits 0-17 of the first
unsigned long denote which lines of the first field are captured. Bits 18-31 of
the first unsigned long and bits 0-3 of the second unsigned long are used for the
second field.

'ITV0': This magic number assumes all VBI lines are captured, i.e. it implicitly
implies that the bitmasks are 0xffffffff and 0xf.

After these magic cookies (and the 8 byte bitmask in case of cookie 'itv0') the
captured VBI lines start:

For each line the least significant 4 bits of the first byte contain the data type.
Possible values are shown in the table below. The payload is in the following 42
bytes.

VBI data type

169-177

가능한 line data type은 Teletext, Closed Captions, Wide Screen Signal, Video Programming System입니다.

IVTV sliced VBI type
SymbolData
IVTV_SLICED_TYPE_TELETEXT0x1Teletext, PAL lines 6–22
IVTV_SLICED_TYPE_CC0x4Closed Captions, NTSC line 21
IVTV_SLICED_TYPE_WSS0x5Wide Screen Signal, PAL line 23
IVTV_SLICED_TYPE_VPS0x7Video Programming System, PAL line 16

type 값과 표준 line 용도를 보존합니다.

Here is the list of possible data types:

.. code-block:: c

	#define IVTV_SLICED_TYPE_TELETEXT       0x1     // Teletext (uses lines 6-22 for PAL)
	#define IVTV_SLICED_TYPE_CC             0x4     // Closed Captions (line 21 NTSC)
	#define IVTV_SLICED_TYPE_WSS            0x5     // Wide Screen Signal (line 23 PAL)
	#define IVTV_SLICED_TYPE_VPS            0x7     // Video Programming System (PAL) (line 16)