docs/pwg/advanced_interfaces.xml: Add documentation on propertyprobing.
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Wed, 28 Jan 2004 14:16:59 +0000 (14:16 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Wed, 28 Jan 2004 14:16:59 +0000 (14:16 +0000)
Original commit message from CVS:
2004-01-28  Ronald Bultje  <rbultje@ronald.bitfreak.net>

* docs/pwg/advanced_interfaces.xml:
Add documentation on propertyprobing.
* docs/pwg/advanced_events.xml:
* docs/pwg/advanced_tagging.xml:
* docs/pwg/building_boiler.xml:
* docs/pwg/building_filterfactory.xml:
* docs/pwg/pwg.xml:
Move filterfactory and tagging into their own chapter, add a chapter
on events. all these are empty placeholders that will be filled in
some day.

ChangeLog
docs/pwg/advanced-events.xml [new file with mode: 0644]
docs/pwg/advanced-interfaces.xml
docs/pwg/advanced-tagging.xml [new file with mode: 0644]
docs/pwg/building-boiler.xml
docs/pwg/building-filterfactory.xml [new file with mode: 0644]
docs/pwg/pwg.xml

index cb3b68a..e2fc021 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,19 @@
 2004-01-28  Ronald Bultje  <rbultje@ronald.bitfreak.net>
 
        * docs/pwg/advanced_interfaces.xml:
+         Add documentation on propertyprobing.
+       * docs/pwg/advanced_events.xml:
+       * docs/pwg/advanced_tagging.xml:
+       * docs/pwg/building_boiler.xml:
+       * docs/pwg/building_filterfactory.xml:
+       * docs/pwg/pwg.xml:
+         Move filterfactory and tagging into their own chapter, add a chapter
+         on events. all these are empty placeholders that will be filled in
+         some day.
+
+2004-01-28  Ronald Bultje  <rbultje@ronald.bitfreak.net>
+
+       * docs/pwg/advanced_interfaces.xml:
          Docs for mixer interface. Also a check for website uploading.
 
 2004-01-28  Thomas Vander Stichele  <thomas at apestaart dot org>
diff --git a/docs/pwg/advanced-events.xml b/docs/pwg/advanced-events.xml
new file mode 100644 (file)
index 0000000..cd0dfbb
--- /dev/null
@@ -0,0 +1,6 @@
+<chapter id="cha-advanced-events">
+  <title>Events: Seeking, Navigation and More</title>
+  <para>
+    WRITEME
+  </para>
+</chapter>
index df5c0ea..5801545 100644 (file)
     allows us to query for interface availability based on runtime properties.
     This extension is called <classname>GstImplementsInterface</classname>.
   </para>
+  <para>
+    One important note: interfaces do <emphasis>not</emphasis> replace
+    properties. Rather, interfaces should be built <emphasis>next to</emphasis>
+    properties. There are two important reasons for this. Firstly, properties
+    can be saved in XML files. Secondly, properties can be specified on the
+    commandline (<filename>gst-launch</filename>).
+  </para>
 
   <sect1 id="sect1-iface-general" xreflabel="How to Implement Interfaces">
     <title>How to Implement Interfaces</title>
@@ -137,6 +144,8 @@ gst_my_filter_some_interface_init (GstSomeInterface *iface)
       to the implementation here.
     </para>
     <programlisting>
+#include &lt;gst/mixer/mixer.h&gt;
+
 typedef struct _GstMyFilter {
 [..]
   gint volume;
@@ -277,7 +286,164 @@ gst_my_filter_mixer_interface_init (GstMixerClass *iface)
   <sect1 id="sect1-iface-propprobe" xreflabel="Property Probe Interface">
     <title>Property Probe Interface</title>
     <para>
-      WRITEME
+      Property probing is a generic solution to the problem that properties'
+      value lists in an enumeration are static. We've shown enumerations in
+      <xref linkend="cha-building-args"/>. Property probing tries to accomplish
+      a goal similar to enumeration lists: to have a limited, explicit list of
+      allowed values for a property. There are two differences between
+      enumeration lists and probing. Firstly, enumerations only allow strings
+      as values; property probing works for any value type. Secondly, the
+      contents of a probed list of allowed values may change during the life
+      of an element. The contents of a enumeraiton list are static. Crrently,
+      property probing is being used for detection of devices (e.g. for OSS
+      elements, Video4linux elements, etc.). It could - in theory - be used
+      for any property, though.
+    </para>
+    <para>
+      Property probing stores the list of allowed (or recommended) values in a
+      <classname>GValueArray</classname> and returns that to the user.
+      <classname>NULL</classname> is a valid return value, too. The process of
+      property probing is separated over two virtual functions: one for probing
+      the property to create a <classname>GValueArray</classname>, and one to
+      retrieve the current <classname>GValueArray</classname>. Those two are
+      separated because probing might take a long time (several seconds). Also,
+      this simpliies interface implementation in elements. For the application,
+      there are functions that wrap those two. For more information on this,
+      have a look at the API reference for the
+      <classname>GstPropertyProbe</classname> interface.
+    </para>
+    <para>
+      Below is a example of property probing for the audio filter element; it
+      will probe for allowed values for the <quote>silent</quote> property.
+      Indeed, this value is a <classname>gboolean</classname> so it doesn't
+      make much sense. Then again, it's only an example.
+    </para>
+    <programlisting>
+#include &lt;gst/propertyprobe/propertyprobe.h&gt;
+
+static void    gst_my_filter_probe_interface_init      (GstPropertyProbeInterface *iface);
+
+GType
+gst_my_filter_get_type (void)
+{
+[..]
+    static const GInterfaceInfo probe_interface_info = {
+      (GInterfaceInitFunc) gst_my_filter_probe_interface_init,
+      NULL,
+      NULL
+    };
+[..]
+    g_type_add_interface_static (my_filter_type,
+                                GST_TYPE_PROPERTY_PROBE,
+                                &amp;probe_interface_info);
+[..]
+}
+
+static const GList *
+gst_my_filter_probe_get_properties (GstPropertyProbe *probe)
+{
+  GObjectClass *klass = G_OBJECT_GET_CLASS (probe);
+  static GList *props = NULL;
+
+  if (!props) {
+    GParamSpec *pspec;
+
+    pspec = g_object_class_find_property (klass, "silent");
+    props = g_list_append (props, pspec);
+  }
+
+  return props;
+}
+
+static gboolean
+gst_my_filter_probe_needs_probe (GstPropertyProbe *probe,
+                                guint             prop_id,
+                                const GParamSpec *pspec)
+{
+  gboolean res = FALSE;
+
+  switch (prop_id) {
+    case ARG_SILENT:
+      res = FALSE;
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
+      break;
+  }
+
+  return res;
+}
+
+static void
+gst_my_filter_probe_probe_property (GstPropertyProbe *probe,
+                                   guint             prop_id,
+                                   const GParamSpec *pspec)
+{
+  switch (prop_id) {
+    case ARG_SILENT:
+      /* don't need to do much here... */
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
+      break;
+  }
+}
+
+static GValueArray *
+gst_my_filter_get_silent_values (GstMyFilter *filter)
+{
+  GValueArray *array = g_value_array_new (2);
+  GValue value = { 0 };
+
+  g_value_init (&amp;value, G_TYPE_BOOLEAN);
+
+  /* add TRUE */
+  g_value_set_boolean (&amp;value, TRUE);
+  g_value_array_append (array, &amp;value);
+
+  /* add FALSE */
+  g_value_set_boolean (&amp;value, FALSE);
+  g_value_array_append (array, &amp;value);
+
+  g_value_unset (&amp;value);
+
+  return array;
+}
+
+static GValueArray *
+gst_my_filter_probe_get_values (GstPropertyProbe *probe,
+                               guint             prop_id,
+                               const GParamSpec *pspec)
+{
+  GstMyFilter *filter = GST_MY_FILTER (probe);
+  GValueArray *array = NULL;
+
+  switch (prop_id) {
+    case ARG_SILENT:
+      array = gst_my_filter_get_silent_values (filter);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
+      break;
+  }
+
+  return array;
+}
+
+static void
+gst_my_filter_probe_interface_init (GstPropertyProbeInterface *iface)
+{
+  iface->get_properties = gst_my_filter_probe_get_properties;
+  iface->needs_probe    = gst_my_filter_probe_needs_probe;
+  iface->probe_property = gst_my_filter_probe_probe_property;
+  iface->get_values     = gst_my_filter_probe_get_values;
+}
+    </programlisting>
+    <para>
+      You don't need to support any functions for getting or setting values.
+      All that is handled via the standard <classname>GObject</classname>
+      <function>_set_property ()</function> and <function>_get_property ()</function>
+      functions.
     </para>
   </sect1>
 
@@ -301,11 +467,4 @@ gst_my_filter_mixer_interface_init (GstMixerClass *iface)
       WRITEME
     </para>
   </sect1>
-
-  <sect1 id="sect1-iface-tagging" xreflabel="Tagging Interface">
-    <title>Tagging Interface</title>
-    <para>
-      WRITEME
-    </para>
-  </sect1>
 </chapter>
diff --git a/docs/pwg/advanced-tagging.xml b/docs/pwg/advanced-tagging.xml
new file mode 100644 (file)
index 0000000..4b239f9
--- /dev/null
@@ -0,0 +1,6 @@
+<chapter id="cha-advanced-tagging">
+  <title>Tagging (Metadata and Streaminfo)</title>
+  <para>
+    WRITEME
+  </para>
+</chapter>
index 5248045..5392df4 100644 (file)
@@ -167,34 +167,6 @@ U gst-template/gst-app/src/Makefile.am
 
   <!-- ############ sect1 ############# -->
 
-  <sect1 id="sect1-boiler-filterfactory" xreflabel="Creating a Filter With FilterFactory">
-    <title>Creating a Filter With FilterFactory (Future)</title>
-    <para>
-      A plan for the future is to create a FilterFactory, to make the process of
-      making a new filter a simple process of specifying a few details, and
-      writing a small amount of code to perform the actual data processing.
-      Ideally, a FilterFactory would perform the tasks of boilerplate creation,
-      code functionality implementation, and filter registration.
-    </para>
-    <para>
-      Unfortunately, this has not yet been implemented. Even when someone
-      eventually does write a FilterFactory, this element will not be able to
-      cover all the possibilities available for filter writing. Thus, some
-      plugins will always need to be manually coded and registered.
-    </para>
-    <para>
-      Here is a rough outline of what is planned: You run the FilterFactory and
-      give the factory a list of appropriate function pointers and data
-      structures to define a filter. With a reasonable measure of preprocessor
-      magic, you just need to provide a name for the filter and definitions of
-      the functions and data structures desired. Then you call a macro from
-      within plugin_init() that registers the new filter. All the fluff that
-      goes into the definition of a filter is thus be hidden from view.
-    </para>
-  </sect1>
-
-  <!-- ############ sect1 ############# -->
-
   <sect1 id="sect1-boiler-details">
     <title>GstElementDetails</title>
     <para>
diff --git a/docs/pwg/building-filterfactory.xml b/docs/pwg/building-filterfactory.xml
new file mode 100644 (file)
index 0000000..4d2e4e8
--- /dev/null
@@ -0,0 +1,24 @@
+<chapter id="cha-building-filterfactory">
+  <title>Creating a Filter with a Filter Factory</title>
+    <para>
+      A plan for the future is to create a FilterFactory, to make the process of      making a new filter a simple process of specifying a few details, and
+      writing a small amount of code to perform the actual data processing.
+      Ideally, a FilterFactory would perform the tasks of boilerplate creation,
+      code functionality implementation, and filter registration.
+    </para>
+    <para>
+      Unfortunately, this has not yet been implemented. Even when someone
+      eventually does write a FilterFactory, this element will not be able to
+      cover all the possibilities available for filter writing. Thus, some
+      plugins will always need to be manually coded and registered.
+    </para>
+    <para>
+      Here is a rough outline of what is planned: You run the FilterFactory and
+      give the factory a list of appropriate function pointers and data
+      structures to define a filter. With a reasonable measure of preprocessor
+      magic, you just need to provide a name for the filter and definitions of
+      the functions and data structures desired. Then you call a macro from
+      within plugin_init() that registers the new filter. All the fluff that
+      goes into the definition of a filter is thus be hidden from view.
+    </para>
+</chapter>
index d4b23cd..8ff9e08 100644 (file)
@@ -17,6 +17,7 @@
 <!ENTITY BUILDING_PROPS       SYSTEM "building_props.xml">
 <!ENTITY BUILDING_SIGNALS     SYSTEM "building_signals.xml">
 <!ENTITY BUILDING_TESTAPP     SYSTEM "building_testapp.xml">
+<!ENTITY BUILDING_FILTERFACT  SYSTEM "building_filterfactory.xml">
 
 <!ENTITY ADVANCED_SCHEDULING  SYSTEM "advanced_scheduling.xml">
 <!ENTITY ADVANCED_TYPES       SYSTEM "advanced_types.xml">
@@ -25,6 +26,8 @@
 <!ENTITY ADVANCED_DPARAMS     SYSTEM "advanced_dparams.xml">
 <!ENTITY ADVANCED_MIDI        SYSTEM "advanced_midi.xml">
 <!ENTITY ADVANCED_INTERFACES  SYSTEM "advanced_interfaces.xml">
+<!ENTITY ADVANCED_TAGGING     SYSTEM "advanced_tagging.xml">
+<!ENTITY ADVANCED_EVENTS      SYSTEM "advanced_events.xml">
 
 <!ENTITY OTHER_SOURCE         SYSTEM "other_source.xml">
 <!ENTITY OTHER_SINK           SYSTEM "other_sink.xml">
     &BUILDING_PROPS;
     &BUILDING_SIGNALS;
     &BUILDING_TESTAPP;
+    &BUILDING_FILTERFACT;
   </part>
 
   <!-- ############ part ############# -->
     &ADVANCED_DPARAMS;
     &ADVANCED_MIDI;
     &ADVANCED_INTERFACES;
+    &ADVANCED_TAGGING;
+    &ADVANCED_EVENTS;
   </part>
 
   <!-- ############ part ############# -->