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