]> git.sesse.net Git - kdenlive/blob - src/v4l/src.c
Complete rewrite of the video4linux capture to use MLT, in progress.
[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 /* Supported palette types. */
26 src_palette_t src_palette[] = {
27         { "PNG" },
28         { "JPEG" },
29         { "MJPEG" },
30         { "S561" },
31         { "RGB32" },
32         { "BGR32" },
33         { "RGB24" },
34         { "BGR24" },
35         { "YUYV" },
36         { "UYVY" },
37         { "YUV420P" },
38         { "NV12MB" },
39         { "BAYER" },
40         { "SGBRG8" },
41         { "SGRBG8" },
42         { "RGB565" },
43         { "RGB555" },
44         { "Y16" },
45         { "GREY" },
46         { NULL }
47 };
48
49
50
51 int v4l2_free_mmap(src_t *src)
52 {
53         src_v4l2_t *s = (src_v4l2_t *) src->state;
54         int i;
55
56         for(i = 0; i < s->req.count; i++)
57                 munmap(s->buffer[i].start, s->buffer[i].length);
58
59         return(0);
60 }
61
62 static int close_v4l2(src_t *src)
63 {
64         src_v4l2_t *s = (src_v4l2_t *) src->state;
65
66         if(s->buffer)
67         {
68                 if(!s->map) free(s->buffer[0].start);
69                 else v4l2_free_mmap(src);
70                 free(s->buffer);
71         }
72         if(s->fd >= 0) close(s->fd);
73         free(s);
74
75         return(0);
76 }
77
78 //static
79 const char *query_v4ldevice(src_t *src, char **pixelformatdescription)
80 {
81         if(!src->source)
82         {
83                 /*ERROR("No device name specified.");*/
84                 fprintf(stderr, "No device name specified.");
85                 return NULL;
86         }
87         src_v4l2_t *s;
88
89         /* Allocate memory for the state structure. */
90         s = calloc(sizeof(src_v4l2_t), 1);
91         if(!s)
92         {
93                 fprintf(stderr, "Out of memory.");
94                 return NULL;
95         }
96
97         src->state = (void *) s;
98         char value[200];
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);
103         if(s->fd < 0)
104         {
105                 fprintf(stderr, "Cannot open device.");
106                 free(s);
107                 return NULL;
108         }
109
110         if(ioctl(s->fd, VIDIOC_QUERYCAP, &s->cap) < 0) {
111             close_v4l2(src);
112             fprintf(stderr, "Cannot get capabilities.");
113             return NULL;
114         }
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
119         }
120         else {
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.");
126                 // Cannot query
127             }
128             struct v4l2_fmtdesc fmt;
129             memset(&fmt,0,sizeof(fmt));
130             fmt.index = 0;
131             fmt.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
132
133             struct v4l2_frmsizeenum sizes;
134             memset(&sizes,0,sizeof(sizes));
135
136             struct v4l2_frmivalenum rates;
137             memset(&rates,0,sizeof(rates));
138
139             while (ioctl(s->fd, VIDIOC_ENUM_FMT, &fmt) != -1)
140             {
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);
147
148                 sizes.pixel_format = fmt.pixelformat;
149                 sizes.index = 0;
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
154                     rates.index = 0;
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);
165                         rates.index ++;
166                     }
167                     fprintf(stderr, "\n");
168                     sizes.index++;
169                 }
170
171
172                 /*[0x%08X] '%c%c%c%c' (%s)", v4l2_pal,
173                       fmt.pixelformat,
174                       fmt.pixelformat >> 0,  fmt.pixelformat >> 8,
175                       fmt.pixelformat >> 16, fmt.pixelformat >> 24*/
176                 fmt.index++;
177             }
178             /*else {
179                 *pixelformatdescription = '\0';
180             }*/
181         }
182         close_v4l2(src);
183         return res;
184 }
185
186
187