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. */
20 #include <sys/ioctl.h>
23 #include "videodev_mjpeg.h"
39 struct mjpeg_requestbuffers mjpeg_breq
;
40 struct mjpeg_sync mjpeg_bsync
;
42 uint32_t buffer_length
;
55 v4l_palette_t v4l_palette
[] = {
56 { SRC_PAL_JPEG
, VIDEO_PALETTE_RGB24
, 24 },
57 { SRC_PAL_MJPEG
, VIDEO_PALETTE_RGB24
, 24 },
58 { SRC_PAL_YUYV
, VIDEO_PALETTE_YUYV
, 16 },
59 { SRC_PAL_UYVY
, VIDEO_PALETTE_UYVY
, 16 },
60 { SRC_PAL_YUV420P
, VIDEO_PALETTE_YUV420P
, 12 },
61 { SRC_PAL_BGR24
, VIDEO_PALETTE_RGB24
, 24 }, /* RGB24/32 in V4L1 */
62 { SRC_PAL_BGR32
, VIDEO_PALETTE_RGB32
, 32 }, /* are actually BGR */
63 { SRC_PAL_RGB565
, VIDEO_PALETTE_RGB565
, 16 },
64 { SRC_PAL_RGB555
, VIDEO_PALETTE_RGB555
, 16 },
65 { SRC_PAL_GREY
, VIDEO_PALETTE_GREY
, 8 },
69 int src_v4l_get_capability(src_t
*src
, int fd
, struct video_capability
*vd
)
71 if(ioctl(fd
, VIDIOCGCAP
, vd
) < 0)
73 ERROR("%s: Not a V4L device?", src
->source
);
74 ERROR("VIDIOCGCAP: %s", strerror(errno
));
78 /* Dump information about the capture card. */
79 DEBUG("%s information:", src
->source
);
80 DEBUG("vd.name: \"%s\"", vd
->name
);
81 DEBUG("vd.type=0x%08x", vd
->type
);
82 if(vd
->type
& VID_TYPE_CAPTURE
) DEBUG("- CAPTURE");
83 if(vd
->type
& VID_TYPE_TUNER
) DEBUG("- TUNER");
84 if(vd
->type
& VID_TYPE_TELETEXT
) DEBUG("- TELETEXT");
85 if(vd
->type
& VID_TYPE_OVERLAY
) DEBUG("- OVERLAY");
86 if(vd
->type
& VID_TYPE_CHROMAKEY
) DEBUG("- CHROMAKEY");
87 if(vd
->type
& VID_TYPE_CLIPPING
) DEBUG("- CLIPPING");
88 if(vd
->type
& VID_TYPE_FRAMERAM
) DEBUG("- FRAMERAM");
89 if(vd
->type
& VID_TYPE_SCALES
) DEBUG("- SCALES");
90 if(vd
->type
& VID_TYPE_MONOCHROME
) DEBUG("- MONOCHROME");
91 if(vd
->type
& VID_TYPE_SUBCAPTURE
) DEBUG("- SUBCAPTURE");
92 if(vd
->type
& VID_TYPE_MJPEG_ENCODER
) DEBUG("- MJPEG_ENCODER");
93 DEBUG("vd.maxwidth=%d", vd
->maxwidth
);
94 DEBUG("vd.maxheight=%d", vd
->maxheight
);
95 DEBUG("vd.minwidth=%d", vd
->minwidth
);
96 DEBUG("vd.minheight=%d", vd
->minheight
);
98 /* Make sure we can capture from this device. */
99 if(!vd
->type
& VID_TYPE_CAPTURE
)
101 ERROR("%s: Device does not support capturing.", src
->source
);
105 /* Make sure we can capture at the requested resolution. */
106 if(vd
->minwidth
&& vd
->minwidth
> src
->width
)
108 WARN("Requested width too small. Adjusting %i -> %i.",
109 src
->width
, vd
->minwidth
);
110 src
->width
= vd
->minwidth
;
113 if(vd
->maxwidth
&& vd
->maxwidth
< src
->width
)
115 WARN("Requested width too large. Adjusting %i -> %i.",
116 src
->width
, vd
->maxwidth
);
117 src
->width
= vd
->maxwidth
;
120 if(vd
->minheight
&& vd
->minheight
> src
->height
)
122 WARN("Requested height too small. Adjusting %i -> %i.",
123 src
->height
, vd
->minheight
);
124 src
->height
= vd
->minheight
;
127 if(vd
->maxheight
&& vd
->maxheight
< src
->height
)
129 WARN("Requested height too large. Adjusting %i -> %i.",
130 src
->height
, vd
->maxheight
);
131 src
->height
= vd
->maxheight
;
137 int src_v4l_set_input(src_t
*src
, int fd
,
138 struct video_capability
*vd
,
139 struct video_channel
*vc
)
141 int count
= 0, i
= -1;
143 if(vd
->channels
== 0)
145 MSG("No inputs available.");
149 if(src
->list
& SRC_LIST_INPUTS
)
151 HEAD("--- Available inputs:");
155 while(!ioctl(fd
, VIDIOCGCHAN
, vc
))
157 MSG("%i: %s", count
, (char *) vc
->name
);
158 vc
->channel
= ++count
;
162 /* If no input was specified, use input 0. */
165 MSG("No input was specified, using the first.");
171 /* Check if the input is specified by name. */
174 while(!ioctl(fd
, VIDIOCGCHAN
, vc
))
176 if(!strncasecmp((char *) vc
->name
, src
->input
, 32))
178 vc
->channel
= ++count
;
185 /* Is the input specified by number? */
186 i
= strtol(src
->input
, &endptr
, 10);
188 if(endptr
== src
->input
) i
= -1;
192 if(i
== -1 || i
>= count
)
194 /* The specified input wasn't found! */
195 ERROR("Unrecognised input \"%s\"", src
->input
);
199 /* Get data about the input channel. */
201 if(ioctl(fd
, VIDIOCGCHAN
, vc
) < 0)
203 ERROR("Error getting information for input \"%s\".",src
->input
);
204 ERROR("VIDIOCGCHAN: %s", strerror(errno
));
208 if(src
->input
) DEBUG("Input %i (%s) information:", i
, src
->input
);
209 else DEBUG("Input %i information:", i
, src
->input
);
210 DEBUG("vc.channel=%d", vc
->channel
);
211 DEBUG("vc.name=\"%s\"", vc
->name
);
212 DEBUG("vc.tuners=%d",vc
->tuners
);
213 DEBUG("vc.flags=0x%08x", vc
->flags
);
214 if(vc
->flags
& VIDEO_VC_TUNER
) DEBUG("- TUNER");
215 if(vc
->flags
& VIDEO_VC_AUDIO
) DEBUG("- AUDIO");
216 DEBUG("vc.type=0x%08x", vc
->type
);
217 if(vc
->type
& VIDEO_TYPE_TV
) DEBUG("- TV");
218 if(vc
->type
& VIDEO_TYPE_CAMERA
) DEBUG("- CAMERA");
219 DEBUG("vc.norm=%d", vc
->norm
);
221 MSG("Setting input to %i.", i
);
223 /* Set the source. */
224 if(ioctl(fd
, VIDIOCSCHAN
, vc
) < 0)
226 ERROR("Error while setting input to %i.", i
);
227 ERROR("VIDIOCSCHAN: %s", strerror(errno
));
234 int src_v4l_set_tuner(src_t
*src
, int fd
,
235 struct video_channel
*vc
,
236 struct video_tuner
*vt
)
242 MSG("No tuners available.");
246 /* Check the requested tuner exists. */
247 if(src
->tuner
>= vc
->tuners
)
249 ERROR("Requested tuner %i and only %i tuner(s) found.",
250 src
->tuner
, vc
->tuners
- 1);
254 /* Get data about the tuner. */
255 vt
->tuner
= src
->tuner
;
256 if(ioctl(fd
, VIDIOCGTUNER
, vt
) < 0)
258 ERROR("Error getting information on tuner %i (input %i).",
259 src
->tuner
, src
->input
);
260 ERROR("VIDIOCGCHAN: %s", strerror(errno
));
264 if(vt
->flags
& VIDEO_TUNER_LOW
) range
= "KHz";
267 DEBUG("Tuner %i information:", src
->tuner
);
268 DEBUG("vt.tuner=%d", vt
->tuner
);
269 DEBUG("vt.name=\"%s\"", vt
->name
);
270 DEBUG("vt.rangelow=%u (%.3f%s)", (unsigned int) vt
->rangelow
,
271 (float) vt
->rangelow
/ 16, range
);
272 DEBUG("vt.rangehigh=%u (%.3f%s)", (unsigned int) vt
->rangehigh
,
273 (float) vt
->rangehigh
/ 16, range
);
274 DEBUG("vt.flags=0x%08x", vt
->flags
);
275 if(vt
->flags
& VIDEO_TUNER_PAL
) DEBUG("- PAL");
276 if(vt
->flags
& VIDEO_TUNER_NTSC
) DEBUG("- NTSC");
277 if(vt
->flags
& VIDEO_TUNER_SECAM
) DEBUG("- SECAM");
278 if(vt
->flags
& VIDEO_TUNER_LOW
) DEBUG("- LOW");
279 if(vt
->flags
& VIDEO_TUNER_NORM
) DEBUG("- NORM");
280 if(vt
->flags
& VIDEO_TUNER_STEREO_ON
) DEBUG("- STEREO_ON");
281 if(vt
->flags
& VIDEO_TUNER_RDS_ON
) DEBUG("- RDS_ON");
282 if(vt
->flags
& VIDEO_TUNER_MBS_ON
) DEBUG("- MBS_ON");
283 DEBUG("vt.mode=0x%08x", vt
->mode
);
284 if(vt
->mode
& VIDEO_MODE_PAL
) DEBUG("- PAL");
285 if(vt
->mode
& VIDEO_MODE_NTSC
) DEBUG("- NTSC");
286 if(vt
->mode
& VIDEO_MODE_SECAM
) DEBUG("- SECAM");
287 if(vt
->mode
& VIDEO_MODE_AUTO
) DEBUG("- AUTO");
288 DEBUG("vt.signal=%d", vt
->signal
);
290 MSG("Setting tuner to %i.", src
->tuner
);
292 if(ioctl(fd
, VIDIOCSTUNER
, vt
) < 0)
294 ERROR("Error setting tuner %i (input %i).",
295 src
->tuner
, src
->input
);
296 ERROR("VIDIOCSTUNER: %s", strerror(errno
));
303 int src_v4l_set_frequency(src_t
*src
, int fd
, struct video_tuner
*vt
)
309 if(vt
->flags
& VIDEO_TUNER_LOW
) range
= "KHz";
312 /* Get the current frequency. */
314 ioctl(fd
, VIDIOCGFREQ
, &freq
);
315 if(freq
) ff
= freq
/ 16;
316 DEBUG("Current frequency is %.3f%s", ff
, range
);
318 /* Don't set the frequency if it's 0. */
319 if(src
->frequency
== 0) return(0);
321 /* Calculate the frequency. */
322 freq
= (src
->frequency
/ 1000) * 16;
324 /* Ensure frequency is within range of the tuner. */
325 if(freq
< vt
->rangelow
)
327 WARN("Frequency is below tuners minimum. Using %.3f%s.",
328 (float) vt
->rangelow
/ 16, range
);
333 if(freq
> vt
->rangehigh
)
335 WARN("Frequency is above tuners maximum. Using %.3f%s.",
336 (float) vt
->rangehigh
/ 16, range
);
338 freq
= vt
->rangehigh
;
341 /* Set the frequency. */
342 MSG("Setting frequency to %.3f%s.", (float) freq
/ 16, range
);
344 if(ioctl(fd
, VIDIOCSFREQ
, &freq
) == -1)
346 ERROR("Error setting frequency.");
347 ERROR("VIDIOCSFREQ: %s", strerror(errno
));
354 int src_v4l_set_picture(src_t
*src
, int fd
, struct video_capability
*vd
)
356 src_v4l_t
*s
= (src_v4l_t
*) src
->state
;
357 struct video_picture vp
;
361 memset(&vp
, 0, sizeof(vp
));
363 if(ioctl(fd
, VIDIOCGPICT
, &vp
) < 0)
365 ERROR("Error getting picture information.");
366 ERROR("VIDIOCGPICT: %s", strerror(errno
));
370 if(src
->list
& SRC_LIST_CONTROLS
)
374 HEAD("--- Available controls:");
376 for(i
= 0; i
< 5; i
++)
386 value
= vp
.brightness
;
402 value
= vp
.whiteness
;
406 snprintf(t
, 63, "%i (%i%%)",
407 SCALE(-100, 100, 0x0000, 0xFFFF, vp
.brightness
),
408 SCALE(0, 100, 0x0000, 0xFFFF, vp
.brightness
));
410 MSG("%-25s %-15s 100 - -100", name
, t
);
414 if(!src_get_option_by_name(src
->option
, "brightness", &value
))
415 vp
.brightness
= SCALE(0x0000, 0xFFFF, -100, 100, atoi(value
));
417 if(!src_get_option_by_name(src
->option
, "hue", &value
))
418 vp
.hue
= SCALE(0x0000, 0xFFFF, -100, 100, atoi(value
));
420 if(!src_get_option_by_name(src
->option
, "colour", &value
))
421 vp
.colour
= SCALE(0x0000, 0xFFFF, -100, 100, atoi(value
));
423 if(!src_get_option_by_name(src
->option
, "contrast", &value
))
424 vp
.contrast
= SCALE(0x0000, 0xFFFF, -100, 100, atoi(value
));
426 if(!src_get_option_by_name(src
->option
, "whiteness", &value
))
427 vp
.whiteness
= SCALE(0x0000, 0xFFFF, -100, 100, atoi(value
));
429 /* MJPEG devices are a special case... */
430 if(vd
->type
& VID_TYPE_MJPEG_ENCODER
)
432 WARN("Device is MJPEG only. Forcing JPEG palette.");
433 src
->palette
= SRC_PAL_JPEG
;
436 if(src
->palette
== SRC_PAL_JPEG
&& !(vd
->type
& VID_TYPE_MJPEG_ENCODER
))
438 ERROR("MJPEG palette requsted for a non-MJPEG device.");
442 if(src
->palette
== SRC_PAL_JPEG
)
444 struct mjpeg_params mparm
;
446 memset(&mparm
, 0, sizeof(mparm
));
448 if(ioctl(s
->fd
, MJPIOC_G_PARAMS
, &mparm
))
450 ERROR("Error querying video parameters.");
451 ERROR("MJPIOC_G_PARAMS: %s", strerror(errno
));
455 DEBUG("%s: Video parameters...", src
->source
);
456 DEBUG("major_version = %i", mparm
.major_version
);
457 DEBUG("minor_version = %i", mparm
.minor_version
);
458 DEBUG("input = %i", mparm
.input
);
459 DEBUG("norm = %i", mparm
.norm
);
460 DEBUG("decimation = %i", mparm
.decimation
);
461 DEBUG("HorDcm = %i", mparm
.HorDcm
);
462 DEBUG("VerDcm = %i", mparm
.VerDcm
);
463 DEBUG("TmpDcm = %i", mparm
.TmpDcm
);
464 DEBUG("field_per_buff = %i", mparm
.field_per_buff
);
465 DEBUG("img_x = %i", mparm
.img_x
);
466 DEBUG("img_y = %i", mparm
.img_y
);
467 DEBUG("img_width = %i", mparm
.img_width
);
468 DEBUG("img_height = %i", mparm
.img_height
);
469 DEBUG("quality = %i", mparm
.quality
);
470 DEBUG("odd_even = %i", mparm
.odd_even
);
471 DEBUG("APPn = %i", mparm
.APPn
);
472 DEBUG("APP_len = %i", mparm
.APP_len
);
473 DEBUG("APP_data = \"%s\"", mparm
.APP_data
);
474 DEBUG("COM_len = %i", mparm
.COM_len
);
475 DEBUG("COM_data = \"%s\"", mparm
.COM_data
);
476 DEBUG("jpeg_markers = %i", mparm
.jpeg_markers
);
477 if(mparm
.jpeg_markers
& JPEG_MARKER_DHT
) DEBUG("- DHT");
478 if(mparm
.jpeg_markers
& JPEG_MARKER_DQT
) DEBUG("- DQT");
479 if(mparm
.jpeg_markers
& JPEG_MARKER_DRI
) DEBUG("- DRI");
480 if(mparm
.jpeg_markers
& JPEG_MARKER_COM
) DEBUG("- COM");
481 if(mparm
.jpeg_markers
& JPEG_MARKER_APP
) DEBUG("- APP");
482 DEBUG("VFIFO_FB = %i", mparm
.VFIFO_FB
);
484 /* Set the usual parameters. */
486 mparm
.norm
= VIDEO_MODE_PAL
;
487 /* TODO: Allow user to select PAL/SECAM/NTSC */
489 mparm
.decimation
= 0;
495 mparm
.field_per_buff
= 2;
497 /* Ask the driver to include the DHT with each frame. */
498 mparm
.jpeg_markers
|= JPEG_MARKER_DHT
;
500 if(ioctl(s
->fd
, MJPIOC_S_PARAMS
, &mparm
))
502 ERROR("Error setting video parameters.");
503 ERROR("MJPIOC_S_PARAMS: %s", strerror(errno
));
507 src
->width
= mparm
.img_width
/ mparm
.HorDcm
;
508 src
->height
= mparm
.img_height
/ mparm
.VerDcm
* mparm
.field_per_buff
;
513 v4l_pal
= 2; /* Skip the JPEG palette. */
515 if(src
->palette
!= -1)
519 while(v4l_palette
[v4l_pal
].depth
)
521 if(v4l_palette
[v4l_pal
].src
== src
->palette
) break;
525 if(!v4l_palette
[v4l_pal
].depth
)
527 ERROR("Unable to handle palette format %s.",
528 src_palette
[src
->palette
]);
534 while(v4l_palette
[v4l_pal
].depth
)
536 vp
.palette
= v4l_palette
[v4l_pal
].v4l
;
537 vp
.depth
= v4l_palette
[v4l_pal
].depth
;
539 if(!ioctl(fd
, VIDIOCSPICT
, &vp
))
541 s
->palette
= v4l_pal
;
542 src
->palette
= v4l_palette
[v4l_pal
].src
;
544 MSG("Using palette %s.",src_palette
[src
->palette
].name
);
549 if(src
->palette
!= -1) break;
551 WARN("The device does not support palette %s.",
552 src_palette
[v4l_palette
[v4l_pal
].src
].name
);
557 ERROR("Unable to find a compatible palette.");
562 int src_v4l_free_mmap(src_t
*src
)
564 src_v4l_t
*s
= (src_v4l_t
*) src
->state
;
566 if(src
->palette
== SRC_PAL_JPEG
)
567 munmap(s
->map
, s
->mjpeg_breq
.count
* s
->mjpeg_breq
.size
);
569 munmap(s
->map
, s
->vm
.size
);
574 int src_v4l_set_mmap(src_t
*src
, int fd
)
576 src_v4l_t
*s
= (src_v4l_t
*) src
->state
;
579 if(src
->palette
== SRC_PAL_JPEG
)
581 s
->mjpeg_breq
.count
= 32;
582 s
->mjpeg_breq
.size
= 256 * 1024;
584 if(ioctl(s
->fd
, MJPIOC_REQBUFS
, &s
->mjpeg_breq
))
586 ERROR("Error requesting video buffers.");
587 ERROR("MJPIOC_REQBUFS: %s", strerror(errno
));
590 DEBUG("Got %ld buffers of size %ld KB",
591 s
->mjpeg_breq
.count
, s
->mjpeg_breq
.size
/ 1024);
593 s
->map
= mmap(0, s
->mjpeg_breq
.count
* s
->mjpeg_breq
.size
,
594 PROT_READ
| PROT_WRITE
, MAP_SHARED
, fd
, 0);
596 if(s
->map
== MAP_FAILED
)
598 WARN("Error mmap'ing buffers.");
599 WARN("mmap: %s", strerror(errno
));
606 /* Find out how many buffers are available. */
607 if(ioctl(fd
, VIDIOCGMBUF
, &s
->vm
) < 0)
609 WARN("Error while querying buffers.");
610 WARN("VIDEOCGMBUF: %s", strerror(errno
));
614 DEBUG("mmap information:");
615 DEBUG("size=%d", s
->vm
.size
);
616 DEBUG("frames=%d", s
->vm
.frames
);
618 /* mmap all available buffers. */
619 s
->map
= mmap(0, s
->vm
.size
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, fd
, 0);
620 if(s
->map
== MAP_FAILED
)
622 WARN("Error mmap'ing all available buffers.");
623 WARN("mmap: %s", strerror(errno
));
627 /* Setup capture options. */
628 s
->mm
.format
= v4l_palette
[s
->palette
].v4l
;
629 s
->mm
.width
= src
->width
;
630 s
->mm
.height
= src
->height
;
632 /* Request the maximum number of frames the device can handle. */
633 for(frame
= 0; frame
< s
->vm
.frames
; frame
++)
636 if(ioctl(fd
, VIDIOCMCAPTURE
, &s
->mm
) < 0)
638 WARN("Error while requesting buffer %i to capture an image.", frame
);
639 WARN("VIDIOCMCAPTURE: %s", strerror(errno
));
640 src_v4l_free_mmap(src
);
648 int src_v4l_set_read(src_t
*src
)
650 src_v4l_t
*s
= (src_v4l_t
*) src
->state
;
651 struct video_window vwin
;
653 memset(&vwin
, 0, sizeof(vwin
));
654 vwin
.width
= src
->width
;
655 vwin
.height
= src
->height
;
656 if(ioctl(s
->fd
, VIDIOCSWIN
, &vwin
) == -1)
658 ERROR("Error setting %ix%i resolution.",
659 src
->width
, src
->height
);
662 /* Ugly!, but should always be large enough. */
663 s
->buffer_length
= src
->width
* src
->height
* 4;
664 s
->buffer
= malloc(s
->buffer_length
);
667 ERROR("Out of memory.");
675 int src_v4l_queue_buffers(src_t
*src
)
677 src_v4l_t
*s
= (src_v4l_t
*) src
->state
;
680 /* Queue all buffers. */
681 for(n
= 0; n
< s
->mjpeg_breq
.count
; n
++)
683 if(ioctl(s
->fd
, MJPIOC_QBUF_CAPT
, &n
))
685 ERROR("Error queing buffer %i.", n
);
686 ERROR("MJPIOC_QBUF_CAPT: %s", strerror(errno
));
694 int src_v4l_open(src_t
*src
)
697 struct video_capability vd
;
698 struct video_channel vc
;
699 struct video_tuner vt
;
703 ERROR("No device name specified.");
707 /* Allocate memory for state structure. */
708 s
= (src_v4l_t
*) calloc(sizeof(src_v4l_t
), 1);
711 ERROR("Out of memory.");
715 src
->state
= (void *) s
;
717 memset(&vd
, 0, sizeof(vd
));
718 memset(&vc
, 0, sizeof(vc
));
719 memset(&vt
, 0, sizeof(vt
));
721 /* Open the device. */
722 s
->fd
= open(src
->source
, O_RDWR
| O_NONBLOCK
);
725 ERROR("Error opening device: %s", src
->source
);
726 ERROR("open: %s", strerror(errno
));
731 MSG("%s opened.", src
->source
);
733 /* Get the device capabilities. */
734 if(src_v4l_get_capability(src
, s
->fd
, &vd
))
741 if(src_v4l_set_input(src
, s
->fd
, &vd
, &vc
))
747 if(vc
.flags
& VIDEO_VC_TUNER
)
750 if(src_v4l_set_tuner(src
, s
->fd
, &vc
, &vt
))
756 /* Set the frequency. */
757 if(src_v4l_set_frequency(src
, s
->fd
, &vt
))
764 /* Set the picture options. */
765 if(src_v4l_set_picture(src
, s
->fd
, &vd
))
771 /* Delay to let the image settle down. */
774 MSG("Delaying %i seconds.", src
->delay
);
775 usleep(src
->delay
* 1000 * 1000);
778 /* Setup the mmap. */
779 if(!src
->use_read
&& src_v4l_set_mmap(src
, s
->fd
))
781 WARN("Unable to use mmap. Using read instead.");
785 if(src
->use_read
&& src_v4l_set_read(src
))
791 /* If this is an MJPEG device, queue the buffers. */
792 if(src
->palette
== SRC_PAL_JPEG
&& src_v4l_queue_buffers(src
))
804 int src_v4l_close(src_t
*src
)
806 src_v4l_t
*s
= (src_v4l_t
*) src
->state
;
810 if(s
->map
) src_v4l_free_mmap(src
);
812 MSG("%s closed.", src
->source
);
815 if(s
->buffer
) free(s
->buffer
);
821 int src_v4l_grab_mjpeg(src_t
*src
)
823 src_v4l_t
*s
= (src_v4l_t
*) src
->state
;
825 /* Finished with the previous frame? */
828 if(ioctl(s
->fd
, MJPIOC_QBUF_CAPT
, &s
->mjpeg_bsync
.frame
))
830 ERROR("Error queing buffer.");
831 ERROR("MJPIOC_QBUF_CAPT: %s", strerror(errno
));
836 if(ioctl(s
->fd
, MJPIOC_SYNC
, &s
->mjpeg_bsync
))
838 ERROR("Error sync'ing buffer.");
839 ERROR("MJPIOC_SYNC: %s", strerror(errno
));
844 src
->img
= s
->map
+ s
->mjpeg_bsync
.frame
* s
->mjpeg_breq
.size
;
845 src
->length
= s
->mjpeg_bsync
.length
;
852 int src_v4l_grab(src_t
*src
)
854 src_v4l_t
*s
= (src_v4l_t
*) src
->state
;
856 /* MJPEG devices are handled differently. */
857 if(src
->palette
== SRC_PAL_JPEG
) return(src_v4l_grab_mjpeg(src
));
859 /* Wait for a frame. */
866 /* Is a frame ready? */
870 tv
.tv_sec
= src
->timeout
;
873 r
= select(s
->fd
+ 1, &fds
, NULL
, NULL
, &tv
);
877 ERROR("select: %s", strerror(errno
));
883 ERROR("Timed out waiting for frame!");
888 /* If using mmap... */
891 /* Finished with the previous frame? */
894 s
->mm
.frame
= s
->pframe
;
895 if(ioctl(s
->fd
, VIDIOCMCAPTURE
, &s
->mm
) < 0)
897 ERROR("Error while requesting buffer %i to capture an image.", s
->pframe
);
898 ERROR("VIDEOCMCAPTURE: %s", strerror(errno
));
903 /* Wait for the frame to be captured. */
904 if(ioctl(s
->fd
, VIDIOCSYNC
, &s
->frame
) < 0)
906 WARN("Error synchronising with buffer %i.", s
->frame
);
907 WARN("VIDIOCSYNC: %s", strerror(errno
));
911 /* Get the pointer to the current frame. */
912 src
->img
= s
->map
+ s
->vm
.offsets
[s
->frame
];
914 /* How big is the frame? */
915 if(s
->frame
== s
->vm
.frames
- 1)
916 src
->length
= s
->vm
.size
- s
->vm
.offsets
[s
->frame
];
918 src
->length
= s
->vm
.offsets
[s
->frame
+ 1] -
919 s
->vm
.offsets
[s
->frame
];
921 s
->pframe
= s
->frame
;
922 if(++s
->frame
== s
->vm
.frames
) s
->frame
= 0;
926 ssize_t r
= read(s
->fd
, s
->buffer
, s
->buffer_length
);
930 WARN("Didn't read a frame.");
931 WARN("read: %s", strerror(errno
));
935 src
->img
= s
->buffer
;
942 src_mod_t src_v4l1
= {
943 "v4l1", SRC_TYPE_DEVICE
,
949 #else /* #ifdef HAVE_V4L1 */
951 src_mod_t src_v4l1
= {
958 #endif /* #ifdef HAVE_V4L1 */