v4l2: Let the device object manage the pool
[platform/upstream/gstreamer.git] / sys / v4l2 / gstv4l2src.c
1 /* GStreamer
2  *
3  * Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
4  *               2006 Edgard Lima <edgard.lima@indt.org.br>
5  *
6  * gstv4l2src.c: Video4Linux2 source element
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 /**
25  * SECTION:element-v4l2src
26  *
27  * v4l2src can be used to capture video from v4l2 devices, like webcams and tv
28  * cards.
29  *
30  * <refsect2>
31  * <title>Example launch lines</title>
32  * |[
33  * gst-launch v4l2src ! xvimagesink
34  * ]| This pipeline shows the video captured from /dev/video0 tv card and for
35  * webcams.
36  * |[
37  * gst-launch v4l2src ! jpegdec ! xvimagesink
38  * ]| This pipeline shows the video captured from a webcam that delivers jpeg
39  * images.
40  * </refsect2>
41  */
42
43 #ifdef HAVE_CONFIG_H
44 #include <config.h>
45 #endif
46
47 #undef HAVE_XVIDEO
48
49 #include <string.h>
50 #include <sys/time.h>
51 #include "v4l2src_calls.h"
52 #include <unistd.h>
53
54 #include "gstv4l2colorbalance.h"
55 #include "gstv4l2tuner.h"
56 #ifdef HAVE_XVIDEO
57 #include "gstv4l2xoverlay.h"
58 #endif
59 #include "gstv4l2vidorient.h"
60
61 #include "gst/gst-i18n-plugin.h"
62
63 GST_DEBUG_CATEGORY (v4l2src_debug);
64 #define GST_CAT_DEFAULT v4l2src_debug
65
66 #define PROP_DEF_QUEUE_SIZE         2
67 #define PROP_DEF_ALWAYS_COPY        TRUE
68 #define PROP_DEF_DECIMATE           1
69
70 #define DEFAULT_PROP_DEVICE   "/dev/video0"
71
72 enum
73 {
74   PROP_0,
75   V4L2_STD_OBJECT_PROPS,
76   PROP_QUEUE_SIZE,
77   PROP_ALWAYS_COPY,
78   PROP_DECIMATE
79 };
80
81 GST_IMPLEMENT_V4L2_PROBE_METHODS (GstV4l2SrcClass, gst_v4l2src);
82 GST_IMPLEMENT_V4L2_COLOR_BALANCE_METHODS (GstV4l2Src, gst_v4l2src);
83 GST_IMPLEMENT_V4L2_TUNER_METHODS (GstV4l2Src, gst_v4l2src);
84 #ifdef HAVE_XVIDEO
85 GST_IMPLEMENT_V4L2_XOVERLAY_METHODS (GstV4l2Src, gst_v4l2src);
86 #endif
87 GST_IMPLEMENT_V4L2_VIDORIENT_METHODS (GstV4l2Src, gst_v4l2src);
88
89 static void gst_v4l2src_uri_handler_init (gpointer g_iface,
90     gpointer iface_data);
91
92 #define gst_v4l2src_parent_class parent_class
93 G_DEFINE_TYPE_WITH_CODE (GstV4l2Src, gst_v4l2src, GST_TYPE_PUSH_SRC,
94     G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, gst_v4l2src_uri_handler_init);
95     G_IMPLEMENT_INTERFACE (GST_TYPE_TUNER, gst_v4l2src_tuner_interface_init);
96 #ifdef HAVE_XVIDEO
97     /* FIXME: does GstXOverlay for v4l2src make sense in a GStreamer context? */
98     G_IMPLEMENT_INTERFACE (GST_TYPE_X_OVERLAY,
99         gst_v4l2src_xoverlay_interface_init);
100 #endif
101     G_IMPLEMENT_INTERFACE (GST_TYPE_COLOR_BALANCE,
102         gst_v4l2src_color_balance_interface_init);
103     G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_ORIENTATION,
104         gst_v4l2src_video_orientation_interface_init);
105     G_IMPLEMENT_INTERFACE (GST_TYPE_PROPERTY_PROBE,
106         gst_v4l2src_property_probe_interface_init));
107
108 static void gst_v4l2src_dispose (GObject * object);
109 static void gst_v4l2src_finalize (GstV4l2Src * v4l2src);
110
111 /* element methods */
112 static GstStateChangeReturn gst_v4l2src_change_state (GstElement * element,
113     GstStateChange transition);
114
115 /* basesrc methods */
116 static gboolean gst_v4l2src_start (GstBaseSrc * src);
117 static gboolean gst_v4l2src_unlock (GstBaseSrc * src);
118 static gboolean gst_v4l2src_unlock_stop (GstBaseSrc * src);
119 static gboolean gst_v4l2src_stop (GstBaseSrc * src);
120 static gboolean gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps);
121 static GstCaps *gst_v4l2src_get_caps (GstBaseSrc * src, GstCaps * filter);
122 static gboolean gst_v4l2src_query (GstBaseSrc * bsrc, GstQuery * query);
123 static GstFlowReturn gst_v4l2src_create (GstPushSrc * src, GstBuffer ** out);
124 static void gst_v4l2src_fixate (GstBaseSrc * basesrc, GstCaps * caps);
125 static gboolean gst_v4l2src_negotiate (GstBaseSrc * basesrc);
126
127 static void gst_v4l2src_set_property (GObject * object, guint prop_id,
128     const GValue * value, GParamSpec * pspec);
129 static void gst_v4l2src_get_property (GObject * object, guint prop_id,
130     GValue * value, GParamSpec * pspec);
131
132 /* get_frame io methods */
133 static GstFlowReturn
134 gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf);
135 static GstFlowReturn
136 gst_v4l2src_get_mmap (GstV4l2Src * v4l2src, GstBuffer ** buf);
137
138 static void
139 gst_v4l2src_class_init (GstV4l2SrcClass * klass)
140 {
141   GObjectClass *gobject_class;
142   GstElementClass *element_class;
143   GstBaseSrcClass *basesrc_class;
144   GstPushSrcClass *pushsrc_class;
145
146   gobject_class = G_OBJECT_CLASS (klass);
147   element_class = GST_ELEMENT_CLASS (klass);
148   basesrc_class = GST_BASE_SRC_CLASS (klass);
149   pushsrc_class = GST_PUSH_SRC_CLASS (klass);
150
151   gobject_class->dispose = gst_v4l2src_dispose;
152   gobject_class->finalize = (GObjectFinalizeFunc) gst_v4l2src_finalize;
153   gobject_class->set_property = gst_v4l2src_set_property;
154   gobject_class->get_property = gst_v4l2src_get_property;
155
156   element_class->change_state = gst_v4l2src_change_state;
157
158   gst_v4l2_object_install_properties_helper (gobject_class,
159       DEFAULT_PROP_DEVICE);
160   g_object_class_install_property (gobject_class, PROP_QUEUE_SIZE,
161       g_param_spec_uint ("queue-size", "Queue size",
162           "Number of buffers to be enqueud in the driver in streaming mode",
163           GST_V4L2_MIN_BUFFERS, GST_V4L2_MAX_BUFFERS, PROP_DEF_QUEUE_SIZE,
164           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
165   g_object_class_install_property (gobject_class, PROP_ALWAYS_COPY,
166       g_param_spec_boolean ("always-copy", "Always Copy",
167           "If the buffer will or not be used directly from mmap",
168           PROP_DEF_ALWAYS_COPY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
169   /**
170    * GstV4l2Src:decimate
171    *
172    * Only use every nth frame
173    *
174    * Since: 0.10.26
175    */
176   g_object_class_install_property (gobject_class, PROP_DECIMATE,
177       g_param_spec_int ("decimate", "Decimate",
178           "Only use every nth frame", 1, G_MAXINT,
179           PROP_DEF_DECIMATE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
180
181   gst_element_class_set_details_simple (element_class,
182       "Video (video4linux2) Source", "Source/Video",
183       "Reads frames from a Video4Linux2 device",
184       "Edgard Lima <edgard.lima@indt.org.br>, "
185       "Stefan Kost <ensonic@users.sf.net>");
186
187   gst_element_class_add_pad_template
188       (element_class,
189       gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
190           gst_v4l2_object_get_all_caps ()));
191
192   basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_v4l2src_get_caps);
193   basesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_v4l2src_set_caps);
194   basesrc_class->start = GST_DEBUG_FUNCPTR (gst_v4l2src_start);
195   basesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_v4l2src_unlock);
196   basesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_v4l2src_unlock_stop);
197   basesrc_class->stop = GST_DEBUG_FUNCPTR (gst_v4l2src_stop);
198   basesrc_class->query = GST_DEBUG_FUNCPTR (gst_v4l2src_query);
199   basesrc_class->fixate = GST_DEBUG_FUNCPTR (gst_v4l2src_fixate);
200   basesrc_class->negotiate = GST_DEBUG_FUNCPTR (gst_v4l2src_negotiate);
201
202   pushsrc_class->create = GST_DEBUG_FUNCPTR (gst_v4l2src_create);
203
204   klass->v4l2_class_devices = NULL;
205
206   GST_DEBUG_CATEGORY_INIT (v4l2src_debug, "v4l2src", 0, "V4L2 source element");
207 }
208
209 static void
210 gst_v4l2src_init (GstV4l2Src * v4l2src)
211 {
212   /* fixme: give an update_fps_function */
213   v4l2src->v4l2object = gst_v4l2_object_new (GST_ELEMENT (v4l2src),
214       V4L2_BUF_TYPE_VIDEO_CAPTURE, DEFAULT_PROP_DEVICE,
215       gst_v4l2_get_input, gst_v4l2_set_input, NULL);
216
217   /* number of buffers requested */
218   v4l2src->v4l2object->num_buffers = PROP_DEF_QUEUE_SIZE;
219
220   v4l2src->always_copy = PROP_DEF_ALWAYS_COPY;
221   v4l2src->decimate = PROP_DEF_DECIMATE;
222
223   gst_base_src_set_format (GST_BASE_SRC (v4l2src), GST_FORMAT_TIME);
224   gst_base_src_set_live (GST_BASE_SRC (v4l2src), TRUE);
225 }
226
227 static void
228 gst_v4l2src_dispose (GObject * object)
229 {
230   GstV4l2Src *v4l2src = GST_V4L2SRC (object);
231
232   if (v4l2src->probed_caps) {
233     gst_caps_unref (v4l2src->probed_caps);
234   }
235
236   G_OBJECT_CLASS (parent_class)->dispose (object);
237 }
238
239
240 static void
241 gst_v4l2src_finalize (GstV4l2Src * v4l2src)
242 {
243   gst_v4l2_object_destroy (v4l2src->v4l2object);
244
245   G_OBJECT_CLASS (parent_class)->finalize ((GObject *) (v4l2src));
246 }
247
248
249 static void
250 gst_v4l2src_set_property (GObject * object,
251     guint prop_id, const GValue * value, GParamSpec * pspec)
252 {
253   GstV4l2Src *v4l2src = GST_V4L2SRC (object);
254
255   if (!gst_v4l2_object_set_property_helper (v4l2src->v4l2object,
256           prop_id, value, pspec)) {
257     switch (prop_id) {
258       case PROP_QUEUE_SIZE:
259         v4l2src->v4l2object->num_buffers = g_value_get_uint (value);
260         break;
261       case PROP_ALWAYS_COPY:
262         v4l2src->always_copy = g_value_get_boolean (value);
263         break;
264       case PROP_DECIMATE:
265         v4l2src->decimate = g_value_get_int (value);
266         break;
267       default:
268         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
269         break;
270     }
271   }
272 }
273
274 static void
275 gst_v4l2src_get_property (GObject * object,
276     guint prop_id, GValue * value, GParamSpec * pspec)
277 {
278   GstV4l2Src *v4l2src = GST_V4L2SRC (object);
279
280   if (!gst_v4l2_object_get_property_helper (v4l2src->v4l2object,
281           prop_id, value, pspec)) {
282     switch (prop_id) {
283       case PROP_QUEUE_SIZE:
284         g_value_set_uint (value, v4l2src->v4l2object->num_buffers);
285         break;
286       case PROP_ALWAYS_COPY:
287         g_value_set_boolean (value, v4l2src->always_copy);
288         break;
289       case PROP_DECIMATE:
290         g_value_set_int (value, v4l2src->decimate);
291         break;
292       default:
293         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
294         break;
295     }
296   }
297 }
298
299 /* this function is a bit of a last resort */
300 static void
301 gst_v4l2src_fixate (GstBaseSrc * basesrc, GstCaps * caps)
302 {
303   GstStructure *structure;
304   gint i;
305
306   GST_DEBUG_OBJECT (basesrc, "fixating caps %" GST_PTR_FORMAT, caps);
307
308   for (i = 0; i < gst_caps_get_size (caps); ++i) {
309     const GValue *v;
310
311     structure = gst_caps_get_structure (caps, i);
312
313     /* We are fixating to a resonable 320x200 resolution
314        and the maximum framerate resolution for that size */
315     gst_structure_fixate_field_nearest_int (structure, "width", 320);
316     gst_structure_fixate_field_nearest_int (structure, "height", 200);
317     gst_structure_fixate_field_nearest_fraction (structure, "framerate",
318         G_MAXINT, 1);
319
320     v = gst_structure_get_value (structure, "format");
321     if (v && G_VALUE_TYPE (v) != G_TYPE_STRING) {
322       const gchar *format;
323
324       g_return_if_fail (G_VALUE_TYPE (v) == GST_TYPE_LIST);
325
326       format = g_value_get_string (gst_value_list_get_value (v, 0));
327       gst_structure_set (structure, "format", G_TYPE_STRING, format, NULL);
328     }
329   }
330
331   GST_DEBUG_OBJECT (basesrc, "fixated caps %" GST_PTR_FORMAT, caps);
332 }
333
334
335 static gboolean
336 gst_v4l2src_negotiate (GstBaseSrc * basesrc)
337 {
338   GstCaps *thiscaps;
339   GstCaps *caps = NULL;
340   GstCaps *peercaps = NULL;
341   gboolean result = FALSE;
342
343   /* first see what is possible on our source pad */
344   thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc), NULL);
345   GST_DEBUG_OBJECT (basesrc, "caps of src: %" GST_PTR_FORMAT, thiscaps);
346   LOG_CAPS (basesrc, thiscaps);
347
348   /* nothing or anything is allowed, we're done */
349   if (thiscaps == NULL || gst_caps_is_any (thiscaps))
350     goto no_nego_needed;
351
352   /* get the peer caps */
353   peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc), thiscaps);
354   GST_DEBUG_OBJECT (basesrc, "caps of peer: %" GST_PTR_FORMAT, peercaps);
355   LOG_CAPS (basesrc, peercaps);
356   if (peercaps && !gst_caps_is_any (peercaps)) {
357     GstCaps *icaps = NULL;
358     int i;
359
360     /* Prefer the first caps we are compatible with that the peer proposed */
361     for (i = 0; i < gst_caps_get_size (peercaps); i++) {
362       /* get intersection */
363       GstCaps *ipcaps = gst_caps_copy_nth (peercaps, i);
364
365       GST_DEBUG_OBJECT (basesrc, "peer: %" GST_PTR_FORMAT, ipcaps);
366       LOG_CAPS (basesrc, ipcaps);
367
368       icaps = gst_caps_intersect (thiscaps, ipcaps);
369       gst_caps_unref (ipcaps);
370
371       if (!gst_caps_is_empty (icaps))
372         break;
373
374       gst_caps_unref (icaps);
375       icaps = NULL;
376     }
377
378     GST_DEBUG_OBJECT (basesrc, "intersect: %" GST_PTR_FORMAT, icaps);
379     LOG_CAPS (basesrc, icaps);
380     if (icaps) {
381       /* If there are multiple intersections pick the one with the smallest
382        * resolution strictly bigger then the first peer caps */
383       if (gst_caps_get_size (icaps) > 1) {
384         GstStructure *s = gst_caps_get_structure (peercaps, 0);
385         int best = 0;
386         int twidth, theight;
387         int width = G_MAXINT, height = G_MAXINT;
388
389         if (gst_structure_get_int (s, "width", &twidth)
390             && gst_structure_get_int (s, "height", &theight)) {
391
392           /* Walk the structure backwards to get the first entry of the
393            * smallest resolution bigger (or equal to) the preferred resolution)
394            */
395           for (i = gst_caps_get_size (icaps) - 1; i >= 0; i--) {
396             GstStructure *is = gst_caps_get_structure (icaps, i);
397             int w, h;
398
399             if (gst_structure_get_int (is, "width", &w)
400                 && gst_structure_get_int (is, "height", &h)) {
401               if (w >= twidth && w <= width && h >= theight && h <= height) {
402                 width = w;
403                 height = h;
404                 best = i;
405               }
406             }
407           }
408         }
409
410         caps = gst_caps_copy_nth (icaps, best);
411         gst_caps_unref (icaps);
412       } else {
413         caps = icaps;
414       }
415     }
416     gst_caps_unref (thiscaps);
417     gst_caps_unref (peercaps);
418   } else {
419     /* no peer or peer have ANY caps, work with our own caps then */
420     caps = thiscaps;
421   }
422   if (caps) {
423     caps = gst_caps_make_writable (caps);
424     gst_caps_truncate (caps);
425
426     /* now fixate */
427     if (!gst_caps_is_empty (caps)) {
428       gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps);
429       GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps);
430       LOG_CAPS (basesrc, caps);
431
432       if (gst_caps_is_any (caps)) {
433         /* hmm, still anything, so element can do anything and
434          * nego is not needed */
435         result = TRUE;
436       } else if (gst_caps_is_fixed (caps)) {
437         /* yay, fixed caps, use those then */
438         gst_pad_push_event (GST_BASE_SRC_PAD (basesrc),
439             gst_event_new_caps (caps));
440         result = gst_v4l2src_set_caps (basesrc, caps);
441       }
442     }
443     gst_caps_unref (caps);
444   }
445   return result;
446
447 no_nego_needed:
448   {
449     GST_DEBUG_OBJECT (basesrc, "no negotiation needed");
450     if (thiscaps)
451       gst_caps_unref (thiscaps);
452     return TRUE;
453   }
454 }
455
456 static GstCaps *
457 gst_v4l2src_get_caps (GstBaseSrc * src, GstCaps * filter)
458 {
459   GstV4l2Src *v4l2src;
460   GstV4l2Object *obj;
461   GstCaps *ret;
462   GSList *walk;
463   GSList *formats;
464
465   v4l2src = GST_V4L2SRC (src);
466   obj = v4l2src->v4l2object;
467
468   if (!GST_V4L2_IS_OPEN (obj)) {
469     /* FIXME: copy? */
470     return
471         gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD
472             (v4l2src)));
473   }
474
475   if (v4l2src->probed_caps)
476     return gst_caps_ref (v4l2src->probed_caps);
477
478   formats = gst_v4l2_object_get_format_list (obj);
479
480   ret = gst_caps_new_empty ();
481
482   for (walk = formats; walk; walk = walk->next) {
483     struct v4l2_fmtdesc *format;
484     GstStructure *template;
485
486     format = (struct v4l2_fmtdesc *) walk->data;
487
488     template = gst_v4l2_object_v4l2fourcc_to_structure (format->pixelformat);
489
490     if (template) {
491       GstCaps *tmp;
492
493       tmp =
494           gst_v4l2_object_probe_caps_for_format (obj,
495           format->pixelformat, template);
496       if (tmp)
497         gst_caps_append (ret, tmp);
498
499       gst_structure_free (template);
500     } else {
501       GST_DEBUG_OBJECT (v4l2src, "unknown format %u", format->pixelformat);
502     }
503   }
504
505   v4l2src->probed_caps = gst_caps_ref (ret);
506
507   GST_INFO_OBJECT (v4l2src, "probed caps: %" GST_PTR_FORMAT, ret);
508
509   return ret;
510 }
511
512 static gboolean
513 gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
514 {
515   GstV4l2Src *v4l2src;
516   GstV4l2Object *obj;
517
518   v4l2src = GST_V4L2SRC (src);
519   obj = v4l2src->v4l2object;
520
521   /* make sure we stop capturing and dealloc buffers */
522   if (!gst_v4l2_object_stop (obj))
523     return FALSE;
524
525   if (!gst_v4l2_object_set_format (obj, caps))
526     /* error already posted */
527     return FALSE;
528
529   if (obj->use_mmap) {
530     v4l2src->get_frame = gst_v4l2src_get_mmap;
531   } else {
532     v4l2src->get_frame = gst_v4l2src_get_read;
533   }
534
535   if (!gst_v4l2_object_start (obj))
536     return FALSE;
537
538   /* now store the expected output size */
539   v4l2src->frame_byte_size = obj->size;
540
541   return TRUE;
542 }
543
544 static gboolean
545 gst_v4l2src_query (GstBaseSrc * bsrc, GstQuery * query)
546 {
547   GstV4l2Src *src;
548
549   gboolean res = FALSE;
550
551   src = GST_V4L2SRC (bsrc);
552
553   switch (GST_QUERY_TYPE (query)) {
554     case GST_QUERY_LATENCY:{
555       GstClockTime min_latency, max_latency;
556       guint32 fps_n, fps_d;
557
558       /* device must be open */
559       if (!GST_V4L2_IS_OPEN (src->v4l2object)) {
560         GST_WARNING_OBJECT (src,
561             "Can't give latency since device isn't open !");
562         goto done;
563       }
564
565       fps_n = GST_V4L2_FPS_N (src->v4l2object);
566       fps_d = GST_V4L2_FPS_D (src->v4l2object);
567
568       /* we must have a framerate */
569       if (fps_n <= 0 || fps_d <= 0) {
570         GST_WARNING_OBJECT (src,
571             "Can't give latency since framerate isn't fixated !");
572         goto done;
573       }
574
575       /* min latency is the time to capture one frame */
576       min_latency = gst_util_uint64_scale_int (GST_SECOND, fps_d, fps_n);
577
578       /* max latency is total duration of the frame buffer */
579       max_latency = src->v4l2object->num_buffers * min_latency;
580
581       GST_DEBUG_OBJECT (bsrc,
582           "report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
583           GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
584
585       /* we are always live, the min latency is 1 frame and the max latency is
586        * the complete buffer of frames. */
587       gst_query_set_latency (query, TRUE, min_latency, max_latency);
588
589       res = TRUE;
590       break;
591     }
592     default:
593       res = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query);
594       break;
595   }
596
597 done:
598
599   return res;
600 }
601
602 /* start and stop are not symmetric -- start will open the device, but not start
603  * capture. it's setcaps that will start capture, which is called via basesrc's
604  * negotiate method. stop will both stop capture and close the device.
605  */
606 static gboolean
607 gst_v4l2src_start (GstBaseSrc * src)
608 {
609   GstV4l2Src *v4l2src = GST_V4L2SRC (src);
610
611   v4l2src->offset = 0;
612
613   /* activate settings for first frame */
614   v4l2src->ctrl_time = 0;
615   gst_object_sync_values (G_OBJECT (src), v4l2src->ctrl_time);
616
617   return TRUE;
618 }
619
620 static gboolean
621 gst_v4l2src_unlock (GstBaseSrc * src)
622 {
623   GstV4l2Src *v4l2src = GST_V4L2SRC (src);
624
625   GST_LOG_OBJECT (src, "Flushing");
626   gst_poll_set_flushing (v4l2src->v4l2object->poll, TRUE);
627
628   return TRUE;
629 }
630
631 static gboolean
632 gst_v4l2src_unlock_stop (GstBaseSrc * src)
633 {
634   GstV4l2Src *v4l2src = GST_V4L2SRC (src);
635
636   GST_LOG_OBJECT (src, "No longer flushing");
637   gst_poll_set_flushing (v4l2src->v4l2object->poll, FALSE);
638
639   return TRUE;
640 }
641
642 static gboolean
643 gst_v4l2src_stop (GstBaseSrc * src)
644 {
645   GstV4l2Src *v4l2src = GST_V4L2SRC (src);
646   GstV4l2Object *obj = v4l2src->v4l2object;
647
648   if (GST_V4L2_IS_ACTIVE (obj)) {
649     if (!gst_v4l2_object_stop (obj))
650       return FALSE;
651   }
652   return TRUE;
653 }
654
655 static GstStateChangeReturn
656 gst_v4l2src_change_state (GstElement * element, GstStateChange transition)
657 {
658   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
659   GstV4l2Src *v4l2src = GST_V4L2SRC (element);
660   GstV4l2Object *obj = v4l2src->v4l2object;
661
662   switch (transition) {
663     case GST_STATE_CHANGE_NULL_TO_READY:
664       /* open the device */
665       if (!gst_v4l2_object_open (obj))
666         return GST_STATE_CHANGE_FAILURE;
667       break;
668     default:
669       break;
670   }
671
672   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
673
674   switch (transition) {
675     case GST_STATE_CHANGE_READY_TO_NULL:
676       /* close the device */
677       if (!gst_v4l2_object_close (obj))
678         return GST_STATE_CHANGE_FAILURE;
679
680       if (v4l2src->probed_caps) {
681         gst_caps_unref (v4l2src->probed_caps);
682         v4l2src->probed_caps = NULL;
683       }
684       break;
685     default:
686       break;
687   }
688
689   return ret;
690 }
691
692 static GstFlowReturn
693 gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf)
694 {
695   GstFlowReturn res;
696   gint amount;
697   gint ret;
698   gpointer data;
699   gint buffersize;
700
701   buffersize = v4l2src->frame_byte_size;
702   /* In case the size per frame is unknown assume it's a streaming format (e.g.
703    * mpegts) and grab a reasonable default size instead */
704   if (buffersize == 0)
705     buffersize = GST_BASE_SRC (v4l2src)->blocksize;
706
707   *buf = gst_buffer_new_and_alloc (buffersize);
708   data = gst_buffer_map (*buf, NULL, NULL, GST_MAP_WRITE);
709
710   do {
711     ret = gst_poll_wait (v4l2src->v4l2object->poll, GST_CLOCK_TIME_NONE);
712     if (G_UNLIKELY (ret < 0)) {
713       if (errno == EBUSY)
714         goto stopped;
715       if (errno == ENXIO) {
716         GST_DEBUG_OBJECT (v4l2src,
717             "v4l2 device doesn't support polling. Disabling");
718         v4l2src->v4l2object->can_poll_device = FALSE;
719       } else {
720         if (errno != EAGAIN && errno != EINTR)
721           goto select_error;
722       }
723     }
724     amount = v4l2_read (v4l2src->v4l2object->video_fd, data, buffersize);
725
726     if (amount == buffersize) {
727       break;
728     } else if (amount == -1) {
729       if (errno == EAGAIN || errno == EINTR) {
730         continue;
731       } else
732         goto read_error;
733     } else {
734       /* short reads can happen if a signal interrupts the read */
735       continue;
736     }
737   } while (TRUE);
738
739   gst_buffer_unmap (*buf, data, amount);
740
741   /* we set the buffer metadata in gst_v4l2src_create() */
742
743   return GST_FLOW_OK;
744
745   /* ERRORS */
746 select_error:
747   {
748     GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, (NULL),
749         ("select error %d: %s (%d)", ret, g_strerror (errno), errno));
750     res = GST_FLOW_ERROR;
751     goto cleanup;
752   }
753 stopped:
754   {
755     GST_DEBUG ("stop called");
756     res = GST_FLOW_WRONG_STATE;
757     goto cleanup;
758   }
759 read_error:
760   {
761     GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
762         (_("Error reading %d bytes from device '%s'."),
763             buffersize, v4l2src->v4l2object->videodev), GST_ERROR_SYSTEM);
764     res = GST_FLOW_ERROR;
765     goto cleanup;
766   }
767 cleanup:
768   {
769     gst_buffer_unmap (*buf, data, 0);
770     gst_buffer_unref (*buf);
771     return res;
772   }
773 }
774
775 static GstFlowReturn
776 gst_v4l2src_get_mmap (GstV4l2Src * v4l2src, GstBuffer ** buf)
777 {
778   GstBuffer *temp;
779   GstFlowReturn ret;
780   guint size;
781   guint count = 0;
782
783 again:
784   ret = gst_v4l2src_grab_frame (v4l2src, &temp);
785   if (G_UNLIKELY (ret != GST_FLOW_OK))
786     goto done;
787
788   if (v4l2src->frame_byte_size > 0) {
789     size = gst_buffer_get_size (temp);
790
791     /* if size does not match what we expected, try again */
792     if (size != v4l2src->frame_byte_size) {
793       GST_ELEMENT_WARNING (v4l2src, RESOURCE, READ,
794           (_("Got unexpected frame size of %u instead of %u."),
795               size, v4l2src->frame_byte_size), (NULL));
796       gst_buffer_unref (temp);
797       if (count++ > 50)
798         goto size_error;
799
800       goto again;
801     }
802   }
803
804   *buf = temp;
805 done:
806   return ret;
807
808   /* ERRORS */
809 size_error:
810   {
811     GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
812         (_("Error reading %d bytes on device '%s'."),
813             v4l2src->frame_byte_size, v4l2src->v4l2object->videodev), (NULL));
814     return GST_FLOW_ERROR;
815   }
816 }
817
818 static GstFlowReturn
819 gst_v4l2src_create (GstPushSrc * src, GstBuffer ** buf)
820 {
821   GstV4l2Src *v4l2src = GST_V4L2SRC (src);
822   int i;
823   GstFlowReturn ret;
824
825   if (v4l2src->get_frame == NULL)
826     goto not_negotiated;
827
828   /* decimate, just capture and throw away frames */
829   for (i = 0; i < v4l2src->decimate - 1; i++) {
830     ret = v4l2src->get_frame (v4l2src, buf);
831     if (ret != GST_FLOW_OK) {
832       return ret;
833     }
834     gst_buffer_unref (*buf);
835   }
836
837   ret = v4l2src->get_frame (v4l2src, buf);
838
839   /* set buffer metadata */
840   if (G_LIKELY (ret == GST_FLOW_OK && *buf)) {
841     GstClock *clock;
842     GstClockTime timestamp, duration;
843
844     GST_BUFFER_OFFSET (*buf) = v4l2src->offset++;
845     GST_BUFFER_OFFSET_END (*buf) = v4l2src->offset;
846
847     /* timestamps, LOCK to get clock and base time. */
848     /* FIXME: element clock and base_time is rarely changing */
849     GST_OBJECT_LOCK (v4l2src);
850     if ((clock = GST_ELEMENT_CLOCK (v4l2src))) {
851       /* we have a clock, get base time and ref clock */
852       timestamp = GST_ELEMENT (v4l2src)->base_time;
853       gst_object_ref (clock);
854     } else {
855       /* no clock, can't set timestamps */
856       timestamp = GST_CLOCK_TIME_NONE;
857     }
858     GST_OBJECT_UNLOCK (v4l2src);
859
860     duration = v4l2src->v4l2object->duration;
861
862     if (G_LIKELY (clock)) {
863       /* the time now is the time of the clock minus the base time */
864       timestamp = gst_clock_get_time (clock) - timestamp;
865       gst_object_unref (clock);
866
867       /* if we have a framerate adjust timestamp for frame latency */
868       if (GST_CLOCK_TIME_IS_VALID (duration)) {
869         if (timestamp > duration)
870           timestamp -= duration;
871         else
872           timestamp = 0;
873       }
874     }
875
876     /* activate settings for next frame */
877     if (GST_CLOCK_TIME_IS_VALID (duration)) {
878       v4l2src->ctrl_time += duration;
879     } else {
880       /* this is not very good (as it should be the next timestamp),
881        * still good enough for linear fades (as long as it is not -1)
882        */
883       v4l2src->ctrl_time = timestamp;
884     }
885     gst_object_sync_values (G_OBJECT (src), v4l2src->ctrl_time);
886     GST_INFO_OBJECT (src, "sync to %" GST_TIME_FORMAT,
887         GST_TIME_ARGS (v4l2src->ctrl_time));
888
889     /* FIXME: use the timestamp from the buffer itself! */
890     GST_BUFFER_TIMESTAMP (*buf) = timestamp;
891     GST_BUFFER_DURATION (*buf) = duration;
892   }
893   return ret;
894
895   /* ERRORS */
896 not_negotiated:
897   {
898     GST_DEBUG_OBJECT (src, "we are not negotiated");
899     return GST_FLOW_NOT_NEGOTIATED;
900   }
901 }
902
903
904 /* GstURIHandler interface */
905 static GstURIType
906 gst_v4l2src_uri_get_type (GType type)
907 {
908   return GST_URI_SRC;
909 }
910
911 static gchar **
912 gst_v4l2src_uri_get_protocols (GType type)
913 {
914   static gchar *protocols[] = { (char *) "v4l2", NULL };
915
916   return protocols;
917 }
918
919 static const gchar *
920 gst_v4l2src_uri_get_uri (GstURIHandler * handler)
921 {
922   GstV4l2Src *v4l2src = GST_V4L2SRC (handler);
923
924   if (v4l2src->v4l2object->videodev != NULL) {
925     gchar uri[256];
926
927     /* need to return a const string, but also don't want to leak the generated
928      * string, so just intern it - there's a limited number of video devices
929      * after all */
930     g_snprintf (uri, sizeof (uri), "v4l2://%s", v4l2src->v4l2object->videodev);
931     return g_intern_string (uri);
932   }
933
934   return "v4l2://";
935 }
936
937 static gboolean
938 gst_v4l2src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
939 {
940   GstV4l2Src *v4l2src = GST_V4L2SRC (handler);
941   const gchar *device = DEFAULT_PROP_DEVICE;
942
943   if (strcmp (uri, "v4l2://") != 0) {
944     device = uri + 7;
945   }
946   g_object_set (v4l2src, "device", device, NULL);
947
948   return TRUE;
949 }
950
951
952 static void
953 gst_v4l2src_uri_handler_init (gpointer g_iface, gpointer iface_data)
954 {
955   GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
956
957   iface->get_type = gst_v4l2src_uri_get_type;
958   iface->get_protocols = gst_v4l2src_uri_get_protocols;
959   iface->get_uri = gst_v4l2src_uri_get_uri;
960   iface->set_uri = gst_v4l2src_uri_set_uri;
961 }