FPS option part 2
[fswebcam.git] / src.c
blob738d209271ace4e6718064b3fe38e6fccd9ba7a5
1 /* fswebcam - FireStorm.cx's webcam generator */
2 /*===========================================================*/
3 /* Copyright (C)2005-2009 Philip Heron <phil@firestorm.cx> */
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. */
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
14 #include <stdlib.h>
15 #include <time.h>
16 #include <string.h>
17 #include <sys/stat.h>
18 #include <errno.h>
19 #include "parse.h"
20 #include "src.h"
21 #include "log.h"
23 #ifdef HAVE_V4L2
24 extern src_mod_t src_v4l2;
25 #endif
26 #ifdef HAVE_V4L1
27 extern src_mod_t src_v4l1;
28 #endif
29 extern src_mod_t src_file;
30 extern src_mod_t src_raw;
31 extern src_mod_t src_test;
33 /* Modules should be listed here in order of preference. */
34 src_mod_t* src_mod[] = {
35 #ifdef HAVE_V4L2
36 &src_v4l2,
37 #endif
38 #ifdef HAVE_V4L1
39 &src_v4l1,
40 #endif
41 &src_file,
42 &src_raw,
43 &src_test,
47 /* Supported palette types. */
48 src_palette_t src_palette[] = {
49 { "PNG" },
50 { "JPEG" },
51 { "MJPEG" },
52 { "RGB32" },
53 { "BGR32" },
54 { "RGB24" },
55 { "BGR24" },
56 { "YUYV" },
57 { "UYVY" },
58 { "YUV420P" },
59 { "NV12MB" },
60 { "BAYER" },
61 { "SGBRG8" },
62 { "RGB565" },
63 { "RGB555" },
64 { "GREY" },
65 { NULL }
68 int src_open(src_t *src, char *source)
70 int i;
71 size_t sl;
72 char *s;
73 struct stat st;
75 if(!source)
77 ERROR("No source was specified.");
78 return(-1);
81 sl = strlen(source) + 1;
82 s = malloc(sl);
83 if(!s)
85 ERROR("Out of memory.");
86 return(-1);
89 /* Get the first part of the source. */
90 if(argncpy(s, sl, source, ":", 0, 0))
92 ERROR("No source was specified.");
93 free(s);
94 return(-1);
97 /* Check if it's a source name. */
98 i = 0;
99 while(src_mod[i])
101 if(!strcasecmp(s, src_mod[i]->name))
103 INFO(">>> Using '%s' source module.", src_mod[i]->name);
105 src->type = i;
106 src->source = NULL;
108 if(!argncpy(s, sl, source, ":", 1, 0)) src->source = s;
109 else free(s);
111 i = src_mod[src->type]->open(src);
112 if(i < 0)
114 free(s);
115 return(-1);
118 return(0);
121 i++;
124 /* No source type was specified. If the name is that of a file or
125 * device we can check each source until we find one that works. */
126 if(stat(s, &st))
128 ERROR("stat: %s", strerror(errno));
129 free(s);
130 return(-1);
133 i = 0;
134 src->source = s;
136 while(src_mod[i])
138 int r = src_mod[i]->flags;
140 if(S_ISCHR(st.st_mode) && r & SRC_TYPE_DEVICE) r = -1;
141 else if(!S_ISCHR(st.st_mode) && r & SRC_TYPE_FILE) r = -1;
142 else r = 0;
144 if(r)
146 MSG("Trying source module %s...", src_mod[i]->name);
148 src->type = i;
149 r = src_mod[src->type]->open(src);
151 if(r != -2) return(r);
154 i++;
157 ERROR("Unable to find a source module that can read %s.", source);
159 free(s);
161 return(-1);
164 int src_close(src_t *src)
166 int r;
168 if(src->captured_frames)
170 double seconds =
171 (src->tv_last.tv_sec + src->tv_last.tv_usec / 1000000.0) -
172 (src->tv_first.tv_sec + src->tv_first.tv_usec / 1000000.0);
174 /* Display FPS if enough frames where captured. */
175 if(src->captured_frames == 1)
177 MSG("Captured frame in %0.2f seconds.", seconds);
179 else if(src->captured_frames < 3)
181 MSG("Captured %i frames in %0.2f seconds.",
182 src->captured_frames, seconds);
184 else
186 MSG("Captured %i frames in %0.2f seconds. (%i fps)",
187 src->captured_frames, seconds,
188 (int) (src->captured_frames / seconds));
192 r = src_mod[src->type]->close(src);
194 if(src->source) free(src->source);
196 return(r);
199 int src_grab(src_t *src)
201 int r = src_mod[src->type]->grab(src);
203 if(!r)
205 if(!src->captured_frames) gettimeofday(&src->tv_first, NULL);
206 gettimeofday(&src->tv_last, NULL);
208 src->captured_frames++;
211 return(r);
214 /* Pointers are great things. Terrible things yes, but great. */
215 /* These work but are very ugly and will be re-written soon. */
217 int src_set_option(src_option_t ***options, char *name, char *value)
219 src_option_t **opts, *opt;
220 int count;
222 if(!options) return(-1);
223 if(!*options)
225 *options = malloc(sizeof(src_option_t *));
226 if(!*options)
228 ERROR("Out of memory.");
229 return(-1);
232 *options[0] = NULL;
235 count = 0;
236 opts = *options;
237 while(*opts)
239 if((*opts)->name) if(!strcasecmp(name, (*opts)->name)) break;
240 opts++;
241 count++;
244 if(!*opts)
246 void *new;
248 opt = (src_option_t *) malloc(sizeof(src_option_t));
249 if(!opt)
251 ERROR("Out of memory.");
252 return(-1);
255 new = realloc(*options, sizeof(src_option_t *) * (count + 2));
256 if(!new)
258 free(opt);
259 ERROR("Out of memory.");
260 return(-1);
263 *options = (src_option_t **) new;
264 (*options)[count++] = opt;
265 (*options)[count++] = NULL;
267 opt->name = strdup(name);
268 opt->value = NULL;
270 else opt = *opts;
272 if(opt->value)
274 free(opt->value);
275 opt->value = NULL;
277 if(value) opt->value = strdup(value);
279 return(0);
282 int src_get_option_by_number(src_option_t **opt, int number,
283 char **name, char **value)
285 int i;
287 if(!opt || !name || !value) return(-1);
289 i = 0;
290 while(*opt)
292 if(i == number)
294 *name = (*opt)->name;
295 *value = (*opt)->value;
296 return(0);
299 i++;
302 return(-1);
305 int src_get_option_by_name(src_option_t **opt, char *name, char **value)
307 if(!opt || !name || !value) return(-1);
309 while(*opt)
311 if((*opt)->name)
313 if(!strcasecmp(name, (*opt)->name))
315 *value = (*opt)->value;
316 return(0);
320 opt++;
323 return(-1);
326 int src_free_options(src_option_t ***options)
328 src_option_t **opts;
330 if(!options || !*options) return(-1);
332 opts = *options;
333 while(*opts)
335 if((*opts)->name) free((*opts)->name);
336 if((*opts)->value) free((*opts)->value);
338 free(*opts);
340 opts++;
343 free(*options);
344 *options = NULL;
346 return(0);