Just make few things more robust and also some identation.
authorEdgard Lima <edgard.lima@indt.org.br>
Sat, 25 Mar 2006 05:31:28 +0000 (05:31 +0000)
committerEdgard Lima <edgard.lima@indt.org.br>
Sat, 25 Mar 2006 05:31:28 +0000 (05:31 +0000)
Original commit message from CVS:
Just make few things more robust and also some identation.

common
sys/v4l2/gstv4l2colorbalance.c
sys/v4l2/gstv4l2colorbalance.h
sys/v4l2/gstv4l2element.c
sys/v4l2/gstv4l2src.c
sys/v4l2/gstv4l2src.h
sys/v4l2/gstv4l2tuner.c
sys/v4l2/v4l2_calls.c
sys/v4l2/v4l2src_calls.c
sys/v4l2/v4l2src_calls.h

diff --git a/common b/common
index 252846b..5685efc 160000 (submodule)
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit 252846b570144570a0aee25b5adefbfac3f5d4eb
+Subproject commit 5685efc3f9976d6abe3fec557353fc2053b0e3fb
index 9c2cfa2..06805fc 100644 (file)
@@ -79,7 +79,7 @@ gst_v4l2_color_balance_channel_class_init (GstV4l2ColorBalanceChannelClass *
 static void
 gst_v4l2_color_balance_channel_init (GstV4l2ColorBalanceChannel * channel)
 {
-  channel->index = 0;
+  channel->id = (guint32) - 1;
 }
 
 void
@@ -125,7 +125,7 @@ gst_v4l2_color_balance_set_value (GstColorBalance * balance,
   g_return_if_fail (gst_v4l2_color_balance_contains_channel (v4l2element,
           v4l2channel));
 
-  gst_v4l2_set_attribute (v4l2element, v4l2channel->index, value);
+  gst_v4l2_set_attribute (v4l2element, v4l2channel->id, value);
 }
 
 static gint
@@ -142,7 +142,7 @@ gst_v4l2_color_balance_get_value (GstColorBalance * balance,
   g_return_val_if_fail (gst_v4l2_color_balance_contains_channel (v4l2element,
           v4l2channel), 0);
 
-  if (!gst_v4l2_get_attribute (v4l2element, v4l2channel->index, &value))
+  if (!gst_v4l2_get_attribute (v4l2element, v4l2channel->id, &value))
     return 0;
 
   return value;
index 487b348..358270f 100644 (file)
@@ -44,7 +44,7 @@ G_BEGIN_DECLS
 typedef struct _GstV4l2ColorBalanceChannel {
   GstColorBalanceChannel parent;
 
-  guint32 index;
+  guint32 id;
 } GstV4l2ColorBalanceChannel;
 
 typedef struct _GstV4l2ColorBalanceChannelClass {
index e5acbf8..d6f14d4 100644 (file)
@@ -1,23 +1,17 @@
-/* GStreamer
- *
- * gstv4l2element.c: base class for V4L2 elements
- *
- * Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
+/*
+ * GStreamer gstv4l2element.c: base class for V4L2 elements Copyright
+ * (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net> This library 
+ * is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Library General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. This library is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU Library General Public License for more details.
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA. 
  */
 
 #ifdef HAVE_CONFIG_H
@@ -56,8 +50,6 @@ static void gst_v4l2element_init_interfaces (GType type);
 
 GST_BOILERPLATE_FULL (GstV4l2Element, gst_v4l2element, GstPushSrc,
     GST_TYPE_PUSH_SRC, gst_v4l2element_init_interfaces)
-
-
      static void gst_v4l2element_dispose (GObject * object);
      static void gst_v4l2element_set_property (GObject * object,
     guint prop_id, const GValue * value, GParamSpec * pspec);
@@ -95,7 +87,9 @@ GST_BOILERPLATE_FULL (GstV4l2Element, gst_v4l2element, GstPushSrc,
 static void
 gst_v4l2_interface_init (GstImplementsInterfaceClass * klass)
 {
-  /* default virtual functions */
+  /*
+   * default virtual functions 
+   */
   klass->supported = gst_v4l2_iface_supported;
 }
 
@@ -130,21 +124,32 @@ gst_v4l2_class_probe_devices (GstV4l2ElementClass * klass, gboolean check)
       g_free (device);
     }
 
-    /* detect /dev entries */
+    /*
+     * detect /dev entries 
+     */
     for (n = 0; n < 64; n++) {
       for (base = 0; dev_base[base] != NULL; base++) {
         struct stat s;
-        gchar *device = g_strdup_printf ("%s%d", dev_base[base], n);
+        gchar *device = g_strdup_printf ("%s%d",
+            dev_base[base],
+            n);
 
-        /* does the /dev/ entry exist at all? */
+        /*
+         * does the /dev/ entry exist at all? 
+         */
         if (stat (device, &s) == 0) {
-          /* yes: is a device attached? */
-          if ((fd = open (device, O_RDONLY)) > 0 || errno == EBUSY) {
-            if (fd > 0)
-              close (fd);
-
-            devices = g_list_append (devices, device);
-            break;
+          /*
+           * yes: is a device attached? 
+           */
+          if (S_ISCHR (s.st_mode)) {
+
+            if ((fd = open (device, O_RDWR | O_NONBLOCK)) > 0 || errno == EBUSY) {
+              if (fd > 0)
+                close (fd);
+
+              devices = g_list_append (devices, device);
+              break;
+            }
           }
         }
         g_free (device);
@@ -256,12 +261,22 @@ gst_v4l2_device_get_type (void)
 
   if (v4l2_device_type == 0) {
     static const GFlagsValue values[] = {
-      {V4L2_CAP_VIDEO_CAPTURE, "CAPTURE", "Device can capture"},
-      {V4L2_CAP_VIDEO_OUTPUT, "PLAYBACK", "Device can playback"},
-      {V4L2_CAP_VIDEO_OVERLAY, "OVERLAY", "Device can do overlay"},
-
-      {V4L2_CAP_TUNER, "TUNER", "Device has a tuner"},
-      {V4L2_CAP_AUDIO, "AUDIO", "Device handles audio"},
+      {V4L2_CAP_VIDEO_CAPTURE, "CAPTURE",
+          "Device supports video capture"},
+      {V4L2_CAP_VIDEO_OUTPUT, "PLAYBACK",
+          "Device supports video playback"},
+      {V4L2_CAP_VIDEO_OVERLAY, "OVERLAY",
+          "Device supports video overlay"},
+
+      {V4L2_CAP_VBI_CAPTURE, "VBI_CAPTURE",
+          "Device supports the VBI capture"},
+      {V4L2_CAP_VBI_OUTPUT, "VBI_OUTPUT",
+          "Device supports the VBI output"},
+
+      {V4L2_CAP_TUNER, "TUNER",
+          "Device has a tuner or modulator"},
+      {V4L2_CAP_AUDIO, "AUDIO",
+          "Device has audio inputs or outputs"},
 
       {0, NULL, NULL}
     };
@@ -312,8 +327,8 @@ gst_v4l2element_init_interfaces (GType type)
 #endif
   g_type_add_interface_static (type,
       GST_TYPE_COLOR_BALANCE, &v4l2_colorbalance_info);
-  g_type_add_interface_static (type,
-      GST_TYPE_PROPERTY_PROBE, &v4l2_propertyprobe_info);
+  g_type_add_interface_static (type, GST_TYPE_PROPERTY_PROBE,
+      &v4l2_propertyprobe_info);
 }
 
 
@@ -338,22 +353,26 @@ gst_v4l2element_class_init (GstV4l2ElementClass * klass)
   gobject_class->get_property = gst_v4l2element_get_property;
 
   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DEVICE,
-      g_param_spec_string ("device", "Device", "Device location",
-          NULL, G_PARAM_READWRITE));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DEVICE_NAME,
-      g_param_spec_string ("device_name", "Device name", "Name of the device",
-          NULL, G_PARAM_READABLE));
+      g_param_spec_string ("device",
+          "Device", "Device location", NULL, G_PARAM_READWRITE));
+  g_object_class_install_property (G_OBJECT_CLASS (klass),
+      PROP_DEVICE_NAME,
+      g_param_spec_string ("device_name",
+          "Device name", "Name of the device", NULL, G_PARAM_READABLE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FLAGS,
-      g_param_spec_flags ("flags", "Flags", "Device type flags",
+      g_param_spec_flags ("flags", "Flags",
+          "Device type flags",
           GST_TYPE_V4L2_DEVICE_FLAGS, 0, G_PARAM_READABLE));
   g_object_class_install_property (gobject_class, PROP_STD,
       g_param_spec_string ("std", "std",
           "standard (norm) to use", NULL, G_PARAM_READWRITE));
   g_object_class_install_property (gobject_class, PROP_INPUT,
-      g_param_spec_string ("input", "input",
+      g_param_spec_string ("input",
+          "input",
           "input/output (channel) to switch to", NULL, G_PARAM_READWRITE));
   g_object_class_install_property (gobject_class, PROP_FREQUENCY,
-      g_param_spec_ulong ("frequency", "frequency",
+      g_param_spec_ulong ("frequency",
+          "frequency",
           "frequency to tune to (in Hz)", 0, G_MAXULONG, 0, G_PARAM_READWRITE));
 
   basesrc_class->start = gst_v4l2element_start;
@@ -366,7 +385,9 @@ gst_v4l2element_class_init (GstV4l2ElementClass * klass)
 static void
 gst_v4l2element_init (GstV4l2Element * v4l2element, GstV4l2ElementClass * klass)
 {
-  /* some default values */
+  /*
+   * some default values 
+   */
   v4l2element->video_fd = -1;
   v4l2element->buffer = NULL;
   v4l2element->videodev = g_strdup ("/dev/video0");
@@ -410,7 +431,8 @@ gst_v4l2element_set_property (GObject * object,
       if (GST_V4L2_IS_OPEN (v4l2element)) {
         GstTuner *tuner = GST_TUNER (v4l2element);
         GstTunerNorm *norm = gst_tuner_find_norm_by_name (tuner,
-            (gchar *) g_value_get_string (value));
+            (gchar *)
+            g_value_get_string (value));
 
         if (norm) {
           gst_tuner_set_norm (tuner, norm);
@@ -425,7 +447,8 @@ gst_v4l2element_set_property (GObject * object,
       if (GST_V4L2_IS_OPEN (v4l2element)) {
         GstTuner *tuner = GST_TUNER (v4l2element);
         GstTunerChannel *channel = gst_tuner_find_channel_by_name (tuner,
-            (gchar *) g_value_get_string (value));
+            (gchar *)
+            g_value_get_string (value));
 
         if (channel) {
           gst_tuner_set_channel (tuner, channel);
@@ -467,7 +490,8 @@ gst_v4l2element_get_property (GObject * object,
     case PROP_DEVICE:
       g_value_set_string (value, v4l2element->videodev);
       break;
-    case PROP_DEVICE_NAME:{
+    case PROP_DEVICE_NAME:
+    {
       gchar *new = NULL;
 
       if (GST_V4L2_IS_OPEN (v4l2element))
@@ -475,12 +499,14 @@ gst_v4l2element_get_property (GObject * object,
       g_value_set_string (value, new);
       break;
     }
-    case PROP_FLAGS:{
+    case PROP_FLAGS:
+    {
       guint flags = 0;
 
       if (GST_V4L2_IS_OPEN (v4l2element)) {
         flags |= v4l2element->vcap.capabilities &
-            (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
+            (V4L2_CAP_VIDEO_CAPTURE |
+            V4L2_CAP_VIDEO_OUTPUT |
             V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_TUNER | V4L2_CAP_AUDIO);
         if (v4l2element->vcap.capabilities & V4L2_CAP_AUDIO)
           flags |= V4L2_FBUF_CAP_CHROMAKEY;
index 2c331dd..ee3c984 100644 (file)
@@ -115,9 +115,8 @@ static void gst_v4l2src_fixate (GstPad * pad, GstCaps * caps);
 static void
 gst_v4l2src_set_property (GObject * object,
     guint prop_id, const GValue * value, GParamSpec * pspec);
-static void
-gst_v4l2src_get_property (GObject * object,
-    guint prop_id, GValue * value, GParamSpec * pspec);
+static void gst_v4l2src_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
 
 static GstCaps *gst_v4l2src_get_all_caps (void);
 
@@ -270,6 +269,7 @@ gst_v4l2src_fixate (GstPad * pad, GstCaps * caps)
 
     gst_structure_fixate_field_nearest_int (structure, "width", G_MAXINT);
     gst_structure_fixate_field_nearest_int (structure, "height", G_MAXINT);
+    gst_structure_fixate_field_nearest_fraction (structure, "framerate", 15, 2);
 
     v = gst_structure_get_value (structure, "format");
     if (v && G_VALUE_TYPE (v) != GST_TYPE_FOURCC) {
@@ -597,7 +597,10 @@ gst_v4l2src_get_caps (GstBaseSrc * src)
   /* build our own capslist */
   caps = gst_caps_new_empty ();
   walk = v4l2src->formats;
-  gst_v4l2src_get_fps (v4l2src, &fps_n, &fps_d);
+  if (!gst_v4l2src_get_fps (v4l2src, &fps_n, &fps_d)) {
+    fps_n = 0;
+    fps_d = 1;
+  }
   while (walk) {
     format = (struct v4l2_fmtdesc *) walk->data;
     walk = g_slist_next (walk);
@@ -619,10 +622,19 @@ gst_v4l2src_get_caps (GstBaseSrc * src)
     if (structure) {
       gst_structure_set (structure,
           "width", GST_TYPE_INT_RANGE, min_w, max_w,
-          "height", GST_TYPE_INT_RANGE, min_h, max_h,
-          "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL);
+          "height", GST_TYPE_INT_RANGE, min_h, max_h, NULL);
+      if (fps_n > 0) {
+        gst_structure_set (structure, "framerate", GST_TYPE_FRACTION,
+            fps_n, fps_d, NULL);
+      }
 
       gst_caps_append_structure (caps, structure);
+
+      if (fps_n <= 0) {
+        gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION_RANGE,
+            1, 1, 100, 1, NULL);
+      }
+
     }
   }
 
index 12c3cd4..3b3f96a 100644 (file)
@@ -32,7 +32,6 @@ GST_DEBUG_CATEGORY_EXTERN (v4l2src_debug);
 #define GST_V4L2_MIN_BUFFERS 2
 
 G_BEGIN_DECLS
-
 #define GST_TYPE_V4L2SRC                       \
   (gst_v4l2src_get_type())
 #define GST_V4L2SRC(obj)                                               \
@@ -43,37 +42,37 @@ G_BEGIN_DECLS
   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_V4L2SRC))
 #define GST_IS_V4L2SRC_CLASS(obj)                      \
   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_V4L2SRC))
-
-
-typedef struct _GstV4l2BufferPool      GstV4l2BufferPool;
-typedef struct _GstV4l2Buffer          GstV4l2Buffer;
+typedef struct _GstV4l2BufferPool GstV4l2BufferPool;
+typedef struct _GstV4l2Buffer GstV4l2Buffer;
 typedef struct _GstV4l2Src GstV4l2Src;
 typedef struct _GstV4l2SrcClass GstV4l2SrcClass;
 
 
 /* global info */
-struct _GstV4l2BufferPool {
-  gint                 refcount; /* number of users: 1 for every buffer, 1 for element */
-  gint                 video_fd;
-  guint                        buffer_count;
-  GstV4l2Buffer *      buffers;
+struct _GstV4l2BufferPool
+{
+  gint refcount;                /* number of users: 1 for every buffer, 1 for element */
+  gint video_fd;
+  guint buffer_count;
+  GstV4l2Buffer *buffers;
 };
 
-struct _GstV4l2Buffer {
-  struct v4l2_buffer   buffer;
-  guint8 *             start;
-  guint                        length;
-  gint                 refcount; /* add 1 if in use by element, add 1 if in use by GstBuffer */
-  GstV4l2BufferPool *  pool;
+struct _GstV4l2Buffer
+{
+  struct v4l2_buffer buffer;
+  guint8 *start;
+  guint length;
+  gint refcount;                /* add 1 if in use by element, add 1 if in use by GstBuffer */
+  GstV4l2BufferPool *pool;
 };
 
 enum
-  {
-    QUEUE_STATE_ERROR = -1,
-    QUEUE_STATE_READY_FOR_QUEUE,  /* the frame is ready to be queued for capture */
-    QUEUE_STATE_QUEUED,           /* the frame is queued for capture */
-    QUEUE_STATE_SYNCED            /* the frame is captured */
-  };
+{
+  QUEUE_STATE_ERROR = -1,
+  QUEUE_STATE_READY_FOR_QUEUE,  /* the frame is ready to be queued for capture */
+  QUEUE_STATE_QUEUED,           /* the frame is queued for capture */
+  QUEUE_STATE_SYNCED            /* the frame is captured */
+};
 
 
 struct _GstV4l2Src
@@ -84,7 +83,7 @@ struct _GstV4l2Src
   GstPad *srcpad;
 
   /* internal lists */
-  GSList *formats; /* list of available capture formats */
+  GSList *formats;              /* list of available capture formats */
 
   /* buffers */
   GstV4l2BufferPool *pool;
@@ -111,6 +110,4 @@ GType gst_v4l2src_get_type (void);
 
 
 G_END_DECLS
-
-
 #endif /* __GST_V4L2SRC_H__ */
index 9fb4e3c..add688c 100644 (file)
@@ -91,9 +91,9 @@ gst_v4l2_tuner_channel_class_init (GstV4l2TunerChannelClass * klass)
 static void
 gst_v4l2_tuner_channel_init (GstV4l2TunerChannel * channel)
 {
-  channel->index = 0;
-  channel->tuner = 0;
-  channel->audio = 0;
+  channel->index = (guint32) - 1;
+  channel->tuner = (guint32) - 1;
+  channel->audio = (guint32) - 1;
 }
 
 GType
@@ -314,8 +314,8 @@ gst_v4l2_tuner_get_frequency (GstTuner * mixer, GstTunerChannel * channel)
   g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2element), 0);
   g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
           GST_TUNER_CHANNEL_FREQUENCY), 0);
-  g_return_val_if_fail (gst_v4l2_tuner_contains_channel (v4l2element,
-          v4l2channel), 0);
+  g_return_val_if_fail (gst_v4l2_tuner_contains_channel
+      (v4l2element, v4l2channel), 0);
 
   gst_v4l2_get_input (v4l2element, &chan);
   if (chan == GST_V4L2_TUNER_CHANNEL (channel)->index &&
@@ -338,8 +338,8 @@ gst_v4l2_tuner_signal_strength (GstTuner * mixer, GstTunerChannel * channel)
   g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2element), 0);
   g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
           GST_TUNER_CHANNEL_FREQUENCY), 0);
-  g_return_val_if_fail (gst_v4l2_tuner_contains_channel (v4l2element,
-          v4l2channel), 0);
+  g_return_val_if_fail (gst_v4l2_tuner_contains_channel
+      (v4l2element, v4l2channel), 0);
 
   gst_v4l2_get_input (v4l2element, &chan);
   if (chan == GST_V4L2_TUNER_CHANNEL (channel)->index &&
index a89122f..81516b4 100644 (file)
@@ -252,7 +252,7 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
     v4l2channel = g_object_new (GST_TYPE_V4L2_COLOR_BALANCE_CHANNEL, NULL);
     channel = GST_COLOR_BALANCE_CHANNEL (v4l2channel);
     channel->label = g_strdup ((const gchar *) control.name);
-    v4l2channel->index = n;
+    v4l2channel->id = n;
 
 #if 0
     if (control.type == V4L2_CTRL_TYPE_MENU) {
@@ -335,9 +335,11 @@ gst_v4l2_set_defaults (GstV4l2Element * v4l2element)
     gst_tuner_set_norm (tuner, norm);
   } else {
     norm = GST_TUNER_NORM (gst_tuner_get_norm (GST_TUNER (v4l2element)));
-    v4l2element->std = g_strdup (norm->label);
-    gst_tuner_norm_changed (tuner, norm);
-    g_object_notify (G_OBJECT (v4l2element), "std");
+    if (norm) {
+      v4l2element->std = g_strdup (norm->label);
+      gst_tuner_norm_changed (tuner, norm);
+      g_object_notify (G_OBJECT (v4l2element), "std");
+    }
   }
 
   if (v4l2element->input)
@@ -377,6 +379,8 @@ gst_v4l2_set_defaults (GstV4l2Element * v4l2element)
 gboolean
 gst_v4l2_open (GstV4l2Element * v4l2element)
 {
+  struct stat st;
+
   GST_DEBUG ("Trying to open device %s", v4l2element->videodev);
   GST_V4L2_CHECK_NOT_OPEN (v4l2element);
   GST_V4L2_CHECK_NOT_ACTIVE (v4l2element);
@@ -385,8 +389,21 @@ gst_v4l2_open (GstV4l2Element * v4l2element)
   if (!v4l2element->videodev)
     v4l2element->videodev = g_strdup ("/dev/video");
 
+  /* check if it is a device */
+  if (-1 == stat (v4l2element->videodev, &st)) {
+    GST_ERROR ("Cannot identify '%s': %d, %s\n",
+        v4l2element->videodev, errno, strerror (errno));
+    goto error;
+  }
+  if (!S_ISCHR (st.st_mode)) {
+    GST_ERROR ("%s is no device\n", v4l2element->videodev);
+    goto error;
+  }
+
   /* open the device */
-  v4l2element->video_fd = open (v4l2element->videodev, O_RDWR);
+  v4l2element->video_fd = open (v4l2element->videodev,
+      O_RDWR /* | O_NONBLOCK */ );
+
   if (!GST_V4L2_IS_OPEN (v4l2element)) {
     GST_ELEMENT_ERROR (v4l2element, RESOURCE, OPEN_READ_WRITE,
         (_("Could not open device \"%s\" for reading and writing."),
@@ -403,8 +420,9 @@ gst_v4l2_open (GstV4l2Element * v4l2element)
   if (GST_IS_V4L2SRC (v4l2element) &&
       !(v4l2element->vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
     GST_ELEMENT_ERROR (v4l2element, RESOURCE, NOT_FOUND,
-        (_("Device \"%s\" is not a capture device."), v4l2element->videodev),
-        ("Capabilities: 0x%x", v4l2element->vcap.capabilities));
+        (_("Device \"%s\" is not a capture device."),
+            v4l2element->videodev), ("Capabilities: 0x%x",
+            v4l2element->vcap.capabilities));
     goto error;
   }
 
@@ -524,8 +542,8 @@ gst_v4l2_get_input (GstV4l2Element * v4l2element, gint * input)
 
   if (ioctl (v4l2element->video_fd, VIDIOC_G_INPUT, &n) < 0) {
     GST_WARNING_OBJECT (v4l2element,
-        "Failed to get current input on device %s: %s", v4l2element->videodev,
-        g_strerror (errno));
+        "Failed to get current input on device %s: %s",
+        v4l2element->videodev, g_strerror (errno));
     return FALSE;
   }
 
@@ -577,8 +595,8 @@ gst_v4l2_get_output (GstV4l2Element * v4l2element, gint * output)
 
   if (ioctl (v4l2element->video_fd, VIDIOC_G_OUTPUT, &n) < 0) {
     GST_WARNING_OBJECT (v4l2element,
-        "Failed to get current output on device %s: %s", v4l2element->videodev,
-        g_strerror (errno));
+        "Failed to get current output on device %s: %s",
+        v4l2element->videodev, g_strerror (errno));
     return FALSE;
   }
 
@@ -735,8 +753,8 @@ gst_v4l2_get_attribute (GstV4l2Element * v4l2element,
 
   if (ioctl (v4l2element->video_fd, VIDIOC_G_CTRL, &control) < 0) {
     GST_WARNING_OBJECT (v4l2element,
-        "Failed to get value for control %d on device %s: %s", attribute_num,
-        v4l2element->videodev, g_strerror (errno));
+        "Failed to get value for control %d on device %s: %s",
+        attribute_num, v4l2element->videodev, g_strerror (errno));
     return FALSE;
   }
 
@@ -768,8 +786,8 @@ gst_v4l2_set_attribute (GstV4l2Element * v4l2element,
 
   if (ioctl (v4l2element->video_fd, VIDIOC_S_CTRL, &control) < 0) {
     GST_WARNING_OBJECT (v4l2element,
-        "Failed to set value %d for control %d on device %s: %s", value,
-        attribute_num, v4l2element->videodev, g_strerror (errno));
+        "Failed to set value %d for control %d on device %s: %s",
+        value, attribute_num, v4l2element->videodev, g_strerror (errno));
     return FALSE;
   }
 
index 6dfe449..73adb04 100644 (file)
@@ -144,8 +144,11 @@ gint
 gst_v4l2src_grab_frame (GstV4l2Src * v4l2src)
 {
   struct v4l2_buffer buffer;
+  gint32 trials = 100;
 
+  memset (&buffer, 0x00, sizeof (buffer));
   buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  buffer.memory = v4l2src->breq.memory;
   while (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_DQBUF, &buffer) < 0) {
     /* if the sync() got interrupted, we can retry */
     switch (errno) {
@@ -168,13 +171,13 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l2src)
                 GST_V4L2ELEMENT (v4l2src)->videodev, g_strerror (errno)));
         break;
       case EIO:
-        GST_ELEMENT_ERROR (v4l2src, RESOURCE, SYNC, (NULL),
-            ("VIDIOC_DQBUF failed due to an internal error."
-                " Can also indicate temporary problems like signal loss."
-                " Note the driver might dequeue an (empty) buffer despite"
-                " returning an error, or even stop capturing."
-                " device %s: %s",
-                GST_V4L2ELEMENT (v4l2src)->videodev, g_strerror (errno)));
+        GST_WARNING_OBJECT (v4l2src,
+            "VIDIOC_DQBUF failed due to an internal error."
+            " Can also indicate temporary problems like signal loss."
+            " Note the driver might dequeue an (empty) buffer despite"
+            " returning an error, or even stop capturing."
+            " device %s: %s",
+            GST_V4L2ELEMENT (v4l2src)->videodev, g_strerror (errno));
         break;
       case EINTR:
         GST_ELEMENT_ERROR (v4l2src, RESOURCE, SYNC, (NULL),
@@ -186,7 +189,14 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l2src)
         break;
     }
 
-    return -1;
+    if (--trials == -1) {
+      return -1;
+    } else {
+      ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_QBUF, &buffer);
+      memset (&buffer, 0x00, sizeof (buffer));
+      buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+      buffer.memory = v4l2src->breq.memory;
+    }
 
   }
 
@@ -292,8 +302,8 @@ gst_v4l2src_capture_init (GstV4l2Src * v4l2src)
       GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
           (_("Could not get buffers from device \"%s\"."),
               GST_V4L2ELEMENT (v4l2src)->videodev),
-          ("error requesting %d buffers: %s", v4l2src->breq.count,
-              g_strerror (errno)));
+          ("error requesting %d buffers: %s",
+              v4l2src->breq.count, g_strerror (errno)));
       return FALSE;
     }
     GST_LOG_OBJECT (v4l2src, "using default mmap method");
@@ -314,8 +324,8 @@ gst_v4l2src_capture_init (GstV4l2Src * v4l2src)
       GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
           (_("Could not get enough buffers from device \"%s\"."),
               GST_V4L2ELEMENT (v4l2src)->videodev),
-          ("we received %d, we want at least %d", v4l2src->breq.count,
-              GST_V4L2_MIN_BUFFERS));
+          ("we received %d, we want at least %d",
+              v4l2src->breq.count, GST_V4L2_MIN_BUFFERS));
       v4l2src->breq.count = buffers;
       return FALSE;
     }
@@ -347,8 +357,8 @@ gst_v4l2src_capture_init (GstV4l2Src * v4l2src)
       if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_QUERYBUF,
               &buffer->buffer) < 0) {
         GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, (NULL),
-            ("Could not get buffer properties of buffer %d: %s", n,
-                g_strerror (errno)));
+            ("Could not get buffer properties of buffer %d: %s",
+                n, g_strerror (errno)));
         gst_v4l2src_capture_deinit (v4l2src);
         return FALSE;
       }
@@ -772,7 +782,10 @@ gst_v4l2src_buffer_new (GstV4l2Src * v4l2src, guint size, guint8 * data,
 
   GST_DEBUG_OBJECT (v4l2src, "creating buffer %d");
 
-  g_return_val_if_fail (gst_v4l2src_get_fps (v4l2src, &fps_n, &fps_d), NULL);
+  if (!gst_v4l2src_get_fps (v4l2src, &fps_n, &fps_d)) {
+    fps_n = 0;
+    fps_d = 1;
+  }
 
   buf = (GstBuffer *) gst_mini_object_new (GST_TYPE_V4L2SRC_BUFFER);
 
@@ -790,8 +803,12 @@ gst_v4l2src_buffer_new (GstV4l2Src * v4l2src, guint size, guint8 * data,
   GST_BUFFER_TIMESTAMP (buf) -= GST_ELEMENT (v4l2src)->base_time;
 
   GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
-  GST_BUFFER_DURATION (buf) = gst_util_uint64_scale_int (GST_SECOND,
-      fps_n, fps_d);
+  if (fps_n > 0) {
+    GST_BUFFER_DURATION (buf) = gst_util_uint64_scale_int (GST_SECOND,
+        fps_n, fps_d);
+  } else {
+    GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
+  }
 
   /* the negotiate() method already set caps on the source pad */
   gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (v4l2src)));
index 8766761..1411083 100644 (file)
 #include "v4l2_calls.h"
 
 
-gboolean       gst_v4l2src_get_capture         (GstV4l2Src *v4l2src);
-gboolean       gst_v4l2src_set_capture         (GstV4l2Src *v4l2src,
-                                                struct v4l2_fmtdesc *fmt,
-                                                gint        width,
-                                                gint        height);
-gboolean       gst_v4l2src_capture_init        (GstV4l2Src *v4l2src);
-gboolean       gst_v4l2src_capture_start       (GstV4l2Src *v4l2src);
-gint           gst_v4l2src_grab_frame          (GstV4l2Src *v4l2src);
-
-gboolean       gst_v4l2src_queue_frame         (GstV4l2Src *v4l2src,
-                                                guint i);
-gboolean       gst_v4l2src_capture_stop        (GstV4l2Src *v4l2src);
-gboolean       gst_v4l2src_capture_deinit      (GstV4l2Src *v4l2src);
-
-gboolean       gst_v4l2src_fill_format_list    (GstV4l2Src *v4l2src);
-gboolean       gst_v4l2src_clear_format_list   (GstV4l2Src *v4l2src);
+gboolean gst_v4l2src_get_capture (GstV4l2Src * v4l2src);
+gboolean gst_v4l2src_set_capture (GstV4l2Src * v4l2src,
+                                  struct v4l2_fmtdesc *fmt,
+                                  gint width, gint height);
+gboolean gst_v4l2src_capture_init (GstV4l2Src * v4l2src);
+gboolean gst_v4l2src_capture_start (GstV4l2Src * v4l2src);
+gint gst_v4l2src_grab_frame (GstV4l2Src * v4l2src);
+
+gboolean gst_v4l2src_queue_frame (GstV4l2Src * v4l2src, guint i);
+gboolean gst_v4l2src_capture_stop (GstV4l2Src * v4l2src);
+gboolean gst_v4l2src_capture_deinit (GstV4l2Src * v4l2src);
+
+gboolean gst_v4l2src_fill_format_list (GstV4l2Src * v4l2src);
+gboolean gst_v4l2src_clear_format_list (GstV4l2Src * v4l2src);
 
 /* hacky */
-gboolean       gst_v4l2src_get_size_limits     (GstV4l2Src *v4l2src,
-                                                struct v4l2_fmtdesc *fmt,
-                                                gint *min_w, gint *max_w,
-                                                gint *min_h, gint *max_h);
+gboolean gst_v4l2src_get_size_limits (GstV4l2Src * v4l2src,
+                                      struct v4l2_fmtdesc *fmt,
+                                      gint * min_w, gint * max_w,
+                                      gint * min_h, gint * max_h);
+
+void gst_v4l2src_free_buffer (GstBuffer * buffer);
 
-void           gst_v4l2src_free_buffer         (GstBuffer *buffer);
 
+gboolean gst_v4l2src_get_fps (GstV4l2Src * v4l2src, gint * fps_n, gint * fps_d);
 
-gboolean        gst_v4l2src_get_fps             (GstV4l2Src * v4l2src, gint * fps_n, gint * fps_d);
+GValue *gst_v4l2src_get_fps_list (GstV4l2Src * v4l2src);
 
-GValue *        gst_v4l2src_get_fps_list        (GstV4l2Src * v4l2src);
+GstBuffer *gst_v4l2src_buffer_new (GstV4l2Src * v4l2src,
+                                   guint size, guint8 * data,
+                                   GstV4l2Buffer * srcbuf);
 
-GstBuffer *     gst_v4l2src_buffer_new          (GstV4l2Src * v4l2src,
-                                                guint size, guint8 * data,
-                                                GstV4l2Buffer * srcbuf);
-  
 #endif /* __V4L2SRC_CALLS_H__ */