1 /* fswebcam - FireStorm.cx's webcam generator */
2 /*============================================================*/
3 /* Copyright (C)2005-2010 Philip Heron <phil@sanslogic.co.uk> */
5 /* This program is distributed under the terms of the GNU */
6 /* General Public License, version 2. You may use, modify, */
7 /* and redistribute it under the terms of this license. A */
8 /* copy should be included with this source. */
22 #include <sys/ioctl.h>
25 /* Supported palette types. */
26 src_palette_t src_palette[] = {
51 int v4l2_free_mmap(src_t *src)
53 src_v4l2_t *s = (src_v4l2_t *) src->state;
56 for(i = 0; i < s->req.count; i++)
57 munmap(s->buffer[i].start, s->buffer[i].length);
62 static int close_v4l2(src_t *src)
64 src_v4l2_t *s = (src_v4l2_t *) src->state;
68 if(!s->map) free(s->buffer[0].start);
69 else v4l2_free_mmap(src);
72 if(s->fd >= 0) close(s->fd);
79 const char *query_v4ldevice(src_t *src, char **pixelformatdescription)
83 /*ERROR("No device name specified.");*/
84 fprintf(stderr, "No device name specified.");
89 /* Allocate memory for the state structure. */
90 s = calloc(sizeof(src_v4l2_t), 1);
93 fprintf(stderr, "Out of memory.");
97 src->state = (void *) s;
99 //snprintf( value, sizeof(value), '\0' );
100 //strcpy(*pixelformatdescription, (char*) value);
101 /* Open the device. */
102 s->fd = open(src->source, O_RDWR | O_NONBLOCK);
105 fprintf(stderr, "Cannot open device.");
110 if(ioctl(s->fd, VIDIOC_QUERYCAP, &s->cap) < 0) {
112 fprintf(stderr, "Cannot get capabilities.");
115 char *res = strdup((char*) s->cap.card);
116 /*strcpy(res, (char*) s->cap.card);*/
117 if(!s->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
118 // Device cannot capture
121 struct v4l2_format format;
122 memset(&format,0,sizeof(format));
123 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
124 if (ioctl(s->fd,VIDIOC_G_FMT,&format) < 0) {
125 fprintf(stderr, "Cannot get format.");
128 struct v4l2_fmtdesc fmt;
129 memset(&fmt,0,sizeof(fmt));
131 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
133 struct v4l2_frmsizeenum sizes;
134 memset(&sizes,0,sizeof(sizes));
136 struct v4l2_frmivalenum rates;
137 memset(&rates,0,sizeof(rates));
139 while (ioctl(s->fd, VIDIOC_ENUM_FMT, &fmt) != -1)
141 /*strcpy(*pixelformatdescription, (char *) fmt.description);*/
142 //*pixelformatdescription = strdup((char*)fmt.description);
143 snprintf( value, sizeof(value), ">%c%c%c%c", fmt.pixelformat >> 0, fmt.pixelformat >> 8, fmt.pixelformat >> 16, fmt.pixelformat >> 24 );
144 strcat(*pixelformatdescription, (char *) value);
145 fprintf(stderr, "detected format: %s: %c%c%c%c\n", fmt.description, fmt.pixelformat >> 0, fmt.pixelformat >> 8,
146 fmt.pixelformat >> 16, fmt.pixelformat >> 24);
148 sizes.pixel_format = fmt.pixelformat;
150 // Query supported frame size
151 while (ioctl(s->fd, VIDIOC_ENUM_FRAMESIZES, &sizes) != -1) {
152 struct v4l2_frmsize_discrete image_size = sizes.un.discrete;
153 // Query supported frame rates
155 rates.pixel_format = fmt.pixelformat;
156 rates.width = image_size.width;
157 rates.height = image_size.height;
158 snprintf( value, sizeof(value), ":%dx%d=", image_size.width, image_size.height );
159 strcat(*pixelformatdescription, (char *) value);
160 fprintf(stderr, "Size: %dx%d: ", image_size.width, image_size.height);
161 while (ioctl(s->fd, VIDIOC_ENUM_FRAMEINTERVALS, &rates) != -1) {
162 snprintf( value, sizeof(value), "%d/%d,", rates.un.discrete.denominator, rates.un.discrete.numerator );
163 strcat(*pixelformatdescription, (char *) value);
164 fprintf(stderr, "%d/%d, ", rates.un.discrete.numerator, rates.un.discrete.denominator);
167 fprintf(stderr, "\n");
172 /*[0x%08X] '%c%c%c%c' (%s)", v4l2_pal,
174 fmt.pixelformat >> 0, fmt.pixelformat >> 8,
175 fmt.pixelformat >> 16, fmt.pixelformat >> 24*/
179 *pixelformatdescription = '\0';