2019-07-21 13:36:14 +02:00
|
|
|
/*
|
|
|
|
* tests pour capturer les webcams
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/ioctl.h>
|
2019-07-24 17:00:07 +02:00
|
|
|
#include <errno.h>
|
2019-07-24 17:06:46 +02:00
|
|
|
#include <inttypes.h>
|
2019-07-21 13:36:14 +02:00
|
|
|
#include <linux/videodev2.h>
|
|
|
|
|
|
|
|
#include "../floatimg.h"
|
|
|
|
|
|
|
|
#include "v4l2_pr_structs.h"
|
|
|
|
#include "funcs.h"
|
|
|
|
|
|
|
|
int verbosity;
|
|
|
|
|
2019-07-27 04:03:57 +02:00
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
int enum_image_formats(int fd, char *txt, int k)
|
|
|
|
{
|
|
|
|
int foo, idx;
|
|
|
|
struct v4l2_fmtdesc fmtd;
|
|
|
|
|
|
|
|
printf("-- image formats enumeration (%s)\n", txt);
|
|
|
|
|
|
|
|
idx = 0;
|
|
|
|
for (;;) {
|
|
|
|
memset(&fmtd, 0, sizeof(fmtd));
|
|
|
|
fmtd.index = idx;
|
|
|
|
fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
|
|
|
|
|
|
|
foo = ioctl(fd, VIDIOC_ENUM_FMT, &fmtd);
|
|
|
|
// fprintf(stderr, "B idx=%d, foo=%d, errno=%d\n", idx, foo, errno);
|
|
|
|
if (foo) {
|
|
|
|
if (EINVAL==errno) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
perror(__func__);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pr_v4l2_fmtdesc(__func__, &fmtd);
|
|
|
|
|
|
|
|
idx++;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
2019-07-22 04:10:00 +02:00
|
|
|
/* --------------------------------------------------------------------- */
|
2019-07-24 17:00:07 +02:00
|
|
|
static int enum_inputs(int fd, char *txt, int k)
|
|
|
|
{
|
|
|
|
int index, foo;
|
|
|
|
struct v4l2_input input;
|
|
|
|
|
|
|
|
printf("-- inputs enumeration '%s'\n", txt);
|
|
|
|
|
|
|
|
index = 0;
|
|
|
|
for(;;) {
|
|
|
|
memset (&input, 0, sizeof (input));
|
|
|
|
input.index = index;
|
|
|
|
foo = ioctl(fd, VIDIOC_ENUMINPUT, &input);
|
|
|
|
if (foo) {
|
|
|
|
if (EINVAL==errno) { break; }
|
|
|
|
else {
|
|
|
|
perror("enuminput");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("%-32s | %-10s\n", input.name,
|
|
|
|
str_input_type(input.type));
|
|
|
|
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
int enum_controls(int fd, char *txt, int k)
|
2019-07-22 04:10:00 +02:00
|
|
|
{
|
2019-07-24 17:00:07 +02:00
|
|
|
struct v4l2_queryctrl qctrl;
|
|
|
|
int foo, idx;
|
|
|
|
|
|
|
|
|
|
|
|
printf("-- controls enumeration '%s'\n", txt);
|
|
|
|
|
|
|
|
memset (&qctrl, 0, sizeof (qctrl));
|
|
|
|
|
|
|
|
/* V4L2_CID_BASE defined in linux/v4l2-controls.h */
|
|
|
|
|
|
|
|
for (idx=V4L2_CID_BASE; idx<V4L2_CID_LASTP1; idx++) {
|
|
|
|
|
|
|
|
qctrl.id = idx;
|
|
|
|
|
|
|
|
if (verbosity) printf(" id %d ", idx);
|
|
|
|
|
|
|
|
if (0 == ioctl (fd, VIDIOC_QUERYCTRL, &qctrl)) {
|
|
|
|
if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
|
|
|
|
printf("disabled\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf(" %-32s %-10s [%d..%d]\n",
|
|
|
|
qctrl.name,
|
|
|
|
str_ctrl_type(qctrl.type),
|
|
|
|
qctrl.minimum, qctrl.maximum);
|
|
|
|
|
|
|
|
}
|
|
|
|
else if (EINVAL==errno) {
|
|
|
|
if (verbosity) puts("einval");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
printf("err %d %s\n", errno, strerror(errno));
|
|
|
|
}
|
|
|
|
fflush(stdout); fflush(stderr);
|
|
|
|
}
|
2019-07-22 04:10:00 +02:00
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
2019-07-24 17:00:07 +02:00
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
/*
|
|
|
|
* code based on :
|
|
|
|
https://www.linuxtv.org/downloads/legacy/video4linux/API/V4L2_API/spec-single/v4l2.html
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
int enum_extended_controls(int fd, char *txt, int k)
|
|
|
|
{
|
|
|
|
struct v4l2_queryctrl qctrl;
|
|
|
|
int idx;
|
|
|
|
|
2019-07-24 17:47:28 +02:00
|
|
|
printf("-- extended controls enumeration '%s'\n", txt);
|
2019-07-24 17:00:07 +02:00
|
|
|
|
|
|
|
memset(&qctrl, 0, sizeof(qctrl));
|
|
|
|
qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
|
|
|
|
|
|
|
|
idx = 0;
|
|
|
|
while (0 == ioctl (fd, VIDIOC_QUERYCTRL, &qctrl)) {
|
2019-07-22 04:10:00 +02:00
|
|
|
|
2019-07-24 17:00:07 +02:00
|
|
|
pr_ctrl_id(qctrl.id);
|
|
|
|
printf(" %-32s %-10s [%d..%d]\n",
|
|
|
|
qctrl.name,
|
|
|
|
str_ctrl_type(qctrl.type),
|
|
|
|
qctrl.minimum, qctrl.maximum);
|
|
|
|
|
|
|
|
qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
|
|
|
|
idx++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
2019-07-21 13:36:14 +02:00
|
|
|
/* --------------------------------------------------------------------- */
|
2019-07-27 04:03:57 +02:00
|
|
|
int show_webcam_infos(char *devname, char *title, int k)
|
2019-07-21 13:36:14 +02:00
|
|
|
{
|
|
|
|
int vfd, foo;
|
|
|
|
|
|
|
|
struct v4l2_capability cap;
|
2019-07-22 04:10:00 +02:00
|
|
|
// struct v4l2_format fmt;
|
|
|
|
struct v4l2_input input;
|
|
|
|
// int index;
|
2019-07-21 13:36:14 +02:00
|
|
|
|
|
|
|
// struct v4l2_requestbuffers reqbuf;
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, ">>> %s ( '%s' %d )\n", __func__, devname, k);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
vfd = open_device(devname);
|
|
|
|
if (vfd < 0) {
|
|
|
|
perror(devname);
|
|
|
|
return -3;
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(stderr, "\topen %s -> %d\n", devname, vfd);
|
|
|
|
|
2019-07-22 04:10:00 +02:00
|
|
|
memset(&cap, 0, sizeof(cap));
|
2019-07-21 13:36:14 +02:00
|
|
|
foo = ioctl(vfd, VIDIOC_QUERYCAP, &cap);
|
|
|
|
if (foo < 0) {
|
|
|
|
perror("ioctl QUERYCAP");
|
|
|
|
return -4;
|
|
|
|
}
|
|
|
|
pr_v4l2_capability(devname, &cap);
|
2019-07-22 04:10:00 +02:00
|
|
|
|
|
|
|
memset(&input, 0, sizeof(input));
|
|
|
|
if (-1 == ioctl(vfd, VIDIOC_ENUMINPUT, &input)) {
|
|
|
|
perror("VIDIOC_ENUMINPUT");
|
|
|
|
exit(EXIT_FAILURE);
|
2019-07-21 13:36:14 +02:00
|
|
|
}
|
2019-07-22 04:10:00 +02:00
|
|
|
pr_v4l2_input("input 0", &input);
|
|
|
|
|
2019-07-27 04:03:57 +02:00
|
|
|
foo = enum_inputs(vfd, "on peut voir quoi ?", 0);
|
2019-07-24 17:00:07 +02:00
|
|
|
|
2019-07-27 04:03:57 +02:00
|
|
|
foo = enum_image_formats(vfd, "Experimental", 0);
|
2019-07-24 17:00:07 +02:00
|
|
|
|
|
|
|
fputs("--\n", stderr);
|
|
|
|
foo = enum_controls(vfd, "is that working ?", 0);
|
|
|
|
|
|
|
|
fputs("--\n", stderr);
|
|
|
|
foo = enum_extended_controls(vfd, "looking for extended", 0);
|
|
|
|
|
2019-07-21 13:36:14 +02:00
|
|
|
|
|
|
|
close(vfd);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
int liste_des_devices(int flag)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s not implemented\n", __func__);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void help(int k)
|
|
|
|
{
|
|
|
|
puts("Options :");
|
|
|
|
puts("\t-d\tselect the video device");
|
|
|
|
puts("\t-K\tset the K parameter");
|
|
|
|
puts("\t-l\tlist video devices");
|
|
|
|
puts("\t-v\tincrease verbosity");
|
|
|
|
|
|
|
|
if (verbosity) { puts(""); fimg_print_version(1); }
|
|
|
|
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
int foo, opt;
|
|
|
|
|
|
|
|
char *device = "/dev/video0";
|
|
|
|
int K = 0;
|
|
|
|
|
|
|
|
while ((opt = getopt(argc, argv, "d:hK:lv")) != -1) {
|
|
|
|
switch(opt) {
|
|
|
|
case 'd': device = optarg; break;
|
|
|
|
case 'h': help(0); break;
|
|
|
|
case 'K': K = atol(optarg); break;
|
|
|
|
case 'l': liste_des_devices(0); break;
|
|
|
|
case 'v': verbosity++; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (verbosity) fimg_print_version(0);
|
|
|
|
|
2019-07-27 04:03:57 +02:00
|
|
|
foo = show_webcam_infos(device, "", K);
|
2019-07-22 04:10:00 +02:00
|
|
|
fprintf(stderr, "\n\tshow_webcam_infos -> %d\n", foo);
|
2019-07-21 13:36:14 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|