ext/raw1394/: Implement GstPropertyProbe interface and add "device-name" property...
authorJulien Puydt <julien.puydt@laposte.net>
Wed, 14 Nov 2007 19:10:37 +0000 (19:10 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Wed, 14 Nov 2007 19:10:37 +0000 (19:10 +0000)
Original commit message from CVS:
Patch by: Julien Puydt <julien dot puydt at laposte net>
* ext/raw1394/Makefile.am:
* ext/raw1394/gst1394probe.c: (gst_1394_get_guid_array),
(gst_1394_property_probe_get_properties),
(gst_1394_property_probe_probe_property),
(gst_1394_property_probe_needs_probe),
(gst_1394_property_probe_get_values),
(gst_1394_property_probe_interface_init),
(gst_1394_type_add_property_probe_interface):
* ext/raw1394/gst1394probe.h: (GST_1394_PROBE_H):
* ext/raw1394/gstdv1394src.c: (_do_init), (gst_dv1394src_class_init),
(gst_dv1394src_init), (gst_dv1394src_dispose),
(gst_dv1394src_set_property), (gst_dv1394src_get_property),
(gst_dv1394src_discover_avc_node), (gst_dv1394src_query),
(gst_dv1394src_update_device_name):
* ext/raw1394/gstdv1394src.h:
Implement GstPropertyProbe interface and add "device-name" property,
so applications can use this to probe for available devices in the
same way they can already with v4lsrc and v4l2src (however horrible
this property probe interface may be). Fixes #358841.

ChangeLog
ext/raw1394/Makefile.am
ext/raw1394/gst1394probe.c [new file with mode: 0644]
ext/raw1394/gst1394probe.h [new file with mode: 0644]
ext/raw1394/gstdv1394src.c
ext/raw1394/gstdv1394src.h

index 2132763..e24a43f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,29 @@
 2007-11-14  Tim-Philipp Müller  <tim at centricular dot net>
 
+       Patch by: Julien Puydt <julien dot puydt at laposte net>
+
+       * ext/raw1394/Makefile.am:
+       * ext/raw1394/gst1394probe.c: (gst_1394_get_guid_array),
+         (gst_1394_property_probe_get_properties),
+         (gst_1394_property_probe_probe_property),
+         (gst_1394_property_probe_needs_probe),
+         (gst_1394_property_probe_get_values),
+         (gst_1394_property_probe_interface_init),
+         (gst_1394_type_add_property_probe_interface):
+       * ext/raw1394/gst1394probe.h: (GST_1394_PROBE_H):
+       * ext/raw1394/gstdv1394src.c: (_do_init), (gst_dv1394src_class_init),
+         (gst_dv1394src_init), (gst_dv1394src_dispose),
+         (gst_dv1394src_set_property), (gst_dv1394src_get_property),
+         (gst_dv1394src_discover_avc_node), (gst_dv1394src_query),
+         (gst_dv1394src_update_device_name):
+       * ext/raw1394/gstdv1394src.h:
+         Implement GstPropertyProbe interface and add "device-name" property,
+         so applications can use this to probe for available devices in the
+         same way they can already with v4lsrc and v4l2src (however horrible
+         this property probe interface may be). Fixes #358841.
+
+2007-11-14  Tim-Philipp Müller  <tim at centricular dot net>
+
        Patch by: Tommi Myöhänen  <ext-tommi dot myohanen at nokia dot com>
 
        * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_handle_src_event),
index 5774908..8c644d3 100644 (file)
@@ -1,8 +1,16 @@
 plugin_LTLIBRARIES = libgst1394.la
 
-libgst1394_la_SOURCES = gst1394.c gstdv1394src.c
-libgst1394_la_CFLAGS = $(GST_CFLAGS) $(DV1394_CFLAGS)
-libgst1394_la_LIBADD = $(GST_BASE_LIBS) $(DV1394_LIBS) 
+libgst1394_la_SOURCES = gst1394.c gst1394probe.c gstdv1394src.c
+libgst1394_la_CFLAGS = \
+       $(GST_PLUGINS_BASE_CFLAGS) \
+       $(GST_BASE_CFLAGS) \
+       $(GST_CFLAGS) \
+       $(DV1394_CFLAGS)
+libgst1394_la_LIBADD = \
+       $(GST_PLUGINS_BASE_LIBS) -lgstinterfaces-$(GST_MAJORMINOR) \
+       $(GST_BASE_LIBS) \
+       $(GST_LIBS) \
+       $(DV1394_LIBS)
 libgst1394_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 
-noinst_HEADERS = gstdv1394src.h
+noinst_HEADERS = gstdv1394src.h gst1394probe.h
diff --git a/ext/raw1394/gst1394probe.c b/ext/raw1394/gst1394probe.c
new file mode 100644 (file)
index 0000000..ee51ba0
--- /dev/null
@@ -0,0 +1,140 @@
+/* GStreamer
+ * Copyright (C) 2007 Julien Puydt <jpuydt@free.fr>
+ *
+ * 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.
+ */
+
+#include <libavc1394/avc1394.h>
+#include <libavc1394/avc1394_vcr.h>
+#include <libavc1394/rom1394.h>
+#include <libraw1394/raw1394.h>
+
+#include <gst/gst.h>
+
+#include "gst1394probe.h"
+#include "gst/interfaces/propertyprobe.h"
+
+static GValueArray *
+gst_1394_get_guid_array (void)
+{
+  GValueArray *result = NULL;
+  raw1394handle_t handle = NULL;
+  int num_ports = 0;
+  int port = 0;
+  int num_nodes = 0;
+  int node = 0;
+  rom1394_directory directory;
+  GValue value = { 0, };
+
+  handle = raw1394_new_handle ();
+
+  if (handle == NULL)
+    return NULL;
+
+  num_ports = raw1394_get_port_info (handle, NULL, 0);
+  for (port = 0; port < num_ports; port++) {
+    if (raw1394_set_port (handle, port) >= 0) {
+      num_nodes = raw1394_get_nodecount (handle);
+      for (node = 0; node < num_nodes; node++) {
+        rom1394_get_directory (handle, node, &directory);
+        if (rom1394_get_node_type (&directory) == ROM1394_NODE_TYPE_AVC &&
+            avc1394_check_subunit_type (handle, node,
+                AVC1394_SUBUNIT_TYPE_VCR)) {
+          if (result == NULL)
+            result = g_value_array_new (3);     /* looks like a sensible default */
+          g_value_init (&value, G_TYPE_UINT64);
+          g_value_set_uint64 (&value, rom1394_get_guid (handle, node));
+          g_value_array_append (result, &value);
+          g_value_unset (&value);
+        }
+      }
+    }
+  }
+
+  return result;
+}
+
+static const GList *
+gst_1394_property_probe_get_properties (GstPropertyProbe * probe)
+{
+  static GList *result = NULL;
+  GObjectClass *klass = NULL;
+  GParamSpec *spec = NULL;
+
+  if (result == NULL) {
+    klass = G_OBJECT_GET_CLASS (probe);
+    spec = g_object_class_find_property (klass, "guid");
+    result = g_list_append (result, spec);
+  }
+
+  return result;
+}
+
+static void
+gst_1394_property_probe_probe_property (GstPropertyProbe * probe, guint prop_id,
+    const GParamSpec * pspec)
+{
+  if (!g_str_equal (pspec->name, "guid"))
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
+}
+
+static gboolean
+gst_1394_property_probe_needs_probe (GstPropertyProbe * probe, guint prop_id,
+    const GParamSpec * pspec)
+{
+  return TRUE;
+}
+
+static GValueArray *
+gst_1394_property_probe_get_values (GstPropertyProbe * probe, guint prop_id,
+    const GParamSpec * pspec)
+{
+  GValueArray *result = NULL;
+
+  if (!g_str_equal (pspec->name, "guid")) {
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
+    return NULL;
+  }
+
+  result = gst_1394_get_guid_array ();
+
+  if (result == NULL)
+    GST_LOG_OBJECT (probe, "No guid found");
+
+  return result;
+}
+
+static void
+gst_1394_property_probe_interface_init (GstPropertyProbeInterface * iface)
+{
+  iface->get_properties = gst_1394_property_probe_get_properties;
+  iface->probe_property = gst_1394_property_probe_probe_property;
+  iface->needs_probe = gst_1394_property_probe_needs_probe;
+  iface->get_values = gst_1394_property_probe_get_values;
+}
+
+void
+gst_1394_type_add_property_probe_interface (GType type)
+{
+  static const GInterfaceInfo probe_iface_info = {
+    (GInterfaceInitFunc) gst_1394_property_probe_interface_init,
+    NULL,
+    NULL,
+  };
+
+  g_type_add_interface_static (type, GST_TYPE_PROPERTY_PROBE,
+      &probe_iface_info);
+}
diff --git a/ext/raw1394/gst1394probe.h b/ext/raw1394/gst1394probe.h
new file mode 100644 (file)
index 0000000..8436e70
--- /dev/null
@@ -0,0 +1,32 @@
+/* GStreamer
+ * Copyright (C) 2007 Julien Puydt <jpuydt@free.fr>
+ *
+ * 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_1394_PROBE_H
+#define GST_1394_PROBE_H
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+void gst_1394_type_add_property_probe_interface (GType type);
+
+G_END_DECLS
+
+#endif /* __GST_1394_PROBE_H */
+
index 8447646..34a354f 100644 (file)
@@ -41,6 +41,7 @@
 #include <gst/gst.h>
 
 #include "gstdv1394src.h"
+#include "gst1394probe.h"
 
 
 #define CONTROL_STOP            'S'     /* stop the select call */
@@ -93,7 +94,8 @@ enum
   PROP_SKIP,
   PROP_DROP_INCOMPLETE,
   PROP_USE_AVC,
-  PROP_GUID
+  PROP_GUID,
+  PROP_DEVICE_NAME
 };
 
 static const GstElementDetails gst_dv1394src_details =
@@ -132,6 +134,7 @@ static gboolean gst_dv1394src_convert (GstPad * pad,
 
 static const GstQueryType *gst_dv1394src_get_query_types (GstPad * pad);
 static gboolean gst_dv1394src_query (GstPad * pad, GstQuery * query);
+static void gst_dv1394src_update_device_name (GstDV1394Src * src);
 
 static void
 _do_init (GType type)
@@ -143,6 +146,8 @@ _do_init (GType type)
   };
   g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info);
 
+  gst_1394_type_add_property_probe_interface (type);
+
   GST_DEBUG_CATEGORY_INIT (dv1394src_debug, "dv1394src", 0,
       "DV firewire source");
 }
@@ -210,6 +215,16 @@ gst_dv1394src_class_init (GstDV1394SrcClass * klass)
           "select one of multiple DV devices by its GUID. use a hexadecimal "
           "like 0xhhhhhhhhhhhhhhhh. (0 = no guid)", 0, G_MAXUINT64,
           DEFAULT_GUID, G_PARAM_READWRITE));
+  /**
+   * GstDV1394Src:device-name
+   *
+   * Descriptive name of the currently opened device
+   *
+   * Since: 0.10.7
+   **/
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DEVICE_NAME,
+      g_param_spec_string ("device-name", "device name",
+          "user-friendly name of the device", "Default", G_PARAM_READABLE));
 
   gstbasesrc_class->negotiate = NULL;
   gstbasesrc_class->start = gst_dv1394src_start;
@@ -239,6 +254,7 @@ gst_dv1394src_init (GstDV1394Src * dv1394src, GstDV1394SrcClass * klass)
   dv1394src->use_avc = DEFAULT_USE_AVC;
   dv1394src->guid = DEFAULT_GUID;
   dv1394src->uri = g_strdup_printf ("dv://%d", dv1394src->port);
+  dv1394src->device_name = g_strdup_printf ("Default");
 
   READ_SOCKET (dv1394src) = -1;
   WRITE_SOCKET (dv1394src) = -1;
@@ -259,6 +275,9 @@ gst_dv1394src_dispose (GObject * object)
   g_free (src->uri);
   src->uri = NULL;
 
+  g_free (src->device_name);
+  src->device_name = NULL;
+
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
@@ -291,6 +310,7 @@ gst_dv1394src_set_property (GObject * object, guint prop_id,
       break;
     case PROP_GUID:
       filter->guid = g_value_get_uint64 (value);
+      gst_dv1394src_update_device_name (filter);
       break;
     default:
       break;
@@ -325,6 +345,9 @@ gst_dv1394src_get_property (GObject * object, guint prop_id, GValue * value,
     case PROP_GUID:
       g_value_set_uint64 (value, filter->guid);
       break;
+    case PROP_DEVICE_NAME:
+      g_value_set_string (value, filter->device_name);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -721,8 +744,11 @@ gst_dv1394src_discover_avc_node (GstDV1394Src * src)
           src->guid = rom1394_get_guid (handle, i);
           g_free (src->uri);
           src->uri = g_strdup_printf ("dv://%d", src->port);
+          g_free (src->device_name);
+          src->device_name = g_strdup (rom_dir.label);
           break;
         }
+        rom1394_free_directory (&rom_dir);
       }
     }
   next:
@@ -1044,6 +1070,58 @@ not_supported:
   }
 }
 
+static void
+gst_dv1394src_update_device_name (GstDV1394Src * src)
+{
+  raw1394handle_t handle;
+  gint portcount, port, nodecount, node;
+  rom1394_directory directory;
+
+  g_free (src->device_name);
+  src->device_name = NULL;
+
+  GST_LOG_OBJECT (src, "updating device name for current GUID");
+
+  handle = raw1394_new_handle ();
+
+  if (handle == NULL)
+    goto gethandle_failed;
+
+  portcount = raw1394_get_port_info (handle, NULL, 0);
+  for (port = 0; port < portcount; port++) {
+    if (raw1394_set_port (handle, port) >= 0) {
+      nodecount = raw1394_get_nodecount (handle);
+      for (node = 0; node < nodecount; node++) {
+        if (src->guid == rom1394_get_guid (handle, node)) {
+          if (rom1394_get_directory (handle, node, &directory) >= 0) {
+            g_free (src->device_name);
+            src->device_name = g_strdup (directory.label);
+            rom1394_free_directory (&directory);
+            goto done;
+          } else {
+            GST_WARNING ("error reading rom directory for node %d", node);
+          }
+        }
+      }
+    }
+  }
+
+  src->device_name = g_strdup ("Unknown");      /* FIXME: translate? */
+
+done:
+
+  raw1394_destroy_handle (handle);
+  return;
+
+/* ERRORS */
+gethandle_failed:
+  {
+    GST_WARNING ("failed to get raw1394 handle: %s", g_strerror (errno));
+    src->device_name = g_strdup ("Unknown");    /* FIXME: translate? */
+    return;
+  }
+}
+
 /*** GSTURIHANDLER INTERFACE *************************************************/
 
 static guint
index f5defe7..0e750dc 100644 (file)
@@ -76,6 +76,8 @@ struct _GstDV1394Src {
 
   gchar *uri;
 
+  gchar *device_name;
+
   gboolean connected;
   #ifdef HAVE_LIBIEC61883
   iec61883_dv_fb_t iec61883dv;