• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * V4L2 run-length image encoder header
4  *
5  * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6  */
7 
8 #ifndef _V4L_STREAM_H_
9 #define _V4L_STREAM_H_
10 
11 #include <linux/videodev2.h>
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif /* __cplusplus */
16 
17 #include <codec-v4l2-fwht.h>
18 
19 /* Default port */
20 #define V4L_STREAM_PORT 8362
21 
22 /*
23  * The stream starts with the stream ID followed by the version
24  * number.
25  *
26  * This is followed by FRAME_VIDEO packets with optional FMT_VIDEO
27  * packets in between if the format changes from one frame to another.
28  *
29  * Before sending the initial FRAME_VIDEO packet you must send the
30  * FMT_VIDEO packet first.
31  *
32  * All values (IDs, sizes, etc) are all uint32_t in network order.
33  */
34 #define V4L_STREAM_ID			v4l2_fourcc('V', '4', 'L', '2')
35 #define V4L_STREAM_VERSION		2
36 
37 /*
38  * Each packet is followed by the size of the packet (not including
39  * the packet ID + size).
40  */
41 
42 /*
43  * The video format is defined as follows:
44  *
45  * uint32_t size_fmt; 	// size in bytes of data after size_fmt up to fmt_plane
46  * uint32_t num_planes;
47  * uint32_t pixelformat;
48  * uint32_t width;
49  * uint32_t height;
50  * uint32_t field;
51  * uint32_t colorspace;
52  * uint32_t ycbcr_enc;
53  * uint32_t quantization;
54  * uint32_t xfer_func;
55  * uint32_t flags;
56  * uint32_t pixel_aspect_numerator;	(pixel_aspect = y/x, same as VIDIOC_CROPCAP)
57  * uint32_t pixel_aspect_denominator;
58  *
59  * struct fmt_plane {
60  * 	uint32_t size_fmt_plane; // size in bytes of this plane format struct excluding this field
61  * 	uint32_t sizeimage;
62  * 	uint32_t bytesperline;
63  * } fmt_planes[num_planes];
64  */
65 #define V4L_STREAM_PACKET_FMT_VIDEO			v4l2_fourcc('f', 'm', 't', 'v')
66 #define V4L_STREAM_PACKET_FMT_VIDEO_SIZE_FMT		(12 * 4)
67 #define V4L_STREAM_PACKET_FMT_VIDEO_SIZE_FMT_PLANE	(2 * 4)
68 #define V4L_STREAM_PACKET_FMT_VIDEO_SIZE(planes)	(V4L_STREAM_PACKET_FMT_VIDEO_SIZE_FMT + 4 + \
69 							 (planes) * (V4L_STREAM_PACKET_FMT_VIDEO_SIZE_FMT_PLANE + 4))
70 
71 /* Run-length encoded frame video packet */
72 #define V4L_STREAM_PACKET_FRAME_VIDEO_RLE		v4l2_fourcc('f', 'r', 'm', 'v')
73 /* FWHT compressed frame video packet */
74 #define V4L_STREAM_PACKET_FRAME_VIDEO_FWHT		v4l2_fourcc('f', 'r', 'm', 'V')
75 
76 #define V4L_STREAM_PACKET_FRAME_VIDEO_SIZE_HDR		(8 * 4)
77 #define V4L_STREAM_PACKET_FRAME_VIDEO_SIZE_PLANE_HDR	(8 * 4)
78 #define V4L_STREAM_PACKET_FRAME_VIDEO_SIZE(planes) 	(V4L_STREAM_PACKET_FRAME_VIDEO_SIZE_HDR + 4 + \
79 							 (planes) * (V4L_STREAM_PACKET_FRAME_VIDEO_SIZE_PLANE_HDR + 4))
80 
81 /*
82  * The frame video packet content is defined as follows:
83  *
84  * uint32_t size_hdr;	// size in bytes of data after size_hdr until planes[]
85  * uint32_t field;
86  * uint32_t flags;
87  * struct plane {
88  * 	uint32_t size_plane_hdr; // size in bytes of data after size_plane_hdr until data[]
89  * 	uint32_t bytesused;
90  * 	uint32_t data_size;
91  * 	uint8_t data[data_size];
92  * } planes[num_planes];
93  */
94 
95 /* Run-length encoding desciption: */
96 
97 #define V4L_STREAM_PACKET_FRAME_VIDEO_X_RLE		0x02dead43
98 #define V4L_STREAM_PACKET_FRAME_VIDEO_Y_RLE		0x02dead41
99 #define V4L_STREAM_PACKET_FRAME_VIDEO_RPLC		0x02dead42
100 
101 /*
102  * The run-length encoding used is optimized for use with test patterns.
103  * The data_size value is always <= bytesused. If it is equal to bytesused
104  * then no RLE was used.
105  *
106  * The RLE works on groups of 4 bytes. The VIDEO_Y_RLE value is only used
107  * if the corresponding bytesperline value of the plane is != 0.
108  *
109  * If duplicate lines are found, then an Y_RLE value followed by the number
110  * of duplicate lines - 1 is inserted (so two identical lines are replaced
111  * by Y_RLE followed by 1 followed by the encoded line).
112  *
113  * If there are more than 3 identical values, then those are replaced by an
114  * X_RLE value followed by the duplicated value followed by the number of
115  * duplicate values within the line. So 0xff, 0xff, 0xff, 0xff would become
116  * X_RLE, 0xff, 4.
117  *
118  * If X_RLE or Y_RLE (if bytesperline != 0) is found in the stream, then
119  * those are replaced by the RPLC value (this makes the encoding very slightly
120  * lossy)
121  */
122 
123 /*
124  * FWHT-compression desciption:
125  *
126  * The compressed encoding is simple but good enough for debugging.
127  * The size value is always <= bytesused + sizeof(struct fwht_cframe_hdr).
128  *
129  * See codec-fwht.h for more information about the compression
130  * details.
131  */
132 
133 /*
134  * This packet ends the stream and, after reading this, the socket can be closed
135  * since no more data will follow.
136  */
137 #define V4L_STREAM_PACKET_END				v4l2_fourcc('e', 'n', 'd', ' ')
138 
139 struct codec_ctx {
140 	struct v4l2_fwht_state	state;
141 	unsigned int		flags;
142 	unsigned int		size;
143 	u32			field;
144 	u32			comp_max_size;
145 };
146 
147 unsigned rle_compress(__u8 *buf, unsigned size, unsigned bytesperline);
148 void rle_decompress(__u8 *buf, unsigned size, unsigned rle_size, unsigned bytesperline);
149 struct codec_ctx *fwht_alloc(unsigned pixfmt, unsigned visible_width, unsigned visible_height,
150 			     unsigned coded_width, unsigned coded_height, unsigned field,
151 			     unsigned colorspace, unsigned xfer_func, unsigned ycbcr_enc,
152 			     unsigned quantization);
153 void fwht_free(struct codec_ctx *ctx);
154 __u8 *fwht_compress(struct codec_ctx *ctx, __u8 *buf, unsigned size, unsigned *comp_size);
155 bool fwht_decompress(struct codec_ctx *ctx, __u8 *read_buf, unsigned comp_size,
156 		     __u8 *buf, unsigned size);
157 unsigned rle_calc_bpl(unsigned bpl, __u32 pixelformat);
158 
159 #ifdef __cplusplus
160 }
161 #endif /* __cplusplus */
162 
163 #endif
164