]> git.sesse.net Git - kdenlive/blob - src/v4l/src.c
f83dfdfbc4bc43709c3e81f99ef96b404d4bd412
[kdenlive] / src / v4l / src.c
1 /* fswebcam - FireStorm.cx's webcam generator                 */
2 /*============================================================*/
3 /* Copyright (C)2005-2010 Philip Heron <phil@sanslogic.co.uk> */
4 /*                                                            */
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.                  */
9
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13
14 #include <stdlib.h>
15 #include <time.h>
16 #include <string.h>
17 #include <sys/stat.h>
18 #include <errno.h>
19 #include <sys/mman.h>
20 #include "src.h"
21
22 #include <sys/ioctl.h>
23
24
25 int v4l2_free_mmap(src_t *src)
26 {
27         src_v4l2_t *s = (src_v4l2_t *) src->state;
28         int i;
29
30         for(i = 0; i < s->req.count; i++)
31                 munmap(s->buffer[i].start, s->buffer[i].length);
32
33         return(0);
34 }
35
36 static int close_v4l2(src_t *src)
37 {
38         src_v4l2_t *s = (src_v4l2_t *) src->state;
39
40         if(s->buffer)
41         {
42                 if(!s->map) free(s->buffer[0].start);
43                 else v4l2_free_mmap(src);
44                 free(s->buffer);
45         }
46         if(s->fd >= 0) close(s->fd);
47         free(s);
48
49         return(0);
50 }
51
52 //static
53 const char *query_v4ldevice(src_t *src, char **pixelformatdescription)
54 {
55         if(!src->source)
56         {
57                 /*ERROR("No device name specified.");*/
58                 fprintf(stderr, "No device name specified.");
59                 return NULL;
60         }
61         src_v4l2_t *s;
62
63         /* Allocate memory for the state structure. */
64         s = calloc(sizeof(src_v4l2_t), 1);
65         if(!s)
66         {
67                 fprintf(stderr, "Out of memory.");
68                 return NULL;
69         }
70
71         src->state = (void *) s;
72         char value[200];
73         //snprintf( value, sizeof(value), '\0' );
74         //strcpy(*pixelformatdescription, (char*) value);
75         /* Open the device. */
76         s->fd = open(src->source, O_RDWR | O_NONBLOCK);
77         if(s->fd < 0)
78         {
79                 fprintf(stderr, "Cannot open device.");
80                 free(s);
81                 return NULL;
82         }
83         char *res = NULL;
84         int captureEnabled = 1;
85         if(ioctl(s->fd, VIDIOC_QUERYCAP, &s->cap) < 0) {
86             fprintf(stderr, "Cannot get capabilities.");
87             //return NULL;
88         }
89         else {
90             res = strdup((char*) s->cap.card);
91             if(!s->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
92                 // Device cannot capture
93                 captureEnabled = 0;
94             }
95         }
96         
97         if (captureEnabled) {
98             struct v4l2_format format;
99             memset(&format,0,sizeof(format));
100             format.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
101
102             struct v4l2_fmtdesc fmt;
103             memset(&fmt,0,sizeof(fmt));
104             fmt.index = 0;
105             fmt.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
106
107             struct v4l2_frmsizeenum sizes;
108             memset(&sizes,0,sizeof(sizes));
109
110             struct v4l2_frmivalenum rates;
111             memset(&rates,0,sizeof(rates));
112
113             while (ioctl(s->fd, VIDIOC_ENUM_FMT, &fmt) != -1)
114             {
115                 snprintf( value, sizeof(value), ">%c%c%c%c", fmt.pixelformat >> 0,  fmt.pixelformat >> 8, fmt.pixelformat >> 16, fmt.pixelformat >> 24 );
116                 strcat(*pixelformatdescription, (char *) value);
117                 fprintf(stderr, "detected format: %s: %c%c%c%c\n", fmt.description, fmt.pixelformat >> 0,  fmt.pixelformat >> 8,
118                       fmt.pixelformat >> 16, fmt.pixelformat >> 24);
119
120                 sizes.pixel_format = fmt.pixelformat;
121                 sizes.index = 0;
122                 // Query supported frame size
123                 while (ioctl(s->fd, VIDIOC_ENUM_FRAMESIZES, &sizes) != -1) {
124                     struct v4l2_frmsize_discrete image_size = sizes.un.discrete;
125                     // Query supported frame rates
126                     rates.index = 0;
127                     rates.pixel_format = fmt.pixelformat;
128                     rates.width = image_size.width;
129                     rates.height = image_size.height;
130                     snprintf( value, sizeof(value), ":%dx%d=", image_size.width, image_size.height );
131                     strcat(*pixelformatdescription, (char *) value);
132                     fprintf(stderr, "Size: %dx%d: ", image_size.width, image_size.height);
133                     while (ioctl(s->fd, VIDIOC_ENUM_FRAMEINTERVALS, &rates) != -1) {
134                         snprintf( value, sizeof(value), "%d/%d,", rates.un.discrete.denominator, rates.un.discrete.numerator );
135                         strcat(*pixelformatdescription, (char *) value);
136                         fprintf(stderr, "%d/%d, ", rates.un.discrete.numerator, rates.un.discrete.denominator);
137                         rates.index ++;
138                     }
139                     fprintf(stderr, "\n");
140                     sizes.index++;
141                 }
142
143
144                 /*[0x%08X] '%c%c%c%c' (%s)", v4l2_pal,
145                       fmt.pixelformat,
146                       fmt.pixelformat >> 0,  fmt.pixelformat >> 8,
147                       fmt.pixelformat >> 16, fmt.pixelformat >> 24*/
148                 fmt.index++;
149             }
150             /*else {
151                 *pixelformatdescription = '\0';
152             }*/
153         }
154         close_v4l2(src);
155         return res;
156 }
157
158
159