Changes proposed by Wingo in bug #338818.
authorEdgard Lima <edgard.lima@indt.org.br>
Thu, 11 May 2006 17:59:59 +0000 (17:59 +0000)
committerEdgard Lima <edgard.lima@indt.org.br>
Thu, 11 May 2006 17:59:59 +0000 (17:59 +0000)
Original commit message from CVS:
Changes proposed by Wingo in bug #338818.

19 files changed:
ChangeLog
sys/v4l2/Makefile.am
sys/v4l2/gstv4l2.c
sys/v4l2/gstv4l2colorbalance.c
sys/v4l2/gstv4l2colorbalance.h
sys/v4l2/gstv4l2element.c [deleted file]
sys/v4l2/gstv4l2element.h [deleted file]
sys/v4l2/gstv4l2object.c [new file with mode: 0644]
sys/v4l2/gstv4l2object.h [new file with mode: 0644]
sys/v4l2/gstv4l2src.c
sys/v4l2/gstv4l2src.h
sys/v4l2/gstv4l2tuner.c
sys/v4l2/gstv4l2tuner.h
sys/v4l2/gstv4l2xoverlay.c
sys/v4l2/gstv4l2xoverlay.h
sys/v4l2/v4l2_calls.c
sys/v4l2/v4l2_calls.h
sys/v4l2/v4l2src_calls.c
sys/v4l2/v4l2src_calls.h

index cc72ecf..448473a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2006-05-11  Edgard Lima <edgard.lima@indt.org.br>
+
+       * sys/v4l2/Makefile.am:
+       * sys/v4l2/gstv4l2.c:
+       * sys/v4l2/gstv4l2colorbalance.c:
+       * sys/v4l2/gstv4l2colorbalance.h:
+       * sys/v4l2/gstv4l2element.c:
+       * sys/v4l2/gstv4l2element.h:
+       * sys/v4l2/gstv4l2object.c:
+       * sys/v4l2/gstv4l2object.h:
+       * sys/v4l2/gstv4l2src.c:
+       * sys/v4l2/gstv4l2src.h:
+       * sys/v4l2/gstv4l2tuner.c:
+       * sys/v4l2/gstv4l2tuner.h:
+       * sys/v4l2/gstv4l2xoverlay.c:
+       * sys/v4l2/gstv4l2xoverlay.h:
+       * sys/v4l2/v4l2_calls.c:
+       * sys/v4l2/v4l2_calls.h:
+       * sys/v4l2/v4l2src_calls.c:
+       * sys/v4l2/v4l2src_calls.h:
+       Changes proposed by Wingo in bug #338818.
+
 2006-05-11  Wim Taymans  <wim@fluendo.com>
 
        * gst/qtdemux/qtdemux.c: (qtdemux_parse), (qtdemux_parse_trak),
index 547e068..b3f5881 100644 (file)
@@ -10,7 +10,7 @@ endif
 
 libgstvideo4linux2_la_SOURCES = gstv4l2.c \
                                gstv4l2colorbalance.c \
-                               gstv4l2element.c \
+                               gstv4l2object.c \
                                gstv4l2src.c \
                                gstv4l2tuner.c \
                                v4l2_calls.c \
@@ -30,7 +30,7 @@ libgstvideo4linux2_la_LIBADD =   $(GST_PLUGINS_BASE_LIBS) \
                                 $(xv_libs) \
                                 -lgstinterfaces-$(GST_MAJORMINOR) 
 
-noinst_HEADERS = gstv4l2element.h v4l2_calls.h \
+noinst_HEADERS = gstv4l2object.h v4l2_calls.h \
                 gstv4l2src.h v4l2src_calls.h \
                 gstv4l2tuner.h gstv4l2xoverlay.h \
                 gstv4l2colorbalance.h
index 513899e..11b3354 100644 (file)
@@ -3,6 +3,7 @@
  * gstv4l2.c: plugin for v4l2 elements
  *
  * Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ * Copyright (C) 2001-2002 Edgard Lima <edgard.lima@indt.org.br>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -28,7 +29,7 @@
 
 #include <gst/gst.h>
 
-#include "gstv4l2element.h"
+#include "gstv4l2object.h"
 #include "gstv4l2src.h"
 /* #include "gstv4l2jpegsrc.h" */
 /* #include "gstv4l2mjpegsrc.h" */
index 7a0378f..d8bfd35 100644 (file)
@@ -1,5 +1,6 @@
 /* GStreamer Color Balance interface implementation
  * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ * Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
  *
  * gstv4l2colorbalance.c: color balance interface implementation for V4L2
  *
 
 #include <gst/gst.h>
 #include "gstv4l2colorbalance.h"
-#include "gstv4l2element.h"
-
-static const GList *gst_v4l2_color_balance_list_channels (GstColorBalance *
-    balance);
-static void gst_v4l2_color_balance_set_value (GstColorBalance * balance,
-    GstColorBalanceChannel * channel, gint value);
-static gint gst_v4l2_color_balance_get_value (GstColorBalance * balance,
-    GstColorBalanceChannel * channel);
-
+#include "gstv4l2object.h"
 
 GST_BOILERPLATE (GstV4l2ColorBalanceChannel,
     gst_v4l2_color_balance_channel,
@@ -59,67 +52,55 @@ gst_v4l2_color_balance_channel_init (GstV4l2ColorBalanceChannel * channel,
   channel->id = (guint32) - 1;
 }
 
-void
-gst_v4l2_color_balance_interface_init (GstColorBalanceClass * klass)
-{
-  GST_COLOR_BALANCE_TYPE (klass) = GST_COLOR_BALANCE_HARDWARE;
-
-  /* default virtual functions */
-  klass->list_channels = gst_v4l2_color_balance_list_channels;
-  klass->set_value = gst_v4l2_color_balance_set_value;
-  klass->get_value = gst_v4l2_color_balance_get_value;
-}
-
 static G_GNUC_UNUSED gboolean
-gst_v4l2_color_balance_contains_channel (GstV4l2Element * v4l2element,
+gst_v4l2_color_balance_contains_channel (GstV4l2Object * v4l2object,
     GstV4l2ColorBalanceChannel * v4l2channel)
 {
   const GList *item;
 
-  for (item = v4l2element->colors; item != NULL; item = item->next)
+  for (item = v4l2object->colors; item != NULL; item = item->next)
     if (item->data == v4l2channel)
       return TRUE;
 
   return FALSE;
 }
 
-static const GList *
-gst_v4l2_color_balance_list_channels (GstColorBalance * balance)
+const GList *
+gst_v4l2_color_balance_list_channels (GstV4l2Object * v4l2object)
 {
-  return GST_V4L2ELEMENT (balance)->colors;
+  return v4l2object->colors;
 }
 
-static void
-gst_v4l2_color_balance_set_value (GstColorBalance * balance,
+void
+gst_v4l2_color_balance_set_value (GstV4l2Object * v4l2object,
     GstColorBalanceChannel * channel, gint value)
 {
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (balance);
+
   GstV4l2ColorBalanceChannel *v4l2channel =
       GST_V4L2_COLOR_BALANCE_CHANNEL (channel);
 
   /* assert that we're opened and that we're using a known item */
-  g_return_if_fail (GST_V4L2_IS_OPEN (v4l2element));
-  g_return_if_fail (gst_v4l2_color_balance_contains_channel (v4l2element,
+  g_return_if_fail (GST_V4L2_IS_OPEN (v4l2object));
+  g_return_if_fail (gst_v4l2_color_balance_contains_channel (v4l2object,
           v4l2channel));
 
-  gst_v4l2_set_attribute (v4l2element, v4l2channel->id, value);
+  gst_v4l2_set_attribute (v4l2object, v4l2channel->id, value);
 }
 
-static gint
-gst_v4l2_color_balance_get_value (GstColorBalance * balance,
+gint
+gst_v4l2_color_balance_get_value (GstV4l2Object * v4l2object,
     GstColorBalanceChannel * channel)
 {
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (balance);
   GstV4l2ColorBalanceChannel *v4l2channel =
       GST_V4L2_COLOR_BALANCE_CHANNEL (channel);
   gint value;
 
   /* assert that we're opened and that we're using a known item */
-  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2element), 0);
-  g_return_val_if_fail (gst_v4l2_color_balance_contains_channel (v4l2element,
+  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), 0);
+  g_return_val_if_fail (gst_v4l2_color_balance_contains_channel (v4l2object,
           v4l2channel), 0);
 
-  if (!gst_v4l2_get_attribute (v4l2element, v4l2channel->id, &value))
+  if (!gst_v4l2_get_attribute (v4l2object, v4l2channel->id, &value))
     return 0;
 
   return value;
index 358270f..761360f 100644 (file)
@@ -1,5 +1,6 @@
 /* G-Streamer generic V4L2 element - Color Balance interface implementation
  * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ * Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
  *
  * gstv4l2colorbalance.h: color balance interface implementation for V4L2
  *
@@ -53,6 +54,52 @@ typedef struct _GstV4l2ColorBalanceChannelClass {
 
 GType  gst_v4l2_color_balance_channel_get_type (void);
 
-void   gst_v4l2_color_balance_interface_init   (GstColorBalanceClass *klass);
+extern const GList *
+gst_v4l2_color_balance_list_channels (GstV4l2Object * v4l2object);
+
+extern void
+gst_v4l2_color_balance_set_value (GstV4l2Object * v4l2object,
+      GstColorBalanceChannel * channel, gint value);
+
+extern gint
+gst_v4l2_color_balance_get_value (GstV4l2Object * v4l2object,
+                                  GstColorBalanceChannel * channel);
+
+#define GST_IMPLEMENT_V4L2_COLOR_BALANCE_METHODS(Type, interface_as_function)         \
+                                                                                      \
+static const GList *                                                                  \
+interface_as_function ## _color_balance_list_channels (GstColorBalance * balance)     \
+{                                                                                     \
+  Type *this = (Type*) balance;                                                       \
+  return gst_v4l2_color_balance_list_channels(this->v4l2object);                      \
+}                                                                                     \
+                                                                                      \
+static void                                                                           \
+interface_as_function ## _color_balance_set_value (GstColorBalance * balance,         \
+                                                   GstColorBalanceChannel * channel,  \
+                                                   gint value)                        \
+{                                                                                     \
+  Type *this = (Type*) balance;                                                       \
+  return gst_v4l2_color_balance_set_value(this->v4l2object, channel, value);          \
+}                                                                                     \
+                                                                                      \
+static gint                                                                           \
+interface_as_function ## _color_balance_get_value (GstColorBalance * balance,         \
+                                                   GstColorBalanceChannel * channel)  \
+{                                                                                     \
+  Type *this = (Type*) balance;                                                       \
+  return gst_v4l2_color_balance_get_value(this->v4l2object, channel);                 \
+}                                                                                     \
+                                                                                      \
+void                                                                                  \
+interface_as_function ## _color_balance_interface_init (GstColorBalanceClass * klass) \
+{                                                                                     \
+  GST_COLOR_BALANCE_TYPE (klass) = GST_COLOR_BALANCE_HARDWARE;                        \
+                                                                                      \
+  /* default virtual functions */                                                     \
+  klass->list_channels = interface_as_function ## _color_balance_list_channels;       \
+  klass->set_value = interface_as_function ## _color_balance_set_value;               \
+  klass->get_value = interface_as_function ## _color_balance_get_value;               \
+}                                                                                     \
 
 #endif /* __GST_V4L2_COLOR_BALANCE_H__ */
diff --git a/sys/v4l2/gstv4l2element.c b/sys/v4l2/gstv4l2element.c
deleted file mode 100644 (file)
index 5bbc260..0000000
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * GStreamer gstv4l2element.c: base class for V4L2 elements
- * Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
- * Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
- * 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. 
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <gst/interfaces/propertyprobe.h>
-
-#include "v4l2_calls.h"
-#include "gstv4l2tuner.h"
-#ifdef HAVE_XVIDEO
-#include "gstv4l2xoverlay.h"
-#endif
-#include "gstv4l2colorbalance.h"
-
-
-enum
-{
-  PROP_0,
-  PROP_DEVICE,
-  PROP_DEVICE_NAME,
-  PROP_FLAGS,
-  PROP_STD,
-  PROP_INPUT,
-  PROP_FREQUENCY
-};
-
-
-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);
-static void gst_v4l2element_get_property (GObject * object,
-    guint prop_id, GValue * value, GParamSpec * pspec);
-static gboolean gst_v4l2element_start (GstBaseSrc * src);
-static gboolean gst_v4l2element_stop (GstBaseSrc * src);
-
-
-static gboolean
-gst_v4l2_iface_supported (GstImplementsInterface * iface, GType iface_type)
-{
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (iface);
-
-#ifdef HAVE_XVIDEO
-  g_assert (iface_type == GST_TYPE_TUNER ||
-      iface_type == GST_TYPE_X_OVERLAY || iface_type == GST_TYPE_COLOR_BALANCE);
-#else
-  g_assert (iface_type == GST_TYPE_TUNER ||
-      iface_type == GST_TYPE_COLOR_BALANCE);
-#endif
-
-  if (v4l2element->video_fd == -1)
-    return FALSE;
-
-#ifdef HAVE_XVIDEO
-  if (iface_type == GST_TYPE_X_OVERLAY && !GST_V4L2_IS_OVERLAY (v4l2element))
-    return FALSE;
-#endif
-
-  return TRUE;
-}
-
-static void
-gst_v4l2_interface_init (GstImplementsInterfaceClass * klass)
-{
-  /*
-   * default virtual functions 
-   */
-  klass->supported = gst_v4l2_iface_supported;
-}
-
-static const GList *
-gst_v4l2_probe_get_properties (GstPropertyProbe * probe)
-{
-  GObjectClass *klass = G_OBJECT_GET_CLASS (probe);
-  static GList *list = NULL;
-
-  /* well, not perfect, but better than no locking at all.
-   * In the worst case we leak a list node, so who cares? */
-  GST_CLASS_LOCK (GST_OBJECT_CLASS (klass));
-
-  if (!list) {
-    list = g_list_append (NULL, g_object_class_find_property (klass, "device"));
-  }
-
-  GST_CLASS_UNLOCK (GST_OBJECT_CLASS (klass));
-
-  return list;
-}
-
-static gboolean
-gst_v4l2_class_probe_devices (GstV4l2ElementClass * klass, gboolean check)
-{
-  static gboolean init = FALSE;
-  static GList *devices = NULL;
-
-  if (!init && !check) {
-    gchar *dev_base[] = { "/dev/video", "/dev/v4l2/video", NULL };
-    gint base, n, fd;
-
-    while (devices) {
-      GList *item = devices;
-      gchar *device = item->data;
-
-      devices = g_list_remove (devices, item);
-      g_free (device);
-    }
-
-    /*
-     * 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);
-
-        /*
-         * does the /dev/ entry exist at all? 
-         */
-        if (stat (device, &s) == 0) {
-          /*
-           * 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);
-      }
-    }
-
-    init = TRUE;
-  }
-
-  klass->devices = devices;
-
-  return init;
-}
-
-static void
-gst_v4l2_probe_probe_property (GstPropertyProbe * probe,
-    guint prop_id, const GParamSpec * pspec)
-{
-  GstV4l2ElementClass *klass = GST_V4L2ELEMENT_GET_CLASS (probe);
-
-  switch (prop_id) {
-    case PROP_DEVICE:
-      gst_v4l2_class_probe_devices (klass, FALSE);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
-      break;
-  }
-}
-
-static gboolean
-gst_v4l2_probe_needs_probe (GstPropertyProbe * probe,
-    guint prop_id, const GParamSpec * pspec)
-{
-  GstV4l2ElementClass *klass = GST_V4L2ELEMENT_GET_CLASS (probe);
-  gboolean ret = FALSE;
-
-  switch (prop_id) {
-    case PROP_DEVICE:
-      ret = !gst_v4l2_class_probe_devices (klass, TRUE);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
-      break;
-  }
-
-  return ret;
-}
-
-static GValueArray *
-gst_v4l2_class_list_devices (GstV4l2ElementClass * klass)
-{
-  GValueArray *array;
-  GValue value = { 0 };
-  GList *item;
-
-  if (!klass->devices)
-    return NULL;
-
-  array = g_value_array_new (g_list_length (klass->devices));
-  item = klass->devices;
-  g_value_init (&value, G_TYPE_STRING);
-  while (item) {
-    gchar *device = item->data;
-
-    g_value_set_string (&value, device);
-    g_value_array_append (array, &value);
-
-    item = item->next;
-  }
-  g_value_unset (&value);
-
-  return array;
-}
-
-static GValueArray *
-gst_v4l2_probe_get_values (GstPropertyProbe * probe,
-    guint prop_id, const GParamSpec * pspec)
-{
-  GstV4l2ElementClass *klass = GST_V4L2ELEMENT_GET_CLASS (probe);
-  GValueArray *array = NULL;
-
-  switch (prop_id) {
-    case PROP_DEVICE:
-      array = gst_v4l2_class_list_devices (klass);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
-      break;
-  }
-
-  return array;
-}
-
-static void
-gst_v4l2_property_probe_interface_init (GstPropertyProbeInterface * iface)
-{
-  iface->get_properties = gst_v4l2_probe_get_properties;
-  iface->probe_property = gst_v4l2_probe_probe_property;
-  iface->needs_probe = gst_v4l2_probe_needs_probe;
-  iface->get_values = gst_v4l2_probe_get_values;
-}
-
-#define GST_TYPE_V4L2_DEVICE_FLAGS (gst_v4l2_device_get_type ())
-GType
-gst_v4l2_device_get_type (void)
-{
-  static GType v4l2_device_type = 0;
-
-  if (v4l2_device_type == 0) {
-    static const GFlagsValue values[] = {
-      {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}
-    };
-
-    v4l2_device_type =
-        g_flags_register_static ("GstV4l2DeviceTypeFlags", values);
-  }
-
-  return v4l2_device_type;
-}
-
-static void
-gst_v4l2element_init_interfaces (GType type)
-{
-  static const GInterfaceInfo v4l2iface_info = {
-    (GInterfaceInitFunc) gst_v4l2_interface_init,
-    NULL,
-    NULL,
-  };
-  static const GInterfaceInfo v4l2_tuner_info = {
-    (GInterfaceInitFunc) gst_v4l2_tuner_interface_init,
-    NULL,
-    NULL,
-  };
-#ifdef HAVE_XVIDEO
-  static const GInterfaceInfo v4l2_xoverlay_info = {
-    (GInterfaceInitFunc) gst_v4l2_xoverlay_interface_init,
-    NULL,
-    NULL,
-  };
-#endif
-  static const GInterfaceInfo v4l2_colorbalance_info = {
-    (GInterfaceInitFunc) gst_v4l2_color_balance_interface_init,
-    NULL,
-    NULL,
-  };
-  static const GInterfaceInfo v4l2_propertyprobe_info = {
-    (GInterfaceInitFunc) gst_v4l2_property_probe_interface_init,
-    NULL,
-    NULL,
-  };
-
-  g_type_add_interface_static (type,
-      GST_TYPE_IMPLEMENTS_INTERFACE, &v4l2iface_info);
-  g_type_add_interface_static (type, GST_TYPE_TUNER, &v4l2_tuner_info);
-#ifdef HAVE_XVIDEO
-  g_type_add_interface_static (type, GST_TYPE_X_OVERLAY, &v4l2_xoverlay_info);
-#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);
-}
-
-
-static void
-gst_v4l2element_base_init (gpointer g_class)
-{
-  GstV4l2ElementClass *klass = GST_V4L2ELEMENT_CLASS (g_class);
-
-  klass->devices = NULL;
-}
-
-static void
-gst_v4l2element_class_init (GstV4l2ElementClass * klass)
-{
-  GObjectClass *gobject_class;
-  GstBaseSrcClass *basesrc_class;
-
-  gobject_class = (GObjectClass *) klass;
-  basesrc_class = (GstBaseSrcClass *) klass;
-
-  gobject_class->set_property = gst_v4l2element_set_property;
-  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_object_class_install_property (G_OBJECT_CLASS (klass), PROP_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",
-          "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",
-          "frequency to tune to (in Hz)", 0, G_MAXULONG, 0, G_PARAM_READWRITE));
-
-  basesrc_class->start = gst_v4l2element_start;
-  basesrc_class->stop = gst_v4l2element_stop;
-
-  gobject_class->dispose = gst_v4l2element_dispose;
-}
-
-
-static void
-gst_v4l2element_init (GstV4l2Element * v4l2element, GstV4l2ElementClass * klass)
-{
-  /*
-   * some default values 
-   */
-  v4l2element->video_fd = -1;
-  v4l2element->buffer = NULL;
-  v4l2element->videodev = g_strdup ("/dev/video0");
-
-  v4l2element->stds = NULL;
-  v4l2element->inputs = NULL;
-  v4l2element->colors = NULL;
-
-  v4l2element->xwindow_id = 0;
-}
-
-
-static void
-gst_v4l2element_dispose (GObject * object)
-{
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (object);
-
-  if (v4l2element->videodev) {
-    g_free (v4l2element->videodev);
-    v4l2element->videodev = NULL;
-  }
-
-  if (((GObjectClass *) parent_class)->dispose)
-    ((GObjectClass *) parent_class)->dispose (object);
-}
-
-
-static void
-gst_v4l2element_set_property (GObject * object,
-    guint prop_id, const GValue * value, GParamSpec * pspec)
-{
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (object);
-
-  switch (prop_id) {
-    case PROP_DEVICE:
-      if (v4l2element->videodev)
-        g_free (v4l2element->videodev);
-      v4l2element->videodev = g_strdup (g_value_get_string (value));
-      break;
-    case PROP_STD:
-      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));
-
-        if (norm) {
-          /* more generic would be gst_tuner_set_norm (tuner, norm)
-             without g_object_notify */
-          gst_v4l2_tuner_set_norm (tuner, norm);
-        }
-      } else {
-        g_free (v4l2element->std);
-        v4l2element->std = g_value_dup_string (value);
-      }
-      break;
-    case PROP_INPUT:
-      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));
-
-        if (channel) {
-          /* more generic would be gst_tuner_set_channel (tuner, channel)
-             without g_object_notify */
-          gst_v4l2_tuner_set_channel (tuner, channel);
-        }
-      } else {
-        g_free (v4l2element->input);
-        v4l2element->input = g_value_dup_string (value);
-      }
-      break;
-    case PROP_FREQUENCY:
-      if (GST_V4L2_IS_OPEN (v4l2element)) {
-        GstTuner *tuner = GST_TUNER (v4l2element);
-        GstTunerChannel *channel = gst_tuner_get_channel (tuner);
-
-        if (channel &&
-            GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
-          /* more generic would be
-             gst_tuner_set_frequency (tuner, channel, g_value_get_ulong (value))
-             without g_object_notify */
-          gst_v4l2_tuner_set_frequency (tuner, channel,
-              g_value_get_ulong (value));
-        }
-      } else {
-        v4l2element->frequency = g_value_get_ulong (value);
-      }
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-
-static void
-gst_v4l2element_get_property (GObject * object,
-    guint prop_id, GValue * value, GParamSpec * pspec)
-{
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (object);
-
-  switch (prop_id) {
-    case PROP_DEVICE:
-      g_value_set_string (value, v4l2element->videodev);
-      break;
-    case PROP_DEVICE_NAME:
-    {
-      gchar *new = NULL;
-
-      if (GST_V4L2_IS_OPEN (v4l2element))
-        new = (gchar *) v4l2element->vcap.card;
-      g_value_set_string (value, new);
-      break;
-    }
-    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_OVERLAY | V4L2_CAP_TUNER | V4L2_CAP_AUDIO);
-        if (v4l2element->vcap.capabilities & V4L2_CAP_AUDIO)
-          flags |= V4L2_FBUF_CAP_CHROMAKEY;
-      }
-      g_value_set_flags (value, flags);
-      break;
-    }
-    case PROP_STD:
-      g_value_set_string (value, v4l2element->std);
-      break;
-    case PROP_INPUT:
-      g_value_set_string (value, v4l2element->input);
-      break;
-    case PROP_FREQUENCY:
-      g_value_set_ulong (value, v4l2element->frequency);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static gboolean
-gst_v4l2element_start (GstBaseSrc * src)
-{
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (src);
-
-  if (!gst_v4l2_open (v4l2element))
-    return FALSE;
-
-#ifdef HAVE_XVIDEO
-  gst_v4l2_xoverlay_start (v4l2element);
-#endif
-
-  return TRUE;
-}
-
-static gboolean
-gst_v4l2element_stop (GstBaseSrc * src)
-{
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (src);
-
-#ifdef HAVE_XVIDEO
-  gst_v4l2_xoverlay_stop (v4l2element);
-#endif
-
-  if (!gst_v4l2_close (v4l2element))
-    return FALSE;
-
-  return TRUE;
-}
diff --git a/sys/v4l2/gstv4l2element.h b/sys/v4l2/gstv4l2element.h
deleted file mode 100644 (file)
index b866769..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/* GStreamer
- *
- * gstv4l2element.h: base class for V4L2 elements
- *
- * Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
- * Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
- *
- * 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.
- */
-
-#ifndef __GST_V4L2ELEMENT_H__
-#define __GST_V4L2ELEMENT_H__
-
-/* Because of some really cool feature in video4linux1, also known as
- * 'not including sys/types.h and sys/time.h', we had to include it
- * ourselves. In all their intelligence, these people decided to fix
- * this in the next version (video4linux2) in such a cool way that it
- * breaks all compilations of old stuff...
- * The real problem is actually that linux/time.h doesn't use proper
- * macro checks before defining types like struct timeval. The proper
- * fix here is to either fuck the kernel header (which is what we do
- * by defining _LINUX_TIME_H, an innocent little hack) or by fixing it
- * upstream, which I'll consider doing later on. If you get compiler
- * errors here, check your linux/time.h && sys/time.h header setup.
- */
-#include <sys/types.h>
-#include <linux/types.h>
-#define _LINUX_TIME_H
-#define __user
-#include <linux/videodev2.h>
-
-#include <gst/gst.h>
-#include <gst/base/gstpushsrc.h>
-
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_V4L2ELEMENT                   \
-  (gst_v4l2element_get_type())
-#define GST_V4L2ELEMENT(obj)                                           \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_V4L2ELEMENT,GstV4l2Element))
-#define GST_V4L2ELEMENT_CLASS(klass)                                   \
-  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_V4L2ELEMENT,GstV4l2ElementClass))
-#define GST_IS_V4L2ELEMENT(obj)                                        \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_V4L2ELEMENT))
-#define GST_IS_V4L2ELEMENT_CLASS(klass)                                \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_V4L2ELEMENT))
-#define GST_V4L2ELEMENT_GET_CLASS(obj)                                 \
-  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_V4L2ELEMENT, GstV4l2ElementClass))
-
-typedef struct _GstV4l2Element GstV4l2Element;
-typedef struct _GstV4l2ElementClass GstV4l2ElementClass;
-typedef struct _GstV4l2Xv GstV4l2Xv;
-
-struct _GstV4l2Element {
-  GstPushSrc element;
-
-  /* the video device */
-  char *videodev;
-
-  /* the video-device's file descriptor */
-  gint video_fd;
-
-  /* the video buffer (mmap()'ed) */
-  guint8 **buffer;
-
-  /* the video device's capabilities */
-  struct v4l2_capability vcap;
-
-  /* the video device's window properties */
-  struct v4l2_window vwin;
-
-  /* some more info about the current input's capabilities */
-  struct v4l2_input vinput;
-
-  /* lists... */
-  GList *colors;
-  GList *stds;
-  GList *inputs;
-
-  /* properties */
-  gchar *std;
-  gchar *input;
-  gulong frequency;
-
-
-  /* X-overlay */
-  GstV4l2Xv *xv;
-  gulong xwindow_id;
-};
-
-struct _GstV4l2ElementClass {
-  GstPushSrcClass parent_class;
-
-  /* probed devices */
-  GList *devices;
-
-  /* actions */
-  gboolean (*get_attribute)   (GstElement  *element,
-                               const gchar *attr_name,
-                               int         *value);
-  gboolean (*set_attribute)   (GstElement  *element,
-                               const gchar *attr_name,
-                               const int    value);
-};
-
-GType gst_v4l2element_get_type(void);
-
-
-G_END_DECLS
-
-#endif /* __GST_V4L2ELEMENT_H__ */
diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c
new file mode 100644 (file)
index 0000000..941f9a6
--- /dev/null
@@ -0,0 +1,519 @@
+/*
+ * GStreamer gstv4l2object.c: base class for V4L2 elements
+ * Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ * Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
+ *
+ * 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. 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "v4l2_calls.h"
+#include "gstv4l2tuner.h"
+#ifdef HAVE_XVIDEO
+#include "gstv4l2xoverlay.h"
+#endif
+#include "gstv4l2colorbalance.h"
+
+OPEN_V4L2OBJECT_PROPS CLOSE_V4L2OBJECT_PROPS const GList *
+gst_v4l2_probe_get_properties (GstPropertyProbe * probe)
+{
+  GObjectClass *klass = G_OBJECT_GET_CLASS (probe);
+  static GList *list = NULL;
+
+  /* well, not perfect, but better than no locking at all.
+   * In the worst case we leak a list node, so who cares? */
+  GST_CLASS_LOCK (GST_OBJECT_CLASS (klass));
+
+  if (!list) {
+    list = g_list_append (NULL, g_object_class_find_property (klass, "device"));
+  }
+
+  GST_CLASS_UNLOCK (GST_OBJECT_CLASS (klass));
+
+  return list;
+}
+
+static gboolean
+gst_v4l2_class_probe_devices (GstElementClass * klass, gboolean check,
+    GList ** klass_devices)
+{
+  static gboolean init = FALSE;
+  static GList *devices = NULL;
+
+  if (!init && !check) {
+    gchar *dev_base[] = { "/dev/video", "/dev/v4l2/video", NULL };
+    gint base, n, fd;
+
+    while (devices) {
+      GList *item = devices;
+      gchar *device = item->data;
+
+      devices = g_list_remove (devices, item);
+      g_free (device);
+    }
+
+    /*
+     * 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);
+
+        /*
+         * does the /dev/ entry exist at all? 
+         */
+        if (stat (device, &s) == 0) {
+          /*
+           * 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);
+      }
+    }
+
+    init = TRUE;
+  }
+
+  *klass_devices = devices;
+
+  return init;
+}
+
+void
+gst_v4l2_probe_probe_property (GstPropertyProbe * probe,
+    guint prop_id, const GParamSpec * pspec, GList ** klass_devices)
+{
+  GstElementClass *klass = GST_ELEMENT_GET_CLASS (probe);
+
+  switch (prop_id) {
+    case PROP_DEVICE:
+      gst_v4l2_class_probe_devices (klass, FALSE, klass_devices);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
+      break;
+  }
+}
+
+gboolean
+gst_v4l2_probe_needs_probe (GstPropertyProbe * probe,
+    guint prop_id, const GParamSpec * pspec, GList ** klass_devices)
+{
+  GstElementClass *klass = GST_ELEMENT_GET_CLASS (probe);
+  gboolean ret = FALSE;
+
+  switch (prop_id) {
+    case PROP_DEVICE:
+      ret = !gst_v4l2_class_probe_devices (klass, TRUE, klass_devices);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
+      break;
+  }
+
+  return ret;
+
+}
+
+static GValueArray *
+gst_v4l2_class_list_devices (GstElementClass * klass, GList ** klass_devices)
+{
+  GValueArray *array;
+  GValue value = { 0 };
+  GList *item;
+
+  if (!*klass_devices)
+    return NULL;
+
+  array = g_value_array_new (g_list_length (*klass_devices));
+  item = *klass_devices;
+  g_value_init (&value, G_TYPE_STRING);
+  while (item) {
+    gchar *device = item->data;
+
+    g_value_set_string (&value, device);
+    g_value_array_append (array, &value);
+
+    item = item->next;
+  }
+  g_value_unset (&value);
+
+  return array;
+}
+
+GValueArray *
+gst_v4l2_probe_get_values (GstPropertyProbe * probe,
+    guint prop_id, const GParamSpec * pspec, GList ** klass_devices)
+{
+  GstElementClass *klass = GST_ELEMENT_GET_CLASS (probe);
+  GValueArray *array = NULL;
+
+  switch (prop_id) {
+    case PROP_DEVICE:
+      array = gst_v4l2_class_list_devices (klass, klass_devices);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
+      break;
+  }
+
+  return array;
+}
+
+#define GST_TYPE_V4L2_DEVICE_FLAGS (gst_v4l2_device_get_type ())
+GType
+gst_v4l2_device_get_type (void)
+{
+  static GType v4l2_device_type = 0;
+
+  if (v4l2_device_type == 0) {
+    static const GFlagsValue values[] = {
+      {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}
+    };
+
+    v4l2_device_type =
+        g_flags_register_static ("GstV4l2DeviceTypeFlags", values);
+  }
+
+  return v4l2_device_type;
+}
+
+void
+gst_v4l2object_install_properties_helper (GObjectClass * gobject_class)
+{
+
+  g_object_class_install_property
+      (G_OBJECT_CLASS (gobject_class), PROP_DEVICE,
+      g_param_spec_string ("device",
+          "Device", "Device location", NULL, G_PARAM_READWRITE));
+  g_object_class_install_property
+      (G_OBJECT_CLASS (gobject_class),
+      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 (gobject_class), PROP_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",
+          "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",
+          "frequency to tune to (in Hz)", 0, G_MAXULONG, 0, G_PARAM_READWRITE));
+
+}
+
+GstV4l2Object *
+gst_v4l2object_new (GstElement * element,
+    GstV4l2GetInOutFunction get_in_out_func,
+    GstV4l2SetInOutFunction set_in_out_func,
+    GstV4l2UpdateFpsFunction update_fps_func)
+{
+
+  GstV4l2Object *v4l2object;
+
+  /*
+   * some default values 
+   */
+
+  v4l2object = g_new0 (GstV4l2Object, 1);
+
+  v4l2object->element = element;
+  v4l2object->get_in_out_func = get_in_out_func;
+  v4l2object->set_in_out_func = set_in_out_func;
+  v4l2object->update_fps_func = update_fps_func;
+
+  v4l2object->video_fd = -1;
+  v4l2object->buffer = NULL;
+  v4l2object->videodev = g_strdup ("/dev/video0");
+
+  v4l2object->stds = NULL;
+  v4l2object->inputs = NULL;
+  v4l2object->colors = NULL;
+
+  v4l2object->xwindow_id = 0;
+
+  return v4l2object;
+
+}
+
+
+void
+gst_v4l2object_destroy (GstV4l2Object ** v4l2object)
+{
+
+  if (*v4l2object) {
+
+    if ((*v4l2object)->videodev) {
+      g_free ((*v4l2object)->videodev);
+      (*v4l2object)->videodev = NULL;
+    }
+
+    g_free (*v4l2object);
+    *v4l2object = NULL;
+
+  }
+
+}
+
+
+gboolean
+gst_v4l2object_set_property_helper (GstV4l2Object * v4l2object,
+    guint prop_id, const GValue * value, GParamSpec * pspec)
+{
+
+  switch (prop_id) {
+    case PROP_DEVICE:
+      if (v4l2object->videodev)
+        g_free (v4l2object->videodev);
+      v4l2object->videodev = g_strdup (g_value_get_string (value));
+      break;
+    case PROP_STD:
+      if (GST_V4L2_IS_OPEN (v4l2object)) {
+        GstTuner *tuner = GST_TUNER (v4l2object->element);
+        GstTunerNorm *norm = gst_tuner_find_norm_by_name (tuner,
+            (gchar *)
+            g_value_get_string (value));
+
+        if (norm) {
+          /* like gst_tuner_set_norm (tuner, norm)
+             without g_object_notify */
+          gst_v4l2_tuner_set_norm (v4l2object, norm);
+        }
+      } else {
+        g_free (v4l2object->std);
+        v4l2object->std = g_value_dup_string (value);
+      }
+      break;
+    case PROP_INPUT:
+      if (GST_V4L2_IS_OPEN (v4l2object)) {
+        GstTuner *tuner = GST_TUNER (v4l2object->element);
+        GstTunerChannel *channel = gst_tuner_find_channel_by_name (tuner,
+            (gchar *)
+            g_value_get_string (value));
+
+        if (channel) {
+          /* like gst_tuner_set_channel (tuner, channel)
+             without g_object_notify */
+          gst_v4l2_tuner_set_channel (v4l2object, channel);
+        }
+      } else {
+        g_free (v4l2object->input);
+        v4l2object->input = g_value_dup_string (value);
+      }
+      break;
+    case PROP_FREQUENCY:
+      if (GST_V4L2_IS_OPEN (v4l2object)) {
+        GstTuner *tuner = GST_TUNER (v4l2object->element);
+        GstTunerChannel *channel = gst_tuner_get_channel (tuner);
+
+        if (channel &&
+            GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
+          /* like
+             gst_tuner_set_frequency (tuner, channel, g_value_get_ulong (value))
+             without g_object_notify */
+          gst_v4l2_tuner_set_frequency (v4l2object, channel,
+              g_value_get_ulong (value));
+        }
+      } else {
+        v4l2object->frequency = g_value_get_ulong (value);
+      }
+      break;
+    default:
+      return FALSE;
+      break;
+  }
+
+  return TRUE;
+
+}
+
+
+gboolean
+gst_v4l2object_get_property_helper (GstV4l2Object * v4l2object,
+    guint prop_id, GValue * value, GParamSpec * pspec)
+{
+  switch (prop_id) {
+    case PROP_DEVICE:
+      g_value_set_string (value, v4l2object->videodev);
+      break;
+    case PROP_DEVICE_NAME:
+    {
+      gchar *new = NULL;
+
+      if (GST_V4L2_IS_OPEN (v4l2object))
+        new = (gchar *) v4l2object->vcap.card;
+      g_value_set_string (value, new);
+      break;
+    }
+    case PROP_FLAGS:
+    {
+      guint flags = 0;
+
+      if (GST_V4L2_IS_OPEN (v4l2object)) {
+        flags |= v4l2object->vcap.capabilities &
+            (V4L2_CAP_VIDEO_CAPTURE |
+            V4L2_CAP_VIDEO_OUTPUT |
+            V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_TUNER | V4L2_CAP_AUDIO);
+        if (v4l2object->vcap.capabilities & V4L2_CAP_AUDIO)
+          flags |= V4L2_FBUF_CAP_CHROMAKEY;
+      }
+      g_value_set_flags (value, flags);
+      break;
+    }
+    case PROP_STD:
+      g_value_set_string (value, v4l2object->std);
+      break;
+    case PROP_INPUT:
+      g_value_set_string (value, v4l2object->input);
+      break;
+    case PROP_FREQUENCY:
+      g_value_set_ulong (value, v4l2object->frequency);
+      break;
+    default:
+      return FALSE;
+      break;
+  }
+
+  return TRUE;
+
+}
+
+static void
+gst_v4l2_set_defaults (GstV4l2Object * v4l2object)
+{
+  GstTunerNorm *norm = NULL;
+  GstTunerChannel *channel = NULL;
+  GstTuner *tuner = GST_TUNER (v4l2object->element);
+
+  if (v4l2object->std)
+    norm = gst_tuner_find_norm_by_name (tuner, v4l2object->std);
+  if (norm) {
+    gst_tuner_set_norm (tuner, norm);
+  } else {
+    norm =
+        GST_TUNER_NORM (gst_tuner_get_norm (GST_TUNER (v4l2object->element)));
+    if (norm) {
+      v4l2object->std = g_strdup (norm->label);
+      gst_tuner_norm_changed (tuner, norm);
+      g_object_notify (G_OBJECT (v4l2object->element), "std");
+    }
+  }
+
+  if (v4l2object->input)
+    channel = gst_tuner_find_channel_by_name (tuner, v4l2object->input);
+  if (channel) {
+    gst_tuner_set_channel (tuner, channel);
+  } else {
+    channel =
+        GST_TUNER_CHANNEL (gst_tuner_get_channel (GST_TUNER (v4l2object->
+                element)));
+    v4l2object->input = g_strdup (channel->label);
+    gst_tuner_channel_changed (tuner, channel);
+    g_object_notify (G_OBJECT (v4l2object->element), "input");
+  }
+
+  if (GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
+    if (v4l2object->frequency != 0) {
+      gst_tuner_set_frequency (tuner, channel, v4l2object->frequency);
+    } else {
+      v4l2object->frequency = gst_tuner_get_frequency (tuner, channel);
+      if (v4l2object->frequency == 0) {
+        /* guess */
+        gst_tuner_set_frequency (tuner, channel, 1000);
+      } else {
+        g_object_notify (G_OBJECT (v4l2object->element), "frequency");
+      }
+    }
+  }
+}
+
+
+gboolean
+gst_v4l2object_start (GstV4l2Object * v4l2object)
+{
+  if (gst_v4l2_open (v4l2object))
+    gst_v4l2_set_defaults (v4l2object);
+  else
+    return FALSE;
+
+
+#ifdef HAVE_XVIDEO
+  gst_v4l2_xoverlay_start (v4l2object);
+#endif
+
+  return TRUE;
+}
+
+gboolean
+gst_v4l2object_stop (GstV4l2Object * v4l2object)
+{
+
+#ifdef HAVE_XVIDEO
+  gst_v4l2_xoverlay_stop (v4l2object);
+#endif
+
+  if (!gst_v4l2_close (v4l2object))
+    return FALSE;
+
+  return TRUE;
+}
diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h
new file mode 100644 (file)
index 0000000..3755218
--- /dev/null
@@ -0,0 +1,211 @@
+/* GStreamer
+ *
+ * gstv4l2object.h: base class for V4L2 elements
+ *
+ * Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ * Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
+ *
+ * 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.
+ */
+
+#ifndef __GST_V4L2OBJECT_H__
+#define __GST_V4L2OBJECT_H__
+
+/* Because of some really cool feature in video4linux1, also known as
+ * 'not including sys/types.h and sys/time.h', we had to include it
+ * ourselves. In all their intelligence, these people decided to fix
+ * this in the next version (video4linux2) in such a cool way that it
+ * breaks all compilations of old stuff...
+ * The real problem is actually that linux/time.h doesn't use proper
+ * macro checks before defining types like struct timeval. The proper
+ * fix here is to either fuck the kernel header (which is what we do
+ * by defining _LINUX_TIME_H, an innocent little hack) or by fixing it
+ * upstream, which I'll consider doing later on. If you get compiler
+ * errors here, check your linux/time.h && sys/time.h header setup.
+ */
+#include <sys/types.h>
+#include <linux/types.h>
+#define _LINUX_TIME_H
+#define __user
+#include <linux/videodev2.h>
+
+#include <gst/gst.h>
+#include <gst/base/gstpushsrc.h>
+
+#include <gst/interfaces/propertyprobe.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GstV4l2Object GstV4l2Object;
+typedef struct _GstV4l2ObjectClassHelper GstV4l2ObjectClassHelper;
+typedef struct _GstV4l2Xv GstV4l2Xv;
+
+typedef gboolean  (*GstV4l2GetInOutFunction) (GstV4l2Object * v4l2object, gint * input);
+typedef gboolean  (*GstV4l2SetInOutFunction) (GstV4l2Object * v4l2object, gint input);
+typedef gboolean  (*GstV4l2UpdateFpsFunction)   (GstV4l2Object * v4l2object);
+
+struct _GstV4l2Object {
+  GstElement * element;
+
+  /* the video device */
+  char *videodev;
+
+  /* the video-device's file descriptor */
+  gint video_fd;
+
+  /* the video buffer (mmap()'ed) */
+  guint8 **buffer;
+
+  /* the video device's capabilities */
+  struct v4l2_capability vcap;
+
+  /* the video device's window properties */
+  struct v4l2_window vwin;
+
+  /* some more info about the current input's capabilities */
+  struct v4l2_input vinput;
+
+  /* lists... */
+  GList *colors;
+  GList *stds;
+  GList *inputs;
+
+  /* properties */
+  gchar *std;
+  gchar *input;
+  gulong frequency;
+
+
+  /* X-overlay */
+  GstV4l2Xv *xv;
+  gulong xwindow_id;
+
+  /* funcs */
+  GstV4l2GetInOutFunction get_in_out_func;
+  GstV4l2SetInOutFunction set_in_out_func;
+  GstV4l2UpdateFpsFunction   update_fps_func;
+
+};
+
+struct _GstV4l2ObjectClassHelper {
+  /* probed devices */
+  GList *devices;
+
+};
+
+
+GType gst_v4l2object_get_type(void);
+
+
+#define OPEN_V4L2OBJECT_PROPS                  \
+  enum {                                       \
+    PROP_0,                                    \
+    PROP_DEVICE,                               \
+    PROP_DEVICE_NAME,                          \
+    PROP_FLAGS,                                        \
+    PROP_STD,                                  \
+    PROP_INPUT,                                        \
+    PROP_FREQUENCY
+
+#define CLOSE_V4L2OBJECT_PROPS   };
+
+extern GstV4l2Object *
+gst_v4l2object_new (GstElement * element,
+                    GstV4l2GetInOutFunction get_in_out_func,
+                    GstV4l2SetInOutFunction set_in_out_func,
+                   GstV4l2UpdateFpsFunction   update_fps_func);
+
+extern void
+gst_v4l2object_destroy (GstV4l2Object ** v4l2object);
+
+extern void
+gst_v4l2object_install_properties_helper (GObjectClass *gobject_class);
+
+extern gboolean
+gst_v4l2object_set_property_helper (GstV4l2Object *v4l2object,
+                                   guint prop_id, const GValue * value, GParamSpec * pspec);
+extern gboolean
+gst_v4l2object_get_property_helper (GstV4l2Object *v4l2object,
+                                   guint prop_id, GValue * value, GParamSpec * pspec);
+
+extern gboolean gst_v4l2object_start (GstV4l2Object *v4l2object);
+extern gboolean gst_v4l2object_stop (GstV4l2Object *v4l2object);
+
+extern const GList *
+gst_v4l2_probe_get_properties (GstPropertyProbe * probe);
+
+extern void
+gst_v4l2_probe_probe_property (GstPropertyProbe * probe,
+                              guint prop_id,
+                               const GParamSpec * pspec,
+                               GList ** klass_devices);
+
+extern gboolean
+gst_v4l2_probe_needs_probe (GstPropertyProbe * probe,
+                           guint prop_id,
+                            const GParamSpec * pspec,
+                            GList ** klass_devices);
+
+extern GValueArray *
+gst_v4l2_probe_get_values (GstPropertyProbe * probe,
+                          guint prop_id,
+                           const GParamSpec * pspec,
+                           GList ** klass_devices);
+
+#define GST_IMPLEMENT_V4L2_PROBE_METHODS(Type_Class, interface_as_function)                 \
+                                                                                            \
+static void                                                                                 \
+interface_as_function ## _probe_probe_property (GstPropertyProbe * probe,                   \
+                                               guint prop_id,                              \
+                                                const GParamSpec * pspec)                   \
+{                                                                                           \
+  Type_Class *this_class = (Type_Class*) probe;                                             \
+  gst_v4l2_probe_probe_property (probe, prop_id, pspec,                                     \
+                                        &this_class->v4l2_class_devices);                  \
+}                                                                                           \
+                                                                                            \
+static gboolean                                                                             \
+interface_as_function ## _probe_needs_probe (GstPropertyProbe * probe,                      \
+                                            guint prop_id,                                 \
+                                             const GParamSpec * pspec)                      \
+{                                                                                           \
+  Type_Class *this_class = (Type_Class*) probe;                                             \
+  return gst_v4l2_probe_needs_probe (probe, prop_id, pspec,                                 \
+                                        &this_class->v4l2_class_devices);                  \
+}                                                                                           \
+                                                                                            \
+static GValueArray *                                                                        \
+interface_as_function ## _probe_get_values (GstPropertyProbe * probe,                       \
+                                           guint prop_id,                                  \
+                                            const GParamSpec * pspec)                       \
+{                                                                                           \
+  Type_Class *this_class = (Type_Class*) probe;                                             \
+  return gst_v4l2_probe_get_values (probe, prop_id, pspec,                                  \
+                                    &this_class->v4l2_class_devices);                      \
+}                                                                                           \
+                                                                                            \
+static void                                                                                \
+interface_as_function ## _property_probe_interface_init (GstPropertyProbeInterface * iface) \
+{                                                                                           \
+  iface->get_properties = gst_v4l2_probe_get_properties;                                    \
+  iface->probe_property = interface_as_function ## _probe_probe_property;                   \
+  iface->needs_probe = interface_as_function ## _probe_needs_probe;                         \
+  iface->get_values = interface_as_function ## _probe_get_values;                                            \
+}
+
+G_END_DECLS
+
+#endif /* __GST_V4L2OBJECT_H__ */
index dc8b7cb..b38d34e 100644 (file)
 #include <string.h>
 #include <sys/time.h>
 #include "v4l2src_calls.h"
-#include <sys/ioctl.h>
 #include <unistd.h>
 
+#include "gstv4l2colorbalance.h"
+#include "gstv4l2tuner.h"
+#include "gstv4l2xoverlay.h"
 
 static const GstElementDetails gst_v4l2src_details =
 GST_ELEMENT_DETAILS ("Video (video4linux2/raw) Source",
@@ -65,14 +67,8 @@ GST_DEBUG_CATEGORY (v4l2src_debug);
 #define GST_CAT_DEFAULT v4l2src_debug
 
 
-enum
-{
-  PROP_0,
-  PROP_USE_FIXED_FPS
-};
-
-
-static guint32 gst_v4l2_formats[] = {
+OPEN_V4L2OBJECT_PROPS, PROP_USE_FIXED_FPS
+    CLOSE_V4L2OBJECT_PROPS static guint32 gst_v4l2_formats[] = {
   /* from Linux 2.6.15 videodev2.h */
   V4L2_PIX_FMT_RGB332,
   V4L2_PIX_FMT_RGB555,
@@ -130,8 +126,93 @@ static guint32 gst_v4l2_formats[] = {
 
 #define GST_V4L2_FORMAT_COUNT (G_N_ELEMENTS (gst_v4l2_formats))
 
+GST_IMPLEMENT_V4L2_PROBE_METHODS (GstV4l2SrcClass, gst_v4l2src)
+
+    GST_IMPLEMENT_V4L2_COLOR_BALANCE_METHODS (GstV4l2Src, gst_v4l2src)
+
+    GST_IMPLEMENT_V4L2_TUNER_METHODS (GstV4l2Src, gst_v4l2src)
+#ifdef HAVE_XVIDEO
+    GST_IMPLEMENT_V4L2_XOVERLAY_METHODS (GstV4l2Src, gst_v4l2src)
+#endif
+     static gboolean
+         gst_v4l2src_iface_supported (GstImplementsInterface * iface,
+    GType iface_type)
+{
+  GstV4l2Object *v4l2object = GST_V4L2SRC (iface)->v4l2object;
+
+#ifdef HAVE_XVIDEO
+  g_assert (iface_type == GST_TYPE_TUNER ||
+      iface_type == GST_TYPE_X_OVERLAY || iface_type == GST_TYPE_COLOR_BALANCE);
+#else
+  g_assert (iface_type == GST_TYPE_TUNER ||
+      iface_type == GST_TYPE_COLOR_BALANCE);
+#endif
+
+  if (v4l2object->video_fd == -1)
+    return FALSE;
+
+#ifdef HAVE_XVIDEO
+  if (iface_type == GST_TYPE_X_OVERLAY && !GST_V4L2_IS_OVERLAY (v4l2object))
+    return FALSE;
+#endif
+
+  return TRUE;
+}
 
-GST_BOILERPLATE (GstV4l2Src, gst_v4l2src, GstV4l2Element, GST_TYPE_V4L2ELEMENT);
+static void
+gst_v4l2src_interface_init (GstImplementsInterfaceClass * klass)
+{
+  /*
+   * default virtual functions 
+   */
+  klass->supported = gst_v4l2src_iface_supported;
+}
+
+void
+gst_v4l2src_init_interfaces (GType type)
+{
+  static const GInterfaceInfo v4l2iface_info = {
+    (GInterfaceInitFunc) gst_v4l2src_interface_init,
+    NULL,
+    NULL,
+  };
+  static const GInterfaceInfo v4l2_tuner_info = {
+    (GInterfaceInitFunc) gst_v4l2src_tuner_interface_init,
+    NULL,
+    NULL,
+  };
+#ifdef HAVE_XVIDEO
+  static const GInterfaceInfo v4l2_xoverlay_info = {
+    (GInterfaceInitFunc) gst_v4l2src_xoverlay_interface_init,
+    NULL,
+    NULL,
+  };
+#endif
+  static const GInterfaceInfo v4l2_colorbalance_info = {
+    (GInterfaceInitFunc) gst_v4l2src_color_balance_interface_init,
+    NULL,
+    NULL,
+  };
+  static const GInterfaceInfo v4l2_propertyprobe_info = {
+    (GInterfaceInitFunc) gst_v4l2src_property_probe_interface_init,
+    NULL,
+    NULL,
+  };
+
+  g_type_add_interface_static (type,
+      GST_TYPE_IMPLEMENTS_INTERFACE, &v4l2iface_info);
+  g_type_add_interface_static (type, GST_TYPE_TUNER, &v4l2_tuner_info);
+#ifdef HAVE_XVIDEO
+  g_type_add_interface_static (type, GST_TYPE_X_OVERLAY, &v4l2_xoverlay_info);
+#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);
+}
+
+GST_BOILERPLATE_FULL (GstV4l2Src, gst_v4l2src, GstPushSrc, GST_TYPE_PUSH_SRC,
+    gst_v4l2src_init_interfaces);
 
 static void gst_v4l2src_dispose (GObject * object);
 
@@ -156,6 +237,9 @@ static void
 gst_v4l2src_base_init (gpointer g_class)
 {
   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
+  GstV4l2SrcClass *gstv4l2src_class = GST_V4L2SRC_CLASS (g_class);
+
+  gstv4l2src_class->v4l2_class_devices = NULL;
 
   GST_DEBUG_CATEGORY_INIT (v4l2src_debug, "v4l2src", 0, "V4L2 source element");
 
@@ -181,6 +265,8 @@ gst_v4l2src_class_init (GstV4l2SrcClass * klass)
   gobject_class->set_property = gst_v4l2src_set_property;
   gobject_class->get_property = gst_v4l2src_get_property;
 
+  gst_v4l2object_install_properties_helper (gobject_class);
+
   g_object_class_install_property
       (gobject_class, PROP_USE_FIXED_FPS,
       g_param_spec_boolean ("use_fixed_fps", "Use Fixed FPS",
@@ -203,6 +289,9 @@ static void
 gst_v4l2src_init (GstV4l2Src * v4l2src, GstV4l2SrcClass * klass)
 {
 
+  v4l2src->v4l2object = gst_v4l2object_new (GST_ELEMENT (v4l2src),
+      gst_v4l2_get_input, gst_v4l2_set_input, gst_v4l2src_update_fps);
+
   v4l2src->breq.count = 0;
 
   v4l2src->formats = NULL;
@@ -244,17 +333,24 @@ gst_v4l2src_set_property (GObject * object,
   g_return_if_fail (GST_IS_V4L2SRC (object));
   v4l2src = GST_V4L2SRC (object);
 
-  switch (prop_id) {
-    case PROP_USE_FIXED_FPS:
-      if (!GST_V4L2_IS_ACTIVE (GST_V4L2ELEMENT (v4l2src))) {
-        v4l2src->use_fixed_fps = g_value_get_boolean (value);
-      }
-      break;
 
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
+  if (!gst_v4l2object_set_property_helper (v4l2src->v4l2object,
+          prop_id, value, pspec)) {
+
+    switch (prop_id) {
+      case PROP_USE_FIXED_FPS:
+        if (!GST_V4L2_IS_ACTIVE (v4l2src->v4l2object)) {
+          v4l2src->use_fixed_fps = g_value_get_boolean (value);
+        }
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+
   }
+
 }
 
 
@@ -267,42 +363,23 @@ gst_v4l2src_get_property (GObject * object,
   g_return_if_fail (GST_IS_V4L2SRC (object));
   v4l2src = GST_V4L2SRC (object);
 
-  switch (prop_id) {
-    case PROP_USE_FIXED_FPS:
-      g_value_set_boolean (value, v4l2src->use_fixed_fps);
-      break;
+  if (!gst_v4l2object_get_property_helper (v4l2src->v4l2object,
+          prop_id, value, pspec)) {
 
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-
-gboolean
-get_fmt_width_height (GstV4l2Src * v4l2src, int *width, int *height)
-{
-  int ret;
-
-  struct v4l2_format format;
-
-  memset (&format, 0x00, sizeof (format));
-
-  format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-  ret = ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_G_FMT, &format);
-
-  if (ret == 0) {
-
-    *width = format.fmt.pix.width;
-    *height = format.fmt.pix.height;
+    switch (prop_id) {
+      case PROP_USE_FIXED_FPS:
+        g_value_set_boolean (value, v4l2src->use_fixed_fps);
+        break;
 
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
   }
 
-  return (ret == 0);
-
 }
 
+
 /* this function is a bit of a last resort */
 static void
 gst_v4l2src_fixate (GstPad * pad, GstCaps * caps)
@@ -636,7 +713,7 @@ gst_v4l2src_get_caps (GstBaseSrc * src)
   GstStructure *structure;
   guint fps_n, fps_d;
 
-  if (!GST_V4L2_IS_OPEN (GST_V4L2ELEMENT (v4l2src))) {
+  if (!GST_V4L2_IS_OPEN (v4l2src->v4l2object)) {
     return
         gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD
             (v4l2src)));
@@ -702,11 +779,11 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
   v4l2src = GST_V4L2SRC (src);
 
   /* if we're not open, punt -- we'll get setcaps'd later via negotiate */
-  if (!GST_V4L2_IS_OPEN (v4l2src))
+  if (!GST_V4L2_IS_OPEN (v4l2src->v4l2object))
     return FALSE;
 
   /* make sure we stop capturing and dealloc buffers */
-  if (GST_V4L2_IS_ACTIVE (v4l2src)) {
+  if (GST_V4L2_IS_ACTIVE (v4l2src->v4l2object)) {
     if (!gst_v4l2src_capture_stop (v4l2src))
       return FALSE;
     if (!gst_v4l2src_capture_deinit (v4l2src))
@@ -751,7 +828,7 @@ gst_v4l2src_start (GstBaseSrc * src)
 {
   GstV4l2Src *v4l2src = GST_V4L2SRC (src);
 
-  if (!GST_BASE_SRC_CLASS (parent_class)->start (src))
+  if (!gst_v4l2object_start (v4l2src->v4l2object))
     return FALSE;
 
   v4l2src->offset = 0;
@@ -764,15 +841,16 @@ gst_v4l2src_stop (GstBaseSrc * src)
 {
   GstV4l2Src *v4l2src = GST_V4L2SRC (src);
 
-  if (GST_V4L2_IS_ACTIVE (v4l2src) && !gst_v4l2src_capture_stop (v4l2src))
+  if (GST_V4L2_IS_ACTIVE (v4l2src->v4l2object)
+      && !gst_v4l2src_capture_stop (v4l2src))
     return FALSE;
 
-  if (GST_V4L2ELEMENT (v4l2src)->buffer != NULL) {
+  if (v4l2src->v4l2object->buffer != NULL) {
     if (!gst_v4l2src_capture_deinit (v4l2src))
       return FALSE;
   }
 
-  if (!GST_BASE_SRC_CLASS (parent_class)->stop (src))
+  if (!gst_v4l2object_stop (v4l2src->v4l2object))
     return FALSE;
 
   return TRUE;
@@ -791,7 +869,7 @@ gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf)
     GST_BUFFER_OFFSET (*buf) = GST_BUFFER_OFFSET_NONE;
 
     amount =
-        read (GST_V4L2ELEMENT (v4l2src)->video_fd, GST_BUFFER_DATA (*buf),
+        read (v4l2src->v4l2object->video_fd, GST_BUFFER_DATA (*buf),
         buffersize);
     if (amount == buffersize) {
       break;
@@ -801,14 +879,14 @@ gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf)
       } else {
         GST_ELEMENT_ERROR (v4l2src, RESOURCE, SYNC, (NULL),
             ("error read()ing a buffer on device %s: %s",
-                GST_V4L2ELEMENT (v4l2src)->videodev, g_strerror (errno)));
+                v4l2src->v4l2object->videodev, g_strerror (errno)));
         gst_buffer_unref (*buf);
         return GST_FLOW_ERROR;
       }
     } else {
       GST_ELEMENT_ERROR (v4l2src, RESOURCE, SYNC, (NULL),
           ("error read()ing a buffer on device %s: got only %d bytes instead of expected %d",
-              GST_V4L2ELEMENT (v4l2src)->videodev, amount, buffersize));
+              v4l2src->v4l2object->videodev, amount, buffersize));
       gst_buffer_unref (*buf);
       return GST_FLOW_ERROR;
     }
index 58815dd..54500ac 100644 (file)
@@ -25,7 +25,7 @@
 #define __GST_V4L2SRC_H__
 
 
-#include <gstv4l2element.h>
+#include <gstv4l2object.h>
 
 GST_DEBUG_CATEGORY_EXTERN (v4l2src_debug);
 
@@ -78,7 +78,9 @@ enum
 
 struct _GstV4l2Src
 {
-  GstV4l2Element v4l2element;
+  GstPushSrc pushsrc;
+
+  GstV4l2Object * v4l2object;
 
   /* pads */
   GstPad *srcpad;
@@ -104,12 +106,14 @@ struct _GstV4l2Src
 
 struct _GstV4l2SrcClass
 {
-  GstV4l2ElementClass parent_class;
+  GstPushSrcClass parent_class;
+  
+  GList *v4l2_class_devices;
+
 };
 
 
 GType gst_v4l2src_get_type (void);
 
-
 G_END_DECLS
 #endif /* __GST_V4L2SRC_H__ */
index ff813b5..d0a9a1f 100644 (file)
 #include <gst/gst.h>
 
 #include "gstv4l2tuner.h"
-#include "gstv4l2element.h"
+#include "gstv4l2object.h"
 #include "v4l2_calls.h"
 #include "v4l2src_calls.h"
 
-#include <sys/ioctl.h>
-
 static void gst_v4l2_tuner_channel_class_init (GstV4l2TunerChannelClass *
     klass);
 static void gst_v4l2_tuner_channel_init (GstV4l2TunerChannel * channel);
@@ -40,36 +38,6 @@ static void gst_v4l2_tuner_channel_init (GstV4l2TunerChannel * channel);
 static void gst_v4l2_tuner_norm_class_init (GstV4l2TunerNormClass * klass);
 static void gst_v4l2_tuner_norm_init (GstV4l2TunerNorm * norm);
 
-static const GList *gst_v4l2_tuner_list_channels (GstTuner * mixer);
-
-static void
-gst_v4l2_tuner_set_channel_and_notify (GstTuner * mixer,
-    GstTunerChannel * channel);
-static GstTunerChannel *gst_v4l2_tuner_get_channel (GstTuner * mixer);
-
-static const GList *gst_v4l2_tuner_list_norms (GstTuner * mixer);
-
-static void
-gst_v4l2_tuner_set_norm_and_notify (GstTuner * mixer, GstTunerNorm * norm);
-static GstTunerNorm *gst_v4l2_tuner_get_norm (GstTuner * mixer);
-
-static void
-gst_v4l2_tuner_set_frequency_and_notify (GstTuner * mixer,
-    GstTunerChannel * channel, gulong frequency);
-static gulong gst_v4l2_tuner_get_frequency (GstTuner * mixer,
-    GstTunerChannel * channel);
-static gint gst_v4l2_tuner_signal_strength (GstTuner * mixer,
-    GstTunerChannel * channel);
-
-static gboolean gst_v4l2_get_input (GstV4l2Element * v4l2element, gint * input);
-static gboolean gst_v4l2_set_input (GstV4l2Element * v4l2element, gint input);
-
-#if 0                           /* output not handled by now */
-static gboolean
-gst_v4l2_get_output (GstV4l2Element * v4l2element, gint * output);
-static gboolean gst_v4l2_set_output (GstV4l2Element * v4l2element, gint output);
-#endif /* #if 0 - output not handled by now */
-
 static GstTunerNormClass *norm_parent_class = NULL;
 static GstTunerChannelClass *channel_parent_class = NULL;
 
@@ -153,26 +121,9 @@ gst_v4l2_tuner_norm_init (GstV4l2TunerNorm * norm)
   norm->index = 0;
 }
 
-void
-gst_v4l2_tuner_interface_init (GstTunerClass * klass)
-{
-  /* default virtual functions */
-  klass->list_channels = gst_v4l2_tuner_list_channels;
-  klass->set_channel = gst_v4l2_tuner_set_channel_and_notify;
-  klass->get_channel = gst_v4l2_tuner_get_channel;
-
-  klass->list_norms = gst_v4l2_tuner_list_norms;
-  klass->set_norm = gst_v4l2_tuner_set_norm_and_notify;
-  klass->get_norm = gst_v4l2_tuner_get_norm;
-
-  klass->set_frequency = gst_v4l2_tuner_set_frequency_and_notify;
-  klass->get_frequency = gst_v4l2_tuner_get_frequency;
-  klass->signal_strength = gst_v4l2_tuner_signal_strength;
-}
-
 #if 0                           /* output not handled by now */
 static gboolean
-gst_v4l2_tuner_is_sink (GstV4l2Element * v4l2element)
+gst_v4l2_tuner_is_sink (GstV4l2Object * v4l2object)
 {
   GstPadDirection dir = GST_PAD_UNKNOWN;
 
@@ -181,56 +132,47 @@ gst_v4l2_tuner_is_sink (GstV4l2Element * v4l2element)
 #endif /* #if 0 - output not handled by now */
 
 static G_GNUC_UNUSED gboolean
-gst_v4l2_tuner_contains_channel (GstV4l2Element * v4l2element,
+gst_v4l2_tuner_contains_channel (GstV4l2Object * v4l2object,
     GstV4l2TunerChannel * v4l2channel)
 {
   const GList *item;
 
-  for (item = v4l2element->inputs; item != NULL; item = item->next)
+  for (item = v4l2object->inputs; item != NULL; item = item->next)
     if (item->data == v4l2channel)
       return TRUE;
 
   return FALSE;
 }
 
-static const GList *
-gst_v4l2_tuner_list_channels (GstTuner * mixer)
+const GList *
+gst_v4l2_tuner_list_channels (GstV4l2Object * v4l2object)
 {
-  return GST_V4L2ELEMENT (mixer)->inputs;
+  return v4l2object->inputs;
 }
 
-static void
-gst_v4l2_tuner_set_channel_and_notify (GstTuner * mixer,
+void
+gst_v4l2_tuner_set_channel_and_notify (GstV4l2Object * v4l2object,
     GstTunerChannel * channel)
 {
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
-
-  if (gst_v4l2_tuner_set_channel (mixer, channel)) {
-    g_object_notify (G_OBJECT (v4l2element), "input");
+  if (gst_v4l2_tuner_set_channel (v4l2object, channel)) {
+    g_object_notify (G_OBJECT (v4l2object->element), "input");
   }
 }
 
 gboolean
-gst_v4l2_tuner_set_channel (GstTuner * mixer, GstTunerChannel * channel)
+gst_v4l2_tuner_set_channel (GstV4l2Object * v4l2object,
+    GstTunerChannel * channel)
 {
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
-  GstV4l2Src *v4l2src = GST_V4L2SRC (v4l2element);
   GstV4l2TunerChannel *v4l2channel = GST_V4L2_TUNER_CHANNEL (channel);
 
   /* assert that we're opened and that we're using a known item */
-  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2element), FALSE);
-  g_return_val_if_fail (gst_v4l2_tuner_contains_channel (v4l2element,
+  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), FALSE);
+  g_return_val_if_fail (gst_v4l2_tuner_contains_channel (v4l2object,
           v4l2channel), FALSE);
 
-  if (
-#if 0                           /* output not handled by now */
-      gst_v4l2_tuner_is_sink (v4l2element) ?
-      gst_v4l2_set_output (v4l2element, v4l2channel->index) :
-#endif /* #if 0 - output not handled by now */
-      gst_v4l2_set_input (v4l2element, v4l2channel->index)
-      ) {
-    gst_tuner_channel_changed (mixer, channel);
-    gst_v4l2src_get_fps (v4l2src, &v4l2src->fps_n, &v4l2src->fps_d);
+  if (v4l2object->set_in_out_func (v4l2object, v4l2channel->index)) {
+    gst_tuner_channel_changed (GST_TUNER (v4l2object->element), channel);
+    v4l2object->update_fps_func (v4l2object);
     return TRUE;
   }
 
@@ -238,62 +180,18 @@ gst_v4l2_tuner_set_channel (GstTuner * mixer, GstTunerChannel * channel)
 
 }
 
-static gboolean
-gst_v4l2_get_input (GstV4l2Element * v4l2element, gint * input)
+GstTunerChannel *
+gst_v4l2_tuner_get_channel (GstV4l2Object * v4l2object)
 {
-  gint n;
-
-  GST_DEBUG_OBJECT (v4l2element, "trying to get input");
-  if (!GST_V4L2_IS_OPEN (v4l2element))
-    return FALSE;
-
-  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));
-    return FALSE;
-  }
-
-  *input = n;
-
-  return TRUE;
-}
-
-static gboolean
-gst_v4l2_set_input (GstV4l2Element * v4l2element, gint input)
-{
-  GST_DEBUG_OBJECT (v4l2element, "trying to set input to %d", input);
-  if (!GST_V4L2_IS_OPEN (v4l2element))
-    return FALSE;
-
-  if (ioctl (v4l2element->video_fd, VIDIOC_S_INPUT, &input) < 0) {
-    GST_WARNING_OBJECT (v4l2element, "Failed to set input %d on device %s: %s",
-        input, v4l2element->videodev, g_strerror (errno));
-    return FALSE;
-  }
-
-  return TRUE;
-}
-
-
-static GstTunerChannel *
-gst_v4l2_tuner_get_channel (GstTuner * mixer)
-{
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
   GList *item;
   gint channel;
 
   /* assert that we're opened and that we're using a known item */
-  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2element), NULL);
+  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), NULL);
 
-#if 0                           /* output not handled by now */
-  if (gst_v4l2_tuner_is_sink (v4l2element))
-    gst_v4l2_get_output (v4l2element, &channel);
-  else
-#endif /* #if 0 - output not handled by now */
-    gst_v4l2_get_input (v4l2element, &channel);
+  v4l2object->get_in_out_func (v4l2object, &channel);
 
-  for (item = v4l2element->inputs; item != NULL; item = item->next) {
+  for (item = v4l2object->inputs; item != NULL; item = item->next) {
     if (channel == GST_V4L2_TUNER_CHANNEL (item->data)->index)
       return (GstTunerChannel *) item->data;
   }
@@ -302,49 +200,46 @@ gst_v4l2_tuner_get_channel (GstTuner * mixer)
 }
 
 static G_GNUC_UNUSED gboolean
-gst_v4l2_tuner_contains_norm (GstV4l2Element * v4l2element,
+gst_v4l2_tuner_contains_norm (GstV4l2Object * v4l2object,
     GstV4l2TunerNorm * v4l2norm)
 {
   const GList *item;
 
-  for (item = v4l2element->stds; item != NULL; item = item->next)
+  for (item = v4l2object->stds; item != NULL; item = item->next)
     if (item->data == v4l2norm)
       return TRUE;
 
   return FALSE;
 }
 
-static const GList *
-gst_v4l2_tuner_list_norms (GstTuner * mixer)
+const GList *
+gst_v4l2_tuner_list_norms (GstV4l2Object * v4l2object)
 {
-  return GST_V4L2ELEMENT (mixer)->stds;
+  return v4l2object->stds;
 }
 
-static void
-gst_v4l2_tuner_set_norm_and_notify (GstTuner * mixer, GstTunerNorm * norm)
+void
+gst_v4l2_tuner_set_norm_and_notify (GstV4l2Object * v4l2object,
+    GstTunerNorm * norm)
 {
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
-
-  if (gst_v4l2_tuner_set_norm (mixer, norm)) {
-    g_object_notify (G_OBJECT (v4l2element), "std");
+  if (gst_v4l2_tuner_set_norm (v4l2object, norm)) {
+    g_object_notify (G_OBJECT (v4l2object->element), "std");
   }
 }
 
 gboolean
-gst_v4l2_tuner_set_norm (GstTuner * mixer, GstTunerNorm * norm)
+gst_v4l2_tuner_set_norm (GstV4l2Object * v4l2object, GstTunerNorm * norm)
 {
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
-  GstV4l2Src *v4l2src = GST_V4L2SRC (v4l2element);
   GstV4l2TunerNorm *v4l2norm = GST_V4L2_TUNER_NORM (norm);
 
   /* assert that we're opened and that we're using a known item */
-  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2element), FALSE);
-  g_return_val_if_fail (gst_v4l2_tuner_contains_norm (v4l2element, v4l2norm),
+  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), FALSE);
+  g_return_val_if_fail (gst_v4l2_tuner_contains_norm (v4l2object, v4l2norm),
       FALSE);
 
-  if (gst_v4l2_set_norm (v4l2element, v4l2norm->index)) {
-    gst_tuner_norm_changed (mixer, norm);
-    gst_v4l2src_get_fps (v4l2src, &v4l2src->fps_n, &v4l2src->fps_d);
+  if (gst_v4l2_set_norm (v4l2object, v4l2norm->index)) {
+    gst_tuner_norm_changed (GST_TUNER (v4l2object->element), norm);
+    v4l2object->update_fps_func (v4l2object);
     return TRUE;
   }
 
@@ -352,19 +247,18 @@ gst_v4l2_tuner_set_norm (GstTuner * mixer, GstTunerNorm * norm)
 
 }
 
-static GstTunerNorm *
-gst_v4l2_tuner_get_norm (GstTuner * mixer)
+GstTunerNorm *
+gst_v4l2_tuner_get_norm (GstV4l2Object * v4l2object)
 {
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
   GList *item;
   v4l2_std_id norm;
 
   /* assert that we're opened and that we're using a known item */
-  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2element), NULL);
+  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), NULL);
 
-  gst_v4l2_get_norm (v4l2element, &norm);
+  gst_v4l2_get_norm (v4l2object, &norm);
 
-  for (item = v4l2element->stds; item != NULL; item = item->next) {
+  for (item = v4l2object->stds; item != NULL; item = item->next) {
     if (norm == GST_V4L2_TUNER_NORM (item->data)->index)
       return (GstTunerNorm *) item->data;
   }
@@ -372,131 +266,85 @@ gst_v4l2_tuner_get_norm (GstTuner * mixer)
   return NULL;
 }
 
-static void
-gst_v4l2_tuner_set_frequency_and_notify (GstTuner * mixer,
+void
+gst_v4l2_tuner_set_frequency_and_notify (GstV4l2Object * v4l2object,
     GstTunerChannel * channel, gulong frequency)
 {
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
-
-  if (gst_v4l2_tuner_set_frequency (mixer, channel, frequency)) {
-    g_object_notify (G_OBJECT (v4l2element), "frequency");
+  if (gst_v4l2_tuner_set_frequency (v4l2object, channel, frequency)) {
+    g_object_notify (G_OBJECT (v4l2object->element), "frequency");
   }
 }
 
 gboolean
-gst_v4l2_tuner_set_frequency (GstTuner * mixer,
+gst_v4l2_tuner_set_frequency (GstV4l2Object * v4l2object,
     GstTunerChannel * channel, gulong frequency)
 {
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
   GstV4l2TunerChannel *v4l2channel = GST_V4L2_TUNER_CHANNEL (channel);
   gint chan;
 
   /* assert that we're opened and that we're using a known item */
-  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2element), FALSE);
+  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), FALSE);
   g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel,
           GST_TUNER_CHANNEL_FREQUENCY), FALSE);
-  g_return_val_if_fail (gst_v4l2_tuner_contains_channel (v4l2element,
+  g_return_val_if_fail (gst_v4l2_tuner_contains_channel (v4l2object,
           v4l2channel), FALSE);
 
-  gst_v4l2_get_input (v4l2element, &chan);
+  v4l2object->get_in_out_func (v4l2object, &chan);
   if (chan == GST_V4L2_TUNER_CHANNEL (channel)->index &&
       GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
-    if (gst_v4l2_set_frequency (v4l2element, v4l2channel->tuner, frequency)) {
-      gst_tuner_frequency_changed (mixer, channel, frequency);
+    if (gst_v4l2_set_frequency (v4l2object, v4l2channel->tuner, frequency)) {
+      gst_tuner_frequency_changed (GST_TUNER (v4l2object->element), channel,
+          frequency);
       return TRUE;
     }
   }
   return FALSE;
 }
 
-static gulong
-gst_v4l2_tuner_get_frequency (GstTuner * mixer, GstTunerChannel * channel)
+gulong
+gst_v4l2_tuner_get_frequency (GstV4l2Object * v4l2object,
+    GstTunerChannel * channel)
 {
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
   GstV4l2TunerChannel *v4l2channel = GST_V4L2_TUNER_CHANNEL (channel);
   gint chan;
   gulong frequency = 0;
 
   /* assert that we're opened and that we're using a known item */
-  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2element), 0);
+  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), 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 (v4l2object,
+          v4l2channel), 0);
 
-  gst_v4l2_get_input (v4l2element, &chan);
+  v4l2object->get_in_out_func (v4l2object, &chan);
   if (chan == GST_V4L2_TUNER_CHANNEL (channel)->index &&
       GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
-    gst_v4l2_get_frequency (v4l2element, v4l2channel->tuner, &frequency);
+    gst_v4l2_get_frequency (v4l2object, v4l2channel->tuner, &frequency);
   }
 
   return frequency;
 }
 
-static gint
-gst_v4l2_tuner_signal_strength (GstTuner * mixer, GstTunerChannel * channel)
+gint
+gst_v4l2_tuner_signal_strength (GstV4l2Object * v4l2object,
+    GstTunerChannel * channel)
 {
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (mixer);
   GstV4l2TunerChannel *v4l2channel = GST_V4L2_TUNER_CHANNEL (channel);
   gint chan;
   gulong signal = 0;
 
   /* assert that we're opened and that we're using a known item */
-  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2element), 0);
+  g_return_val_if_fail (GST_V4L2_IS_OPEN (v4l2object), 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 (v4l2object,
+          v4l2channel), 0);
 
-  gst_v4l2_get_input (v4l2element, &chan);
+  v4l2object->get_in_out_func (v4l2object, &chan);
   if (chan == GST_V4L2_TUNER_CHANNEL (channel)->index &&
       GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
-    gst_v4l2_signal_strength (v4l2element, v4l2channel->tuner, &signal);
+    gst_v4l2_signal_strength (v4l2object, v4l2channel->tuner, &signal);
   }
 
   return signal;
 }
-
-#if 0                           /* output not handled by now */
-
-static gboolean
-gst_v4l2_get_output (GstV4l2Element * v4l2element, gint * output)
-{
-  gint n;
-
-  GST_DEBUG_OBJECT (v4l2element, "trying to get output");
-  if (!GST_V4L2_IS_OPEN (v4l2element))
-    return FALSE;
-
-  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));
-    return FALSE;
-  }
-
-  *output = n;
-
-  return TRUE;
-}
-
-static gboolean
-gst_v4l2_set_output (GstV4l2Element * v4l2element, gint output)
-{
-  GST_DEBUG_OBJECT (v4l2element, "trying to set output to %d", output);
-  if (!GST_V4L2_IS_OPEN (v4l2element))
-    return FALSE;
-  if (!GST_V4L2_IS_ACTIVE (v4l2element))
-    return FALSE;
-
-  if (ioctl (v4l2element->video_fd, VIDIOC_S_OUTPUT, &output) < 0) {
-    GST_WARNING_OBJECT (v4l2element,
-        "Failed to set current output on device %s to %d: %s",
-        v4l2element->videodev, output, g_strerror (errno));
-    return FALSE;
-  }
-
-  return TRUE;
-}
-
-#endif /* #if 0 - output not handled by now */
index ede9ab2..523eea3 100644 (file)
@@ -26,7 +26,7 @@
 #include <gst/gst.h>
 #include <gst/interfaces/tuner.h>
 
-#include "gstv4l2element.h"
+#include "gstv4l2object.h"
 
 G_BEGIN_DECLS
 
@@ -34,10 +34,10 @@ G_BEGIN_DECLS
   (gst_v4l2_tuner_channel_get_type ())
 #define GST_V4L2_TUNER_CHANNEL(obj) \
   (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2_TUNER_CHANNEL, \
-                              GstV4l2TunerChannel))
+          GstV4l2TunerChannel))
 #define GST_V4L2_TUNER_CHANNEL_CLASS(klass) \
   (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_V4L2_TUNER_CHANNEL, \
-                           GstV4l2TunerChannelClass))
+       GstV4l2TunerChannelClass))
 #define GST_IS_V4L2_TUNER_CHANNEL(obj) \
   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L2_TUNER_CHANNEL))
 #define GST_IS_V4L2_TUNER_CHANNEL_CLASS(klass) \
@@ -59,10 +59,10 @@ typedef struct _GstV4l2TunerChannelClass {
   (gst_v4l2_tuner_norm_get_type ())
 #define GST_V4L2_TUNER_NORM(obj) \
   (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2_TUNER_NORM, \
-                              GstV4l2TunerNorm))
+          GstV4l2TunerNorm))
 #define GST_V4L2_TUNER_NORM_CLASS(klass) \
   (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_V4L2_TUNER_NORM, \
-                           GstV4l2TunerNormClass))
+       GstV4l2TunerNormClass))
 #define GST_IS_V4L2_TUNER_NORM(obj) \
   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L2_TUNER_NORM))
 #define GST_IS_V4L2_TUNER_NORM_CLASS(klass) \
@@ -78,19 +78,121 @@ typedef struct _GstV4l2TunerNormClass {
   GstTunerNormClass parent;
 } GstV4l2TunerNormClass;
 
-GType  gst_v4l2_tuner_channel_get_type (void);
-GType  gst_v4l2_tuner_norm_get_type    (void);
-
-void   gst_v4l2_tuner_interface_init   (GstTunerClass *klass);
-
 extern gboolean
-gst_v4l2_tuner_set_channel (GstTuner * mixer, GstTunerChannel * channel);
-
-gboolean
-gst_v4l2_tuner_set_norm (GstTuner * mixer, GstTunerNorm * norm);
-
+gst_v4l2_tuner_set_channel (GstV4l2Object * v4l2object, GstTunerChannel * channel);
+extern gboolean
+gst_v4l2_tuner_set_norm (GstV4l2Object * v4l2object, GstTunerNorm * norm);
 extern gboolean
-gst_v4l2_tuner_set_frequency (GstTuner * mixer,
-                             GstTunerChannel * channel, gulong frequency);
+gst_v4l2_tuner_set_frequency (GstV4l2Object * v4l2object,
+                              GstTunerChannel * channel, gulong frequency);
+
+GType gst_v4l2_tuner_channel_get_type (void);
+GType gst_v4l2_tuner_norm_get_type (void);
+
+extern const GList *
+gst_v4l2_tuner_list_channels (GstV4l2Object * v4l2object);
+extern void
+gst_v4l2_tuner_set_channel_and_notify (GstV4l2Object * v4l2object, GstTunerChannel * channel);
+extern GstTunerChannel *
+gst_v4l2_tuner_get_channel (GstV4l2Object * v4l2object);
+
+extern const GList *
+gst_v4l2_tuner_list_norms (GstV4l2Object * v4l2object);
+extern void
+gst_v4l2_tuner_set_norm_and_notify (GstV4l2Object * v4l2object, GstTunerNorm * norm);
+extern GstTunerNorm *
+gst_v4l2_tuner_get_norm (GstV4l2Object * v4l2object);
+
+extern void
+gst_v4l2_tuner_set_frequency_and_notify (GstV4l2Object * v4l2object,
+                                         GstTunerChannel * channel, gulong frequency);
+extern gulong
+gst_v4l2_tuner_get_frequency (GstV4l2Object * v4l2object, GstTunerChannel * channel);
+extern gint
+gst_v4l2_tuner_signal_strength (GstV4l2Object * v4l2object, GstTunerChannel * channel);
+
+#define GST_IMPLEMENT_V4L2_TUNER_METHODS(Type, interface_as_function)                 \
+                                                                                      \
+static const GList *                                                                  \
+interface_as_function ## _tuner_list_channels (GstTuner * mixer)                      \
+{                                                                                     \
+  Type *this = (Type*) mixer;                                                         \
+  return gst_v4l2_tuner_list_channels (this->v4l2object);                             \
+}                                                                                     \
+                                                                                      \
+static void                                                                           \
+interface_as_function ## _tuner_set_channel_and_notify (GstTuner * mixer,             \
+                                                        GstTunerChannel * channel)    \
+{                                                                                     \
+  Type *this = (Type*) mixer;                                                         \
+  gst_v4l2_tuner_set_channel_and_notify (this->v4l2object, channel);                  \
+}                                                                                     \
+static GstTunerChannel *                                                              \
+interface_as_function ## _tuner_get_channel (GstTuner * mixer)                        \
+{                                                                                     \
+  Type *this = (Type*) mixer;                                                         \
+  return gst_v4l2_tuner_get_channel (this->v4l2object);                               \
+}                                                                                     \
+static const GList *                                                                  \
+interface_as_function ## _tuner_list_norms (GstTuner * mixer)                         \
+{                                                                                     \
+  Type *this = (Type*) mixer;                                                         \
+  return gst_v4l2_tuner_list_norms (this->v4l2object);                                \
+}                                                                                     \
+static void                                                                           \
+interface_as_function ## _tuner_set_norm_and_notify (GstTuner * mixer,                \
+                                                     GstTunerNorm * norm)             \
+{                                                                                     \
+  Type *this = (Type*) mixer;                                                         \
+  gst_v4l2_tuner_set_norm_and_notify (this->v4l2object, norm);                        \
+}                                                                                     \
+static GstTunerNorm *                                                                 \
+interface_as_function ## _tuner_get_norm (GstTuner * mixer)                           \
+{                                                                                     \
+  Type *this = (Type*) mixer;                                                         \
+  return gst_v4l2_tuner_get_norm (this->v4l2object);                                  \
+}                                                                                     \
+                                                                                      \
+static void                                                                           \
+interface_as_function ## _tuner_set_frequency_and_notify (GstTuner * mixer,           \
+                                                          GstTunerChannel * channel,  \
+                                                          gulong frequency)           \
+{                                                                                     \
+  Type *this = (Type*) mixer;                                                         \
+  gst_v4l2_tuner_set_frequency_and_notify (this->v4l2object, channel, frequency);     \
+}                                                                                     \
+                                                                                      \
+static gulong                                                                         \
+interface_as_function ## _tuner_get_frequency (GstTuner * mixer,                      \
+                                               GstTunerChannel * channel)             \
+{                                                                                     \
+  Type *this = (Type*) mixer;                                                         \
+  return gst_v4l2_tuner_get_frequency (this->v4l2object, channel);                    \
+}                                                                                     \
+                                                                                      \
+static gint                                                                           \
+interface_as_function ## _tuner_signal_strength (GstTuner * mixer,                    \
+                                                 GstTunerChannel * channel)           \
+{                                                                                     \
+  Type *this = (Type*) mixer;                                                         \
+  return gst_v4l2_tuner_signal_strength (this->v4l2object, channel);                  \
+}                                                                                     \
+                                                                                      \
+void                                                                                  \
+interface_as_function ## _tuner_interface_init (GstTunerClass * klass)                \
+{                                                                                     \
+  /* default virtual functions */                                                     \
+  klass->list_channels = interface_as_function ## _tuner_list_channels;               \
+  klass->set_channel = interface_as_function ## _tuner_set_channel_and_notify;        \
+  klass->get_channel = interface_as_function ## _tuner_get_channel;                   \
+                                                                                      \
+  klass->list_norms = interface_as_function ## _tuner_list_norms;                     \
+  klass->set_norm = interface_as_function ## _tuner_set_norm_and_notify;              \
+  klass->get_norm = interface_as_function ## _tuner_get_norm;                         \
+                                                                                      \
+  klass->set_frequency = interface_as_function ## _tuner_set_frequency_and_notify;    \
+  klass->get_frequency = interface_as_function ## _tuner_get_frequency;               \
+  klass->signal_strength = interface_as_function ## _tuner_signal_strength;           \
+}                                                                                     \
 
 #endif /* __GST_V4L2_TUNER_H__ */
index 8d597a4..bcf095e 100644 (file)
@@ -1,5 +1,6 @@
 /* GStreamer X-based overlay interface implementation
  * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ * Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
  *
  * gstv4l2xoverlay.c: X-based overlay interface implementation for V4L2
  *
 #include <sys/stat.h>
 
 #include "gstv4l2xoverlay.h"
-#include "gstv4l2element.h"
+#include "gstv4l2object.h"
 #include "v4l2_calls.h"
 
-GST_DEBUG_CATEGORY_STATIC (v4l2xv_debug);
-#define GST_CAT_DEFAULT v4l2xv_debug
-
 struct _GstV4l2Xv
 {
   Display *dpy;
@@ -45,21 +43,18 @@ struct _GstV4l2Xv
   GMutex *mutex;
 };
 
-static void gst_v4l2_xoverlay_set_xwindow_id (GstXOverlay * overlay,
-    XID xwindow_id);
+GST_DEBUG_CATEGORY_STATIC (v4l2xv_debug);
+#define GST_CAT_DEFAULT v4l2xv_debug
 
 void
 gst_v4l2_xoverlay_interface_init (GstXOverlayClass * klass)
 {
-  /* default virtual functions */
-  klass->set_xwindow_id = gst_v4l2_xoverlay_set_xwindow_id;
-
   GST_DEBUG_CATEGORY_INIT (v4l2xv_debug, "v4l2xv", 0,
       "V4L2 XOverlay interface debugging");
 }
 
 static void
-gst_v4l2_xoverlay_open (GstV4l2Element * v4l2element)
+gst_v4l2_xoverlay_open (GstV4l2Object * v4l2object)
 {
   struct stat s;
   GstV4l2Xv *v4l2xv;
@@ -71,33 +66,35 @@ gst_v4l2_xoverlay_open (GstV4l2Element * v4l2element)
 
   /* we need a display, obviously */
   if (!name || !(dpy = XOpenDisplay (name))) {
-    GST_WARNING_OBJECT (v4l2element,
+    GST_WARNING_OBJECT (v4l2object->element,
         "No $DISPLAY set or failed to open - no overlay");
     return;
   }
 
   /* First let's check that XVideo extension is available */
   if (!XQueryExtension (dpy, "XVideo", &i, &i, &i)) {
-    GST_WARNING_OBJECT (v4l2element, "Xv extension not available - no overlay");
+    GST_WARNING_OBJECT (v4l2object->element,
+        "Xv extension not available - no overlay");
     XCloseDisplay (dpy);
     return;
   }
 
   /* find port that belongs to this device */
   if (XvQueryExtension (dpy, &ver, &rel, &req, &ev, &err) != Success) {
-    GST_WARNING_OBJECT (v4l2element, "Xv extension not supported - no overlay");
+    GST_WARNING_OBJECT (v4l2object->element,
+        "Xv extension not supported - no overlay");
     XCloseDisplay (dpy);
     return;
   }
   if (XvQueryAdaptors (dpy, DefaultRootWindow (dpy), &anum, &ai) != Success) {
-    GST_WARNING_OBJECT (v4l2element, "Failed to query Xv adaptors");
+    GST_WARNING_OBJECT (v4l2object->element, "Failed to query Xv adaptors");
     XCloseDisplay (dpy);
     return;
   }
-  if (fstat (v4l2element->video_fd, &s) < 0) {
-    GST_ELEMENT_ERROR (v4l2element, RESOURCE, GST_RESOURCE_ERROR_NOT_FOUND,
+  if (fstat (v4l2object->video_fd, &s) < 0) {
+    GST_ELEMENT_ERROR (v4l2object, RESOURCE, GST_RESOURCE_ERROR_NOT_FOUND,
         (_("Cannot identify '%s': %d, %s\n"),
-            v4l2element->videodev, errno, strerror (errno)), GST_ERROR_SYSTEM);
+            v4l2object->videodev, errno, strerror (errno)), GST_ERROR_SYSTEM);
     XCloseDisplay (dpy);
     return;
   }
@@ -115,7 +112,7 @@ gst_v4l2_xoverlay_open (GstV4l2Element * v4l2element)
   XvFreeAdaptorInfo (ai);
 
   if (id == 0) {
-    GST_WARNING (v4l2element, "Did not find XvPortID for device - no overlay");
+    GST_WARNING (v4l2object, "Did not find XvPortID for device - no overlay");
     XCloseDisplay (dpy);
     return;
   }
@@ -125,24 +122,23 @@ gst_v4l2_xoverlay_open (GstV4l2Element * v4l2element)
   v4l2xv->port = id;
   v4l2xv->mutex = g_mutex_new ();
   v4l2xv->idle_id = 0;
-  v4l2element->xv = v4l2xv;
+  v4l2object->xv = v4l2xv;
 
-  if (v4l2element->xwindow_id) {
-    gst_v4l2_xoverlay_set_xwindow_id (GST_X_OVERLAY (v4l2element),
-        v4l2element->xwindow_id);
+  if (v4l2object->xwindow_id) {
+    gst_v4l2_xoverlay_set_xwindow_id (v4l2object, v4l2object->xwindow_id);
   }
 }
 
 static void
-gst_v4l2_xoverlay_close (GstV4l2Element * v4l2element)
+gst_v4l2_xoverlay_close (GstV4l2Object * v4l2object)
 {
-  GstV4l2Xv *v4l2xv = v4l2element->xv;
+  GstV4l2Xv *v4l2xv = v4l2object->xv;
 
-  if (!v4l2element->xv)
+  if (!v4l2object->xv)
     return;
 
-  if (v4l2element->xwindow_id) {
-    gst_v4l2_xoverlay_set_xwindow_id (GST_X_OVERLAY (v4l2element), 0);
+  if (v4l2object->xwindow_id) {
+    gst_v4l2_xoverlay_set_xwindow_id (v4l2object, 0);
   }
 
   XCloseDisplay (v4l2xv->dpy);
@@ -150,35 +146,35 @@ gst_v4l2_xoverlay_close (GstV4l2Element * v4l2element)
   if (v4l2xv->idle_id)
     g_source_remove (v4l2xv->idle_id);
   g_free (v4l2xv);
-  v4l2element->xv = NULL;
+  v4l2object->xv = NULL;
 }
 
 void
-gst_v4l2_xoverlay_start (GstV4l2Element * v4l2element)
+gst_v4l2_xoverlay_start (GstV4l2Object * v4l2object)
 {
-  if (v4l2element->xwindow_id) {
-    gst_v4l2_xoverlay_open (v4l2element);
+  if (v4l2object->xwindow_id) {
+    gst_v4l2_xoverlay_open (v4l2object);
   }
 }
 
 void
-gst_v4l2_xoverlay_stop (GstV4l2Element * v4l2element)
+gst_v4l2_xoverlay_stop (GstV4l2Object * v4l2object)
 {
-  gst_v4l2_xoverlay_close (v4l2element);
+  gst_v4l2_xoverlay_close (v4l2object);
 }
 
 static gboolean
 idle_refresh (gpointer data)
 {
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (data);
-  GstV4l2Xv *v4l2xv = v4l2element->xv;
+  GstV4l2Object *v4l2object = GST_V4L2OBJECT (data);
+  GstV4l2Xv *v4l2xv = v4l2object->xv;
   XWindowAttributes attr;
 
   if (v4l2xv) {
     g_mutex_lock (v4l2xv->mutex);
 
-    XGetWindowAttributes (v4l2xv->dpy, v4l2element->xwindow_id, &attr);
-    XvPutVideo (v4l2xv->dpy, v4l2xv->port, v4l2element->xwindow_id,
+    XGetWindowAttributes (v4l2xv->dpy, v4l2object->xwindow_id, &attr);
+    XvPutVideo (v4l2xv->dpy, v4l2xv->port, v4l2object->xwindow_id,
         DefaultGC (v4l2xv->dpy, DefaultScreen (v4l2xv->dpy)),
         0, 0, attr.width, attr.height, 0, 0, attr.width, attr.height);
 
@@ -191,34 +187,34 @@ idle_refresh (gpointer data)
 }
 
 static void
-gst_v4l2_xoverlay_set_xwindow_id (GstXOverlay * overlay, XID xwindow_id)
+gst_v4l2_xoverlay_set_xwindow_id (GstV4l2Object * v4l2object, XID xwindow_id)
 {
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (overlay);
   GstV4l2Xv *v4l2xv;
   XWindowAttributes attr;
-  gboolean change = (v4l2element->xwindow_id != xwindow_id);
+  gboolean change = (v4l2object->xwindow_id != xwindow_id);
 
-  GST_LOG_OBJECT (v4l2element, "Setting XID to %lx", (gulong) xwindow_id);
+  GST_LOG_OBJECT (v4l2object->element, "Setting XID to %lx",
+      (gulong) xwindow_id);
 
-  if (!v4l2element->xv && GST_V4L2_IS_OPEN (v4l2element))
-    gst_v4l2_xoverlay_open (v4l2element);
+  if (!v4l2object->xv && GST_V4L2_IS_OPEN (v4l2object))
+    gst_v4l2_xoverlay_open (v4l2object);
 
-  v4l2xv = v4l2element->xv;
+  v4l2xv = v4l2object->xv;
 
   if (v4l2xv)
     g_mutex_lock (v4l2xv->mutex);
 
   if (change) {
-    if (v4l2element->xwindow_id && v4l2xv) {
-      GST_DEBUG_OBJECT (v4l2element,
-          "Deactivating old port %lx", v4l2element->xwindow_id);
+    if (v4l2object->xwindow_id && v4l2xv) {
+      GST_DEBUG_OBJECT (v4l2object->element,
+          "Deactivating old port %lx", v4l2object->xwindow_id);
 
       XvSelectPortNotify (v4l2xv->dpy, v4l2xv->port, 0);
-      XvSelectVideoNotify (v4l2xv->dpy, v4l2element->xwindow_id, 0);
-      XvStopVideo (v4l2xv->dpy, v4l2xv->port, v4l2element->xwindow_id);
+      XvSelectVideoNotify (v4l2xv->dpy, v4l2object->xwindow_id, 0);
+      XvStopVideo (v4l2xv->dpy, v4l2xv->port, v4l2object->xwindow_id);
     }
 
-    v4l2element->xwindow_id = xwindow_id;
+    v4l2object->xwindow_id = xwindow_id;
   }
 
   if (!v4l2xv || xwindow_id == 0) {
@@ -228,20 +224,21 @@ gst_v4l2_xoverlay_set_xwindow_id (GstXOverlay * overlay, XID xwindow_id)
   }
 
   if (change) {
-    GST_DEBUG_OBJECT (v4l2element, "Activating new port %lx", xwindow_id);
+    GST_DEBUG_OBJECT (v4l2object->element, "Activating new port %lx",
+        xwindow_id);
 
     /* draw */
     XvSelectPortNotify (v4l2xv->dpy, v4l2xv->port, 1);
-    XvSelectVideoNotify (v4l2xv->dpy, v4l2element->xwindow_id, 1);
+    XvSelectVideoNotify (v4l2xv->dpy, v4l2object->xwindow_id, 1);
   }
 
-  XGetWindowAttributes (v4l2xv->dpy, v4l2element->xwindow_id, &attr);
-  XvPutVideo (v4l2xv->dpy, v4l2xv->port, v4l2element->xwindow_id,
+  XGetWindowAttributes (v4l2xv->dpy, v4l2object->xwindow_id, &attr);
+  XvPutVideo (v4l2xv->dpy, v4l2xv->port, v4l2object->xwindow_id,
       DefaultGC (v4l2xv->dpy, DefaultScreen (v4l2xv->dpy)),
       0, 0, attr.width, attr.height, 0, 0, attr.width, attr.height);
 
   if (v4l2xv->idle_id)
     g_source_remove (v4l2xv->idle_id);
-  v4l2xv->idle_id = g_idle_add (idle_refresh, v4l2element);
+  v4l2xv->idle_id = g_idle_add (idle_refresh, v4l2object);
   g_mutex_unlock (v4l2xv->mutex);
 }
index a0c25ab..1f39cc7 100644 (file)
@@ -1,5 +1,6 @@
 /* G-Streamer generic V4L2 element - X overlay interface implementation
  * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ * Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
  *
  * gstv4l2xoverlay.h: tv mixer interface implementation for V4L2
  *
 #ifndef __GST_V4L2_X_OVERLAY_H__
 #define __GST_V4L2_X_OVERLAY_H__
 
+#include <X11/X.h>
+
 #include <gst/gst.h>
 #include <gst/interfaces/xoverlay.h>
 
-#include "gstv4l2element.h"
+#include "gstv4l2object.h"
 
 G_BEGIN_DECLS
 
-void   gst_v4l2_xoverlay_interface_init (GstXOverlayClass *klass);
+void gst_v4l2_xoverlay_start (GstV4l2Object  *v4l2object);
+void gst_v4l2_xoverlay_stop  (GstV4l2Object  *v4l2object);
+
+extern void gst_v4l2_xoverlay_set_xwindow_id (GstV4l2Object  *v4l2object,
+                                              XID xwindow_id);
+
+extern void
+gst_v4l2_xoverlay_interface_init (GstXOverlayClass * klass);
+
+#define GST_IMPLEMENT_V4L2_XOVERLAY_METHODS(Type, interface_as_function)              \
+                                                                                      \
+static void                                                                           \
+interface_as_function ## _xoverlay_set_xwindow_id (GstXOverlay * xoverlay,            \
+                                                   XID xwindow_id)                    \
+{                                                                                     \
+  Type *this = (Type*) xoverlay;                                                      \
+  gst_v4l2_xoverlay_set_xwindow_id (this->v4l2object, xwindow_id);                    \
+}                                                                                     \
+                                                                                      \
+static void                                                                           \
+interface_as_function ## _xoverlay_interface_init (GstXOverlayClass * klass)          \
+{                                                                                     \
+  /* default virtual functions */                                                     \
+  klass->set_xwindow_id = interface_as_function ## _xoverlay_set_xwindow_id;          \
+                                                                                      \
+  gst_v4l2_xoverlay_interface_init(GstXOverlayClass * klass);                         \
+}                                                                                     \
+                                                                                      \
 
-void   gst_v4l2_xoverlay_start         (GstV4l2Element  *v4l2element);
-void   gst_v4l2_xoverlay_stop          (GstV4l2Element  *v4l2element);
 
 #endif /* __GST_V4L2_X_OVERLAY_H__ */
index 2ca2d86..b77389c 100644 (file)
@@ -47,16 +47,15 @@ GST_DEBUG_CATEGORY_EXTERN (v4l2_debug);
  ******************************************************/
 
 gboolean
-gst_v4l2_get_capabilities (GstV4l2Element * v4l2element)
+gst_v4l2_get_capabilities (GstV4l2Object * v4l2object)
 {
-  GST_DEBUG_OBJECT (v4l2element, "getting capabilities");
-  if (!GST_V4L2_IS_OPEN (v4l2element))
+  GST_DEBUG_OBJECT (v4l2object->element, "getting capabilities");
+  if (!GST_V4L2_IS_OPEN (v4l2object))
     return FALSE;
 
-  if (ioctl (v4l2element->video_fd, VIDIOC_QUERYCAP, &(v4l2element->vcap)) < 0) {
-    GST_ELEMENT_ERROR (v4l2element, RESOURCE, SETTINGS,
-        (_("Error getting capabilities '%s': %d, %s\n"),
-            v4l2element->videodev, errno, strerror (errno)), GST_ERROR_SYSTEM);
+  if (ioctl (v4l2object->video_fd, VIDIOC_QUERYCAP, &(v4l2object->vcap)) < 0) {
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
+        (_("Error getting capabilities '%s': %d, %s. It isn't a v4l2 driver. Check if it is a v4l1 driver\n"), v4l2object->videodev, errno, strerror (errno)), GST_ERROR_SYSTEM);
     return FALSE;
   }
 
@@ -71,7 +70,7 @@ gst_v4l2_get_capabilities (GstV4l2Element * v4l2element)
  ******************************************************/
 
 static gboolean
-gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
+gst_v4l2_fill_lists (GstV4l2Object * v4l2object)
 {
   gint n;
 
@@ -79,8 +78,8 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
   GstPadDirection dir = GST_PAD_UNKNOWN;
 #endif /* #if 0 - output not handled by now */
 
-  GST_DEBUG_OBJECT (v4l2element, "getting enumerations");
-  GST_V4L2_CHECK_OPEN (v4l2element);
+  GST_DEBUG_OBJECT (v4l2object->element, "getting enumerations");
+  GST_V4L2_CHECK_OPEN (v4l2object);
 
 #if 0                           /* output not handled by now */
   if (dir != GST_PAD_SINK) {
@@ -93,13 +92,13 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
       GstTunerChannel *channel;
 
       input.index = n;
-      if (ioctl (v4l2element->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {
+      if (ioctl (v4l2object->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {
         if (errno == EINVAL)
           break;                /* end of enumeration */
         else {
-          GST_ELEMENT_ERROR (v4l2element, RESOURCE, SETTINGS, (NULL),
+          GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, (NULL),
               ("Failed to get %d in input enumeration for %s: %s",
-                  n, v4l2element->videodev, g_strerror (errno)));
+                  n, v4l2object->videodev, g_strerror (errno)));
           return FALSE;
         }
       }
@@ -116,10 +115,10 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
         channel->flags |= GST_TUNER_CHANNEL_FREQUENCY;
 
         vtun.index = input.tuner;
-        if (ioctl (v4l2element->video_fd, VIDIOC_G_TUNER, &vtun) < 0) {
-          GST_ELEMENT_ERROR (v4l2element, RESOURCE, SETTINGS, (NULL),
+        if (ioctl (v4l2object->video_fd, VIDIOC_G_TUNER, &vtun) < 0) {
+          GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, (NULL),
               ("Failed to get tuner %d settings on %s: %s",
-                  input.tuner, v4l2element->videodev, g_strerror (errno)));
+                  input.tuner, v4l2object->videodev, g_strerror (errno)));
           g_object_unref (G_OBJECT (channel));
           return FALSE;
         }
@@ -138,8 +137,8 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
         channel->flags |= GST_TUNER_CHANNEL_AUDIO;
       }
 
-      v4l2element->inputs =
-          g_list_append (v4l2element->inputs, (gpointer) channel);
+      v4l2object->inputs =
+          g_list_append (v4l2object->inputs, (gpointer) channel);
     }
 
 #if 0                           /* output not handled by now */
@@ -151,13 +150,13 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
       GstTunerChannel *channel;
 
       output.index = n;
-      if (ioctl (v4l2element->video_fd, VIDIOC_ENUMOUTPUT, &output) < 0) {
+      if (ioctl (v4l2object->video_fd, VIDIOC_ENUMOUTPUT, &output) < 0) {
         if (errno == EINVAL)
           break;                /* end of enumeration */
         else {
-          GST_ELEMENT_ERROR (v4l2element, RESOURCE, SETTINGS, (NULL),
+          GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, (NULL),
               ("Failed to get %d in output enumeration for %s: %s",
-                  n, v4l2element->videodev, g_strerror (errno)));
+                  n, v4l2object->videodev, g_strerror (errno)));
           return FALSE;
         }
       }
@@ -175,8 +174,8 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
         channel->flags |= GST_TUNER_CHANNEL_AUDIO;
       }
 
-      v4l2element->inputs =
-          g_list_append (v4l2element->inputs, (gpointer) channel);
+      v4l2object->inputs =
+          g_list_append (v4l2object->inputs, (gpointer) channel);
     }
   }
 #endif /* #if 0 - output not handled by now */
@@ -188,13 +187,13 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
     GstTunerNorm *norm;
 
     standard.index = n;
-    if (ioctl (v4l2element->video_fd, VIDIOC_ENUMSTD, &standard) < 0) {
+    if (ioctl (v4l2object->video_fd, VIDIOC_ENUMSTD, &standard) < 0) {
       if (errno == EINVAL)
         break;                  /* end of enumeration */
       else {
-        GST_ELEMENT_ERROR (v4l2element, RESOURCE, SETTINGS, (NULL),
+        GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, (NULL),
             ("Failed to get %d in norm enumeration for %s: %s",
-                n, v4l2element->videodev, g_strerror (errno)));
+                n, v4l2object->videodev, g_strerror (errno)));
         return FALSE;
       }
     }
@@ -206,7 +205,7 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
         standard.frameperiod.denominator, standard.frameperiod.numerator);
     v4l2norm->index = standard.id;
 
-    v4l2element->stds = g_list_append (v4l2element->stds, (gpointer) norm);
+    v4l2object->stds = g_list_append (v4l2object->stds, (gpointer) norm);
   }
 
   /* and lastly, controls+menus (if appropriate) */
@@ -220,16 +219,16 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
       n = V4L2_CID_PRIVATE_BASE;
 
     control.id = n;
-    if (ioctl (v4l2element->video_fd, VIDIOC_QUERYCTRL, &control) < 0) {
+    if (ioctl (v4l2object->video_fd, VIDIOC_QUERYCTRL, &control) < 0) {
       if (errno == EINVAL) {
         if (n < V4L2_CID_PRIVATE_BASE)
           continue;
         else
           break;
       } else {
-        GST_ELEMENT_ERROR (v4l2element, RESOURCE, SETTINGS, (NULL),
+        GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, (NULL),
             ("Failed to get %d in control enumeration for %s: %s",
-                n, v4l2element->videodev, g_strerror (errno)));
+                n, v4l2object->videodev, g_strerror (errno)));
         return FALSE;
       }
     }
@@ -253,8 +252,8 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
         /* we only handle these for now */
         break;
       default:
-        GST_DEBUG_OBJECT (v4l2element, "ControlID %s (%d) unhandled, FIXME",
-            control.name, n);
+        GST_DEBUG_OBJECT (v4l2object->element,
+            "ControlID %s (%d) unhandled, FIXME", control.name, n);
         control.id++;
         break;
     }
@@ -274,13 +273,13 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
       menu.id = n;
       for (i = 0;; i++) {
         menu.index = i;
-        if (ioctl (v4l2element->video_fd, VIDIOC_QUERYMENU, &menu) < 0) {
+        if (ioctl (v4l2object->video_fd, VIDIOC_QUERYMENU, &menu) < 0) {
           if (errno == EINVAL)
             break;              /* end of enumeration */
           else {
-            GST_ELEMENT_ERROR (v4l2element, RESOURCE, SETTINGS, (NULL),
+            GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, (NULL),
                 ("Failed to get %d in menu enumeration for %s: %s",
-                    n, v4l2element->videodev, g_strerror (errno)));
+                    n, v4l2object->videodev, g_strerror (errno)));
             return FALSE;
           }
         }
@@ -289,7 +288,7 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
         menus = g_list_append (menus, mptr);
       }
     }
-    v4l2element->menus = g_list_append (v4l2element->menus, menus);
+    v4l2object->menus = g_list_append (v4l2object->menus, menus);
 #endif
 
     switch (control.type) {
@@ -306,8 +305,7 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
         break;
     }
 
-    v4l2element->colors = g_list_append (v4l2element->colors,
-        (gpointer) channel);
+    v4l2object->colors = g_list_append (v4l2object->colors, (gpointer) channel);
   }
 
   return TRUE;
@@ -315,153 +313,101 @@ gst_v4l2_fill_lists (GstV4l2Element * v4l2element)
 
 
 static void
-gst_v4l2_empty_lists (GstV4l2Element * v4l2element)
+gst_v4l2_empty_lists (GstV4l2Object * v4l2object)
 {
-  GST_DEBUG_OBJECT (v4l2element, "deleting enumerations");
+  GST_DEBUG_OBJECT (v4l2object->element, "deleting enumerations");
 
-  g_list_foreach (v4l2element->inputs, (GFunc) g_object_unref, NULL);
-  g_list_free (v4l2element->inputs);
-  v4l2element->inputs = NULL;
+  g_list_foreach (v4l2object->inputs, (GFunc) g_object_unref, NULL);
+  g_list_free (v4l2object->inputs);
+  v4l2object->inputs = NULL;
 
-  g_list_foreach (v4l2element->stds, (GFunc) g_object_unref, NULL);
-  g_list_free (v4l2element->stds);
-  v4l2element->stds = NULL;
+  g_list_foreach (v4l2object->stds, (GFunc) g_object_unref, NULL);
+  g_list_free (v4l2object->stds);
+  v4l2object->stds = NULL;
 
-  g_list_foreach (v4l2element->colors, (GFunc) g_object_unref, NULL);
-  g_list_free (v4l2element->colors);
-  v4l2element->colors = NULL;
+  g_list_foreach (v4l2object->colors, (GFunc) g_object_unref, NULL);
+  g_list_free (v4l2object->colors);
+  v4l2object->colors = NULL;
 }
 
-/* FIXME: move this stuff to gstv4l2tuner.c? */
-
-static void
-gst_v4l2_set_defaults (GstV4l2Element * v4l2element)
-{
-  GstTunerNorm *norm = NULL;
-  GstTunerChannel *channel = NULL;
-  GstTuner *tuner = GST_TUNER (v4l2element);
-
-  if (v4l2element->std)
-    norm = gst_tuner_find_norm_by_name (tuner, v4l2element->std);
-  if (norm) {
-    gst_tuner_set_norm (tuner, norm);
-  } else {
-    norm = GST_TUNER_NORM (gst_tuner_get_norm (GST_TUNER (v4l2element)));
-    if (norm) {
-      v4l2element->std = g_strdup (norm->label);
-      gst_tuner_norm_changed (tuner, norm);
-      g_object_notify (G_OBJECT (v4l2element), "std");
-    }
-  }
-
-  if (v4l2element->input)
-    channel = gst_tuner_find_channel_by_name (tuner, v4l2element->input);
-  if (channel) {
-    gst_tuner_set_channel (tuner, channel);
-  } else {
-    channel =
-        GST_TUNER_CHANNEL (gst_tuner_get_channel (GST_TUNER (v4l2element)));
-    v4l2element->input = g_strdup (channel->label);
-    gst_tuner_channel_changed (tuner, channel);
-    g_object_notify (G_OBJECT (v4l2element), "input");
-  }
-
-  if (GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
-    if (v4l2element->frequency != 0) {
-      gst_tuner_set_frequency (tuner, channel, v4l2element->frequency);
-    } else {
-      v4l2element->frequency = gst_tuner_get_frequency (tuner, channel);
-      if (v4l2element->frequency == 0) {
-        /* guess */
-        gst_tuner_set_frequency (tuner, channel, 1000);
-      } else {
-        g_object_notify (G_OBJECT (v4l2element), "frequency");
-      }
-    }
-  }
-}
-
-
 /******************************************************
  * gst_v4l2_open():
- *   open the video device (v4l2element->videodev)
+ *   open the video device (v4l2object->videodev)
  * return value: TRUE on success, FALSE on error
  ******************************************************/
 
 gboolean
-gst_v4l2_open (GstV4l2Element * v4l2element)
+gst_v4l2_open (GstV4l2Object * v4l2object)
 {
   struct stat st;
 
-  GST_DEBUG_OBJECT (v4l2element, "Trying to open device %s",
-      v4l2element->videodev);
-  GST_V4L2_CHECK_NOT_OPEN (v4l2element);
-  GST_V4L2_CHECK_NOT_ACTIVE (v4l2element);
+  GST_DEBUG_OBJECT (v4l2object->element, "Trying to open device %s",
+      v4l2object->videodev);
+  GST_V4L2_CHECK_NOT_OPEN (v4l2object);
+  GST_V4L2_CHECK_NOT_ACTIVE (v4l2object);
 
   /* be sure we have a device */
-  if (!v4l2element->videodev)
-    v4l2element->videodev = g_strdup ("/dev/video");
+  if (!v4l2object->videodev)
+    v4l2object->videodev = g_strdup ("/dev/video");
 
   /* check if it is a device */
-  if (-1 == stat (v4l2element->videodev, &st)) {
-    GST_ELEMENT_ERROR (v4l2element, RESOURCE, NOT_FOUND,
+  if (-1 == stat (v4l2object->videodev, &st)) {
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND,
         (_("Cannot identify '%s': %d, %s\n"),
-            v4l2element->videodev, errno, strerror (errno)), GST_ERROR_SYSTEM);
+            v4l2object->videodev, errno, strerror (errno)), GST_ERROR_SYSTEM);
     goto error;
   }
   if (!S_ISCHR (st.st_mode)) {
-    GST_ELEMENT_ERROR (v4l2element, RESOURCE, NOT_FOUND,
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND,
         (_("It isn't a device '%s': %d, %s\n"),
-            v4l2element->videodev, errno, strerror (errno)), GST_ERROR_SYSTEM);
+            v4l2object->videodev, errno, strerror (errno)), GST_ERROR_SYSTEM);
     goto error;
   }
 
   /* open the device */
-  v4l2element->video_fd = open (v4l2element->videodev,
-      O_RDWR /* | O_NONBLOCK */ );
+  v4l2object->video_fd =
+      open (v4l2object->videodev, O_RDWR /* | O_NONBLOCK */ );
 
-  if (!GST_V4L2_IS_OPEN (v4l2element)) {
-    GST_ELEMENT_ERROR (v4l2element, RESOURCE, OPEN_READ_WRITE,
+  if (!GST_V4L2_IS_OPEN (v4l2object)) {
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, OPEN_READ_WRITE,
         (_("Could not open device \"%s\" for reading and writing."),
-            v4l2element->videodev), GST_ERROR_SYSTEM);
+            v4l2object->videodev), GST_ERROR_SYSTEM);
     goto error;
   }
 
   /* get capabilities */
-  if (!gst_v4l2_get_capabilities (v4l2element)) {
+  if (!gst_v4l2_get_capabilities (v4l2object)) {
     goto error;
   }
 
   /* do we need to be a capture device? */
-  if (GST_IS_V4L2SRC (v4l2element) &&
-      !(v4l2element->vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
-    GST_ELEMENT_ERROR (v4l2element, RESOURCE, NOT_FOUND,
+  if (GST_IS_V4L2SRC (v4l2object) &&
+      !(v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND,
         (_("Device \"%s\" is not a capture device."),
-            v4l2element->videodev), ("Capabilities: 0x%x",
-            v4l2element->vcap.capabilities));
+            v4l2object->videodev), ("Capabilities: 0x%x",
+            v4l2object->vcap.capabilities));
     goto error;
   }
 
   /* create enumerations */
-  if (!gst_v4l2_fill_lists (v4l2element))
+  if (!gst_v4l2_fill_lists (v4l2object))
     goto error;
 
-  /* set defaults */
-  gst_v4l2_set_defaults (v4l2element);
-
-  GST_INFO_OBJECT (v4l2element, "Opened device '%s' (%s) successfully\n",
-      v4l2element->vcap.card, v4l2element->videodev);
+  GST_INFO_OBJECT (v4l2object->element,
+      "Opened device '%s' (%s) successfully\n", v4l2object->vcap.card,
+      v4l2object->videodev);
 
   return TRUE;
 
 error:
-  if (GST_V4L2_IS_OPEN (v4l2element)) {
+  if (GST_V4L2_IS_OPEN (v4l2object)) {
     /* close device */
-    close (v4l2element->video_fd);
-    v4l2element->video_fd = -1;
+    close (v4l2object->video_fd);
+    v4l2object->video_fd = -1;
   }
   /* empty lists */
-  gst_v4l2_empty_lists (v4l2element);
+  gst_v4l2_empty_lists (v4l2object);
 
   return FALSE;
 }
@@ -469,23 +415,24 @@ error:
 
 /******************************************************
  * gst_v4l2_close():
- *   close the video device (v4l2element->video_fd)
+ *   close the video device (v4l2object->video_fd)
  * return value: TRUE on success, FALSE on error
  ******************************************************/
 
 gboolean
-gst_v4l2_close (GstV4l2Element * v4l2element)
+gst_v4l2_close (GstV4l2Object * v4l2object)
 {
-  GST_DEBUG_OBJECT (v4l2element, "Trying to close %s", v4l2element->videodev);
-  GST_V4L2_CHECK_OPEN (v4l2element);
-  GST_V4L2_CHECK_NOT_ACTIVE (v4l2element);
+  GST_DEBUG_OBJECT (v4l2object->element, "Trying to close %s",
+      v4l2object->videodev);
+  GST_V4L2_CHECK_OPEN (v4l2object);
+  GST_V4L2_CHECK_NOT_ACTIVE (v4l2object);
 
   /* close device */
-  close (v4l2element->video_fd);
-  v4l2element->video_fd = -1;
+  close (v4l2object->video_fd);
+  v4l2object->video_fd = -1;
 
   /* empty lists */
-  gst_v4l2_empty_lists (v4l2element);
+  gst_v4l2_empty_lists (v4l2object);
 
   return TRUE;
 }
@@ -498,16 +445,16 @@ gst_v4l2_close (GstV4l2Element * v4l2element)
  ******************************************************/
 
 gboolean
-gst_v4l2_get_norm (GstV4l2Element * v4l2element, v4l2_std_id * norm)
+gst_v4l2_get_norm (GstV4l2Object * v4l2object, v4l2_std_id * norm)
 {
-  GST_DEBUG_OBJECT (v4l2element, "getting norm");
-  if (!GST_V4L2_IS_OPEN (v4l2element))
+  GST_DEBUG_OBJECT (v4l2object->element, "getting norm");
+  if (!GST_V4L2_IS_OPEN (v4l2object))
     return FALSE;
 
-  if (ioctl (v4l2element->video_fd, VIDIOC_G_STD, norm) < 0) {
-    GST_WARNING_OBJECT (v4l2element,
+  if (ioctl (v4l2object->video_fd, VIDIOC_G_STD, norm) < 0) {
+    GST_WARNING_OBJECT (v4l2object->element,
         "Failed to get the current norm for device %s: %s",
-        v4l2element->videodev, g_strerror (errno));
+        v4l2object->videodev, g_strerror (errno));
     return FALSE;
   }
 
@@ -524,16 +471,16 @@ gst_v4l2_get_norm (GstV4l2Element * v4l2element, v4l2_std_id * norm)
  ******************************************************/
 
 gboolean
-gst_v4l2_set_norm (GstV4l2Element * v4l2element, v4l2_std_id norm)
+gst_v4l2_set_norm (GstV4l2Object * v4l2object, v4l2_std_id norm)
 {
-  GST_DEBUG_OBJECT (v4l2element, "trying to set norm to %llx", norm);
-  if (!GST_V4L2_IS_OPEN (v4l2element))
+  GST_DEBUG_OBJECT (v4l2object->element, "trying to set norm to %llx", norm);
+  if (!GST_V4L2_IS_OPEN (v4l2object))
     return FALSE;
 
-  if (ioctl (v4l2element->video_fd, VIDIOC_S_STD, &norm) < 0) {
-    GST_WARNING_OBJECT (v4l2element,
+  if (ioctl (v4l2object->video_fd, VIDIOC_S_STD, &norm) < 0) {
+    GST_WARNING_OBJECT (v4l2object->element,
         "Failed to set norm 0x%llx for device %s: %s", norm,
-        v4l2element->videodev, g_strerror (errno));
+        v4l2object->videodev, g_strerror (errno));
     return FALSE;
   }
 
@@ -547,23 +494,23 @@ gst_v4l2_set_norm (GstV4l2Element * v4l2element, v4l2_std_id norm)
  ******************************************************/
 
 gboolean
-gst_v4l2_get_frequency (GstV4l2Element * v4l2element,
+gst_v4l2_get_frequency (GstV4l2Object * v4l2object,
     gint tunernum, gulong * frequency)
 {
   struct v4l2_frequency freq;
   GstTunerChannel *channel;
 
-  GST_DEBUG_OBJECT (v4l2element, "getting current tuner frequency");
-  if (!GST_V4L2_IS_OPEN (v4l2element))
+  GST_DEBUG_OBJECT (v4l2object->element, "getting current tuner frequency");
+  if (!GST_V4L2_IS_OPEN (v4l2object))
     return FALSE;
 
-  channel = gst_tuner_get_channel (GST_TUNER (v4l2element));
+  channel = gst_tuner_get_channel (GST_TUNER (v4l2object->element));
 
   freq.tuner = tunernum;
-  if (ioctl (v4l2element->video_fd, VIDIOC_G_FREQUENCY, &freq) < 0) {
-    GST_WARNING_OBJECT (v4l2element,
+  if (ioctl (v4l2object->video_fd, VIDIOC_G_FREQUENCY, &freq) < 0) {
+    GST_WARNING_OBJECT (v4l2object->element,
         "Failed to get current tuner frequency for device %s: %s",
-        v4l2element->videodev, g_strerror (errno));
+        v4l2object->videodev, g_strerror (errno));
     return FALSE;
   }
 
@@ -580,28 +527,28 @@ gst_v4l2_get_frequency (GstV4l2Element * v4l2element,
  ******************************************************/
 
 gboolean
-gst_v4l2_set_frequency (GstV4l2Element * v4l2element,
+gst_v4l2_set_frequency (GstV4l2Object * v4l2object,
     gint tunernum, gulong frequency)
 {
   struct v4l2_frequency freq;
   GstTunerChannel *channel;
 
-  GST_DEBUG_OBJECT (v4l2element, "setting current tuner frequency to %lu",
-      frequency);
-  if (!GST_V4L2_IS_OPEN (v4l2element))
+  GST_DEBUG_OBJECT (v4l2object->element,
+      "setting current tuner frequency to %lu", frequency);
+  if (!GST_V4L2_IS_OPEN (v4l2object))
     return FALSE;
 
-  channel = gst_tuner_get_channel (GST_TUNER (v4l2element));
+  channel = gst_tuner_get_channel (GST_TUNER (v4l2object->element));
 
   freq.tuner = tunernum;
   /* fill in type - ignore error */
-  ioctl (v4l2element->video_fd, VIDIOC_G_FREQUENCY, &freq);
+  ioctl (v4l2object->video_fd, VIDIOC_G_FREQUENCY, &freq);
   freq.frequency = frequency / channel->freq_multiplicator;
 
-  if (ioctl (v4l2element->video_fd, VIDIOC_S_FREQUENCY, &freq) < 0) {
-    GST_WARNING_OBJECT (v4l2element,
+  if (ioctl (v4l2object->video_fd, VIDIOC_S_FREQUENCY, &freq) < 0) {
+    GST_WARNING_OBJECT (v4l2object->element,
         "Failed to set current tuner frequency for device %s to %lu: %s",
-        v4l2element->videodev, frequency, g_strerror (errno));
+        v4l2object->videodev, frequency, g_strerror (errno));
     return FALSE;
   }
 
@@ -616,20 +563,20 @@ gst_v4l2_set_frequency (GstV4l2Element * v4l2element,
  ******************************************************/
 
 gboolean
-gst_v4l2_signal_strength (GstV4l2Element * v4l2element,
+gst_v4l2_signal_strength (GstV4l2Object * v4l2object,
     gint tunernum, gulong * signal_strength)
 {
   struct v4l2_tuner tuner;
 
-  GST_DEBUG_OBJECT (v4l2element, "trying to get signal strength");
-  if (!GST_V4L2_IS_OPEN (v4l2element))
+  GST_DEBUG_OBJECT (v4l2object->element, "trying to get signal strength");
+  if (!GST_V4L2_IS_OPEN (v4l2object))
     return FALSE;
 
   tuner.index = tunernum;
-  if (ioctl (v4l2element->video_fd, VIDIOC_G_TUNER, &tuner) < 0) {
-    GST_WARNING_OBJECT (v4l2element,
+  if (ioctl (v4l2object->video_fd, VIDIOC_G_TUNER, &tuner) < 0) {
+    GST_WARNING_OBJECT (v4l2object->element,
         "Failed to get signal strength for device %s: %s",
-        v4l2element->videodev, g_strerror (errno));
+        v4l2object->videodev, g_strerror (errno));
     return FALSE;
   }
 
@@ -646,23 +593,23 @@ gst_v4l2_signal_strength (GstV4l2Element * v4l2element,
  ******************************************************/
 
 gboolean
-gst_v4l2_get_attribute (GstV4l2Element * v4l2element,
+gst_v4l2_get_attribute (GstV4l2Object * v4l2object,
     int attribute_num, int *value)
 {
   struct v4l2_control control;
 
-  if (!GST_V4L2_IS_OPEN (v4l2element))
+  if (!GST_V4L2_IS_OPEN (v4l2object))
     return FALSE;
 
-  GST_DEBUG_OBJECT (v4l2element, "getting value of attribute %d",
+  GST_DEBUG_OBJECT (v4l2object->element, "getting value of attribute %d",
       attribute_num);
 
   control.id = attribute_num;
 
-  if (ioctl (v4l2element->video_fd, VIDIOC_G_CTRL, &control) < 0) {
-    GST_WARNING_OBJECT (v4l2element,
+  if (ioctl (v4l2object->video_fd, VIDIOC_G_CTRL, &control) < 0) {
+    GST_WARNING_OBJECT (v4l2object->element,
         "Failed to get value for control %d on device %s: %s",
-        attribute_num, v4l2element->videodev, g_strerror (errno));
+        attribute_num, v4l2object->videodev, g_strerror (errno));
     return FALSE;
   }
 
@@ -679,26 +626,109 @@ gst_v4l2_get_attribute (GstV4l2Element * v4l2element,
  ******************************************************/
 
 gboolean
-gst_v4l2_set_attribute (GstV4l2Element * v4l2element,
+gst_v4l2_set_attribute (GstV4l2Object * v4l2object,
     int attribute_num, const int value)
 {
   struct v4l2_control control;
 
-  if (!GST_V4L2_IS_OPEN (v4l2element))
+  if (!GST_V4L2_IS_OPEN (v4l2object))
     return FALSE;
 
-  GST_DEBUG_OBJECT (v4l2element, "setting value of attribute %d to %d",
+  GST_DEBUG_OBJECT (v4l2object->element, "setting value of attribute %d to %d",
       attribute_num, value);
 
   control.id = attribute_num;
   control.value = value;
 
-  if (ioctl (v4l2element->video_fd, VIDIOC_S_CTRL, &control) < 0) {
-    GST_WARNING_OBJECT (v4l2element,
+  if (ioctl (v4l2object->video_fd, VIDIOC_S_CTRL, &control) < 0) {
+    GST_WARNING_OBJECT (v4l2object->element,
         "Failed to set value %d for control %d on device %s: %s",
-        value, attribute_num, v4l2element->videodev, g_strerror (errno));
+        value, attribute_num, v4l2object->videodev, g_strerror (errno));
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+gboolean
+gst_v4l2_get_input (GstV4l2Object * v4l2object, gint * input)
+{
+  gint n;
+
+  GST_DEBUG_OBJECT (v4l2object->element, "trying to get input");
+  if (!GST_V4L2_IS_OPEN (v4l2object))
+    return FALSE;
+
+  if (ioctl (v4l2object->video_fd, VIDIOC_G_INPUT, &n) < 0) {
+    GST_WARNING_OBJECT (v4l2object->element,
+        "Failed to get current input on device %s: %s",
+        v4l2object->videodev, g_strerror (errno));
+    return FALSE;
+  }
+
+  *input = n;
+
+  return TRUE;
+}
+
+gboolean
+gst_v4l2_set_input (GstV4l2Object * v4l2object, gint input)
+{
+  GST_DEBUG_OBJECT (v4l2object->element, "trying to set input to %d", input);
+  if (!GST_V4L2_IS_OPEN (v4l2object))
+    return FALSE;
+
+  if (ioctl (v4l2object->video_fd, VIDIOC_S_INPUT, &input) < 0) {
+    GST_WARNING_OBJECT (v4l2object->element,
+        "Failed to set input %d on device %s: %s", input, v4l2object->videodev,
+        g_strerror (errno));
     return FALSE;
   }
 
   return TRUE;
 }
+
+
+#if 0                           /* output not handled by now */
+
+gboolean
+gst_v4l2_get_output (GstV4l2Object * v4l2object, gint * output)
+{
+  gint n;
+
+  GST_DEBUG_OBJECT (v4l2object->element, "trying to get output");
+  if (!GST_V4L2_IS_OPEN (v4l2object))
+    return FALSE;
+
+  if (ioctl (v4l2object->video_fd, VIDIOC_G_OUTPUT, &n) < 0) {
+    GST_WARNING_OBJECT (v4l2object->element,
+        "Failed to get current output on device %s: %s",
+        v4l2object->videodev, g_strerror (errno));
+    return FALSE;
+  }
+
+  *output = n;
+
+  return TRUE;
+}
+
+gboolean
+gst_v4l2_set_output (GstV4l2Object * v4l2object, gint output)
+{
+  GST_DEBUG_OBJECT (v4l2object->element, "trying to set output to %d", output);
+  if (!GST_V4L2_IS_OPEN (v4l2object))
+    return FALSE;
+  if (!GST_V4L2_IS_ACTIVE (v4l2object))
+    return FALSE;
+
+  if (ioctl (v4l2object->video_fd, VIDIOC_S_OUTPUT, &output) < 0) {
+    GST_WARNING_OBJECT (v4l2object->element,
+        "Failed to set current output on device %s to %d: %s",
+        v4l2object->videodev, output, g_strerror (errno));
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+#endif /* #if 0 - output not handled by now */
index 35d80d5..36075c6 100644 (file)
 #ifndef __V4L2_CALLS_H__
 #define __V4L2_CALLS_H__
 
-#include "gstv4l2element.h"
+#include "gstv4l2object.h"
 #include "gst/gst-i18n-plugin.h"
 
 
 /* simple check whether the device is open */
-#define GST_V4L2_IS_OPEN(element) \
-  (GST_V4L2ELEMENT(element)->video_fd > 0)
+#define GST_V4L2_IS_OPEN(v4l2object) \
+  (v4l2object->video_fd > 0)
 
 /* check whether the device is 'active' */
-#define GST_V4L2_IS_ACTIVE(element) \
-  (GST_V4L2ELEMENT(element)->buffer != NULL)
+#define GST_V4L2_IS_ACTIVE(v4l2object) \
+  (v4l2object->buffer != NULL)
 
-#define GST_V4L2_IS_OVERLAY(element) \
-  (GST_V4L2ELEMENT(element)->vcap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
+#define GST_V4L2_IS_OVERLAY(v4l2object) \
+  (v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
 
-/* checks whether the current v4lelement has already been open()'ed or not */
-#define GST_V4L2_CHECK_OPEN(element)                           \
-  if (!GST_V4L2_IS_OPEN(element))                              \
+/* checks whether the current v4lv4l2object has already been open()'ed or not */
+#define GST_V4L2_CHECK_OPEN(v4l2object)                                \
+  if (!GST_V4L2_IS_OPEN(v4l2object))                           \
   {                                                            \
-    GST_ELEMENT_ERROR (element, RESOURCE, TOO_LAZY,            \
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, TOO_LAZY,        \
       (_("Device is not open.")), (NULL));                      \
     return FALSE;                                              \
   }
 
-/* checks whether the current v4lelement is close()'ed or whether it is still open */
-#define GST_V4L2_CHECK_NOT_OPEN(element)                       \
-  if (GST_V4L2_IS_OPEN(element))                               \
+/* checks whether the current v4lv4l2object is close()'ed or whether it is still open */
+#define GST_V4L2_CHECK_NOT_OPEN(v4l2object)                    \
+  if (GST_V4L2_IS_OPEN(v4l2object))                            \
   {                                                            \
-    GST_ELEMENT_ERROR (element, RESOURCE, TOO_LAZY,            \
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, TOO_LAZY,        \
       (_("Device is open.")), (NULL));                          \
     return FALSE;                                              \
   }
 
-/* checks whether the current v4lelement does video overlay */
-#define GST_V4L2_CHECK_OVERLAY(element)                                \
-  if (!GST_V4L2_IS_OVERLAY(element))                           \
+/* checks whether the current v4lv4l2object does video overlay */
+#define GST_V4L2_CHECK_OVERLAY(v4l2object)                     \
+  if (!GST_V4L2_IS_OVERLAY(v4l2object))                                \
   {                                                            \
-    GST_ELEMENT_ERROR (element, RESOURCE, TOO_LAZY,             \
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, TOO_LAZY, \
       (NULL), ("Device cannot handle overlay"));                \
     return FALSE;                                              \
   }
 
 /* checks whether we're in capture mode or not */
-#define GST_V4L2_CHECK_ACTIVE(element)                         \
-  if (!GST_V4L2_IS_ACTIVE(element))                            \
+#define GST_V4L2_CHECK_ACTIVE(v4l2object)                      \
+  if (!GST_V4L2_IS_ACTIVE(v4l2object))                         \
   {                                                            \
-    GST_ELEMENT_ERROR (element, RESOURCE, SETTINGS,             \
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, \
       (NULL), ("Device is not in streaming mode"));             \
     return FALSE;                                              \
   }
 
 /* checks whether we're out of capture mode or not */
-#define GST_V4L2_CHECK_NOT_ACTIVE(element)                     \
-  if (GST_V4L2_IS_ACTIVE(element))                             \
+#define GST_V4L2_CHECK_NOT_ACTIVE(v4l2object)                  \
+  if (GST_V4L2_IS_ACTIVE(v4l2object))                          \
   {                                                            \
-    GST_ELEMENT_ERROR (element, RESOURCE, SETTINGS,             \
+    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, \
       (NULL), ("Device is in streaming mode"));                 \
     return FALSE;                                              \
   }
 
 
 /* open/close the device */
-gboolean       gst_v4l2_open                   (GstV4l2Element *v4l2element);
-gboolean       gst_v4l2_close                  (GstV4l2Element *v4l2element);
+gboolean       gst_v4l2_open                   (GstV4l2Object *v4l2object);
+gboolean       gst_v4l2_close                  (GstV4l2Object *v4l2object);
 
 /* norm/input/output */
-gboolean       gst_v4l2_get_norm               (GstV4l2Element *v4l2element,
+gboolean       gst_v4l2_get_norm               (GstV4l2Object *v4l2object,
                                                 v4l2_std_id    *norm);
-gboolean       gst_v4l2_set_norm               (GstV4l2Element *v4l2element,
+gboolean       gst_v4l2_set_norm               (GstV4l2Object *v4l2object,
                                                 v4l2_std_id     norm);
-gboolean       gst_v4l2_get_output             (GstV4l2Element *v4l2element,
+gboolean        gst_v4l2_get_input              (GstV4l2Object * v4l2object,
+                                                 gint * input);
+gboolean        gst_v4l2_set_input              (GstV4l2Object * v4l2object,
+                                                 gint input);
+#if 0 /* output not handled by now */
+gboolean       gst_v4l2_get_output             (GstV4l2Object *v4l2object,
                                                 gint           *output);
-gboolean       gst_v4l2_set_output             (GstV4l2Element *v4l2element,
+gboolean       gst_v4l2_set_output             (GstV4l2Object *v4l2object,
                                                 gint            output);
+#endif /* #if 0 - output not handled by now */
 
 /* frequency control */
-gboolean       gst_v4l2_get_frequency          (GstV4l2Element *v4l2element,
+gboolean       gst_v4l2_get_frequency          (GstV4l2Object *v4l2object,
                                                 gint            tunernum,
                                                 gulong         *frequency);
-gboolean       gst_v4l2_set_frequency          (GstV4l2Element *v4l2element,
+gboolean       gst_v4l2_set_frequency          (GstV4l2Object *v4l2object,
                                                 gint            tunernum,
                                                 gulong          frequency);
-gboolean       gst_v4l2_signal_strength        (GstV4l2Element *v4l2element,
+gboolean       gst_v4l2_signal_strength        (GstV4l2Object *v4l2object,
                                                 gint            tunernum,
                                                 gulong         *signal);
 
 /* attribute control */
-gboolean       gst_v4l2_get_attribute          (GstV4l2Element *v4l2element,
+gboolean       gst_v4l2_get_attribute          (GstV4l2Object *v4l2object,
                                                 int             attribute,
                                                 int            *value);
-gboolean       gst_v4l2_set_attribute          (GstV4l2Element *v4l2element,
+gboolean       gst_v4l2_set_attribute          (GstV4l2Object *v4l2object,
                                                 int             attribute,
                                                 const int       value);
 
-gboolean        gst_v4l2_get_capabilities       (GstV4l2Element * v4l2element);
+gboolean        gst_v4l2_get_capabilities       (GstV4l2Object * v4l2object);
 
 #endif /* __V4L2_CALLS_H__ */
index 4f55d8b..f50c647 100644 (file)
@@ -73,14 +73,13 @@ gst_v4l2src_fill_format_list (GstV4l2Src * v4l2src)
 
     format->index = n;
     format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_ENUM_FMT,
-            format) < 0) {
+    if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_ENUM_FMT, format) < 0) {
       if (errno == EINVAL) {
         break;                  /* end of enumeration */
       } else {
         GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS, (NULL),
             ("failed to get number %d in pixelformat enumeration for %s: %s",
-                n, GST_V4L2ELEMENT (v4l2src)->videodev, g_strerror (errno)));
+                n, v4l2src->v4l2object->videodev, g_strerror (errno)));
         g_free (format);
         return FALSE;
       }
@@ -122,11 +121,11 @@ gst_v4l2src_queue_frame (GstV4l2Src * v4l2src, guint i)
 {
   GST_LOG_OBJECT (v4l2src, "queueing frame %u", i);
 
-  if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_QBUF,
+  if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_QBUF,
           &v4l2src->pool->buffers[i].buffer) < 0) {
     GST_ELEMENT_ERROR (v4l2src, RESOURCE, WRITE,
         (_("Could not write to device \"%s\"."),
-            GST_V4L2ELEMENT (v4l2src)->videodev),
+            v4l2src->v4l2object->videodev),
         ("Error queueing buffer %u on device %s", i, g_strerror (errno)));
     return FALSE;
   }
@@ -150,26 +149,26 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l2src)
   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) {
+  while (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_DQBUF, &buffer) < 0) {
     /* if the sync() got interrupted, we can retry */
     switch (errno) {
       case EAGAIN:
         GST_ELEMENT_ERROR (v4l2src, RESOURCE, SYNC, (NULL),
             ("Non-blocking I/O has been selected using O_NONBLOCK and"
                 " no buffer was in the outgoing queue. device %s: %s",
-                GST_V4L2ELEMENT (v4l2src)->videodev, g_strerror (errno)));
+                v4l2src->v4l2object->videodev, g_strerror (errno)));
         break;
       case EINVAL:
         GST_ELEMENT_ERROR (v4l2src, RESOURCE, SYNC, (NULL),
             ("The buffer type is not supported, or the index is out of bounds,"
                 " or no buffers have been allocated yet, or the userptr"
                 " or length are invalid. device %s: %s",
-                GST_V4L2ELEMENT (v4l2src)->videodev, g_strerror (errno)));
+                v4l2src->v4l2object->videodev, g_strerror (errno)));
         break;
       case ENOMEM:
         GST_ELEMENT_ERROR (v4l2src, RESOURCE, SYNC, (NULL),
             ("isufficient memory to enqueue a user pointer buffer. device %s: %s",
-                GST_V4L2ELEMENT (v4l2src)->videodev, g_strerror (errno)));
+                v4l2src->v4l2object->videodev, g_strerror (errno)));
         break;
       case EIO:
         GST_WARNING_OBJECT (v4l2src,
@@ -178,12 +177,12 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l2src)
             " 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));
+            v4l2src->v4l2object->videodev, g_strerror (errno));
         break;
       case EINTR:
         GST_ELEMENT_ERROR (v4l2src, RESOURCE, SYNC, (NULL),
             ("could not sync on a buffer on device %s: %s",
-                GST_V4L2ELEMENT (v4l2src)->videodev, g_strerror (errno)));
+                v4l2src->v4l2object->videodev, g_strerror (errno)));
         break;
       default:
         GST_DEBUG_OBJECT (v4l2src, "grab got interrupted");
@@ -193,7 +192,7 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l2src)
     if (--trials == -1) {
       return -1;
     } else {
-      ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_QBUF, &buffer);
+      ioctl (v4l2src->v4l2object->video_fd, VIDIOC_QBUF, &buffer);
       memset (&buffer, 0x00, sizeof (buffer));
       buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
       buffer.memory = v4l2src->breq.memory;
@@ -218,14 +217,13 @@ gst_v4l2src_get_capture (GstV4l2Src * v4l2src)
 {
   DEBUG ("Getting capture format");
 
-  GST_V4L2_CHECK_OPEN (GST_V4L2ELEMENT (v4l2src));
+  GST_V4L2_CHECK_OPEN (v4l2src->v4l2object);
 
   v4l2src->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-  if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_G_FMT,
-          &v4l2src->format) < 0) {
+  if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_G_FMT, &v4l2src->format) < 0) {
     GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS, (NULL),
         ("failed to get pixelformat for device %s: %s",
-            GST_V4L2ELEMENT (v4l2src)->videodev, g_strerror (errno)));
+            v4l2src->v4l2object->videodev, g_strerror (errno)));
     return FALSE;
   }
 
@@ -246,8 +244,8 @@ gst_v4l2src_set_capture (GstV4l2Src * v4l2src,
   DEBUG ("Setting capture format to %dx%d, format %s",
       width, height, fmt->description);
 
-  GST_V4L2_CHECK_OPEN (GST_V4L2ELEMENT (v4l2src));
-  GST_V4L2_CHECK_NOT_ACTIVE (GST_V4L2ELEMENT (v4l2src));
+  GST_V4L2_CHECK_OPEN (v4l2src->v4l2object);
+  GST_V4L2_CHECK_NOT_ACTIVE (v4l2src->v4l2object);
 
   memset (&v4l2src->format, 0, sizeof (struct v4l2_format));
   v4l2src->format.fmt.pix.width = width;
@@ -256,12 +254,11 @@ gst_v4l2src_set_capture (GstV4l2Src * v4l2src,
   v4l2src->format.fmt.pix.field = V4L2_FIELD_INTERLACED;
   v4l2src->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
-  if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_S_FMT,
-          &v4l2src->format) < 0) {
+  if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_S_FMT, &v4l2src->format) < 0) {
     GST_ELEMENT_ERROR (v4l2src, RESOURCE, SETTINGS, (NULL),
         ("failed to set pixelformat to %s @ %dx%d for device %s: %s",
             fmt->description, width, height,
-            GST_V4L2ELEMENT (v4l2src)->videodev, g_strerror (errno)));
+            v4l2src->v4l2object->videodev, g_strerror (errno)));
     return FALSE;
   }
 
@@ -284,8 +281,8 @@ gst_v4l2src_capture_init (GstV4l2Src * v4l2src)
 
   GST_DEBUG_OBJECT (v4l2src, "initting the capture system");
 
-  GST_V4L2_CHECK_OPEN (GST_V4L2ELEMENT (v4l2src));
-  GST_V4L2_CHECK_NOT_ACTIVE (GST_V4L2ELEMENT (v4l2src));
+  GST_V4L2_CHECK_OPEN (v4l2src->v4l2object);
+  GST_V4L2_CHECK_NOT_ACTIVE (v4l2src->v4l2object);
 
   /* request buffer info */
   buffers = v4l2src->breq.count;
@@ -296,32 +293,32 @@ gst_v4l2src_capture_init (GstV4l2Src * v4l2src)
     v4l2src->breq.count = GST_V4L2_MIN_BUFFERS;
   }
   v4l2src->breq.type = v4l2src->format.type;
-  if (GST_V4L2ELEMENT (v4l2src)->vcap.capabilities & V4L2_CAP_STREAMING) {
+  if (v4l2src->v4l2object->vcap.capabilities & V4L2_CAP_STREAMING) {
     v4l2src->breq.memory = V4L2_MEMORY_MMAP;
-    if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_REQBUFS,
+    if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_REQBUFS,
             &v4l2src->breq) < 0) {
       GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
           (_("Could not get buffers from device \"%s\"."),
-              GST_V4L2ELEMENT (v4l2src)->videodev),
+              v4l2src->v4l2object->videodev),
           ("error requesting %d buffers: %s",
               v4l2src->breq.count, g_strerror (errno)));
       return FALSE;
     }
     GST_LOG_OBJECT (v4l2src, "using default mmap method");
-  } else if (GST_V4L2ELEMENT (v4l2src)->vcap.capabilities & V4L2_CAP_READWRITE) {
+  } else if (v4l2src->v4l2object->vcap.capabilities & V4L2_CAP_READWRITE) {
     v4l2src->breq.memory = 0;
     GST_INFO_OBJECT (v4l2src, "using fallback read method");
   } else {
     GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
         (_("the driver of device \"%s\" is broken."),
-            GST_V4L2ELEMENT (v4l2src)->videodev),
+            v4l2src->v4l2object->videodev),
         ("no supported read capability from %s",
-            GST_V4L2ELEMENT (v4l2src)->videodev));
+            v4l2src->v4l2object->videodev));
     return FALSE;
   }
 
   /* Determine the device's framerate */
-  if (!gst_v4l2src_get_fps (v4l2src, &v4l2src->fps_n, &v4l2src->fps_d)) {
+  if (!gst_v4l2src_update_fps (v4l2src->v4l2object)) {
     GST_DEBUG_OBJECT (v4l2src, "frame rate is unknown.");
     v4l2src->fps_d = 1;
     v4l2src->fps_n = 0;
@@ -331,7 +328,7 @@ gst_v4l2src_capture_init (GstV4l2Src * v4l2src)
     if (v4l2src->breq.count < GST_V4L2_MIN_BUFFERS) {
       GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
           (_("Could not get enough buffers from device \"%s\"."),
-              GST_V4L2ELEMENT (v4l2src)->videodev),
+              v4l2src->v4l2object->videodev),
           ("we received %d, we want at least %d",
               v4l2src->breq.count, GST_V4L2_MIN_BUFFERS));
       v4l2src->breq.count = buffers;
@@ -351,7 +348,7 @@ gst_v4l2src_capture_init (GstV4l2Src * v4l2src)
 
     v4l2src->pool = g_new (GstV4l2BufferPool, 1);
     gst_atomic_int_set (&v4l2src->pool->refcount, 1);
-    v4l2src->pool->video_fd = GST_V4L2ELEMENT (v4l2src)->video_fd;
+    v4l2src->pool->video_fd = v4l2src->v4l2object->video_fd;
     v4l2src->pool->buffer_count = v4l2src->breq.count;
     v4l2src->pool->buffers = g_new0 (GstV4l2Buffer, v4l2src->breq.count);
 
@@ -365,7 +362,7 @@ gst_v4l2src_capture_init (GstV4l2Src * v4l2src)
       buffer->buffer.type = v4l2src->breq.type;
       buffer->buffer.memory = v4l2src->breq.memory;
 
-      if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_QUERYBUF,
+      if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_QUERYBUF,
               &buffer->buffer) < 0) {
         GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, (NULL),
             ("Could not get buffer properties of buffer %d: %s",
@@ -375,7 +372,7 @@ gst_v4l2src_capture_init (GstV4l2Src * v4l2src)
       }
       buffer->start =
           mmap (0, buffer->buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED,
-          GST_V4L2ELEMENT (v4l2src)->video_fd, buffer->buffer.m.offset);
+          v4l2src->v4l2object->video_fd, buffer->buffer.m.offset);
       if (buffer->start == MAP_FAILED) {
         GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, (NULL),
             ("Could not mmap video buffer %d: %s", n, g_strerror (errno)));
@@ -394,7 +391,7 @@ gst_v4l2src_capture_init (GstV4l2Src * v4l2src)
     v4l2src->pool = NULL;
   }
 
-  GST_V4L2_SET_ACTIVE (GST_V4L2ELEMENT (v4l2src));
+  GST_V4L2_SET_ACTIVE (v4l2src->v4l2object);
 
   return TRUE;
 }
@@ -413,19 +410,19 @@ gst_v4l2src_capture_start (GstV4l2Src * v4l2src)
 
   GST_DEBUG_OBJECT (v4l2src, "starting the capturing");
 
-  GST_V4L2_CHECK_OPEN (GST_V4L2ELEMENT (v4l2src));
-  if (!GST_V4L2_IS_ACTIVE (GST_V4L2ELEMENT (v4l2src))) {
+  GST_V4L2_CHECK_OPEN (v4l2src->v4l2object);
+  if (!GST_V4L2_IS_ACTIVE (v4l2src->v4l2object)) {
     /* gst_pad_renegotiate (v4l2src->srcpad); FIX: is it still required in 0.10 */
   }
-  GST_V4L2_CHECK_ACTIVE (GST_V4L2ELEMENT (v4l2src));
+  GST_V4L2_CHECK_ACTIVE (v4l2src->v4l2object);
 
   v4l2src->quit = FALSE;
 
   if (v4l2src->breq.memory != 0) {
-    if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_STREAMON, &type) < 0) {
+    if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_STREAMON, &type) < 0) {
       GST_ELEMENT_ERROR (v4l2src, RESOURCE, OPEN_READ, (NULL),
           ("Error starting streaming capture from device %s: %s",
-              GST_V4L2ELEMENT (v4l2src)->videodev, g_strerror (errno)));
+              v4l2src->v4l2object->videodev, g_strerror (errno)));
       return FALSE;
     }
   }
@@ -448,17 +445,16 @@ gst_v4l2src_capture_stop (GstV4l2Src * v4l2src)
   gint type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
   GST_DEBUG_OBJECT (v4l2src, "stopping capturing");
-  GST_V4L2_CHECK_OPEN (GST_V4L2ELEMENT (v4l2src));
-  GST_V4L2_CHECK_ACTIVE (GST_V4L2ELEMENT (v4l2src));
+  GST_V4L2_CHECK_OPEN (v4l2src->v4l2object);
+  GST_V4L2_CHECK_ACTIVE (v4l2src->v4l2object);
 
   if (v4l2src->breq.memory != 0) {
     /* we actually need to sync on all queued buffers but not
      * on the non-queued ones */
-    if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_STREAMOFF,
-            &type) < 0) {
+    if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_STREAMOFF, &type) < 0) {
       GST_ELEMENT_ERROR (v4l2src, RESOURCE, CLOSE, (NULL),
           ("Error stopping streaming capture from device %s: %s",
-              GST_V4L2ELEMENT (v4l2src)->videodev, g_strerror (errno)));
+              v4l2src->v4l2object->videodev, g_strerror (errno)));
       return FALSE;
     }
   }
@@ -524,14 +520,14 @@ gst_v4l2src_capture_deinit (GstV4l2Src * v4l2src)
 
   GST_DEBUG_OBJECT (v4l2src, "deinitting capture system");
 
-  GST_V4L2_CHECK_OPEN (GST_V4L2ELEMENT (v4l2src));
-  GST_V4L2_CHECK_ACTIVE (GST_V4L2ELEMENT (v4l2src));
+  GST_V4L2_CHECK_OPEN (v4l2src->v4l2object);
+  GST_V4L2_CHECK_ACTIVE (v4l2src->v4l2object);
 
   if (v4l2src->pool) {
     /* free the buffers */
     for (i = 0; i < v4l2src->breq.count; i++) {
       if (g_atomic_int_dec_and_test (&v4l2src->pool->buffers[i].refcount)) {
-        if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_DQBUF,
+        if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_DQBUF,
                 &v4l2src->pool->buffers[i].buffer) < 0)
           GST_WARNING_OBJECT (v4l2src,
               "Could not dequeue buffer on uninitialization: %s - will try reinit instead",
@@ -558,7 +554,7 @@ gst_v4l2src_capture_deinit (GstV4l2Src * v4l2src)
     }
   }
 
-  GST_V4L2_SET_INACTIVE (GST_V4L2ELEMENT (v4l2src));
+  GST_V4L2_SET_INACTIVE (v4l2src->v4l2object);
   return TRUE;
 }
 
@@ -585,7 +581,7 @@ gst_v4l2src_get_size_limits (GstV4l2Src * v4l2src,
   fmt.fmt.pix.height = 0;
   fmt.fmt.pix.pixelformat = format->pixelformat;
   fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
-  if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_TRY_FMT, &fmt) < 0) {
+  if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_TRY_FMT, &fmt) < 0) {
     return FALSE;
   }
 
@@ -598,7 +594,7 @@ gst_v4l2src_get_size_limits (GstV4l2Src * v4l2src,
 
   fmt.fmt.pix.width = G_MAXINT;
   fmt.fmt.pix.height = G_MAXINT;
-  if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_TRY_FMT, &fmt) < 0) {
+  if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_TRY_FMT, &fmt) < 0) {
     return FALSE;
   }
 
@@ -613,19 +609,28 @@ gst_v4l2src_get_size_limits (GstV4l2Src * v4l2src,
 }
 
 gboolean
+gst_v4l2src_update_fps (GstV4l2Object * v4l2object)
+{
+  GstV4l2Src *v4l2src = GST_V4L2SRC (v4l2object->element);
+
+  return gst_v4l2src_get_fps (v4l2src, &v4l2src->fps_n, &v4l2src->fps_d);
+}
+
+gboolean
 gst_v4l2src_get_fps (GstV4l2Src * v4l2src, guint * fps_n, guint * fps_d)
 {
+  GstV4l2Object *v4l2object = v4l2src->v4l2object;
   v4l2_std_id std;
   struct v4l2_streamparm stream;
   const GList *item;
 
-  if (!GST_V4L2_IS_OPEN (GST_V4L2ELEMENT (v4l2src)))
+  if (!GST_V4L2_IS_OPEN (v4l2object))
     return FALSE;
 
   /* Try to get the frame rate directly from the device using VIDIOC_G_PARM */
   stream.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-  if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_G_PARM, &stream) == 0
-      && stream.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
+  if (ioctl (v4l2object->video_fd, VIDIOC_G_PARM, &stream) == 0 &&
+      stream.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
     /* Note: V4L2 gives us the frame interval, we need the frame rate */
     *fps_n = stream.parm.capture.timeperframe.denominator;
     *fps_d = stream.parm.capture.timeperframe.numerator;
@@ -635,9 +640,9 @@ gst_v4l2src_get_fps (GstV4l2Src * v4l2src, guint * fps_n, guint * fps_d)
   }
 
   /* If G_PARM failed, try to get the same information from the video standard */
-  if (!gst_v4l2_get_norm (GST_V4L2ELEMENT (v4l2src), &std))
+  if (!gst_v4l2_get_norm (v4l2object, &std))
     return FALSE;
-  for (item = GST_V4L2ELEMENT (v4l2src)->stds; item != NULL; item = item->next) {
+  for (item = v4l2object->stds; item != NULL; item = item->next) {
     GstV4l2TunerNorm *v4l2norm = item->data;
 
     if (v4l2norm->index == std) {
@@ -667,8 +672,8 @@ GValue *
 gst_v4l2src_get_fps_list (GstV4l2Src * v4l2src)
 {
   gint fps_index;
-  struct video_window *vwin = &GST_V4L2ELEMENT (v4l2src)->vwin;
-  GstV4l2Element *v4l2element = GST_V4L2ELEMENT (v4l2src);
+  struct video_window *vwin = &v4l2src->v4l2object->vwin;
+  GstV4l2Object *v4l2object = v4l2src->v4l2object;
 
   /* check if we have vwin window properties giving a framerate,
    * as is done for webcams
@@ -701,7 +706,7 @@ gst_v4l2src_get_fps_list (GstV4l2Src * v4l2src)
       vwin->flags &= (0x3F00 - 1);
       /* set bits 16 to 21 to the index */
       vwin->flags |= i << 16;
-      if (gst_v4l2_set_window_properties (v4l2element)) {
+      if (gst_v4l2_set_window_properties (v4l2object)) {
         /* setting it succeeded.  FIXME: get it and check. */
         g_value_init (&value, GST_TYPE_FRACTION);
         gst_value_set_fraction (&value, i * 15, 16);
@@ -712,7 +717,7 @@ gst_v4l2src_get_fps_list (GstV4l2Src * v4l2src)
     /* FIXME: set back the original fps_index */
     vwin->flags &= (0x3F00 - 1);
     vwin->flags |= fps_index << 16;
-    gst_v4l2_set_window_properties (v4l2element);
+    gst_v4l2_set_window_properties (v4l2object);
     return list;
   }
   return NULL;
index 3839ef2..51d871f 100644 (file)
@@ -48,8 +48,11 @@ gboolean gst_v4l2src_get_size_limits (GstV4l2Src * v4l2src,
 
 void gst_v4l2src_free_buffer (GstBuffer * buffer);
 
+extern gboolean
+gst_v4l2src_update_fps (GstV4l2Object * v4l2object);
 
-gboolean gst_v4l2src_get_fps (GstV4l2Src * v4l2src, guint * fps_n, guint * fps_d);
+extern gboolean
+gst_v4l2src_get_fps (GstV4l2Src * v4l2src, guint * fps_n, guint * fps_d);
 
 GValue *gst_v4l2src_get_fps_list (GstV4l2Src * v4l2src);