• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <endian.h>
2 
3 #include "v4l2-ctl.h"
4 
5 static struct v4l2_format vfmt;	/* set_format/get_format */
6 static unsigned mbus_code;
7 static unsigned mbus_code_out;
8 
meta_usage()9 void meta_usage()
10 {
11 	printf("\nMetadata Formats options:\n"
12 	       "  --list-formats-meta [<mbus_code>] display supported metadata capture formats.\n"
13 	       "		     <mbus_code> is an optional media bus code, if the device has\n"
14 	       "		     capability V4L2_CAP_IO_MC then only formats that support this\n"
15 	       "		     media bus code are listed [VIDIOC_ENUM_FMT]\n"
16 	       "  --get-fmt-meta     query the metadata capture format [VIDIOC_G_FMT]\n"
17 	       "  --set-fmt-meta <f> set the metadata capture format [VIDIOC_S_FMT]\n"
18 	       "                     parameter is either the format index as reported by\n"
19 	       "                     --list-formats-meta, or the fourcc value as a string\n"
20 	       "  --try-fmt-meta <f> try the metadata capture format [VIDIOC_TRY_FMT]\n"
21 	       "                     parameter is either the format index as reported by\n"
22 	       "                     --list-formats-meta, or the fourcc value as a string\n"
23 	       "  --list-formats-meta-out [<mbus_code>] display supported metadata output formats.\n"
24 	       "		     <mbus_code> is an optional media bus code, if the device has\n"
25 	       "		     capability V4L2_CAP_IO_MC then only formats that support this\n"
26 	       "		     media bus code are listed [VIDIOC_ENUM_FMT]\n"
27 	       "  --get-fmt-meta-out query the metadata output format [VIDIOC_G_FMT]\n"
28 	       "  --set-fmt-meta-out <f> set the metadata output format [VIDIOC_S_FMT]\n"
29 	       "                     parameter is either the format index as reported by\n"
30 	       "                     --list-formats-meta-out, or the fourcc value as a string\n"
31 	       "  --try-fmt-meta-out <f> try the metadata output format [VIDIOC_TRY_FMT]\n"
32 	       "                     parameter is either the format index as reported by\n"
33 	       "                     --list-formats-meta-out, or the fourcc value as a string\n"
34 	       );
35 }
36 
meta_cmd(int ch,char * optarg)37 void meta_cmd(int ch, char *optarg)
38 {
39 	switch (ch) {
40 	case OptSetMetaFormat:
41 	case OptTryMetaFormat:
42 	case OptSetMetaOutFormat:
43 	case OptTryMetaOutFormat:
44 		if (strlen(optarg) == 0) {
45 			meta_usage();
46 			std::exit(EXIT_FAILURE);
47 		} else if (strlen(optarg) == 4) {
48 			vfmt.fmt.meta.dataformat = v4l2_fourcc(optarg[0],
49 					optarg[1], optarg[2], optarg[3]);
50 		} else {
51 			vfmt.fmt.meta.dataformat = strtol(optarg, nullptr, 0);
52 		}
53 		break;
54 	case OptListMetaFormats:
55 		if (optarg)
56 			mbus_code = strtoul(optarg, nullptr, 0);
57 		break;
58 	case OptListMetaOutFormats:
59 		if (optarg)
60 			mbus_code_out = strtoul(optarg, nullptr, 0);
61 		break;
62 	}
63 }
64 
__meta_set(cv4l_fd & _fd,bool set,bool _try,__u32 type)65 static void __meta_set(cv4l_fd &_fd, bool set, bool _try, __u32 type)
66 {
67 	struct v4l2_format in_vfmt;
68 	int fd = _fd.g_fd();
69 	int ret;
70 
71 	if (!set && !_try)
72 		return;
73 
74 	in_vfmt.type = type;
75 	in_vfmt.fmt.meta.dataformat = vfmt.fmt.meta.dataformat;
76 
77 	if (in_vfmt.fmt.meta.dataformat < 256) {
78 		struct v4l2_fmtdesc fmt = {};
79 
80 		fmt.index = in_vfmt.fmt.meta.dataformat;
81 		fmt.type = in_vfmt.type;
82 
83 		if (doioctl(fd, VIDIOC_ENUM_FMT, &fmt))
84 			fmt.pixelformat = 0;
85 
86 		in_vfmt.fmt.meta.dataformat = fmt.pixelformat;
87 	}
88 
89 	if (set)
90 		ret = doioctl(fd, VIDIOC_S_FMT, &in_vfmt);
91 	else
92 		ret = doioctl(fd, VIDIOC_TRY_FMT, &in_vfmt);
93 	if (ret == 0 && (verbose || _try))
94 		printfmt(fd, in_vfmt);
95 }
96 
meta_set(cv4l_fd & _fd)97 void meta_set(cv4l_fd &_fd)
98 {
99 	__meta_set(_fd, options[OptSetMetaFormat], options[OptTryMetaFormat],
100 		   V4L2_BUF_TYPE_META_CAPTURE);
101 	__meta_set(_fd, options[OptSetMetaOutFormat],
102 		   options[OptTryMetaOutFormat], V4L2_BUF_TYPE_META_OUTPUT);
103 }
104 
__meta_get(cv4l_fd & fd,__u32 type)105 static void __meta_get(cv4l_fd &fd, __u32 type)
106 {
107 	vfmt.type = type;
108 	if (doioctl(fd.g_fd(), VIDIOC_G_FMT, &vfmt) == 0)
109 		printfmt(fd.g_fd(), vfmt);
110 }
111 
meta_get(cv4l_fd & fd)112 void meta_get(cv4l_fd &fd)
113 {
114 	if (options[OptGetMetaFormat])
115 		__meta_get(fd, V4L2_BUF_TYPE_META_CAPTURE);
116 	if (options[OptGetMetaOutFormat])
117 		__meta_get(fd, V4L2_BUF_TYPE_META_OUTPUT);
118 }
119 
meta_list(cv4l_fd & fd)120 void meta_list(cv4l_fd &fd)
121 {
122 	if (options[OptListMetaFormats]) {
123 		printf("ioctl: VIDIOC_ENUM_FMT\n");
124 		print_video_formats(fd, V4L2_BUF_TYPE_META_CAPTURE, mbus_code);
125 	}
126 
127 	if (options[OptListMetaOutFormats]) {
128 		printf("ioctl: VIDIOC_ENUM_FMT\n");
129 		print_video_formats(fd, V4L2_BUF_TYPE_META_OUTPUT, mbus_code_out);
130 	}
131 }
132 
133 struct uvc_meta_buf {
134 	__u64 ns;
135 	__u16 sof;
136 	__u8 length;
137 	__u8 flags;
138 	__u8 buf[10];
139 };
140 
141 #define UVC_STREAM_SCR	(1 << 3)
142 #define UVC_STREAM_PTS	(1 << 2)
143 
144 struct vivid_meta_out_buf {
145         __u16	brightness;
146         __u16	contrast;
147         __u16	saturation;
148         __s16	hue;
149 };
150 
print_meta_buffer(FILE * f,cv4l_buffer & buf,cv4l_fmt & fmt,cv4l_queue & q)151 void print_meta_buffer(FILE *f, cv4l_buffer &buf, cv4l_fmt &fmt, cv4l_queue &q)
152 {
153 	struct uvc_meta_buf *vbuf;
154 	int buf_off = 0;
155 	struct vivid_meta_out_buf *vbuf_out;
156 
157 	switch (fmt.g_pixelformat()) {
158 	case V4L2_META_FMT_UVC:
159 		fprintf(f, "UVC: ");
160 		vbuf = static_cast<uvc_meta_buf *>(q.g_dataptr(buf.g_index(), 0));
161 
162 		fprintf(f, "%.6fs sof: %4d len: %u flags: 0x%02x",
163 			static_cast<double>(vbuf->ns) / 1000000000.0,
164 			vbuf->sof,
165 			vbuf->length,
166 			vbuf->flags);
167 		if (vbuf->flags & UVC_STREAM_PTS) {
168 			fprintf(f, " PTS: %u", le32toh(*(__u32*)(vbuf->buf)));
169 			buf_off = 4;
170 		}
171 		if (vbuf->flags & UVC_STREAM_SCR)
172 			fprintf(f, " STC: %u SOF counter: %u",
173 				le32toh(*(__u32*)(vbuf->buf + buf_off)),
174 				le16toh(*(__u16*)(vbuf->buf + buf_off + 4)));
175 		fprintf(f, "\n");
176 		break;
177 	case V4L2_META_FMT_VIVID:
178 		fprintf(f, "VIVID:");
179 		vbuf_out = static_cast<vivid_meta_out_buf *>(q.g_dataptr(buf.g_index(), 0));
180 
181 		fprintf(f, " brightness: %u contrast: %u saturation: %u  hue: %d\n",
182 			vbuf_out->brightness, vbuf_out->contrast,
183 			vbuf_out->saturation, vbuf_out->hue);
184 		break;
185 	}
186 }
187 
meta_fillbuffer(cv4l_buffer & buf,cv4l_fmt & fmt,cv4l_queue & q)188 void meta_fillbuffer(cv4l_buffer &buf, cv4l_fmt &fmt, cv4l_queue &q)
189 {
190 	struct vivid_meta_out_buf *vbuf;
191 
192 	switch (fmt.g_pixelformat()) {
193 		case V4L2_META_FMT_VIVID:
194 			vbuf = static_cast<vivid_meta_out_buf *>(q.g_dataptr(buf.g_index(), 0));
195 			vbuf->brightness = buf.g_sequence() % 192 + 64;
196 			vbuf->contrast = (buf.g_sequence() + 10) % 192 + 64;
197 			vbuf->saturation = (buf.g_sequence() + 20) % 256;
198 			vbuf->hue = buf.g_sequence() % 257 - 128;
199 			break;
200 	}
201 }
202