]> git.sesse.net Git - kdenlive/blob - src/v4l/src_v4l2.c
Complete rewrite of the video4linux capture to use MLT, in progress.
[kdenlive] / src / v4l / src_v4l2.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 <stdio.h>
15 #include <stdlib.h>
16 #include <fcntl.h>
17 #include <unistd.h>
18 #include <string.h>
19 #include <errno.h>
20 #include <sys/ioctl.h>
21 #include <sys/mman.h>
22 #include "videodev2.h"
23 #include "src.h"
24
25 #ifdef HAVE_V4L2
26
27 int src_v4l2_get_capability(src_t *src)
28 {
29         src_v4l2_t *s = (src_v4l2_t *) src->state;
30         
31         if(ioctl(s->fd, VIDIOC_QUERYCAP, &s->cap) < 0)
32         {
33                 /*ERROR("%s: Not a V4L2 device?", src->source);*/
34                 return(-1);
35         }
36         fprintf(stderr, "cap.card: \"%s\"", s->cap.card);
37         /*DEBUG("%s information:", src->source);
38         DEBUG("cap.driver: \"%s\"", s->cap.driver);
39         DEBUG("cap.card: \"%s\"", s->cap.card);
40         DEBUG("cap.bus_info: \"%s\"", s->cap.bus_info);
41         DEBUG("cap.capabilities=0x%08X", s->cap.capabilities);*/
42         /*if(s->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) DEBUG("- VIDEO_CAPTURE");
43         if(s->cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)  DEBUG("- VIDEO_OUTPUT");
44         if(s->cap.capabilities & V4L2_CAP_VIDEO_OVERLAY) DEBUG("- VIDEO_OVERLAY");
45         if(s->cap.capabilities & V4L2_CAP_VBI_CAPTURE)   DEBUG("- VBI_CAPTURE");
46         if(s->cap.capabilities & V4L2_CAP_VBI_OUTPUT)    DEBUG("- VBI_OUTPUT");
47         if(s->cap.capabilities & V4L2_CAP_RDS_CAPTURE)   DEBUG("- RDS_CAPTURE");
48         if(s->cap.capabilities & V4L2_CAP_TUNER)         DEBUG("- TUNER");
49         if(s->cap.capabilities & V4L2_CAP_AUDIO)         DEBUG("- AUDIO");
50         if(s->cap.capabilities & V4L2_CAP_RADIO)         DEBUG("- RADIO");
51         if(s->cap.capabilities & V4L2_CAP_READWRITE)     DEBUG("- READWRITE");
52         if(s->cap.capabilities & V4L2_CAP_ASYNCIO)       DEBUG("- ASYNCIO");
53         if(s->cap.capabilities & V4L2_CAP_STREAMING)     DEBUG("- STREAMING");
54         if(s->cap.capabilities & V4L2_CAP_TIMEPERFRAME)  DEBUG("- TIMEPERFRAME");*/
55         
56         if(!s->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
57         {
58                 /*ERROR("Device does not support capturing.");*/
59                 return(-1);
60         }
61         
62         return(0);
63 }
64
65 int src_v4l2_set_input(src_t *src)
66 {
67         src_v4l2_t *s = (src_v4l2_t *) src->state;
68         struct v4l2_input input;
69         int count = 0, i = -1;
70         
71         memset(&input, 0, sizeof(input));
72         
73         if(src->list & SRC_LIST_INPUTS)
74         {
75                 /*HEAD("--- Available inputs:");*/
76                 
77                 input.index = count;
78                 while(!ioctl(s->fd, VIDIOC_ENUMINPUT, &input))
79                 {
80                         /*MSG("%i: %s", count, input.name);*/
81                         input.index = ++count;
82                 }
83         }
84         
85         /* If no input was specified, use input 0. */
86         if(!src->input)
87         {
88                 /*MSG("No input was specified, using the first.");*/
89                 count = 1;
90                 i = 0;
91         }
92         
93         /* Check if the input is specified by name. */
94         if(i == -1)
95         {
96                 input.index = count;
97                 while(!ioctl(s->fd, VIDIOC_ENUMINPUT, &input))
98                 {
99                         if(!strncasecmp((char *) input.name, src->input, 32))
100                                 i = count;
101                         input.index = ++count;
102                 }
103         }
104         
105         if(i == -1)
106         {
107                 char *endptr;
108                 
109                 /* Is the input specified by number? */
110                 i = strtol(src->input, &endptr, 10);
111                 
112                 if(endptr == src->input) i = -1;
113         }
114         
115         if(i == -1 || i >= count)
116         {
117                 /* The specified input wasn't found! */
118                 /*ERROR("Unrecognised input \"%s\"", src->input);*/
119                 return(-1);
120         }
121         
122         /* Set the input. */
123         input.index = i;
124         if(ioctl(s->fd, VIDIOC_ENUMINPUT, &input) == -1)
125         {
126                 /*ERROR("Unable to query input %i.", i);
127                 ERROR("VIDIOC_ENUMINPUT: %s", strerror(errno));*/
128                 return(-1);
129         }
130         
131         /*DEBUG("%s: Input %i information:", src->source, i);
132         DEBUG("name = \"%s\"", input.name);
133         DEBUG("type = %08X", input.type);
134         if(input.type & V4L2_INPUT_TYPE_TUNER) DEBUG("- TUNER");
135         if(input.type & V4L2_INPUT_TYPE_CAMERA) DEBUG("- CAMERA");
136         DEBUG("audioset = %08X", input.audioset);
137         DEBUG("tuner = %08X", input.tuner);
138         DEBUG("status = %08X", input.status);
139         if(input.status & V4L2_IN_ST_NO_POWER) DEBUG("- NO_POWER");
140         if(input.status & V4L2_IN_ST_NO_SIGNAL) DEBUG("- NO_SIGNAL");
141         if(input.status & V4L2_IN_ST_NO_COLOR) DEBUG("- NO_COLOR");
142         if(input.status & V4L2_IN_ST_NO_H_LOCK) DEBUG("- NO_H_LOCK");
143         if(input.status & V4L2_IN_ST_COLOR_KILL) DEBUG("- COLOR_KILL");
144         if(input.status & V4L2_IN_ST_NO_SYNC) DEBUG("- NO_SYNC");
145         if(input.status & V4L2_IN_ST_NO_EQU) DEBUG("- NO_EQU");
146         if(input.status & V4L2_IN_ST_NO_CARRIER) DEBUG("- NO_CARRIER");
147         if(input.status & V4L2_IN_ST_MACROVISION) DEBUG("- MACROVISION");
148         if(input.status & V4L2_IN_ST_NO_ACCESS) DEBUG("- NO_ACCESS");
149         if(input.status & V4L2_IN_ST_VTR) DEBUG("- VTR");*/
150         
151         if(ioctl(s->fd, VIDIOC_S_INPUT, &i) == -1)
152         {
153                 /*ERROR("Error selecting input %i", i);
154                 ERROR("VIDIOC_S_INPUT: %s", strerror(errno));*/
155                 return(-1);
156         }
157         
158         /* If this input is attached to a tuner, set the frequency. */
159         if(input.type & V4L2_INPUT_TYPE_TUNER)
160         {
161                 char *range;
162                 struct v4l2_tuner tuner;
163                 struct v4l2_frequency freq;
164                 
165                 /* Query the tuners capabilities. */
166                 
167                 memset(&tuner, 0, sizeof(tuner));
168                 tuner.index = input.tuner;
169                 
170                 if(ioctl(s->fd, VIDIOC_G_TUNER, &tuner) == -1)
171                 {
172                         /*WARN("Error querying tuner %i.", input.tuner);
173                         WARN("VIDIOC_G_TUNER: %s", strerror(errno));*/
174                         return(0);
175                 }
176                 
177                 if(tuner.capability & V4L2_TUNER_CAP_LOW) range = "kHz";
178                 else range = "MHz";
179                 
180                 /*DEBUG("%s: Tuner %i information:", src->source, input.tuner);
181                 DEBUG("name = \"%s\"", tuner.name);
182                 DEBUG("type = %08X", tuner.type);
183                 if(tuner.type == V4L2_TUNER_RADIO) DEBUG("- RADIO");
184                 if(tuner.type == V4L2_TUNER_ANALOG_TV) DEBUG("- ANALOG_TV");
185                 DEBUG("capability = %08X", tuner.capability);
186                 if(tuner.capability & V4L2_TUNER_CAP_LOW) DEBUG("- LOW");
187                 if(tuner.capability & V4L2_TUNER_CAP_NORM) DEBUG("- NORM");
188                 if(tuner.capability & V4L2_TUNER_CAP_STEREO) DEBUG("- STEREO");
189                 if(tuner.capability & V4L2_TUNER_CAP_LANG1) DEBUG("- LANG1");
190                 if(tuner.capability & V4L2_TUNER_CAP_LANG2) DEBUG("- LANG2");
191                 if(tuner.capability & V4L2_TUNER_CAP_SAP) DEBUG("- SAP");
192                 DEBUG("rangelow = %08X, (%.3f%s)", tuner.rangelow, (double) tuner.rangelow * 16 / 1000, range);
193                 DEBUG("rangehigh = %08X, (%.3f%s)", tuner.rangehigh, (double) tuner.rangehigh * 16 / 1000, range);
194                 DEBUG("signal = %08X", tuner.signal);
195                 DEBUG("afc = %08X", tuner.afc);*/
196                 
197                 /* Set the frequency. */
198                 memset(&freq, 0, sizeof(freq));
199                 freq.tuner = input.tuner;
200                 freq.type = V4L2_TUNER_ANALOG_TV;
201                 freq.frequency = (src->frequency / 1000) * 16;
202                 
203                 if(ioctl(s->fd, VIDIOC_S_FREQUENCY, &freq) == -1)
204                 {
205                         /*WARN("Error setting frequency %.3f%s", src->frequency / 16.0, range);
206                         WARN("VIDIOC_S_FREQUENCY: %s", strerror(errno));*/
207                         return(0);
208                 }
209                 
210                 /*MSG("Set frequency to %.3f%s",
211                     (double) src->frequency / 1000, range);*/
212         }
213         
214         return(0);
215 }
216
217 int src_v4l2_show_control(src_t *src, struct v4l2_queryctrl *queryctrl)
218 {
219         src_v4l2_t *s = (src_v4l2_t *) src->state;
220         struct v4l2_querymenu querymenu;
221         struct v4l2_control control;
222         char *t;
223         int m;
224         
225         if(queryctrl->flags & V4L2_CTRL_FLAG_DISABLED) return(0);
226         
227         memset(&querymenu, 0, sizeof(querymenu));
228         memset(&control, 0, sizeof(control));
229         
230         if(queryctrl->type != V4L2_CTRL_TYPE_BUTTON)
231         {
232                 control.id = queryctrl->id;
233                 if(ioctl(s->fd, VIDIOC_G_CTRL, &control))
234                 {
235                         /*ERROR("Error reading value of control '%s'.", queryctrl->name);
236                         ERROR("VIDIOC_G_CTRL: %s", strerror(errno));*/
237                 }
238         }
239         
240         switch(queryctrl->type)
241         {
242         case V4L2_CTRL_TYPE_INTEGER:
243                 
244                 t = malloc(64); /* Ick ... TODO: re-write this. */
245                 if(!t)
246                 {
247                         /*ERROR("Out of memory.");*/
248                         return(-1);
249                 }
250                 
251                 if(queryctrl->maximum - queryctrl->minimum <= 10)
252                 {
253                         snprintf(t, 63, "%i", control.value);
254                 }
255                 else
256                 {
257                         snprintf(t, 63, "%i (%i%%)",
258                                  control.value,
259                                  SCALE(0, 100,
260                                        queryctrl->minimum,
261                                        queryctrl->maximum,
262                                        control.value));
263                 }
264                 
265                 /*MSG("%-25s %-15s %i - %i", queryctrl->name, t,
266                     queryctrl->minimum, queryctrl->maximum);*/
267                 
268                 free(t);
269                 
270                 break;
271                 
272         case V4L2_CTRL_TYPE_BOOLEAN:
273                 /*MSG("%-25s %-15s True | False", queryctrl->name,
274                     (control.value ? "True" : "False"));*/
275                 break;
276                 
277         case V4L2_CTRL_TYPE_MENU:
278                 
279                 querymenu.id = queryctrl->id;
280                 
281                 t = calloc((queryctrl->maximum - queryctrl->minimum) + 1, 34);
282                 m = queryctrl->minimum;
283                 for(m = queryctrl->minimum; m <= queryctrl->maximum; m++)
284                 {
285                         querymenu.index = m;
286                         if(!ioctl(s->fd, VIDIOC_QUERYMENU, &querymenu))
287                         {
288                                 strncat(t, (char *) querymenu.name, 32);
289                                 if(m < queryctrl->maximum) strncat(t, " | ", 3);
290                         }
291                 }
292                 
293                 querymenu.index = control.value;
294                 if(ioctl(s->fd, VIDIOC_QUERYMENU, &querymenu))
295                 {
296                         free(t);
297                         /*ERROR("Error reading value of menu item %i for control '%s'",
298                               control.value, queryctrl->name);
299                         ERROR("VIDIOC_QUERYMENU: %s", strerror(errno));*/
300                         return(0);
301                 }
302                 
303                 /*MSG("%-25s %-15s %s", queryctrl->name, querymenu.name, t);*/
304                 free(t);
305                 
306                 break;
307         
308         case V4L2_CTRL_TYPE_BUTTON:
309                 /*MSG("%-25s %-15s %s", queryctrl->name, "-", "[Button]");*/
310                 break;
311                 
312         default:
313                 /*MSG("%-25s %-15s %s", queryctrl->name, "N/A", "[Unknown Control Type]");*/
314                 break;
315         }
316         
317         return(0);
318 }
319
320 int src_v4l2_set_control(src_t *src, struct v4l2_queryctrl *queryctrl)
321 {
322         src_v4l2_t *s = (src_v4l2_t *) src->state;
323         struct v4l2_control control;
324         struct v4l2_querymenu querymenu;
325         char *sv;
326         int iv;
327         
328         if(queryctrl->flags & V4L2_CTRL_FLAG_DISABLED) return(0);
329         if(src_get_option_by_name(src->option, (char *) queryctrl->name, &sv))
330                 return(0);
331         
332         memset(&querymenu, 0, sizeof(querymenu));
333         memset(&control, 0, sizeof(control));
334         
335         control.id = queryctrl->id;
336         
337         switch(queryctrl->type)
338         {
339         case V4L2_CTRL_TYPE_INTEGER:
340                 
341                 /* Convert the value to an integer. */
342                 iv = atoi(sv);
343                 
344                 /* Is the value a precentage? */
345                 if(strchr(sv, '%'))
346                 {
347                         /* Adjust the precentage to fit the controls range. */
348                         iv = SCALE(queryctrl->minimum, queryctrl->maximum,
349                                    0, 100, iv);
350                 }
351                 
352                 /*MSG("Setting %s to %i (%i%%).", queryctrl->name, iv,
353                     SCALE(0, 100, queryctrl->minimum, queryctrl->maximum, iv));*/
354                 
355                 /*if(iv < queryctrl->minimum || iv > queryctrl->maximum)
356                         WARN("Value is out of range. Setting anyway.");*/
357                 
358                 control.value = iv;
359                 ioctl(s->fd, VIDIOC_S_CTRL, &control);
360                 break;
361         
362         case V4L2_CTRL_TYPE_BOOLEAN:
363                 
364                 iv = -1;
365                 if(!strcasecmp(sv, "1") || !strcasecmp(sv, "true")) iv = 1;
366                 if(!strcasecmp(sv, "0") || !strcasecmp(sv, "false")) iv = 0;
367                 
368                 if(iv == -1)
369                 {
370                         /*WARN("Unknown boolean value '%s' for %s.",
371                              sv, queryctrl->name);*/
372                         return(-1);
373                 }
374                 
375                 /*MSG("Setting %s to %s (%i).", queryctrl->name, sv, iv);*/
376                 
377                 control.value = iv;
378                 ioctl(s->fd, VIDIOC_S_CTRL, &control);
379                 
380                 break;
381         
382         case V4L2_CTRL_TYPE_MENU:
383                 
384                 /* Scan for a matching value. */
385                 querymenu.id = queryctrl->id;
386                 
387                 for(iv = queryctrl->minimum; iv <= queryctrl->maximum; iv++)
388                 {
389                         querymenu.index = iv;
390                         
391                         if(ioctl(s->fd, VIDIOC_QUERYMENU, &querymenu))
392                         {
393                                 /*ERROR("Error querying menu.");*/
394                                 continue;
395                         }
396                         
397                         if(!strncasecmp((char *) querymenu.name, sv, 32))
398                                 break;
399                 }
400                 
401                 if(iv > queryctrl->maximum)
402                 {
403                         /*MSG("Unknown value '%s' for %s.", sv, queryctrl->name);*/
404                         return(-1);
405                 }
406                 
407                 /*MSG("Setting %s to %s (%i).",
408                     queryctrl->name, querymenu.name, iv);*/
409                 
410                 control.value = iv;
411                 ioctl(s->fd, VIDIOC_S_CTRL, &control);
412                 
413                 break;
414         
415         case V4L2_CTRL_TYPE_BUTTON:
416                 
417                 /*MSG("Triggering %s control.", queryctrl->name);
418                 ioctl(s->fd, VIDIOC_S_CTRL, &control);*/
419                 
420                 break;
421         
422         default:
423                 /*WARN("Not setting unknown control type %i (%s).",
424                      queryctrl->name);*/
425                 break;
426         }
427         
428         return(0);
429 }
430
431 int src_v4l2_set_controls(src_t *src)
432 {
433         src_v4l2_t *s = (src_v4l2_t *) src->state;
434         struct v4l2_queryctrl queryctrl;
435         int c;
436         
437         memset(&queryctrl, 0, sizeof(queryctrl));
438         
439         if(src->list & SRC_LIST_CONTROLS)
440         {
441                 /*HEAD("%-25s %-15s %s", "Available Controls", "Current Value", "Range");
442                 MSG("%-25s %-15s %s",  "------------------", "-------------", "-----");*/
443                 
444                 /* Display normal controls. */
445                 for(c = V4L2_CID_BASE; c < V4L2_CID_LASTP1; c++)
446                 {
447                         queryctrl.id = c;
448                         
449                         if(ioctl(s->fd, VIDIOC_QUERYCTRL, &queryctrl)) continue;
450                         src_v4l2_show_control(src, &queryctrl);
451                 }
452                 
453                 /* Display device-specific controls. */
454                 for(c = V4L2_CID_PRIVATE_BASE; ; c++)
455                 {
456                         queryctrl.id = c;
457                         
458                         if(ioctl(s->fd, VIDIOC_QUERYCTRL, &queryctrl)) break;
459                         src_v4l2_show_control(src, &queryctrl);
460                 }
461         }
462         
463         /* Scan normal controls. */
464         for(c = V4L2_CID_BASE; c < V4L2_CID_LASTP1; c++)
465         {
466                 queryctrl.id = c;
467                 
468                 if(ioctl(s->fd, VIDIOC_QUERYCTRL, &queryctrl)) continue;
469                 src_v4l2_set_control(src, &queryctrl);
470         }
471         
472         /* Scan device-specific controls. */
473         for(c = V4L2_CID_PRIVATE_BASE; ; c++)
474         {
475                 queryctrl.id = c;
476                 
477                 if(ioctl(s->fd, VIDIOC_QUERYCTRL, &queryctrl)) break;
478                 src_v4l2_set_control(src, &queryctrl);
479         }
480         
481         return(0);
482 }
483
484 int src_v4l2_set_pix_format(src_t *src)
485 {
486         src_v4l2_t *s = (src_v4l2_t *) src->state;
487         struct v4l2_fmtdesc fmt;
488         int v4l2_pal;
489         
490         /* Dump a list of formats the device supports. */
491         /*DEBUG("Device offers the following V4L2 pixel formats:");*/
492         
493         v4l2_pal = 0;
494         memset(&fmt, 0, sizeof(fmt));
495         fmt.index = v4l2_pal;
496         fmt.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
497         
498         while(ioctl(s->fd, VIDIOC_ENUM_FMT, &fmt) != -1)
499         {
500                 /*DEBUG("%i: [0x%08X] '%c%c%c%c' (%s)", v4l2_pal,
501                       fmt.pixelformat,
502                       fmt.pixelformat >> 0,  fmt.pixelformat >> 8,
503                       fmt.pixelformat >> 16, fmt.pixelformat >> 24,
504                       fmt.description);*/
505                 
506                 memset(&fmt, 0, sizeof(fmt));
507                 fmt.index = ++v4l2_pal;
508                 fmt.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
509         }
510         
511         /* Step through each palette type. */
512         v4l2_pal = 0;
513         
514         if(src->palette != -1)
515         {
516                 while(v4l2_palette[v4l2_pal].v4l2)
517                 {
518                         if(v4l2_palette[v4l2_pal].src == src->palette) break;
519                         v4l2_pal++;
520                 }
521                 
522                 if(!v4l2_palette[v4l2_pal].v4l2)
523                 {
524                         /*ERROR("Unable to handle palette format %s.",
525                               src_palette[src->palette]);*/
526                         
527                         return(-1);
528                 }
529         }
530         
531         while(v4l2_palette[v4l2_pal].v4l2)
532         {
533                 /* Try the palette... */
534                 memset(&s->fmt, 0, sizeof(s->fmt));
535                 s->fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
536                 s->fmt.fmt.pix.width       = src->width;
537                 s->fmt.fmt.pix.height      = src->height;
538                 s->fmt.fmt.pix.pixelformat = v4l2_palette[v4l2_pal].v4l2;
539                 s->fmt.fmt.pix.field       = V4L2_FIELD_ANY;
540                 
541                 if(ioctl(s->fd, VIDIOC_TRY_FMT, &s->fmt) != -1 &&
542                    s->fmt.fmt.pix.pixelformat == v4l2_palette[v4l2_pal].v4l2)
543                 {
544                         src->palette = v4l2_palette[v4l2_pal].src;
545                         
546                         /*INFO("Using palette %s", src_palette[src->palette].name);*/
547                         
548                         if(s->fmt.fmt.pix.width != src->width ||
549                            s->fmt.fmt.pix.height != src->height)
550                         {
551                                 /*MSG("Adjusting resolution from %ix%i to %ix%i.",
552                                     src->width, src->height,
553                                     s->fmt.fmt.pix.width,
554                                     s->fmt.fmt.pix.height);*/
555                                 src->width = s->fmt.fmt.pix.width;
556                                 src->height = s->fmt.fmt.pix.height;
557                         }
558                         
559                         if(ioctl(s->fd, VIDIOC_S_FMT, &s->fmt) == -1)
560                         {
561                                 /*ERROR("Error setting pixel format.");
562                                 ERROR("VIDIOC_S_FMT: %s", strerror(errno));*/
563                                 return(-1);
564                         }
565                         
566                         if(v4l2_palette[v4l2_pal].v4l2 == V4L2_PIX_FMT_MJPEG)
567                         {
568                                 struct v4l2_jpegcompression jpegcomp;
569                                 
570                                 memset(&jpegcomp, 0, sizeof(jpegcomp));
571                                 ioctl(s->fd, VIDIOC_G_JPEGCOMP, &jpegcomp);
572                                 jpegcomp.jpeg_markers |= V4L2_JPEG_MARKER_DHT;
573                                 ioctl(s->fd, VIDIOC_S_JPEGCOMP, &jpegcomp);
574                         }
575                         
576                         return(0);
577                 }
578                 
579                 if(src->palette != -1) break;
580                 
581                 v4l2_pal++;
582         }
583         
584         /*ERROR("Unable to find a compatible palette format.");*/
585         
586         return(-1);
587 }
588
589 int src_v4l2_set_fps(src_t *src)
590 {
591         src_v4l2_t *s = (src_v4l2_t *) src->state;
592         struct v4l2_streamparm setfps;
593         
594         memset(&setfps, 0, sizeof(setfps));
595         
596         setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
597         setfps.parm.capture.timeperframe.numerator = 1;
598         setfps.parm.capture.timeperframe.denominator = src->fps;
599         if(ioctl(s->fd, VIDIOC_S_PARM, setfps) == -1)
600         {
601                 /* Not fatal - just warn about it */
602                 /*WARN("Error setting frame rate:");
603                 WARN("VIDIOC_S_PARM: %s", strerror(errno));*/
604                 return(-1);
605         }
606         
607         return(0);
608 }
609
610 int src_v4l2_free_mmap(src_t *src)
611 {
612         src_v4l2_t *s = (src_v4l2_t *) src->state;
613         int i;
614         
615         for(i = 0; i < s->req.count; i++)
616                 munmap(s->buffer[i].start, s->buffer[i].length);
617         
618         return(0);
619 }
620
621 int src_v4l2_set_mmap(src_t *src)
622 {
623         src_v4l2_t *s = (src_v4l2_t *) src->state;
624         enum v4l2_buf_type type;
625         uint32_t b;
626         
627         /* Does the device support streaming? */
628         if(~s->cap.capabilities & V4L2_CAP_STREAMING) return(-1);
629         
630         memset(&s->req, 0, sizeof(s->req));
631         
632         s->req.count  = 4;
633         s->req.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
634         s->req.memory = V4L2_MEMORY_MMAP;
635         
636         if(ioctl(s->fd, VIDIOC_REQBUFS, &s->req) == -1)
637         {
638                 /*ERROR("Error requesting buffers for memory map.");
639                 ERROR("VIDIOC_REQBUFS: %s", strerror(errno));*/
640                 return(-1);
641         }
642         
643         /*DEBUG("mmap information:");
644         DEBUG("frames=%d", s->req.count);*/
645         
646         if(s->req.count < 2)
647         {
648                 /*ERROR("Insufficient buffer memory.");*/
649                 return(-1);
650         }
651         
652         s->buffer = calloc(s->req.count, sizeof(v4l2_buffer_t));
653         if(!s->buffer)
654         {
655                 /*ERROR("Out of memory.");*/
656                 return(-1);
657         }
658         
659         for(b = 0; b < s->req.count; b++)
660         {
661                 struct v4l2_buffer buf;
662                 
663                 memset(&buf, 0, sizeof(buf));
664                 
665                 buf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
666                 buf.memory = V4L2_MEMORY_MMAP;
667                 buf.index  = b;
668                 
669                 if(ioctl(s->fd, VIDIOC_QUERYBUF, &buf) == -1)
670                 {
671                         /*ERROR("Error querying buffer %i", b);
672                         ERROR("VIDIOC_QUERYBUF: %s", strerror(errno));*/
673                         free(s->buffer);
674                         return(-1);
675                 }
676                 
677                 s->buffer[b].length = buf.length;
678                 s->buffer[b].start = mmap(NULL, buf.length,
679                    PROT_READ | PROT_WRITE, MAP_SHARED, s->fd, buf.m.offset);
680                 
681                 if(s->buffer[b].start == MAP_FAILED)
682                 {
683                         /*ERROR("Error mapping buffer %i", b);
684                         ERROR("mmap: %s", strerror(errno));*/
685                         s->req.count = b;
686                         src_v4l2_free_mmap(src);
687                         free(s->buffer);
688                         return(-1);
689                 }
690                 
691                 /*DEBUG("%i length=%d", b, buf.length);*/
692         }
693         
694         s->map = -1;
695         
696         for(b = 0; b < s->req.count; b++)
697         {
698                 memset(&s->buf, 0, sizeof(s->buf));
699                 
700                 s->buf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
701                 s->buf.memory = V4L2_MEMORY_MMAP;
702                 s->buf.index  = b;
703                 
704                 if(ioctl(s->fd, VIDIOC_QBUF, &s->buf) == -1)
705                 {
706                         /*ERROR("VIDIOC_QBUF: %s", strerror(errno));*/
707                         src_v4l2_free_mmap(src);
708                         free(s->buffer);
709                         return(-1);
710                 }
711         }
712         
713         type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
714         
715         if(ioctl(s->fd, VIDIOC_STREAMON, &type) == -1)
716         {
717                 /*ERROR("Error starting stream.");
718                 ERROR("VIDIOC_STREAMON: %s", strerror(errno));*/
719                 src_v4l2_free_mmap(src);
720                 free(s->buffer);
721                 return(-1);
722         }
723         
724         return(0);
725 }
726
727 int src_v4l2_set_read(src_t *src)
728 {
729         src_v4l2_t *s = (src_v4l2_t *) src->state;
730         
731         if(~s->cap.capabilities & V4L2_CAP_READWRITE) return(-1);
732         
733         s->buffer = calloc(1, sizeof(v4l2_buffer_t));
734         if(!s->buffer)
735         {
736                 /*ERROR("Out of memory.");*/
737                 return(-1);
738         }
739         
740         s->buffer[0].length = s->fmt.fmt.pix.sizeimage;
741         s->buffer[0].start  = malloc(s->buffer[0].length);
742         
743         if(!s->buffer[0].start)
744         {
745                 /*ERROR("Out of memory.");*/
746                 
747                 free(s->buffer);
748                 s->buffer = NULL;
749                 
750                 return(-1);
751         }
752         
753         return(0);
754 }
755
756 static const char *src_v4l2_query(src_t *src, uint *width, uint *height, char **pixelformatdescription)
757 {
758         if(!src->source)
759         {
760                 /*ERROR("No device name specified.");*/
761                 fprintf(stderr, "No device name specified.");
762                 return NULL;
763         }
764         src_v4l2_t *s;  
765
766         /* Allocate memory for the state structure. */
767         s = calloc(sizeof(src_v4l2_t), 1);
768         if(!s)
769         {
770                 fprintf(stderr, "Out of memory.");
771                 return NULL;
772         }
773         
774         src->state = (void *) s;
775
776         /* Open the device. */
777         s->fd = open(src->source, O_RDWR | O_NONBLOCK);
778         if(s->fd < 0)
779         {
780                 fprintf(stderr, "Cannot open device.");
781                 free(s);
782                 return NULL;
783         }
784
785         if(ioctl(s->fd, VIDIOC_QUERYCAP, &s->cap) < 0) {
786             src_v4l2_close(src);
787             fprintf(stderr, "Cannot get capabilities.");
788             return NULL;
789         }
790         char *res = strdup((char*) s->cap.card);
791         /*strcpy(res, (char*) s->cap.card);*/
792         if(!s->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
793             *width = 0;
794             *height = 0;
795         }
796         else {
797             struct v4l2_format format;
798             memset(&format,0,sizeof(format));
799             format.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
800             if (ioctl(s->fd,VIDIOC_G_FMT,&format) < 0) {
801                 fprintf(stderr, "Cannot get format.");
802             }
803             else {
804                 *width = format.fmt.pix.width;
805                 *height = format.fmt.pix.height;
806             }
807             struct v4l2_fmtdesc fmt;
808             memset(&fmt,0,sizeof(fmt));
809             fmt.index = 0;
810             fmt.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
811
812             struct v4l2_frmsizeenum sizes;
813             memset(&sizes,0,sizeof(sizes));
814
815             struct v4l2_frmivalenum rates;
816             memset(&rates,0,sizeof(rates));
817             char value[200];
818             *pixelformatdescription = strdup((char *) "result:");
819
820             while (ioctl(s->fd, VIDIOC_ENUM_FMT, &fmt) != -1)
821             {
822                 /*strcpy(*pixelformatdescription, (char *) fmt.description);*/
823                 //*pixelformatdescription = strdup((char*)fmt.description);
824                 snprintf( value, sizeof(value), "%c%c%c%c:", fmt.pixelformat >> 0,  fmt.pixelformat >> 8, fmt.pixelformat >> 16, fmt.pixelformat >> 24 );
825                 strcat(*pixelformatdescription, strdup((char *) value));
826                 fprintf(stderr, "detected format: %s: %c%c%c%c\n", fmt.description, fmt.pixelformat >> 0,  fmt.pixelformat >> 8,
827                       fmt.pixelformat >> 16, fmt.pixelformat >> 24);
828
829                 sizes.pixel_format = fmt.pixelformat;
830                 sizes.index = 0;
831                 // Query supported frame size
832                 while (ioctl(s->fd, VIDIOC_ENUM_FRAMESIZES, &sizes) != -1) {
833                     struct v4l2_frmsize_discrete image_size = sizes.un.discrete;
834                     // Query supported frame rates
835                     rates.index = 0;
836                     rates.pixel_format = fmt.pixelformat;
837                     rates.width = image_size.width;
838                     rates.height = image_size.height;
839                     snprintf( value, sizeof(value), "%dx%d,", image_size.width, image_size.height );
840                     strcat(*pixelformatdescription, strdup((char *) value));
841                     fprintf(stderr, "Size: %dx%d: ", image_size.width, image_size.height);
842                     while (ioctl(s->fd, VIDIOC_ENUM_FRAMEINTERVALS, &rates) != -1) {
843                         snprintf( value, sizeof(value), "%d/%d,", rates.un.discrete.numerator, rates.un.discrete.denominator );
844                         strcat(*pixelformatdescription, strdup((char *) value));
845                         fprintf(stderr, "%d/%d, ", rates.un.discrete.numerator, rates.un.discrete.denominator);
846                         rates.index ++;
847                     }
848                     fprintf(stderr, "\n");
849                     sizes.index++;
850                 }
851                 
852
853                 /*[0x%08X] '%c%c%c%c' (%s)", v4l2_pal,
854                       fmt.pixelformat,
855                       fmt.pixelformat >> 0,  fmt.pixelformat >> 8,
856                       fmt.pixelformat >> 16, fmt.pixelformat >> 24*/
857                 fmt.index++;
858             }
859             /*else {
860                 *pixelformatdescription = '\0';
861             }*/
862         }
863         src_v4l2_close(src);
864         return res;
865 }
866
867 static int src_v4l2_open(src_t *src)
868 {
869         src_v4l2_t *s;
870         
871         if(!src->source)
872         {
873                 /*ERROR("No device name specified.");*/
874                 return(-2);
875         }
876         
877         /* Allocate memory for the state structure. */
878         s = calloc(sizeof(src_v4l2_t), 1);
879         if(!s)
880         {
881                 /*ERROR("Out of memory.");*/
882                 return(-2);
883         }
884         
885         src->state = (void *) s;
886         
887         /* Open the device. */
888         s->fd = open(src->source, O_RDWR | O_NONBLOCK);
889         if(s->fd < 0)
890         {
891                 /*ERROR("Error opening device: %s", src->source);
892                 ERROR("open: %s", strerror(errno));*/
893                 free(s);
894                 return(-2);
895         }
896         
897         /*MSG("%s opened.", src->source);*/
898         
899         /* Get the device capabilities. */
900         if(src_v4l2_get_capability(src))
901         {
902                 src_v4l2_close(src);
903                 return(-2);
904         }
905         
906         /* Set the input. */
907         if(src_v4l2_set_input(src))
908         {
909                 src_v4l2_close(src);
910                 return(-1);
911         }
912         
913         /* Set picture options. */
914         src_v4l2_set_controls(src);
915         
916         /* Set the pixel format. */
917         if(src_v4l2_set_pix_format(src))
918         {
919                 src_v4l2_close(src);
920                 return(-1);
921         }
922         
923         /* Set the frame-rate if > 0 */
924         if(src->fps) src_v4l2_set_fps(src);
925         
926         /* Delay to let the image settle down. */
927         if(src->delay)
928         {
929                 /*MSG("Delaying %i seconds.", src->delay);*/
930                 usleep(src->delay * 1000 * 1000);
931         }
932         
933         /* Try to setup mmap. */
934         if(!src->use_read && src_v4l2_set_mmap(src))
935         {
936                 /*WARN("Unable to use mmap. Using read instead.");*/
937                 src->use_read = -1;
938         }
939         
940         /* If unable to use mmap or user requested read(). */
941         if(src->use_read)
942         {
943                 if(src_v4l2_set_read(src))
944                 {
945                         /*ERROR("Unable to use read.");*/
946                         src_v4l2_close(src);
947                         return(-1);
948                 }
949         }
950         
951         s->pframe = -1;
952         
953         return(0);
954 }
955
956 static int src_v4l2_close(src_t *src)
957 {
958         src_v4l2_t *s = (src_v4l2_t *) src->state;
959         
960         if(s->buffer)
961         {
962                 if(!s->map) free(s->buffer[0].start);
963                 else src_v4l2_free_mmap(src);
964                 free(s->buffer);
965         }
966         if(s->fd >= 0) close(s->fd);
967         free(s);
968         
969         return(0);
970 }
971
972 static int src_v4l2_grab(src_t *src)
973 {
974         src_v4l2_t *s = (src_v4l2_t *) src->state;
975         
976         if(src->timeout)
977         {
978                 fd_set fds;
979                 struct timeval tv;
980                 int r;
981                 
982                 /* Is a frame ready? */
983                 FD_ZERO(&fds);
984                 FD_SET(s->fd, &fds);
985                 
986                 tv.tv_sec = src->timeout;
987                 tv.tv_usec = 0;
988                 
989                 r = select(s->fd + 1, &fds, NULL, NULL, &tv);
990                 
991                 if(r == -1)
992                 {
993                         /*ERROR("select: %s", strerror(errno));*/
994                         return(-1);
995                 }
996                 
997                 if(!r)
998                 {
999                         /*ERROR("Timed out waiting for frame!");*/
1000                         return(-1);
1001                 }
1002         }
1003         
1004         if(s->map)
1005         {
1006                 if(s->pframe >= 0)
1007                 {
1008                         if(ioctl(s->fd, VIDIOC_QBUF, &s->buf) == -1)
1009                         {
1010                                 /*ERROR("VIDIOC_QBUF: %s", strerror(errno));*/
1011                                 return(-1);
1012                         }
1013                 }
1014                 
1015                 memset(&s->buf, 0, sizeof(s->buf));
1016                 
1017                 s->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1018                 s->buf.memory = V4L2_MEMORY_MMAP;
1019                 
1020                 if(ioctl(s->fd, VIDIOC_DQBUF, &s->buf) == -1)
1021                 {
1022                         /*ERROR("VIDIOC_DQBUF: %s", strerror(errno));*/
1023                         return(-1);
1024                 }
1025                 
1026                 src->img    = s->buffer[s->buf.index].start;
1027                 src->length = s->buffer[s->buf.index].length;
1028                 
1029                 s->pframe = s->buf.index;
1030         }
1031         else
1032         {
1033                 ssize_t r;
1034                 
1035                 r = read(s->fd, s->buffer[0].start, s->buffer[0].length);
1036                 if(r <= 0)
1037                 {
1038                         /*ERROR("Unable to read a frame.");
1039                         ERROR("read: %s", strerror(errno));*/
1040                         return(-1);
1041                 }
1042                 
1043                 src->img = s->buffer[0].start;
1044                 src->length = r;
1045         }
1046         
1047         return(0);
1048 }
1049
1050 src_mod_t src_v4l2 = {
1051         "v4l2", SRC_TYPE_DEVICE,
1052         src_v4l2_open,
1053         src_v4l2_close,
1054         src_v4l2_grab,
1055         src_v4l2_query
1056 };
1057
1058 #else /* #ifdef HAVE_V4L2 */
1059
1060 src_mod_t src_v4l2 = {
1061         "", SRC_TYPE_NONE,
1062         NULL,
1063         NULL,
1064         NULL,
1065         NULL
1066 };
1067
1068 #endif /* #ifdef HAVE_V4L2 */
1069