1 #include <unistd.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <inttypes.h>
6 #include <getopt.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <fcntl.h>
10 #include <ctype.h>
11 #include <errno.h>
12 #include <sys/ioctl.h>
13 #include <sys/time.h>
14 #include <dirent.h>
15 #include <math.h>
16 
17 #include <vector>
18 
19 #include "v4l2-ctl.h"
20 
21 #if !defined(__FreeBSD__) && !defined(__DragonFly__)
22 #include <linux/fb.h>
23 
24 static unsigned int set_fbuf;
25 static unsigned int set_overlay_fmt;
26 static struct v4l2_format overlay_fmt;	/* set_format/get_format video overlay */
27 static struct v4l2_framebuffer fbuf;	/* fbuf */
28 static int overlay;			/* overlay */
29 static const char *fb_device;
30 static std::vector<struct v4l2_clip> clips;
31 static std::vector<struct v4l2_rect> bitmap_rects;
32 
overlay_usage()33 void overlay_usage()
34 {
35 	printf("\nVideo Overlay options:\n"
36 	       "  --list-formats-overlay\n"
37 	       "                     display supported overlay formats [VIDIOC_ENUM_FMT]\n"
38 	       "  --find-fb          find the fb device corresponding with the overlay\n"
39 	       "  --overlay <on>     turn overlay on (1) or off (0) (VIDIOC_OVERLAY)\n"
40 	       "  --get-fmt-overlay  query the video or video output overlay format [VIDIOC_G_FMT]\n"
41 	       "  --set-fmt-overlay\n"
42 	       "  --try-fmt-overlay chromakey=<key>,global_alpha=<alpha>,\n"
43 	       "                           top=<t>,left=<l>,width=<w>,height=<h>,field=<f>\n"
44 	       "     		     set/try the video or video output overlay format [VIDIOC_TRY/S_FMT]\n"
45 	       "                     <f> can be one of:\n"
46 	       "                     any, none, top, bottom, interlaced, seq_tb, seq_bt,\n"
47 	       "                     alternate, interlaced_tb, interlaced_bt\n"
48 	       "                     If the width or height changed then the old clip list and bitmap will\n"
49 	       "                     be invalidated.\n"
50 	       "  --clear-clips      clear any old clips, to be used in combination with --try/set-fmt-overlay\n"
51 	       "  --clear-bitmap     clear any old bitmap, to be used in combination with --try/set-fmt-overlay\n"
52 	       "  --add-clip top=<t>,left=<l>,width=<w>,height=<h>\n"
53 	       "                     Add an entry to the clip list. May be used multiple times.\n"
54 	       "                     This clip list will be passed to --try/set-fmt-overlay\n"
55 	       "  --add-bitmap top=<t>,left=<l>,width=<w>,height=<h>\n"
56 	       "                     Set the bits in the given rectangle in the bitmap to 1. May be\n"
57 	       "                     used multiple times.\n"
58 	       "                     The bitmap will be passed to --try/set-fmt-overlay\n"
59 	       "  --get-fbuf         query the overlay framebuffer data [VIDIOC_G_FBUF]\n"
60 	       "  --set-fbuf chromakey=<b>,src_chromakey=<b>,global_alpha=<b>,local_alpha=<b>,local_inv_alpha=<b>,fb=<fb>\n"
61 	       "		     set the overlay framebuffer [VIDIOC_S_FBUF]\n"
62 	       "                     <b> is 0 or 1\n"
63 	       "                     <fb> is the framebuffer device (/dev/fbX)\n"
64 	       "                     if <fb> starts with a digit, then /dev/fb<fb> is used\n"
65 	       );
66 }
67 
printfbuf(const struct v4l2_framebuffer & fb)68 static void printfbuf(const struct v4l2_framebuffer &fb)
69 {
70 	int is_ext = fb.capability & V4L2_FBUF_CAP_EXTERNOVERLAY;
71 
72 	printf("Framebuffer Format:\n");
73 	printf("\tCapability    : %s", fbufcap2s(fb.capability).c_str() + 3);
74 	printf("\tFlags         : %s", fbufflags2s(fb.flags).c_str() + 3);
75 	if (fb.base)
76 		printf("\tBase          : %p\n", fb.base);
77 	printf("\tWidth         : %d\n", fb.fmt.width);
78 	printf("\tHeight        : %d\n", fb.fmt.height);
79 	printf("\tPixel Format  : '%s'\n", fcc2s(fb.fmt.pixelformat).c_str());
80 	if (!is_ext) {
81 		printf("\tBytes per Line: %d\n", fb.fmt.bytesperline);
82 		printf("\tSize image    : %d\n", fb.fmt.sizeimage);
83 		printf("\tColorspace    : %s\n", colorspace2s(fb.fmt.colorspace).c_str());
84 		if (fb.fmt.priv)
85 			printf("\tCustom Info   : %08x\n", fb.fmt.priv);
86 	}
87 }
88 
find_fb(int fd)89 static void find_fb(int fd)
90 {
91 	struct v4l2_framebuffer fbuf;
92 	unsigned int i;
93 	int fb_fd;
94 
95 	if (doioctl(fd, VIDIOC_G_FBUF, &fbuf))
96 		return;
97 	if (fbuf.base == 0) {
98 		printf("No framebuffer base address was defined\n");
99 		return;
100 	}
101 
102 	for (i = 0; i < 30; i++) {
103 		struct fb_fix_screeninfo si;
104 		char dev_name[16];
105 
106 		snprintf(dev_name, sizeof(dev_name), "/dev/fb%u", i);
107 
108 		fb_fd = open(dev_name, O_RDWR);
109 		if (fb_fd == -1) {
110 			switch (errno) {
111 			case ENOENT: /* no such file */
112 			case ENXIO:  /* no driver */
113 				continue;
114 
115 			default:
116 				return;
117 			}
118 		}
119 
120 		if (!ioctl(fb_fd, FBIOGET_FSCREENINFO, &si))
121 			if (si.smem_start == (unsigned long)fbuf.base) {
122 				printf("%s is the framebuffer associated with base address %p\n",
123 					dev_name, fbuf.base);
124 				close(fb_fd);
125 				return;
126 			}
127 		close(fb_fd);
128 		fb_fd = -1;
129 	}
130 	printf("No matching framebuffer found for base address %p\n", fbuf.base);
131 }
132 
133 struct bitfield2fmt {
134 	unsigned red_off, red_len;
135 	unsigned green_off, green_len;
136 	unsigned blue_off, blue_len;
137 	unsigned transp_off, transp_len;
138 	uint32_t pixfmt;
139 };
140 
141 static const struct bitfield2fmt fb_formats[] = {
142 	{ 10, 5,  5, 5,  0, 5, 15, 1, V4L2_PIX_FMT_ARGB555 },
143 	{ 11, 5,  5, 6,  0, 5,  0, 0, V4L2_PIX_FMT_RGB565 },
144 	{  1, 5,  6, 5, 11, 5,  0, 1, V4L2_PIX_FMT_RGB555X },
145 	{  0, 5,  5, 6, 11, 5,  0, 0, V4L2_PIX_FMT_RGB565X },
146 	{ 16, 8,  8, 8,  0, 8,  0, 0, V4L2_PIX_FMT_BGR24 },
147 	{  0, 8,  8, 8, 16, 8,  0, 0, V4L2_PIX_FMT_RGB24 },
148 	{ 16, 8,  8, 8,  0, 8, 24, 8, V4L2_PIX_FMT_ABGR32 },
149 	{  8, 8, 16, 8, 24, 8,  0, 8, V4L2_PIX_FMT_ARGB32 },
150 	{ }
151 };
152 
match_bitfield(const struct fb_bitfield & bf,unsigned off,unsigned len)153 static bool match_bitfield(const struct fb_bitfield &bf, unsigned off, unsigned len)
154 {
155 	if (bf.msb_right || bf.length != len)
156 		return false;
157 	return !len || bf.offset == off;
158 }
159 
fbuf_fill_from_fb(struct v4l2_framebuffer & fb,const char * fb_device)160 static int fbuf_fill_from_fb(struct v4l2_framebuffer &fb, const char *fb_device)
161 {
162 	struct fb_fix_screeninfo si;
163 	struct fb_var_screeninfo vi;
164 	int fb_fd;
165 
166 	if (fb_device == NULL)
167 		return 0;
168 	fb_fd = open(fb_device, O_RDWR);
169 	if (fb_fd == -1) {
170 		fprintf(stderr, "cannot open %s\n", fb_device);
171 		return -1;
172 	}
173 	if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &si)) {
174 		fprintf(stderr, "could not obtain fscreeninfo from %s\n", fb_device);
175 		close(fb_fd);
176 		return -1;
177 	}
178 	if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vi)) {
179 		fprintf(stderr, "could not obtain vscreeninfo from %s\n", fb_device);
180 		close(fb_fd);
181 		return -1;
182 	}
183 	fb.base = (void *)si.smem_start;
184 	fb.fmt.sizeimage = si.smem_len;
185 	fb.fmt.width = vi.xres;
186 	fb.fmt.height = vi.yres;
187 	fb.fmt.bytesperline = si.line_length;
188 	if (fb.fmt.height * fb.fmt.bytesperline > fb.fmt.sizeimage) {
189 		fprintf(stderr, "height * bytesperline > sizeimage?!\n");
190 		close(fb_fd);
191 		return -1;
192 	}
193 	fb.fmt.pixelformat = 0;
194 	if ((si.capabilities & FB_CAP_FOURCC) && vi.grayscale > 1) {
195 		fb.fmt.pixelformat = vi.grayscale;
196 		fb.fmt.colorspace = vi.colorspace;
197 	} else {
198 		if (vi.grayscale == 1) {
199 			if (vi.bits_per_pixel == 8)
200 				fb.fmt.pixelformat = V4L2_PIX_FMT_GREY;
201 		} else {
202 			for (int i = 0; fb_formats[i].pixfmt; i++) {
203 				const struct bitfield2fmt &p = fb_formats[i];
204 
205 				if (match_bitfield(vi.blue, p.blue_off, p.blue_len) &&
206 				    match_bitfield(vi.green, p.green_off, p.green_len) &&
207 				    match_bitfield(vi.red, p.red_off, p.red_len) &&
208 				    match_bitfield(vi.transp, p.transp_off, p.transp_len)) {
209 					fb.fmt.pixelformat = p.pixfmt;
210 					break;
211 				}
212 			}
213 		}
214 		fb.fmt.colorspace = V4L2_COLORSPACE_SRGB;
215 	}
216 	printfbuf(fb);
217 	close(fb_fd);
218 	return 0;
219 }
220 
overlay_cmd(int ch,char * optarg)221 void overlay_cmd(int ch, char *optarg)
222 {
223 	struct v4l2_rect r;
224 	char *value, *subs;
225 
226 	switch (ch) {
227 	case OptSetOverlayFormat:
228 	case OptTryOverlayFormat:
229 		subs = optarg;
230 		while (subs && *subs != '\0') {
231 			static const char *const subopts[] = {
232 				"chromakey",
233 				"global_alpha",
234 				"left",
235 				"top",
236 				"width",
237 				"height",
238 				"field",
239 				NULL
240 			};
241 
242 			switch (parse_subopt(&subs, subopts, &value)) {
243 			case 0:
244 				overlay_fmt.fmt.win.chromakey = strtoul(value, 0L, 0);
245 				set_overlay_fmt |= FmtChromaKey;
246 				break;
247 			case 1:
248 				overlay_fmt.fmt.win.global_alpha = strtoul(value, 0L, 0);
249 				set_overlay_fmt |= FmtGlobalAlpha;
250 				break;
251 			case 2:
252 				overlay_fmt.fmt.win.w.left = strtol(value, 0L, 0);
253 				set_overlay_fmt |= FmtLeft;
254 				break;
255 			case 3:
256 				overlay_fmt.fmt.win.w.top = strtol(value, 0L, 0);
257 				set_overlay_fmt |= FmtTop;
258 				break;
259 			case 4:
260 				overlay_fmt.fmt.win.w.width = strtoul(value, 0L, 0);
261 				set_overlay_fmt |= FmtWidth;
262 				break;
263 			case 5:
264 				overlay_fmt.fmt.win.w.height = strtoul(value, 0L, 0);
265 				set_overlay_fmt |= FmtHeight;
266 				break;
267 			case 6:
268 				overlay_fmt.fmt.win.field = parse_field(value);
269 				set_overlay_fmt |= FmtField;
270 				break;
271 			default:
272 				overlay_usage();
273 				break;
274 			}
275 		}
276 		break;
277 	case OptAddClip:
278 	case OptAddBitmap:
279 		subs = optarg;
280 		memset(&r, 0, sizeof(r));
281 		while (*subs != '\0') {
282 			static const char *const subopts[] = {
283 				"left",
284 				"top",
285 				"width",
286 				"height",
287 				NULL
288 			};
289 
290 			switch (parse_subopt(&subs, subopts, &value)) {
291 			case 0:
292 				r.left = strtoul(value, 0L, 0);
293 				break;
294 			case 1:
295 				r.top = strtoul(value, 0L, 0);
296 				break;
297 			case 2:
298 				r.width = strtoul(value, 0L, 0);
299 				break;
300 			case 3:
301 				r.height = strtoul(value, 0L, 0);
302 				break;
303 			default:
304 				overlay_usage();
305 				return;
306 			}
307 		}
308 		if (r.width == 0 || r.height == 0) {
309 			overlay_usage();
310 			return;
311 		}
312 		if (ch == OptAddBitmap) {
313 			bitmap_rects.push_back(r);
314 		} else {
315 			struct v4l2_clip c;
316 
317 			c.c = r;
318 			c.next = NULL;
319 			clips.push_back(c);
320 		}
321 		break;
322 	case OptSetFBuf:
323 		subs = optarg;
324 		while (*subs != '\0') {
325 			const unsigned chroma_flags = V4L2_FBUF_FLAG_CHROMAKEY |
326 						      V4L2_FBUF_FLAG_SRC_CHROMAKEY;
327 			const unsigned alpha_flags = V4L2_FBUF_FLAG_GLOBAL_ALPHA |
328 						     V4L2_FBUF_FLAG_LOCAL_ALPHA |
329 						     V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
330 			static const char *const subopts[] = {
331 				"chromakey",
332 				"src_chromakey",
333 				"global_alpha",
334 				"local_alpha",
335 				"local_inv_alpha",
336 				"fb",
337 				NULL
338 			};
339 
340 			switch (parse_subopt(&subs, subopts, &value)) {
341 			case 0:
342 				fbuf.flags &= ~chroma_flags;
343 				fbuf.flags |= strtol(value, 0L, 0) ? V4L2_FBUF_FLAG_CHROMAKEY : 0;
344 				set_fbuf |= chroma_flags;
345 				break;
346 			case 1:
347 				fbuf.flags &= ~chroma_flags;
348 				fbuf.flags |= strtol(value, 0L, 0) ? V4L2_FBUF_FLAG_SRC_CHROMAKEY : 0;
349 				set_fbuf |= chroma_flags;
350 				break;
351 			case 2:
352 				fbuf.flags &= ~alpha_flags;
353 				fbuf.flags |= strtol(value, 0L, 0) ? V4L2_FBUF_FLAG_GLOBAL_ALPHA : 0;
354 				set_fbuf |= alpha_flags;
355 				break;
356 			case 3:
357 				fbuf.flags &= ~alpha_flags;
358 				fbuf.flags |= strtol(value, 0L, 0) ? V4L2_FBUF_FLAG_LOCAL_ALPHA : 0;
359 				set_fbuf |= alpha_flags;
360 				break;
361 			case 4:
362 				fbuf.flags &= ~alpha_flags;
363 				fbuf.flags |= strtol(value, 0L, 0) ? V4L2_FBUF_FLAG_LOCAL_INV_ALPHA : 0;
364 				set_fbuf |= alpha_flags;
365 				break;
366 			case 5:
367 				fb_device = value;
368 				if (fb_device[0] >= '0' && fb_device[0] <= '9' && strlen(fb_device) <= 3) {
369 					static char newdev[20];
370 
371 					sprintf(newdev, "/dev/fb%s", fb_device);
372 					fb_device = newdev;
373 				}
374 				break;
375 			default:
376 				overlay_usage();
377 				break;
378 			}
379 		}
380 		break;
381 	case OptOverlay:
382 		overlay = strtol(optarg, 0L, 0);
383 		break;
384 	}
385 }
386 
do_try_set_overlay(struct v4l2_format & fmt,int fd)387 static void do_try_set_overlay(struct v4l2_format &fmt, int fd)
388 {
389 	struct v4l2_window &win = fmt.fmt.win;
390 	bool keep_old_clip = true;
391 	bool keep_old_bitmap = true;
392 	struct v4l2_clip *cliplist = NULL;
393 	unsigned stride = (win.w.width + 7) / 8;
394 	unsigned char *bitmap = NULL;
395 	int ret;
396 
397 	if (((set_overlay_fmt & FmtWidth) && win.w.width != overlay_fmt.fmt.win.w.width) ||
398 	    ((set_overlay_fmt & FmtHeight) && win.w.height != overlay_fmt.fmt.win.w.height))
399 		keep_old_bitmap = keep_old_clip = false;
400 	if (options[OptClearBitmap] || !bitmap_rects.empty())
401 		keep_old_bitmap = false;
402 	if (options[OptClearClips] || !clips.empty())
403 		keep_old_clip = false;
404 
405 	win.bitmap = NULL;
406 	if (keep_old_bitmap) {
407 		bitmap = static_cast<unsigned char *>(calloc(1, stride * win.w.height));
408 		win.bitmap = bitmap;
409 	}
410 	if (keep_old_clip) {
411 		if (win.clipcount)
412 			cliplist = static_cast<struct v4l2_clip *>(malloc(win.clipcount * sizeof(*cliplist)));
413 		win.clips = cliplist;
414 	}
415 	if (keep_old_clip || keep_old_bitmap)
416 		if (doioctl(fd, VIDIOC_G_FMT, &fmt))
417 			goto free;
418 
419 	if (set_overlay_fmt & FmtChromaKey)
420 		win.chromakey = overlay_fmt.fmt.win.chromakey;
421 	if (set_overlay_fmt & FmtGlobalAlpha)
422 		win.global_alpha = overlay_fmt.fmt.win.global_alpha;
423 	if (set_overlay_fmt & FmtLeft)
424 		win.w.left = overlay_fmt.fmt.win.w.left;
425 	if (set_overlay_fmt & FmtTop)
426 		win.w.top = overlay_fmt.fmt.win.w.top;
427 	if (set_overlay_fmt & FmtWidth)
428 		win.w.width = overlay_fmt.fmt.win.w.width;
429 	if (set_overlay_fmt & FmtHeight)
430 		win.w.height = overlay_fmt.fmt.win.w.height;
431 	if (set_overlay_fmt & FmtField)
432 		win.field = overlay_fmt.fmt.win.field;
433 	if (!clips.empty()) {
434 		win.clipcount = clips.size();
435 		win.clips = &clips[0];
436 	}
437 	if (!bitmap_rects.empty()) {
438 		free(bitmap);
439 		stride = (win.w.width + 7) / 8;
440 		bitmap = static_cast<unsigned char *>(calloc(1, stride * win.w.height));
441 		win.bitmap = bitmap;
442 		for (unsigned i = 0; i < bitmap_rects.size(); i++) {
443 			const v4l2_rect &r = bitmap_rects[i];
444 
445 			if (r.left + r.width > win.w.width ||
446 			    r.top + r.height > win.w.height) {
447 				fprintf(stderr, "rectangle is out of range\n");
448 				return;
449 			}
450 			for (unsigned y = r.top; y < r.top + r.height; y++)
451 				for (unsigned x = r.left; x < r.left + r.width; x++)
452 					bitmap[y * stride + x / 8] |= 1 << (x & 7);
453 		}
454 		win.bitmap = bitmap;
455 	}
456 	if (options[OptSetOverlayFormat])
457 		ret = doioctl(fd, VIDIOC_S_FMT, &fmt);
458 	else
459 		ret = doioctl(fd, VIDIOC_TRY_FMT, &fmt);
460 	if (ret == 0 && (verbose || options[OptTryOverlayFormat]))
461 		printfmt(fd, fmt);
462 
463 free:
464 	if (bitmap)
465 		free(bitmap);
466 	if (cliplist)
467 		free(cliplist);
468 }
469 
overlay_set(cv4l_fd & _fd)470 void overlay_set(cv4l_fd &_fd)
471 {
472 	int fd = _fd.g_fd();
473 
474 	if ((options[OptSetOverlayFormat] || options[OptTryOverlayFormat]) &&
475 			(set_overlay_fmt || options[OptClearClips] || options[OptClearBitmap] ||
476 			 !bitmap_rects.empty() || !clips.empty())) {
477 		struct v4l2_format fmt;
478 
479 		memset(&fmt, 0, sizeof(fmt));
480 		// You can never have both VIDEO_OVERLAY and VIDEO_OUTPUT_OVERLAY
481 		if (capabilities & V4L2_CAP_VIDEO_OVERLAY)
482 			fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
483 		else
484 			fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY;
485 		if (doioctl(fd, VIDIOC_G_FMT, &fmt) == 0)
486 			do_try_set_overlay(fmt, fd);
487 	}
488 
489 	if (options[OptSetFBuf]) {
490 		struct v4l2_framebuffer fb;
491 
492 		if (doioctl(fd, VIDIOC_G_FBUF, &fb) == 0) {
493 			fb.flags &= ~set_fbuf;
494 			fb.flags |= fbuf.flags;
495 			if (!fbuf_fill_from_fb(fb, fb_device))
496 				doioctl(fd, VIDIOC_S_FBUF, &fb);
497 		}
498 	}
499 
500 	if (options[OptOverlay]) {
501 		doioctl(fd, VIDIOC_OVERLAY, &overlay);
502 	}
503 }
504 
overlay_get(cv4l_fd & _fd)505 void overlay_get(cv4l_fd &_fd)
506 {
507 	int fd = _fd.g_fd();
508 
509 	if (options[OptGetOverlayFormat]) {
510 		struct v4l2_format fmt;
511 		unsigned char *bitmap = NULL;
512 
513 		memset(&fmt, 0, sizeof(fmt));
514 		// You can never have both VIDEO_OVERLAY and VIDEO_OUTPUT_OVERLAY
515 		if (capabilities & V4L2_CAP_VIDEO_OVERLAY)
516 			fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
517 		else
518 			fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY;
519 		if (doioctl(fd, VIDIOC_G_FMT, &fmt) == 0) {
520 			unsigned stride = (fmt.fmt.win.w.width + 7) / 8;
521 
522 			if (fmt.fmt.win.clipcount)
523 				fmt.fmt.win.clips = static_cast<struct v4l2_clip *>(malloc(fmt.fmt.win.clipcount * sizeof(clips[0])));
524 			bitmap = static_cast<unsigned char *>(calloc(1, stride * fmt.fmt.win.w.height));
525 			fmt.fmt.win.bitmap = bitmap;
526 			doioctl(fd, VIDIOC_G_FMT, &fmt);
527 			printfmt(fd, fmt);
528 			if (fmt.fmt.win.clips)
529 				free(fmt.fmt.win.clips);
530 			if (bitmap)
531 				free(bitmap);
532 		}
533 	}
534 
535 	if (options[OptGetFBuf]) {
536 		struct v4l2_framebuffer fb;
537 		if (doioctl(fd, VIDIOC_G_FBUF, &fb) == 0)
538 			printfbuf(fb);
539 	}
540 }
541 
overlay_list(cv4l_fd & fd)542 void overlay_list(cv4l_fd &fd)
543 {
544 	if (options[OptListOverlayFormats]) {
545 		printf("ioctl: VIDIOC_ENUM_FMT\n");
546 		print_video_formats(fd, V4L2_BUF_TYPE_VIDEO_OVERLAY);
547 	}
548 	if (options[OptFindFb])
549 		find_fb(fd.g_fd());
550 }
551 #else
overlay_usage(void)552 void overlay_usage(void)
553 {
554 }
555 
overlay_cmd(int ch,char * optarg)556 void overlay_cmd(int ch, char *optarg)
557 {
558 }
559 
overlay_set(cv4l_fd & _fd)560 void overlay_set(cv4l_fd &_fd)
561 {
562 }
563 
overlay_get(cv4l_fd & _fd)564 void overlay_get(cv4l_fd &_fd)
565 {
566 }
567 
overlay_list(cv4l_fd & fd)568 void overlay_list(cv4l_fd &fd)
569 {
570 }
571 #endif
572