1 /* fswebcam - FireStorm.cx's webcam generator */
2 /*===========================================================*/
3 /* Copyright (C)2005-2009 Philip Heron <phil@firestorm.cx> */
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. */
24 extern src_mod_t src_v4l2
;
27 extern src_mod_t src_v4l1
;
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
[] = {
47 /* Supported palette types. */
48 src_palette_t src_palette
[] = {
68 int src_open(src_t
*src
, char *source
)
77 ERROR("No source was specified.");
81 sl
= strlen(source
) + 1;
85 ERROR("Out of memory.");
89 /* Get the first part of the source. */
90 if(argncpy(s
, sl
, source
, ":", 0, 0))
92 ERROR("No source was specified.");
97 /* Check if it's a source name. */
101 if(!strcasecmp(s
, src_mod
[i
]->name
))
103 INFO(">>> Using '%s' source module.", src_mod
[i
]->name
);
108 if(!argncpy(s
, sl
, source
, ":", 1, 0)) src
->source
= s
;
111 i
= src_mod
[src
->type
]->open(src
);
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. */
128 ERROR("stat: %s", strerror(errno
));
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;
146 MSG("Trying source module %s...", src_mod
[i
]->name
);
149 r
= src_mod
[src
->type
]->open(src
);
151 if(r
!= -2) return(r
);
157 ERROR("Unable to find a source module that can read %s.", source
);
164 int src_close(src_t
*src
)
168 if(src
->captured_frames
)
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
);
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
);
199 int src_grab(src_t
*src
)
201 int r
= src_mod
[src
->type
]->grab(src
);
205 if(!src
->captured_frames
) gettimeofday(&src
->tv_first
, NULL
);
206 gettimeofday(&src
->tv_last
, NULL
);
208 src
->captured_frames
++;
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
;
222 if(!options
) return(-1);
225 *options
= malloc(sizeof(src_option_t
*));
228 ERROR("Out of memory.");
239 if((*opts
)->name
) if(!strcasecmp(name
, (*opts
)->name
)) break;
248 opt
= (src_option_t
*) malloc(sizeof(src_option_t
));
251 ERROR("Out of memory.");
255 new = realloc(*options
, sizeof(src_option_t
*) * (count
+ 2));
259 ERROR("Out of memory.");
263 *options
= (src_option_t
**) new;
264 (*options
)[count
++] = opt
;
265 (*options
)[count
++] = NULL
;
267 opt
->name
= strdup(name
);
277 if(value
) opt
->value
= strdup(value
);
282 int src_get_option_by_number(src_option_t
**opt
, int number
,
283 char **name
, char **value
)
287 if(!opt
|| !name
|| !value
) return(-1);
294 *name
= (*opt
)->name
;
295 *value
= (*opt
)->value
;
305 int src_get_option_by_name(src_option_t
**opt
, char *name
, char **value
)
307 if(!opt
|| !name
|| !value
) return(-1);
313 if(!strcasecmp(name
, (*opt
)->name
))
315 *value
= (*opt
)->value
;
326 int src_free_options(src_option_t
***options
)
330 if(!options
|| !*options
) return(-1);
335 if((*opts
)->name
) free((*opts
)->name
);
336 if((*opts
)->value
) free((*opts
)->value
);