FloatImg/v4l2/video-infos.c

324 lines
6.5 KiB
C
Raw Normal View History

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-08-31 19:46:37 +02:00
/* --------------------------------------------------------------------- */
/*
* this code was written from a strace output :)
*/
int enum_image_framesizes(int fd, char *txt, int k)
{
int foo, idx;
struct v4l2_frmsizeenum fmtsz;
printf("-- image framesizes enumeration (%s)\n", txt);
for (idx=0; ; idx++) {
memset(&fmtsz, 0, sizeof(fmtsz));
fmtsz.index = idx;
foo = ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &fmtsz);
if (foo) {
if (EINVAL==errno) {
break;
}
else {
perror(__func__);
break;
}
}
printf("%4d %4d %4d\n", idx, fmtsz.pixel_format, fmtsz.type);
}
return 0;
}
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;
}
}
2019-07-28 00:28:22 +02:00
// pr_v4l2_fmtdesc(__func__, &fmtd);
printf(" %2d %-10s 0x%02x %s %-32s \n",
fmtd.index, str_buf_type(fmtd.type), fmtd.flags,
str_fourcc(fmtd.pixelformat), fmtd.description);
2019-07-27 04:03:57 +02:00
idx++;
}
return -1;
}
/* --------------------------------------------------------------------- */
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;
2019-07-30 14:56:35 +02:00
char ligne[50];
2019-07-24 17:00:07 +02:00
2019-08-31 19:46:37 +02:00
printf("-- inputs enumeration (%s)\n", txt);
2019-07-24 17:00:07 +02:00
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;
}
}
2019-07-30 14:56:35 +02:00
if (verbosity) {
sprintf(ligne, "input %d", index);
pr_v4l2_input(ligne, &input);
}
else {
printf("%-32s | %-10s\n", input.name,
2019-07-24 17:00:07 +02:00
str_input_type(input.type));
2019-07-30 14:56:35 +02:00
}
2019-07-24 17:00:07 +02:00
index++;
}
return 0;
}
/* --------------------------------------------------------------------- */
int enum_controls(int fd, char *txt, int k)
{
2019-07-24 17:00:07 +02:00
struct v4l2_queryctrl qctrl;
int idx;
2019-07-24 17:00:07 +02:00
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;
2019-07-28 00:28:22 +02:00
// if (verbosity>1) printf(" id %d ", idx);
2019-07-24 17:00:07 +02:00
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) {
2019-08-02 02:12:54 +02:00
#if DEBUG_LEVEL
2019-07-28 00:28:22 +02:00
if (verbosity) fprintf(stderr, "id %d einval\n", idx);
2019-08-02 02:12:54 +02:00
#endif
2019-07-24 17:00:07 +02:00
continue;
}
else {
printf("err %d %s\n", errno, strerror(errno));
}
fflush(stdout); fflush(stderr);
}
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-28 00:28:22 +02:00
if (verbosity) pr_ctrl_id(qctrl.id);
2019-07-24 17:00:07 +02:00
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
{
2019-07-29 02:53:28 +02:00
int vfd, foo;
char ligne[100];
2019-07-21 13:36:14 +02:00
struct v4l2_capability cap;
2019-08-02 03:33:59 +02:00
struct v4l2_format fmt;
2019-08-10 18:37:52 +02:00
// 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);
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-30 14:56:35 +02:00
foo = enum_inputs(vfd, "on peut voir quoi ?", 0);
2019-07-24 17:00:07 +02:00
2019-08-02 03:33:59 +02:00
memset(&fmt, 0, sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
foo = ioctl(vfd, VIDIOC_G_FMT, &fmt);
if (0 != foo) {
perror("ioctl G_FMT");
2019-08-10 18:37:52 +02:00
}
else {
pr_v4l2_format("Experimental", &fmt);
2019-08-02 03:33:59 +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
foo = enum_controls(vfd, "is that working ?", 0);
foo = enum_extended_controls(vfd, "looking for extended", 0);
2019-08-31 19:46:37 +02:00
enum_image_framesizes(vfd, "code pas fini", 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;
}
/* --------------------------------------------------------------------- */
2019-08-15 12:06:21 +02:00
static void help(int k)
2019-07-21 13:36:14 +02:00
{
puts("Options :");
2019-08-15 12:06:21 +02:00
puts("\t-d\t\tselect the video device");
puts("\t-K\t\tset the K parameter");
puts("\t-l\t\tlist video devices");
puts("\t-T bla\t\tadd a title");
puts("\t-v\t\tincrease verbosity");
2019-07-21 13:36:14 +02:00
exit(0);
}
/* --------------------------------------------------------------------- */
2019-08-15 12:06:21 +02:00
static void print_title(char *txt)
{
int foo, l;
l = strlen(txt);
for (foo=0; foo<l+18; foo++)
putchar('*');
puts("");
2019-08-15 12:06:21 +02:00
printf("****** %s ******\n", txt);
for (foo=0; foo<l+18; foo++)
putchar('*');
puts("\n");
2019-08-15 12:06:21 +02:00
}
/* --------------------------------------------------------------------- */
2019-07-21 13:36:14 +02:00
int main(int argc, char *argv[])
{
int foo, opt;
char *device = "/dev/video0";
2019-08-15 12:06:21 +02:00
char *title = NULL;
2019-07-21 13:36:14 +02:00
int K = 0;
2019-08-15 12:06:21 +02:00
while ((opt = getopt(argc, argv, "d:hK:lT:v")) != -1) {
2019-07-21 13:36:14 +02:00
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;
2019-08-15 12:06:21 +02:00
case 'T': title = optarg; break;
2019-07-21 13:36:14 +02:00
case 'v': verbosity++; break;
}
}
2019-08-15 12:06:21 +02:00
if (NULL != title) {
print_title(title);
}
2019-07-27 04:03:57 +02:00
foo = show_webcam_infos(device, "", K);
fprintf(stderr, "\n\tshow_webcam_infos -> %d\n", foo);
2019-07-21 13:36:14 +02:00
return 0;
}
/* --------------------------------------------------------------------- */