dd0101fb5d39a5749c7906073be63e0d4d910e87
[platform/upstream/gst-plugins-good.git] / sys / v4l2 / v4l2src_calls.c
1 /* GStreamer
2  *
3  * Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
4  *               2006 Edgard Lima <edgard.lima@indt.org.br>
5  *
6  * v4l2src.c - system calls
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <stdlib.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <sys/ioctl.h>
33 #include <sys/mman.h>
34 #include <string.h>
35 #include <errno.h>
36 #include "v4l2src_calls.h"
37 #include <sys/time.h>
38 #include <unistd.h>
39
40 #include "gstv4l2tuner.h"
41
42 GST_DEBUG_CATEGORY_EXTERN (v4l2src_debug);
43 #define GST_CAT_DEFAULT v4l2src_debug
44
45 /* lalala... */
46 #define GST_V4L2_SET_ACTIVE(element) (element)->buffer = GINT_TO_POINTER (-1)
47 #define GST_V4L2_SET_INACTIVE(element) (element)->buffer = NULL
48
49 #define DEBUG(format, args...) \
50         GST_CAT_DEBUG_OBJECT (\
51                 v4l2src_debug, v4l2src, \
52                 "V4L2SRC: " format, ##args)
53
54 /* On some systems MAP_FAILED seems to be missing */
55 #ifndef MAP_FAILED
56 #define MAP_FAILED ((caddr_t) -1)
57 #endif
58
59 /******************************************************
60  * gst_v4l2src_fill_format_list():
61  *   create list of supported capture formats
62  * return value: TRUE on success, FALSE on error
63  ******************************************************/
64 gboolean
65 gst_v4l2src_fill_format_list (GstV4l2Src * v4l2src)
66 {
67   gint n;
68   struct v4l2_fmtdesc *format;
69
70   GST_DEBUG_OBJECT (v4l2src, "getting src format enumerations");
71
72   /* format enumeration */
73   for (n = 0;; n++) {
74     format = g_new (struct v4l2_fmtdesc, 1);
75
76     format->index = n;
77     format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
78     if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_ENUM_FMT, format) < 0) {
79       if (errno == EINVAL) {
80         break;                  /* end of enumeration */
81       } else
82         goto failed;
83     }
84     GST_DEBUG_OBJECT (v4l2src, "got format %" GST_FOURCC_FORMAT,
85         GST_FOURCC_ARGS (format->pixelformat));
86
87     v4l2src->formats = g_slist_prepend (v4l2src->formats, format);
88   }
89   v4l2src->formats = g_slist_reverse (v4l2src->formats);
90   return TRUE;
91
92   /* ERRORS */
93 failed:
94   {
95     GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS,
96         (_("Failed to enumerate possible video formats device '%s' can work with"), v4l2src->v4l2object->videodev), ("Failed to get number %d in pixelformat enumeration for %s. (%d - %s)", n, v4l2src->v4l2object->videodev, errno, g_strerror (errno)));
97     g_free (format);
98     return FALSE;
99   }
100 }
101
102 /******************************************************
103  * gst_v4l2src_clear_format_list():
104  *   free list of supported capture formats
105  * return value: TRUE on success, FALSE on error
106  ******************************************************/
107 gboolean
108 gst_v4l2src_clear_format_list (GstV4l2Src * v4l2src)
109 {
110   g_slist_foreach (v4l2src->formats, (GFunc) g_free, NULL);
111   g_slist_free (v4l2src->formats);
112   v4l2src->formats = NULL;
113
114   return TRUE;
115 }
116
117 static GstStructure *
118 gst_v4l2src_probe_caps_for_format_and_size (GstV4l2Src * v4l2src,
119     guint32 pixelformat,
120     guint32 width, guint32 height, const GstStructure * template)
121 {
122   GstCaps *ret;
123   gint fd = v4l2src->v4l2object->video_fd;
124   struct v4l2_frmivalenum ival;
125   guint32 num, denom;
126   GstStructure *s;
127   GValue rate = { 0, };
128
129   ret = gst_caps_new_empty ();
130
131   memset (&ival, 0, sizeof (struct v4l2_frmivalenum));
132   ival.index = 0;
133   ival.pixel_format = pixelformat;
134   ival.width = width;
135   ival.height = height;
136
137   /* keep in mind that v4l2 gives us frame intervals (durations); we invert the
138    * fraction to get framerate */
139
140   if (ioctl (fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) < 0)
141     goto enum_frameintervals_failed;
142
143   if (ival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
144     GValue frac = { 0, };
145
146     g_value_init (&rate, GST_TYPE_LIST);
147
148     g_value_init (&frac, GST_TYPE_FRACTION);
149
150     do {
151       num = ival.discrete.numerator;
152       denom = ival.discrete.denominator;
153
154       if (num > G_MAXINT || denom > G_MAXINT) {
155         /* let us hope we don't get here... */
156         num >>= 1;
157         denom >>= 1;
158       }
159
160       gst_value_set_fraction (&frac, denom, num);
161       gst_value_list_append_value (&rate, &frac);
162
163       ival.index++;
164     } while (ioctl (fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) >= 0);
165   } else if (ival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
166     GValue frac = { 0, };
167     GValue step = { 0, };
168     GValue max = { 0, };
169
170     g_value_init (&rate, GST_TYPE_LIST);
171
172     g_value_init (&frac, GST_TYPE_FRACTION);
173     g_value_init (&step, GST_TYPE_FRACTION);
174     g_value_init (&max, GST_TYPE_FRACTION);
175
176     num = ival.stepwise.min.numerator;
177     denom = ival.stepwise.min.denominator;
178     if (num > G_MAXINT || denom > G_MAXINT) {
179       num >>= 1;
180       denom >>= 1;
181     }
182     gst_value_set_fraction (&frac, num, denom);
183
184     num = ival.stepwise.step.numerator;
185     denom = ival.stepwise.step.denominator;
186     if (num > G_MAXINT || denom > G_MAXINT) {
187       num >>= 1;
188       denom >>= 1;
189     }
190     /* since we only have gst_value_fraction_subtract and not add, negate the
191        numerator */
192     gst_value_set_fraction (&step, -num, denom);
193
194     num = ival.stepwise.max.numerator;
195     denom = ival.stepwise.max.denominator;
196     if (num > G_MAXINT || denom > G_MAXINT) {
197       num >>= 1;
198       denom >>= 1;
199     }
200     gst_value_set_fraction (&max, num, denom);
201
202     while (gst_value_compare (&frac, &max) == GST_VALUE_LESS_THAN) {
203       GValue frac = { 0, };
204       g_value_init (&frac, GST_TYPE_FRACTION);
205       /* invert */
206       gst_value_set_fraction (&frac,
207           gst_value_get_fraction_denominator (&frac),
208           gst_value_get_fraction_numerator (&frac));
209       gst_value_list_append_value (&rate, &frac);
210
211       if (!gst_value_fraction_subtract (&frac, &frac, &step)) {
212         GST_INFO_OBJECT (v4l2src, "could not step fraction!");
213         break;
214       }
215     }
216   } else if (ival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) {
217     guint32 maxnum, maxdenom;
218
219     g_value_init (&rate, GST_TYPE_FRACTION_RANGE);
220
221     num = ival.stepwise.min.numerator;
222     denom = ival.stepwise.min.denominator;
223     if (num > G_MAXINT || denom > G_MAXINT) {
224       num >>= 1;
225       denom >>= 1;
226     }
227
228     maxnum = ival.stepwise.step.numerator;
229     maxdenom = ival.stepwise.step.denominator;
230     if (maxnum > G_MAXINT || maxdenom > G_MAXINT) {
231       maxnum >>= 1;
232       maxdenom >>= 1;
233     }
234
235     gst_value_set_fraction_range_full (&rate, maxdenom, maxnum, denom, num);
236   } else {
237     goto unknown_type;
238   }
239
240   s = gst_structure_copy (template);
241   gst_structure_set (s, "width", G_TYPE_INT, (gint) width,
242       "height", G_TYPE_INT, (gint) height, NULL);
243   gst_structure_set_value (s, "framerate", &rate);
244   g_value_unset (&rate);
245   return s;
246
247 enum_frameintervals_failed:
248   {
249     GST_DEBUG_OBJECT (v4l2src,
250         "Failed to enumerate frame sizes for %" GST_FOURCC_FORMAT "@%ux%u",
251         GST_FOURCC_ARGS (pixelformat), width, height);
252     return NULL;
253   }
254 unknown_type:
255   {
256     /* I don't see how this is actually an error */
257     GST_WARNING_OBJECT (v4l2src,
258         "Unknown frame interval type at %" GST_FOURCC_FORMAT "@%ux%u: %u",
259         GST_FOURCC_ARGS (pixelformat), width, height, ival.type);
260     return NULL;
261   }
262 }
263
264 GstCaps *
265 gst_v4l2src_probe_caps_for_format (GstV4l2Src * v4l2src, guint32 pixelformat,
266     const GstStructure * template)
267 {
268   GstCaps *ret;
269   GstStructure *tmp;
270   gint fd = v4l2src->v4l2object->video_fd;
271   struct v4l2_frmsizeenum size;
272   guint32 w, h;
273
274   ret = gst_caps_new_empty ();
275
276   memset (&size, 0, sizeof (struct v4l2_frmsizeenum));
277   size.index = 0;
278   size.pixel_format = pixelformat;
279
280   if (ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &size) < 0)
281     goto enum_framesizes_failed;
282
283   if (size.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
284     do {
285       w = MIN (size.discrete.width, G_MAXINT);
286       h = MIN (size.discrete.height, G_MAXINT);
287
288       tmp = gst_v4l2src_probe_caps_for_format_and_size (v4l2src, pixelformat,
289           w, h, template);
290       if (tmp)
291         gst_caps_append_structure (ret, tmp);
292
293       size.index++;
294     } while (ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &size) >= 0);
295   } else if (size.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
296     for (w = size.stepwise.min_width, h = size.stepwise.min_height;
297         w < size.stepwise.max_width && h < size.stepwise.max_height;
298         w += size.stepwise.step_width, h += size.stepwise.step_height) {
299       if (w == 0 || h == 0)
300         continue;
301
302       tmp = gst_v4l2src_probe_caps_for_format_and_size (v4l2src, pixelformat,
303           w, h, template);
304       if (tmp)
305         gst_caps_append_structure (ret, tmp);
306     }
307   } else if (size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) {
308     guint32 maxw, maxh;
309
310     w = MAX (size.stepwise.min_width, 1);
311     h = MAX (size.stepwise.min_height, 1);
312     maxw = MIN (size.stepwise.max_width, G_MAXINT);
313     maxh = MIN (size.stepwise.max_height, G_MAXINT);
314
315     tmp = gst_v4l2src_probe_caps_for_format_and_size (v4l2src, pixelformat,
316         w, h, template);
317     if (tmp) {
318       gst_structure_set (tmp, "width", GST_TYPE_INT_RANGE, (gint) w,
319           (gint) maxw, "height", GST_TYPE_INT_RANGE, (gint) h, (gint) maxh,
320           NULL);
321       gst_caps_append_structure (ret, tmp);
322     }
323   } else {
324     goto unknown_type;
325   }
326
327   return ret;
328
329   /* ERRORS */
330 enum_framesizes_failed:
331   {
332     /* I don't see how this is actually an error */
333     GST_DEBUG_OBJECT (v4l2src,
334         "Failed to enumerate frame sizes for pixelformat %" GST_FOURCC_FORMAT
335         " (%s)", GST_FOURCC_ARGS (pixelformat), g_strerror (errno));
336     return NULL;
337   }
338 unknown_type:
339   {
340     GST_WARNING_OBJECT (v4l2src,
341         "Unknown frame sizeenum type for pixelformat %" GST_FOURCC_FORMAT
342         ": %u", GST_FOURCC_ARGS (pixelformat), size.type);
343     return NULL;
344   }
345 }
346
347 /******************************************************
348  * gst_v4l2src_queue_frame():
349  *   queue a frame for capturing
350  * return value: TRUE on success, FALSE on error
351  ******************************************************/
352 gboolean
353 gst_v4l2src_queue_frame (GstV4l2Src * v4l2src, guint i)
354 {
355   GST_LOG_OBJECT (v4l2src, "queueing frame %u", i);
356
357   if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_QBUF,
358           &v4l2src->pool->buffers[i].buffer) < 0)
359     goto qbuf_failed;
360
361   return TRUE;
362
363   /* ERRORS */
364 qbuf_failed:
365   {
366     GST_ELEMENT_ERROR (v4l2src, RESOURCE, WRITE,
367         (_("Could not exchange data with device '%s'."),
368             v4l2src->v4l2object->videodev),
369         ("Error queueing buffer %u on device %s. system error: %s", i,
370             v4l2src->v4l2object->videodev, g_strerror (errno)));
371     return FALSE;
372   }
373 }
374
375 /******************************************************
376  * gst_v4l2src_grab_frame ():
377  *   grab a frame for capturing
378  * return value: The captured frame number or -1 on error.
379  ******************************************************/
380 gint
381 gst_v4l2src_grab_frame (GstV4l2Src * v4l2src)
382 {
383 #define NUM_TRIALS 50
384   struct v4l2_buffer buffer;
385   gint32 trials = NUM_TRIALS;
386
387   memset (&buffer, 0x00, sizeof (buffer));
388   buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
389   buffer.memory = V4L2_MEMORY_MMAP;
390   while (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_DQBUF, &buffer) < 0) {
391
392     GST_LOG_OBJECT (v4l2src,
393         "problem grabbing frame %d (ix=%d), trials=%d, pool-ct=%d, buf.flags=%d",
394         buffer.sequence, buffer.index, trials, v4l2src->pool->refcount,
395         buffer.flags);
396
397     /* if the sync() got interrupted, we can retry */
398     switch (errno) {
399       case EAGAIN:
400         GST_WARNING_OBJECT (v4l2src,
401             "Non-blocking I/O has been selected using O_NONBLOCK and"
402             " no buffer was in the outgoing queue. device %s",
403             v4l2src->v4l2object->videodev);
404         break;
405       case EINVAL:
406         goto einval;
407       case ENOMEM:
408         goto enomem;
409       case EIO:
410         GST_INFO_OBJECT (v4l2src,
411             "VIDIOC_DQBUF failed due to an internal error."
412             " Can also indicate temporary problems like signal loss."
413             " Note the driver might dequeue an (empty) buffer despite"
414             " returning an error, or even stop capturing."
415             " device %s", v4l2src->v4l2object->videodev);
416         /* have we de-queued a buffer ? */
417         if (!(buffer.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))) {
418           /* this fails
419              if ((buffer.index >= 0) && (buffer.index < v4l2src->breq.count)) {
420              GST_DEBUG_OBJECT (v4l2src, "reenqueing buffer (ix=%ld)", buffer.index);
421              gst_v4l2src_queue_frame (v4l2src, buffer.index);
422              }
423              else {
424            */
425           GST_DEBUG_OBJECT (v4l2src, "reenqueing buffer");
426           if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_QBUF, &buffer) < 0) {
427             goto qbuf_failed;
428           }
429           /*} */
430         }
431         break;
432       case EINTR:
433         GST_WARNING_OBJECT (v4l2src,
434             "could not sync on a buffer on device %s",
435             v4l2src->v4l2object->videodev);
436         break;
437       default:
438         GST_WARNING_OBJECT (v4l2src,
439             "Grabbing frame got interrupted on %s. No expected reason.",
440             v4l2src->v4l2object->videodev);
441         break;
442     }
443
444     /* check nr. of attempts to capture */
445     if (--trials == -1) {
446       goto too_many_trials;
447     } else {
448       memset (&buffer, 0x00, sizeof (buffer));
449       buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
450       buffer.memory = V4L2_MEMORY_MMAP;
451     }
452   }
453
454   GST_LOG_OBJECT (v4l2src, "grabbed frame %d (ix=%d), pool-ct=%d",
455       buffer.sequence, buffer.index, v4l2src->pool->refcount);
456
457   return buffer.index;
458
459   /* ERRORS */
460 einval:
461   {
462     GST_ELEMENT_ERROR (v4l2src, RESOURCE, FAILED,
463         (_("Failed trying to get video frames from device '%s'."),
464             v4l2src->v4l2object->videodev),
465         (_("The buffer type is not supported, or the index is out of bounds,"
466                 " or no buffers have been allocated yet, or the userptr"
467                 " or length are invalid. device %s"),
468             v4l2src->v4l2object->videodev));
469     return -1;
470   }
471 enomem:
472   {
473     GST_ELEMENT_ERROR (v4l2src, RESOURCE, FAILED,
474         (_("Failed trying to get video frames from device '%s'. Not enough memory."), v4l2src->v4l2object->videodev), (_("insufficient memory to enqueue a user pointer buffer. device %s."), v4l2src->v4l2object->videodev));
475     return -1;
476   }
477 too_many_trials:
478   {
479     GST_ELEMENT_ERROR (v4l2src, RESOURCE, FAILED,
480         (_("Failed trying to get video frames from device '%s'."),
481             v4l2src->v4l2object->videodev),
482         (_("Failed after %d tries. device %s. system error: %s"),
483             NUM_TRIALS, v4l2src->v4l2object->videodev, g_strerror (errno)));
484     return -1;
485   }
486 qbuf_failed:
487   {
488     GST_ELEMENT_ERROR (v4l2src, RESOURCE, WRITE,
489         (_("Could not exchange data with device '%s'."),
490             v4l2src->v4l2object->videodev),
491         ("Error queueing buffer on device %s. system error: %s",
492             v4l2src->v4l2object->videodev, g_strerror (errno)));
493     return -1;
494   }
495 }
496
497
498 /******************************************************
499  * gst_v4l2src_set_capture():
500  *   set capture parameters
501  * return value: TRUE on success, FALSE on error
502  ******************************************************/
503 gboolean
504 gst_v4l2src_set_capture (GstV4l2Src * v4l2src, guint32 pixelformat,
505     guint32 width, guint32 height, guint fps_n, guint fps_d)
506 {
507   gint fd = v4l2src->v4l2object->video_fd;
508   struct v4l2_format format;
509   struct v4l2_streamparm stream;
510
511   DEBUG ("Setting capture format to %dx%d, format %" GST_FOURCC_FORMAT,
512       width, height, GST_FOURCC_ARGS (pixelformat));
513
514   GST_V4L2_CHECK_OPEN (v4l2src->v4l2object);
515   GST_V4L2_CHECK_NOT_ACTIVE (v4l2src->v4l2object);
516
517   memset (&format, 0x00, sizeof (struct v4l2_format));
518   format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
519
520   if (ioctl (fd, VIDIOC_G_FMT, &format) < 0)
521     goto get_fmt_failed;
522
523   format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
524   format.fmt.pix.width = width;
525   format.fmt.pix.height = height;
526   format.fmt.pix.pixelformat = pixelformat;
527   /* request whole frames; change when gstreamer supports interlaced video */
528   format.fmt.pix.field = V4L2_FIELD_INTERLACED;
529
530   if (ioctl (fd, VIDIOC_S_FMT, &format) < 0)
531     goto set_fmt_failed;
532
533   if (format.fmt.pix.width != width || format.fmt.pix.height != height)
534     goto invalid_dimensions;
535
536   if (format.fmt.pix.pixelformat != pixelformat)
537     goto invalid_pixelformat;
538
539   memset (&stream, 0x00, sizeof (struct v4l2_streamparm));
540   stream.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
541   if (ioctl (fd, VIDIOC_G_PARM, &stream) < 0)
542     goto get_parm_failed;
543
544   /* Note: V4L2 gives us the frame interval, we need the frame rate */
545   stream.parm.capture.timeperframe.numerator = fps_d;
546   stream.parm.capture.timeperframe.denominator = fps_n;
547
548   if (ioctl (fd, VIDIOC_S_PARM, &stream) < 0)
549     goto set_parm_failed;
550
551
552   /* FIXME: better test for fraction equality */
553   if (stream.parm.capture.timeperframe.numerator != fps_d
554       || stream.parm.capture.timeperframe.denominator != fps_n)
555     goto invalid_framerate;
556
557   return TRUE;
558
559   /* ERRORS */
560 get_fmt_failed:
561   {
562     GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS,
563         (_("Device '%s' does not support video capture"),
564             v4l2src->v4l2object->videodev),
565         ("Call to G_FMT failed: (%s)", g_strerror (errno)));
566     return FALSE;
567   }
568 set_fmt_failed:
569   {
570     GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS,
571         (_("Device '%s' cannot capture at %dx%d"),
572             v4l2src->v4l2object->videodev, width, height),
573         ("Call to S_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
574             GST_FOURCC_ARGS (pixelformat), width, height, g_strerror (errno)));
575     return FALSE;
576   }
577 invalid_dimensions:
578   {
579     GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS,
580         (_("Device '%s' cannot capture at %dx%d"),
581             v4l2src->v4l2object->videodev, width, height),
582         ("Tried to capture at %dx%d, but device returned size %dx%d",
583             width, height, format.fmt.pix.width, format.fmt.pix.height));
584     return FALSE;
585   }
586 invalid_pixelformat:
587   {
588     GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS,
589         (_("Device '%s' cannot capture in the specified format"),
590             v4l2src->v4l2object->videodev),
591         ("Tried to capture in %" GST_FOURCC_FORMAT
592             ", but device returned format" " %" GST_FOURCC_FORMAT,
593             GST_FOURCC_ARGS (pixelformat),
594             GST_FOURCC_ARGS (format.fmt.pix.pixelformat)));
595     return FALSE;
596   }
597 get_parm_failed:
598   {
599     GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS,
600         (_("Could not get parameters on device '%s'"),
601             v4l2src->v4l2object->videodev), GST_ERROR_SYSTEM);
602     return FALSE;
603   }
604 set_parm_failed:
605   {
606     GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS,
607         (_("Could not set parameters on device '%s'"),
608             v4l2src->v4l2object->videodev), GST_ERROR_SYSTEM);
609     return FALSE;
610   }
611 invalid_framerate:
612   {
613     GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS,
614         (_("Device '%s' cannot capture at %d/%d frames per second"),
615             v4l2src->v4l2object->videodev, fps_n, fps_d),
616         ("Tried to capture at %d/%d fps, but device returned %d/%d fps",
617             fps_n, fps_d, stream.parm.capture.timeperframe.denominator,
618             stream.parm.capture.timeperframe.numerator));
619     return FALSE;
620   }
621 }
622
623 /******************************************************
624  * gst_v4l2src_capture_init():
625  *   initialize the capture system
626  * return value: TRUE on success, FALSE on error
627  ******************************************************/
628 gboolean
629 gst_v4l2src_capture_init (GstV4l2Src * v4l2src)
630 {
631   gint n;
632   GstV4l2Buffer *buffer;
633   gint fd = v4l2src->v4l2object->video_fd;
634   struct v4l2_requestbuffers breq;
635
636   memset (&breq, 0, sizeof (struct v4l2_requestbuffers));
637
638   GST_DEBUG_OBJECT (v4l2src, "initializing the capture system");
639
640   GST_V4L2_CHECK_OPEN (v4l2src->v4l2object);
641   GST_V4L2_CHECK_NOT_ACTIVE (v4l2src->v4l2object);
642
643   if (v4l2src->v4l2object->vcap.capabilities & V4L2_CAP_STREAMING) {
644     breq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
645     breq.count = v4l2src->num_buffers;
646
647     breq.memory = V4L2_MEMORY_MMAP;
648     if (ioctl (fd, VIDIOC_REQBUFS, &breq) < 0)
649       goto reqbufs_failed;
650
651     if (breq.count < GST_V4L2_MIN_BUFFERS)
652       goto no_buffers;
653
654     if (v4l2src->num_buffers != breq.count) {
655       v4l2src->num_buffers = breq.count;
656       g_object_notify (G_OBJECT (v4l2src), "queue-size");
657     }
658
659     GST_INFO_OBJECT (v4l2src, "Got %d buffers of size %d kB",
660         breq.count, v4l2src->frame_byte_size / 1024);
661
662     /* Map the buffers */
663     GST_LOG_OBJECT (v4l2src, "initiating buffer pool");
664
665     v4l2src->pool = g_new (GstV4l2BufferPool, 1);
666     gst_atomic_int_set (&v4l2src->pool->refcount, 1);
667     v4l2src->pool->video_fd = fd;
668     v4l2src->pool->buffer_count = v4l2src->num_buffers;
669     v4l2src->pool->buffers = g_new0 (GstV4l2Buffer, v4l2src->num_buffers);
670
671     for (n = 0; n < v4l2src->num_buffers; n++) {
672       buffer = &v4l2src->pool->buffers[n];
673
674       gst_atomic_int_set (&buffer->refcount, 1);
675       buffer->pool = v4l2src->pool;
676       memset (&buffer->buffer, 0x00, sizeof (buffer->buffer));
677       buffer->buffer.index = n;
678       buffer->buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
679       buffer->buffer.memory = V4L2_MEMORY_MMAP;
680
681       if (ioctl (fd, VIDIOC_QUERYBUF, &buffer->buffer) < 0)
682         goto querybuf_failed;
683
684       buffer->start = mmap (0, buffer->buffer.length, PROT_READ | PROT_WRITE,
685           MAP_SHARED, fd, buffer->buffer.m.offset);
686
687       if (buffer->start == MAP_FAILED)
688         goto mmap_failed;
689
690       buffer->length = buffer->buffer.length;
691       if (!gst_v4l2src_queue_frame (v4l2src, n))
692         goto queue_failed;
693     }
694
695     GST_INFO_OBJECT (v4l2src, "capturing buffers via mmap()");
696     v4l2src->use_mmap = TRUE;
697   } else if (v4l2src->v4l2object->vcap.capabilities & V4L2_CAP_READWRITE) {
698     GST_INFO_OBJECT (v4l2src, "capturing buffers via read()");
699     v4l2src->use_mmap = FALSE;
700     v4l2src->pool = NULL;
701   } else {
702     goto no_supported_capture_method;
703   }
704
705   GST_V4L2_SET_ACTIVE (v4l2src->v4l2object);
706
707   return TRUE;
708
709   /* ERRORS */
710 reqbufs_failed:
711   {
712     GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
713         (_("Could not get buffers from device '%s'."),
714             v4l2src->v4l2object->videodev),
715         ("error requesting %d buffers: %s",
716             v4l2src->num_buffers, g_strerror (errno)));
717     return FALSE;
718   }
719 no_buffers:
720   {
721     GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
722         (_("Could not get enough buffers from device '%s'."),
723             v4l2src->v4l2object->videodev),
724         ("we received %d from device '%s', we want at least %d",
725             breq.count, v4l2src->v4l2object->videodev, GST_V4L2_MIN_BUFFERS));
726     return FALSE;
727   }
728 querybuf_failed:
729   {
730     GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
731         (_("Could not retrieve buffer from device '%s'"),
732             v4l2src->v4l2object->videodev),
733         ("Failed QUERYBUF: %s", g_strerror (errno)));
734     gst_v4l2src_capture_deinit (v4l2src);
735     return FALSE;
736   }
737 mmap_failed:
738   {
739     GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
740         (_("Could not map memory in device '%s'."),
741             v4l2src->v4l2object->videodev),
742         ("mmap failed: %s", g_strerror (errno)));
743     gst_v4l2src_capture_deinit (v4l2src);
744     /* CHECKME: buffer->start = 0; */
745     return FALSE;
746   }
747 queue_failed:
748   {
749     GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
750         (_("Could not enqueue buffers in device '%s'."),
751             v4l2src->v4l2object->videodev),
752         ("enqueing buffer %d/%d failed: %s",
753             n, v4l2src->num_buffers, g_strerror (errno)));
754     gst_v4l2src_capture_deinit (v4l2src);
755     return FALSE;
756   }
757 no_supported_capture_method:
758   {
759     GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
760         (_("The driver of device '%s' does not support any known capture "
761                 "method."), v4l2src->v4l2object->videodev), (NULL));
762     return FALSE;
763   }
764 }
765
766
767 /******************************************************
768  * gst_v4l2src_capture_start():
769  *   start streaming capture
770  * return value: TRUE on success, FALSE on error
771  ******************************************************/
772 gboolean
773 gst_v4l2src_capture_start (GstV4l2Src * v4l2src)
774 {
775   gint type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
776
777   GST_DEBUG_OBJECT (v4l2src, "starting the capturing");
778   //GST_V4L2_CHECK_OPEN (v4l2src->v4l2object);
779   GST_V4L2_CHECK_ACTIVE (v4l2src->v4l2object);
780
781   v4l2src->quit = FALSE;
782
783   if (v4l2src->use_mmap) {
784     if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_STREAMON, &type) < 0)
785       goto streamon_failed;
786   }
787
788   v4l2src->is_capturing = TRUE;
789
790   return TRUE;
791
792   /* ERRORS */
793 streamon_failed:
794   {
795     GST_ELEMENT_ERROR (v4l2src, RESOURCE, OPEN_READ,
796         (_("Error starting streaming capture from device '%s'."),
797             v4l2src->v4l2object->videodev), GST_ERROR_SYSTEM);
798     return FALSE;
799   }
800 }
801
802 /******************************************************
803  * gst_v4l2src_capture_stop():
804  *   stop streaming capture
805  * return value: TRUE on success, FALSE on error
806  ******************************************************/
807 gboolean
808 gst_v4l2src_capture_stop (GstV4l2Src * v4l2src)
809 {
810   gint type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
811
812   GST_DEBUG_OBJECT (v4l2src, "stopping capturing");
813
814   if (!GST_V4L2_IS_OPEN (v4l2src->v4l2object)) {
815     goto done;
816   }
817   if (!GST_V4L2_IS_ACTIVE (v4l2src->v4l2object)) {
818     goto done;
819   }
820
821   if (v4l2src->use_mmap) {
822     /* we actually need to sync on all queued buffers but not
823      * on the non-queued ones */
824     if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_STREAMOFF, &type) < 0)
825       goto streamoff_failed;
826   }
827
828 done:
829
830   /* make an optional pending wait stop */
831   v4l2src->quit = TRUE;
832   v4l2src->is_capturing = FALSE;
833
834   return TRUE;
835
836   /* ERRORS */
837 streamoff_failed:
838   {
839     GST_ELEMENT_ERROR (v4l2src, RESOURCE, CLOSE,
840         (_("Error stopping streaming capture from device '%s'."),
841             v4l2src->v4l2object->videodev), GST_ERROR_SYSTEM);
842     return FALSE;
843   }
844 }
845
846 static void
847 gst_v4l2src_buffer_pool_free (GstV4l2BufferPool * pool, gboolean do_close)
848 {
849   guint i;
850
851   for (i = 0; i < pool->buffer_count; i++) {
852     gst_atomic_int_set (&pool->buffers[i].refcount, 0);
853     munmap (pool->buffers[i].start, pool->buffers[i].length);
854   }
855   g_free (pool->buffers);
856   gst_atomic_int_set (&pool->refcount, 0);
857   if (do_close)
858     close (pool->video_fd);
859   g_free (pool);
860 }
861
862 /******************************************************
863  * gst_v4l2src_capture_deinit():
864  *   deinitialize the capture system
865  * return value: TRUE on success, FALSE on error
866  ******************************************************/
867 gboolean
868 gst_v4l2src_capture_deinit (GstV4l2Src * v4l2src)
869 {
870   gint i;
871   gboolean try_reinit = FALSE;
872
873   GST_DEBUG_OBJECT (v4l2src, "deinitting capture system");
874
875   if (!GST_V4L2_IS_OPEN (v4l2src->v4l2object)) {
876     return TRUE;
877   }
878   if (!GST_V4L2_IS_ACTIVE (v4l2src->v4l2object)) {
879     return TRUE;
880   }
881
882   if (v4l2src->pool) {
883     /* free the buffers */
884     for (i = 0; i < v4l2src->num_buffers; i++) {
885       if (g_atomic_int_dec_and_test (&v4l2src->pool->buffers[i].refcount)) {
886         if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_DQBUF,
887                 &v4l2src->pool->buffers[i].buffer) < 0) {
888           GST_DEBUG_OBJECT (v4l2src,
889               "Could not dequeue buffer on uninitialization."
890               "system error: %s. Will try reinit instead", g_strerror (errno));
891           try_reinit = TRUE;
892         }
893       }
894     }
895     if (g_atomic_int_dec_and_test (&v4l2src->pool->refcount)) {
896       /* we're last thing that used all this */
897       gst_v4l2src_buffer_pool_free (v4l2src->pool, FALSE);
898     }
899     v4l2src->pool = NULL;
900     /* This is our second try to get the buffers dequeued.
901      * Since buffers are normally dequeued automatically when capturing is
902      * stopped, but may be enqueued before capturing has started, you get
903      * a problem when you abort before capturing started but have enqueued
904      * the buffers. We avoid that by starting/stopping capturing once so
905      * they get auto-dequeued.
906      */
907     if (try_reinit) {
908       gst_v4l2src_capture_start (v4l2src);
909       if (!gst_v4l2src_capture_stop (v4l2src)) {
910         /* stop throws an element-error on failure */
911         GST_WARNING_OBJECT (v4l2src, "failed reinit device");
912         return FALSE;
913       }
914     }
915   }
916
917   GST_V4L2_SET_INACTIVE (v4l2src->v4l2object);
918
919   return TRUE;
920 }
921
922 /*
923  */
924 gboolean
925 gst_v4l2src_get_size_limits (GstV4l2Src * v4l2src,
926     struct v4l2_fmtdesc * format,
927     gint * min_w, gint * max_w, gint * min_h, gint * max_h)
928 {
929
930   struct v4l2_format fmt;
931
932   GST_LOG_OBJECT (v4l2src,
933       "getting size limits with format %" GST_FOURCC_FORMAT,
934       GST_FOURCC_ARGS (format->pixelformat));
935
936   /* get size delimiters */
937   memset (&fmt, 0, sizeof (fmt));
938   fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
939   fmt.fmt.pix.width = 0;
940   fmt.fmt.pix.height = 0;
941   fmt.fmt.pix.pixelformat = format->pixelformat;
942   fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
943   if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_TRY_FMT, &fmt) < 0) {
944     GST_DEBUG_OBJECT (v4l2src, "failed to get min size: %s",
945         g_strerror (errno));
946     return FALSE;
947   }
948
949   if (min_w)
950     *min_w = fmt.fmt.pix.width;
951   if (min_h)
952     *min_h = fmt.fmt.pix.height;
953
954   GST_LOG_OBJECT (v4l2src,
955       "got min size %dx%d", fmt.fmt.pix.width, fmt.fmt.pix.height);
956
957   fmt.fmt.pix.width = GST_V4L2_MAX_SIZE;
958   fmt.fmt.pix.height = GST_V4L2_MAX_SIZE;
959   if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_TRY_FMT, &fmt) < 0) {
960     GST_DEBUG_OBJECT (v4l2src, "failed to get max size: %s",
961         g_strerror (errno));
962     return FALSE;
963   }
964
965   if (max_w)
966     *max_w = fmt.fmt.pix.width;
967   if (max_h)
968     *max_h = fmt.fmt.pix.height;
969
970   GST_LOG_OBJECT (v4l2src,
971       "got max size %dx%d", fmt.fmt.pix.width, fmt.fmt.pix.height);
972
973   return TRUE;
974 }
975
976 #define GST_TYPE_V4L2SRC_BUFFER (gst_v4l2src_buffer_get_type())
977 #define GST_IS_V4L2SRC_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L2SRC_BUFFER))
978 #define GST_V4L2SRC_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2SRC_BUFFER, GstV4l2SrcBuffer))
979
980 typedef struct _GstV4l2SrcBuffer
981 {
982   GstBuffer buffer;
983
984   GstV4l2Buffer *buf;
985 } GstV4l2SrcBuffer;
986
987 static void gst_v4l2src_buffer_class_init (gpointer g_class,
988     gpointer class_data);
989 static void gst_v4l2src_buffer_init (GTypeInstance * instance,
990     gpointer g_class);
991 static void gst_v4l2src_buffer_finalize (GstV4l2SrcBuffer * v4l2src_buffer);
992
993 GType
994 gst_v4l2src_buffer_get_type (void)
995 {
996   static GType _gst_v4l2src_buffer_type;
997
998   if (G_UNLIKELY (_gst_v4l2src_buffer_type == 0)) {
999     static const GTypeInfo v4l2src_buffer_info = {
1000       sizeof (GstBufferClass),
1001       NULL,
1002       NULL,
1003       gst_v4l2src_buffer_class_init,
1004       NULL,
1005       NULL,
1006       sizeof (GstV4l2SrcBuffer),
1007       0,
1008       gst_v4l2src_buffer_init,
1009       NULL
1010     };
1011     _gst_v4l2src_buffer_type = g_type_register_static (GST_TYPE_BUFFER,
1012         "GstV4l2SrcBuffer", &v4l2src_buffer_info, 0);
1013   }
1014   return _gst_v4l2src_buffer_type;
1015 }
1016
1017 static void
1018 gst_v4l2src_buffer_class_init (gpointer g_class, gpointer class_data)
1019 {
1020   GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
1021
1022   mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
1023       gst_v4l2src_buffer_finalize;
1024 }
1025
1026 static void
1027 gst_v4l2src_buffer_init (GTypeInstance * instance, gpointer g_class)
1028 {
1029
1030 }
1031
1032 static void
1033 gst_v4l2src_buffer_finalize (GstV4l2SrcBuffer * v4l2src_buffer)
1034 {
1035   GstV4l2Buffer *buf = v4l2src_buffer->buf;
1036
1037   if (buf) {
1038     GST_LOG ("freeing buffer %p (nr. %d)", buf, buf->buffer.index);
1039
1040     if (!g_atomic_int_dec_and_test (&buf->refcount)) {
1041       /* we're still in use, add to queue again
1042        * note: this might fail because the device is already stopped (race)
1043        */
1044       if (ioctl (buf->pool->video_fd, VIDIOC_QBUF, &buf->buffer) < 0)
1045         GST_INFO ("readding to queue failed, assuming video device is stopped");
1046     }
1047     if (g_atomic_int_dec_and_test (&buf->pool->refcount)) {
1048       /* we're last thing that used all this */
1049       gst_v4l2src_buffer_pool_free (buf->pool, TRUE);
1050     }
1051   }
1052 }
1053
1054 /* Create a V4l2Src buffer from our mmap'd data area */
1055 GstBuffer *
1056 gst_v4l2src_buffer_new (GstV4l2Src * v4l2src, guint size, guint8 * data,
1057     GstV4l2Buffer * srcbuf)
1058 {
1059   GstBuffer *buf;
1060   GstClockTime timestamp;
1061   GstClock *clock;
1062
1063   if (data == NULL) {
1064     buf = gst_buffer_new_and_alloc (size);
1065   } else {
1066     buf = (GstBuffer *) gst_mini_object_new (GST_TYPE_V4L2SRC_BUFFER);
1067     GST_BUFFER_DATA (buf) = data;
1068     GST_V4L2SRC_BUFFER (buf)->buf = srcbuf;
1069     GST_LOG_OBJECT (v4l2src,
1070         "creating buffer  %p (nr. %d)", srcbuf, srcbuf->buffer.index);
1071   }
1072   GST_BUFFER_SIZE (buf) = size;
1073
1074   GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
1075
1076   /* timestamps, LOCK to get clock and base time. */
1077   GST_OBJECT_LOCK (v4l2src);
1078   if ((clock = GST_ELEMENT_CLOCK (v4l2src))) {
1079     /* we have a clock, get base time and ref clock */
1080     timestamp = GST_ELEMENT (v4l2src)->base_time;
1081     gst_object_ref (clock);
1082   } else {
1083     /* no clock, can't set timestamps */
1084     timestamp = GST_CLOCK_TIME_NONE;
1085   }
1086   GST_OBJECT_UNLOCK (v4l2src);
1087
1088   if (clock) {
1089     /* the time now is the time of the clock minus the base time */
1090     timestamp = gst_clock_get_time (clock) - timestamp;
1091     gst_object_unref (clock);
1092   }
1093
1094   /* FIXME: use the timestamp from the buffer itself! */
1095   GST_BUFFER_TIMESTAMP (buf) = timestamp;
1096
1097   /* offsets */
1098   GST_BUFFER_OFFSET (buf) = v4l2src->offset++;
1099   GST_BUFFER_OFFSET_END (buf) = v4l2src->offset;
1100
1101   /* the negotiate() method already set caps on the source pad */
1102   gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (v4l2src)));
1103
1104   return buf;
1105 }