18c2ecf20Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ciThe cx2341x driver
48c2ecf20Sopenharmony_ci==================
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ciNon-compressed file format
78c2ecf20Sopenharmony_ci--------------------------
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ciThe cx23416 can produce (and the cx23415 can also read) raw YUV output. The
108c2ecf20Sopenharmony_ciformat of a YUV frame is specific to this chip and is called HM12. 'HM' stands
118c2ecf20Sopenharmony_cifor 'Hauppauge Macroblock', which is a misnomer as 'Conexant Macroblock' would
128c2ecf20Sopenharmony_cibe more accurate.
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ciThe format is YUV 4:2:0 which uses 1 Y byte per pixel and 1 U and V byte per
158c2ecf20Sopenharmony_cifour pixels.
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ciThe data is encoded as two macroblock planes, the first containing the Y
188c2ecf20Sopenharmony_civalues, the second containing UV macroblocks.
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ciThe Y plane is divided into blocks of 16x16 pixels from left to right
218c2ecf20Sopenharmony_ciand from top to bottom. Each block is transmitted in turn, line-by-line.
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ciSo the first 16 bytes are the first line of the top-left block, the
248c2ecf20Sopenharmony_cisecond 16 bytes are the second line of the top-left block, etc. After
258c2ecf20Sopenharmony_citransmitting this block the first line of the block on the right to the
268c2ecf20Sopenharmony_cifirst block is transmitted, etc.
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ciThe UV plane is divided into blocks of 16x8 UV values going from left
298c2ecf20Sopenharmony_cito right, top to bottom. Each block is transmitted in turn, line-by-line.
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ciSo the first 16 bytes are the first line of the top-left block and
328c2ecf20Sopenharmony_cicontain 8 UV value pairs (16 bytes in total). The second 16 bytes are the
338c2ecf20Sopenharmony_cisecond line of 8 UV pairs of the top-left block, etc. After transmitting
348c2ecf20Sopenharmony_cithis block the first line of the block on the right to the first block is
358c2ecf20Sopenharmony_citransmitted, etc.
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ciThe code below is given as an example on how to convert HM12 to separate
388c2ecf20Sopenharmony_ciY, U and V planes. This code assumes frames of 720x576 (PAL) pixels.
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ciThe width of a frame is always 720 pixels, regardless of the actual specified
418c2ecf20Sopenharmony_ciwidth.
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ciIf the height is not a multiple of 32 lines, then the captured video is
448c2ecf20Sopenharmony_cimissing macroblocks at the end and is unusable. So the height must be a
458c2ecf20Sopenharmony_cimultiple of 32.
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ciRaw format c example
488c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci.. code-block:: c
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	#include <stdio.h>
538c2ecf20Sopenharmony_ci	#include <stdlib.h>
548c2ecf20Sopenharmony_ci	#include <string.h>
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	static unsigned char frame[576*720*3/2];
578c2ecf20Sopenharmony_ci	static unsigned char framey[576*720];
588c2ecf20Sopenharmony_ci	static unsigned char frameu[576*720 / 4];
598c2ecf20Sopenharmony_ci	static unsigned char framev[576*720 / 4];
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	static void de_macro_y(unsigned char* dst, unsigned char *src, int dstride, int w, int h)
628c2ecf20Sopenharmony_ci	{
638c2ecf20Sopenharmony_ci	unsigned int y, x, i;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	// descramble Y plane
668c2ecf20Sopenharmony_ci	// dstride = 720 = w
678c2ecf20Sopenharmony_ci	// The Y plane is divided into blocks of 16x16 pixels
688c2ecf20Sopenharmony_ci	// Each block in transmitted in turn, line-by-line.
698c2ecf20Sopenharmony_ci	for (y = 0; y < h; y += 16) {
708c2ecf20Sopenharmony_ci		for (x = 0; x < w; x += 16) {
718c2ecf20Sopenharmony_ci		for (i = 0; i < 16; i++) {
728c2ecf20Sopenharmony_ci			memcpy(dst + x + (y + i) * dstride, src, 16);
738c2ecf20Sopenharmony_ci			src += 16;
748c2ecf20Sopenharmony_ci		}
758c2ecf20Sopenharmony_ci		}
768c2ecf20Sopenharmony_ci	}
778c2ecf20Sopenharmony_ci	}
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci	static void de_macro_uv(unsigned char *dstu, unsigned char *dstv, unsigned char *src, int dstride, int w, int h)
808c2ecf20Sopenharmony_ci	{
818c2ecf20Sopenharmony_ci	unsigned int y, x, i;
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	// descramble U/V plane
848c2ecf20Sopenharmony_ci	// dstride = 720 / 2 = w
858c2ecf20Sopenharmony_ci	// The U/V values are interlaced (UVUV...).
868c2ecf20Sopenharmony_ci	// Again, the UV plane is divided into blocks of 16x16 UV values.
878c2ecf20Sopenharmony_ci	// Each block in transmitted in turn, line-by-line.
888c2ecf20Sopenharmony_ci	for (y = 0; y < h; y += 16) {
898c2ecf20Sopenharmony_ci		for (x = 0; x < w; x += 8) {
908c2ecf20Sopenharmony_ci		for (i = 0; i < 16; i++) {
918c2ecf20Sopenharmony_ci			int idx = x + (y + i) * dstride;
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci			dstu[idx+0] = src[0];  dstv[idx+0] = src[1];
948c2ecf20Sopenharmony_ci			dstu[idx+1] = src[2];  dstv[idx+1] = src[3];
958c2ecf20Sopenharmony_ci			dstu[idx+2] = src[4];  dstv[idx+2] = src[5];
968c2ecf20Sopenharmony_ci			dstu[idx+3] = src[6];  dstv[idx+3] = src[7];
978c2ecf20Sopenharmony_ci			dstu[idx+4] = src[8];  dstv[idx+4] = src[9];
988c2ecf20Sopenharmony_ci			dstu[idx+5] = src[10]; dstv[idx+5] = src[11];
998c2ecf20Sopenharmony_ci			dstu[idx+6] = src[12]; dstv[idx+6] = src[13];
1008c2ecf20Sopenharmony_ci			dstu[idx+7] = src[14]; dstv[idx+7] = src[15];
1018c2ecf20Sopenharmony_ci			src += 16;
1028c2ecf20Sopenharmony_ci		}
1038c2ecf20Sopenharmony_ci		}
1048c2ecf20Sopenharmony_ci	}
1058c2ecf20Sopenharmony_ci	}
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci	/*************************************************************************/
1088c2ecf20Sopenharmony_ci	int main(int argc, char **argv)
1098c2ecf20Sopenharmony_ci	{
1108c2ecf20Sopenharmony_ci	FILE *fin;
1118c2ecf20Sopenharmony_ci	int i;
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci	if (argc == 1) fin = stdin;
1148c2ecf20Sopenharmony_ci	else fin = fopen(argv[1], "r");
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	if (fin == NULL) {
1178c2ecf20Sopenharmony_ci		fprintf(stderr, "cannot open input\n");
1188c2ecf20Sopenharmony_ci		exit(-1);
1198c2ecf20Sopenharmony_ci	}
1208c2ecf20Sopenharmony_ci	while (fread(frame, sizeof(frame), 1, fin) == 1) {
1218c2ecf20Sopenharmony_ci		de_macro_y(framey, frame, 720, 720, 576);
1228c2ecf20Sopenharmony_ci		de_macro_uv(frameu, framev, frame + 720 * 576, 720 / 2, 720 / 2, 576 / 2);
1238c2ecf20Sopenharmony_ci		fwrite(framey, sizeof(framey), 1, stdout);
1248c2ecf20Sopenharmony_ci		fwrite(framev, sizeof(framev), 1, stdout);
1258c2ecf20Sopenharmony_ci		fwrite(frameu, sizeof(frameu), 1, stdout);
1268c2ecf20Sopenharmony_ci	}
1278c2ecf20Sopenharmony_ci	fclose(fin);
1288c2ecf20Sopenharmony_ci	return 0;
1298c2ecf20Sopenharmony_ci	}
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ciFormat of embedded V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data
1338c2ecf20Sopenharmony_ci---------------------------------------------------------
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ciAuthor: Hans Verkuil <hverkuil@xs4all.nl>
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ciThis section describes the V4L2_MPEG_STREAM_VBI_FMT_IVTV format of the VBI data
1398c2ecf20Sopenharmony_ciembedded in an MPEG-2 program stream. This format is in part dictated by some
1408c2ecf20Sopenharmony_cihardware limitations of the ivtv driver (the driver for the Conexant cx23415/6
1418c2ecf20Sopenharmony_cichips), in particular a maximum size for the VBI data. Anything longer is cut
1428c2ecf20Sopenharmony_cioff when the MPEG stream is played back through the cx23415.
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ciThe advantage of this format is it is very compact and that all VBI data for
1458c2ecf20Sopenharmony_ciall lines can be stored while still fitting within the maximum allowed size.
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ciThe stream ID of the VBI data is 0xBD. The maximum size of the embedded data is
1488c2ecf20Sopenharmony_ci4 + 43 * 36, which is 4 bytes for a header and 2 * 18 VBI lines with a 1 byte
1498c2ecf20Sopenharmony_ciheader and a 42 bytes payload each. Anything beyond this limit is cut off by
1508c2ecf20Sopenharmony_cithe cx23415/6 firmware. Besides the data for the VBI lines we also need 36 bits
1518c2ecf20Sopenharmony_cifor a bitmask determining which lines are captured and 4 bytes for a magic cookie,
1528c2ecf20Sopenharmony_cisignifying that this data package contains V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data.
1538c2ecf20Sopenharmony_ciIf all lines are used, then there is no longer room for the bitmask. To solve this
1548c2ecf20Sopenharmony_citwo different magic numbers were introduced:
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci'itv0': After this magic number two unsigned longs follow. Bits 0-17 of the first
1578c2ecf20Sopenharmony_ciunsigned long denote which lines of the first field are captured. Bits 18-31 of
1588c2ecf20Sopenharmony_cithe first unsigned long and bits 0-3 of the second unsigned long are used for the
1598c2ecf20Sopenharmony_cisecond field.
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci'ITV0': This magic number assumes all VBI lines are captured, i.e. it implicitly
1628c2ecf20Sopenharmony_ciimplies that the bitmasks are 0xffffffff and 0xf.
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ciAfter these magic cookies (and the 8 byte bitmask in case of cookie 'itv0') the
1658c2ecf20Sopenharmony_cicaptured VBI lines start:
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ciFor each line the least significant 4 bits of the first byte contain the data type.
1688c2ecf20Sopenharmony_ciPossible values are shown in the table below. The payload is in the following 42
1698c2ecf20Sopenharmony_cibytes.
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ciHere is the list of possible data types:
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci.. code-block:: c
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci	#define IVTV_SLICED_TYPE_TELETEXT       0x1     // Teletext (uses lines 6-22 for PAL)
1768c2ecf20Sopenharmony_ci	#define IVTV_SLICED_TYPE_CC             0x4     // Closed Captions (line 21 NTSC)
1778c2ecf20Sopenharmony_ci	#define IVTV_SLICED_TYPE_WSS            0x5     // Wide Screen Signal (line 23 PAL)
1788c2ecf20Sopenharmony_ci	#define IVTV_SLICED_TYPE_VPS            0x7     // Video Programming System (PAL) (line 16)
1798c2ecf20Sopenharmony_ci
180