[gstreamermm] RingBuffer: Wrap virtual functions.



commit 0d0b327c7b0e1276a25fcbb3d2301271657b614c
Author: José Alburquerque <jaalburqu svn gnome org>
Date:   Wed Dec 9 23:56:07 2009 -0500

    	RingBuffer: Wrap virtual functions.
    
    	* gstreamer/src/ringbuffer.ccg:
    	* gstreamer/src/ringbuffer.hg: Wrapped virtual functions.
    	(RingBufferSpec): Declare it as a struct and make the members public.
    	Document the use of the members and justify why it was declared as a
    	struct and not a class.
    	(RingBufferSpec::silence_sample): Use a std::vector<> for the member
    	type instead of int[32].
    	(RingBufferSpec::copy_fields_from): Renamed to copy_from().
    	(RingBufferSpec::copy_fields_to): Renamed to copy_to().
    	(RingBufferSpec::RingBufferSpec): Deleted "castitem" constructor.
    	(RingBuffer::SlotFill): Use std::vector<guint8> instead of a guint8*
    	for the data parameter.
    	(RingBuffer::commit):
    	(RingBuffer::read):  Use a Glib::ArrayHandle<guchar> for the data
    	parameter in these three methods instead of a guchar*.
    	(RingBuffer::prepare_read): Use a std::vector<guint8> for the readptr
    	parameter instead of a guint8*&.
    	(slot): Renamed member to m_slot and used a std::auto_ptr<> for
    	automatic memory management.  This made it unnecessary to use the bool
    	member _slot_set and to have custom constructors and destructors.
    	(_slot_set): Deleted.
    	* gstreamer/src/gst_vfuncs.defs: Alphabetized and added
    	GstRingBuffer's virtual method definitions.
    
    	* gstreamer/src/audiofilter.ccg:
    	* gstreamer/src/audiofilter.hg: Correct class docs.
    	(setup_vfunc):
    	* gstreamer/src/audiosink.ccg:
    	* gstreamer/src/audiosink.hg:
    	(prepare_vfunc):
    	* gstreamer/src/audiosrc.ccg:
    	* gstreamer/src/audiosrc.hg:
    	(prepare_vfunc): Use a non-const RingBufferSpec in the virtual
    	methods as it could be modified.  Also correct the implementation of
    	the methods (and their callbacks) to copy back and forth between the C
    	struct and the C++ struct.

 ChangeLog                     |   41 ++
 gstreamer/src/audiofilter.ccg |   15 +-
 gstreamer/src/audiofilter.hg  |    8 +-
 gstreamer/src/audiosink.ccg   |   15 +-
 gstreamer/src/audiosink.hg    |    2 +-
 gstreamer/src/audiosrc.ccg    |   15 +-
 gstreamer/src/audiosrc.hg     |    2 +-
 gstreamer/src/gst_vfuncs.defs |  995 ++++++++++++++++++++++-------------------
 gstreamer/src/ringbuffer.ccg  |  201 +++++++--
 gstreamer/src/ringbuffer.hg   |  170 +++++--
 10 files changed, 892 insertions(+), 572 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 03f0387..aa44ac7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,46 @@
 2009-12-09  José Alburquerque  <jaalburqu svn gnome org>
 
+	RingBuffer: Wrap virtual functions.
+
+	* gstreamer/src/ringbuffer.ccg:
+	* gstreamer/src/ringbuffer.hg: Wrapped virtual functions.
+	(RingBufferSpec): Declare it as a struct and make the members public.
+	Document the use of the members and justify why it was declared as a
+	struct and not a class.
+	(RingBufferSpec::silence_sample): Use a std::vector<> for the member
+	type instead of int[32].
+	(RingBufferSpec::copy_fields_from): Renamed to copy_from().
+	(RingBufferSpec::copy_fields_to): Renamed to copy_to().
+	(RingBufferSpec::RingBufferSpec): Deleted "castitem" constructor.
+	(RingBuffer::SlotFill): Use std::vector<guint8> instead of a guint8*
+	for the data parameter.
+	(RingBuffer::commit):
+	(RingBuffer::read):  Use a Glib::ArrayHandle<guchar> for the data
+	parameter in these three methods instead of a guchar*.
+	(RingBuffer::prepare_read): Use a std::vector<guint8> for the readptr
+	parameter instead of a guint8*&.
+	(slot): Renamed member to m_slot and used a std::auto_ptr<> for
+	automatic memory management.  This made it unnecessary to use the bool
+	member _slot_set and to have custom constructors and destructors.
+	(_slot_set): Deleted.
+	* gstreamer/src/gst_vfuncs.defs: Alphabetized and added
+	GstRingBuffer's virtual method definitions.
+
+	* gstreamer/src/audiofilter.ccg:
+	* gstreamer/src/audiofilter.hg: Correct class docs.
+	(setup_vfunc):
+	* gstreamer/src/audiosink.ccg:
+	* gstreamer/src/audiosink.hg:
+	(prepare_vfunc):
+	* gstreamer/src/audiosrc.ccg:
+	* gstreamer/src/audiosrc.hg:
+	(prepare_vfunc): Use a non-const RingBufferSpec in the virtual
+	methods as it could be modified.  Also correct the implementation of
+	the methods (and their callbacks) to copy back and forth between the C
+	struct and the C++ struct.
+
+2009-12-09  José Alburquerque  <jaalburqu svn gnome org>
+
 	Make single argument constructors explicit.
 
 	* gstreamer/src/format.hg:
diff --git a/gstreamer/src/audiofilter.ccg b/gstreamer/src/audiofilter.ccg
index 2f7c8f5..9fdb97c 100644
--- a/gstreamer/src/audiofilter.ccg
+++ b/gstreamer/src/audiofilter.ccg
@@ -44,9 +44,12 @@ gboolean AudioFilter_Class::setup_vfunc_callback(GstAudioFilter* self, GstRingBu
       try // Trap C++ exceptions which would normally be lost because this is a C callback.
       {
       #endif //GLIBMM_EXCEPTIONS_ENABLED
-        Gst::RingBufferSpec spec(format);
+        Gst::RingBufferSpec spec;
+        spec.copy_from(*format);
         // Call the virtual member method, which derived classes might override.
-        return static_cast<int>(obj->setup_vfunc(spec));
+        const gboolean result = static_cast<int>(obj->setup_vfunc(spec));
+        spec.copy_to(*format);
+        return result;
       #ifdef GLIBMM_EXCEPTIONS_ENABLED
       }
       catch(...)
@@ -69,7 +72,7 @@ gboolean AudioFilter_Class::setup_vfunc_callback(GstAudioFilter* self, GstRingBu
   typedef gboolean RType;
   return RType();
 }
-bool Gst::AudioFilter::setup_vfunc(const Gst::RingBufferSpec& format)
+bool Gst::AudioFilter::setup_vfunc(Gst::RingBufferSpec& format)
 {
   BaseClassType *const base = static_cast<BaseClassType*>(
       g_type_class_peek_parent(G_OBJECT_GET_CLASS(gobject_)) // Get the parent class of the object class (The original underlying C class).
@@ -78,8 +81,10 @@ bool Gst::AudioFilter::setup_vfunc(const Gst::RingBufferSpec& format)
   if(base && base->setup)
   {
     GstRingBufferSpec gst_spec;
-    format.copy_fields_to(gst_spec);
-    return (*base->setup)(gobj(),&gst_spec);
+    format.copy_to(gst_spec);
+    const bool result = static_cast<bool>((*base->setup)(gobj(),&gst_spec));
+    format.copy_from(gst_spec);
+    return result;
   }
 
   typedef bool RType;
diff --git a/gstreamer/src/audiofilter.hg b/gstreamer/src/audiofilter.hg
index 65a3752..d77216a 100644
--- a/gstreamer/src/audiofilter.hg
+++ b/gstreamer/src/audiofilter.hg
@@ -35,9 +35,9 @@ namespace Gst
  * their base_init function to easily configure the set of caps/formats that
  * the element is able to handle.
  *
- * Derived classes should override the Gst::AudioFilter::setup() and
- * Gst::BaseTransform::transform_ip() and/or Gst::BaseTransform::transform()
- * virtual functions in their class_init function.
+ * Derived classes should override the Gst::AudioFilter::setup_vfunc() and
+ * Gst::BaseTransform::transform_ip_vfunc() and/or
+ * Gst::BaseTransform::transform_vfunc() virtual functions.
  *
  * @ingroup GstBaseClasses
  */
@@ -49,7 +49,7 @@ public:
 #ifdef GLIBMM_VFUNCS_ENABLED
   /** Virtual function, called whenever the format changes.
    */
-  virtual bool setup_vfunc(const Gst::RingBufferSpec& format);
+  virtual bool setup_vfunc(Gst::RingBufferSpec& format);
 #endif //GLIBMM_VFUNCS_ENABLED
 
 protected:
diff --git a/gstreamer/src/audiosink.ccg b/gstreamer/src/audiosink.ccg
index c97aab7..6e623ee 100644
--- a/gstreamer/src/audiosink.ccg
+++ b/gstreamer/src/audiosink.ccg
@@ -43,9 +43,12 @@ gboolean AudioSink_Class::prepare_vfunc_callback(GstAudioSink* self, GstRingBuff
       try // Trap C++ exceptions which would normally be lost because this is a C callback.
       {
       #endif //GLIBMM_EXCEPTIONS_ENABLED
+        Gst::RingBufferSpec cpp_spec;
+        cpp_spec.copy_from(*spec);
         // Call the virtual member method, which derived classes might override.
-        Gst::RingBufferSpec cpp_spec(spec);
-        return static_cast<int>(obj->prepare_vfunc(cpp_spec));
+        const gboolean result = static_cast<int>(obj->prepare_vfunc(cpp_spec));
+        cpp_spec.copy_to(*spec);
+        return result;
       #ifdef GLIBMM_EXCEPTIONS_ENABLED
       }
       catch(...)
@@ -68,7 +71,7 @@ gboolean AudioSink_Class::prepare_vfunc_callback(GstAudioSink* self, GstRingBuff
   typedef gboolean RType;
   return RType();
 }
-bool Gst::AudioSink::prepare_vfunc(const Gst::RingBufferSpec& spec)
+bool Gst::AudioSink::prepare_vfunc(Gst::RingBufferSpec& spec)
 {
   BaseClassType *const base = static_cast<BaseClassType*>(
       g_type_class_peek_parent(G_OBJECT_GET_CLASS(gobject_)) // Get the parent class of the object class (The original underlying C class).
@@ -77,8 +80,10 @@ bool Gst::AudioSink::prepare_vfunc(const Gst::RingBufferSpec& spec)
   if(base && base->prepare)
   {
     GstRingBufferSpec gst_spec;
-    spec.copy_fields_to(gst_spec);
-    return (*base->prepare)(gobj(),&gst_spec);
+    spec.copy_to(gst_spec);
+    const bool result = static_cast<bool>((*base->prepare)(gobj(),&gst_spec));
+    spec.copy_from(gst_spec);
+    return result;
   }
 
   typedef bool RType;
diff --git a/gstreamer/src/audiosink.hg b/gstreamer/src/audiosink.hg
index ba732cf..e313299 100644
--- a/gstreamer/src/audiosink.hg
+++ b/gstreamer/src/audiosink.hg
@@ -63,7 +63,7 @@ public:
 #ifdef GLIBMM_VFUNCS_ENABLED
   /** vfunc to prepare the device to operate with the specified parameters.
    */
-  virtual bool prepare_vfunc(const Gst::RingBufferSpec& spec);
+  virtual bool prepare_vfunc(Gst::RingBufferSpec& spec);
 #endif //GLIBMM_VFUNCS_ENABLED
 
   //TODO: Some boolean vfuncs cause strange incorrect functionality when their
diff --git a/gstreamer/src/audiosrc.ccg b/gstreamer/src/audiosrc.ccg
index d9d458f..d22c7b6 100644
--- a/gstreamer/src/audiosrc.ccg
+++ b/gstreamer/src/audiosrc.ccg
@@ -43,9 +43,12 @@ gboolean AudioSrc_Class::prepare_vfunc_callback(GstAudioSrc* self, GstRingBuffer
       try // Trap C++ exceptions which would normally be lost because this is a C callback.
       {
       #endif //GLIBMM_EXCEPTIONS_ENABLED
+        Gst::RingBufferSpec cpp_spec;
+        cpp_spec.copy_from(*spec);
         // Call the virtual member method, which derived classes might override.
-        Gst::RingBufferSpec cpp_spec(spec);
-        return static_cast<int>(obj->prepare_vfunc(cpp_spec));
+        const gboolean result = static_cast<int>(obj->prepare_vfunc(cpp_spec));
+        cpp_spec.copy_to(*spec);
+        return result;
       #ifdef GLIBMM_EXCEPTIONS_ENABLED
       }
       catch(...)
@@ -68,7 +71,7 @@ gboolean AudioSrc_Class::prepare_vfunc_callback(GstAudioSrc* self, GstRingBuffer
   typedef gboolean RType;
   return RType();
 }
-bool Gst::AudioSrc::prepare_vfunc(const Gst::RingBufferSpec& spec)
+bool Gst::AudioSrc::prepare_vfunc(Gst::RingBufferSpec& spec)
 {
   BaseClassType *const base = static_cast<BaseClassType*>(
       g_type_class_peek_parent(G_OBJECT_GET_CLASS(gobject_)) // Get the parent class of the object class (The original underlying C class).
@@ -77,8 +80,10 @@ bool Gst::AudioSrc::prepare_vfunc(const Gst::RingBufferSpec& spec)
   if(base && base->prepare)
   {
     GstRingBufferSpec gst_spec;
-    spec.copy_fields_to(gst_spec);
-    return (*base->prepare)(gobj(),&gst_spec);
+    spec.copy_to(gst_spec);
+    const bool result = static_cast<bool>((*base->prepare)(gobj(),&gst_spec));
+    spec.copy_from(gst_spec);
+    return result;
   }
 
   typedef bool RType;
diff --git a/gstreamer/src/audiosrc.hg b/gstreamer/src/audiosrc.hg
index a962cd4..0ec1b16 100644
--- a/gstreamer/src/audiosrc.hg
+++ b/gstreamer/src/audiosrc.hg
@@ -62,7 +62,7 @@ public:
 #ifdef GLIBMM_VFUNCS_ENABLED
   /** vfunc to configure device with spec.
    */
-  virtual bool prepare_vfunc(const Gst::RingBufferSpec& spec);
+  virtual bool prepare_vfunc(Gst::RingBufferSpec& spec);
 #endif //GLIBMM_VFUNCS_ENABLED
 
   //TODO: Some boolean vfuncs cause strange incorrect functionality when their
diff --git a/gstreamer/src/gst_vfuncs.defs b/gstreamer/src/gst_vfuncs.defs
index b21a7a0..23333f3 100644
--- a/gstreamer/src/gst_vfuncs.defs
+++ b/gstreamer/src/gst_vfuncs.defs
@@ -3,381 +3,217 @@
 ; define-vfunc is g*mm-specific
 ; These are hand-written.
 
-; GstBin
-
-(define-vfunc add_element
-  (of-object "GstBin")
-  (return-type "gboolean")
-  (parameters
-   '("GstElement*" "element")
-  )
-)
+; GstAudioFilter
 
-(define-vfunc remove_element
-  (of-object "GstBin")
+(define-vfunc setup
+  (of-object "GstAudioFilter")
   (return-type "gboolean")
   (parameters
-   '("GstElement*" "element")
-  )
-)
-
-(define-vfunc handle_message
-  (of-object "GstBin")
-  (return-type "void")
-  (parameters
-   '("GstMessage*" "message")
-  )
-)
-
-; GstChildProxy
-
-(define-vfunc get_child_by_index
-  (of-object "GstChildProxy")
-  (return-type "GstObject*")
-  (parameters
-   '("guint" "index")
-  )
-)
-
-(define-vfunc get_children_count
-  (of-object "GstChildProxy")
-  (return-type "guint")
-)
-
-; GstClock
-
-(define-vfunc change_resolution
-  (of-object "GstClock")
-  (return-type "GstClockTime")
-  (parameters
-   '("GstClockTime" "old_resolution")
-   '("GstClockTime" "new_resolution")
+   '("GstRingBufferSpec*" "format")
   )
 )
 
-(define-vfunc get_resolution
-  (of-object "GstClock")
-  (return-type "GstClockTime")
-)
+; GstAudioSink
 
-(define-vfunc get_internal_time
-  (of-object "GstClock")
-  (return-type "GstClockTime")
+(define-vfunc open
+  (of-object "GstAudioSink")
+  (return-type "gboolean")
 )
 
-(define-vfunc wait
-  (of-object "GstClock")
-  (return-type "GstClockReturn")
+(define-vfunc prepare
+  (of-object "GstAudioSink")
+  (return-type "gboolean")
   (parameters
-   '("GstClockEntry*" "entry")
+   '("GstRingBufferSpec*" "spec")
   )
 )
 
-(define-vfunc wait_async
-  (of-object "GstClock")
-  (return-type "GstClockReturn")
-  (parameters
-   '("GstClockEntry*" "entry")
-  )
+(define-vfunc unprepare
+  (of-object "GstAudioSink")
+  (return-type "gboolean")
 )
 
-(define-vfunc unschedule
-  (of-object "GstClock")
-  (return-type "void")
-  (parameters
-   '("GstClockEntry*" "entry")
-  )
+(define-vfunc close
+  (of-object "GstAudioSink")
+  (return-type "gboolean")
 )
 
-(define-vfunc wait_jitter
-  (of-object "GstClock")
-  (return-type "GstClockReturn")
+(define-vfunc write
+  (of-object "GstAudioSink")
+  (return-type "guint")
   (parameters
-   '("GstClockEntry*" "entry")
-   '("GstClockTimeDiff*" "jitter")
+   '("gpointer" "data")
+   '("guint" "length")
   )
 )
 
-; GstElement
-
-(define-vfunc request_new_pad
-  (of-object "GstElement")
-  (return-type "GstPad*")
-  (parameters
-   '("GstPadTemplate*" "templ")
-   '("const-gchar*" "name")
-  )
+(define-vfunc delay
+  (of-object "GstAudioSink")
+  (return-type "guint")
 )
 
-(define-vfunc release_pad
-  (of-object "GstElement")
+(define-vfunc reset
+  (of-object "GstAudioSink")
   (return-type "void")
-  (parameters
-   '("GstPad*" "pad")
-  )
 )
 
-(define-vfunc get_state
-  (of-object "GstElement")
-  (return-type "GstStateChangeReturn")
-  (parameters
-   '("GstState*" "state")
-   '("GstState*" "pending")
-   '("GstClockTime" "timeout")
-  )
-)
-
-(define-vfunc set_state
-  (of-object "GstElement")
-  (return-type "GstStateChangeReturn")
-  (parameters
-   '("GstState" "state")
-  )
-)
-
-(define-vfunc change_state
-  (of-object "GstElement")
-  (return-type "GstStateChangeReturn")
-  (parameters
-   '("GstStateChange" "transition")
-  )
-)
-
-(define-vfunc set_bus
-  (of-object "GstElement")
-  (return-type "void")
-  (parameters
-   '("GstBus*" "bus")
-  )
-)
+; GstAudioSrc
 
-(define-vfunc provide_clock
-  (of-object "GstElement")
-  (return-type "GstClock*")
+(define-vfunc open
+  (of-object "GstAudioSrc")
+  (return-type "gboolean")
 )
 
-(define-vfunc set_clock
-  (of-object "GstElement")
+(define-vfunc prepare
+  (of-object "GstAudioSrc")
   (return-type "gboolean")
   (parameters
-   '("GstClock*" "clock")
+   '("GstRingBufferSpec*" "spec")
   )
 )
 
-(define-vfunc get_index
-  (of-object "GstElement")
-  (return-type "GstIndex*")
+(define-vfunc unprepare
+  (of-object "GstAudioSrc")
+  (return-type "gboolean")
 )
 
-(define-vfunc set_index
-  (of-object "GstElement")
-  (return-type "void")
-  (parameters
-   '("GstIndex*" "index")
-  )
+(define-vfunc close
+  (of-object "GstAudioSrc")
+  (return-type "gboolean")
 )
 
-(define-vfunc send_event
-  (of-object "GstElement")
-  (return-type "gboolean")
+(define-vfunc read
+  (of-object "GstAudioSrc")
+  (return-type "guint")
   (parameters
-   '("GstEvent*" "event")
+   '("gpointer" "data")
+   '("guint" "length")
   )
 )
 
-(define-vfunc get_query_types
-  (of-object "GstElement")
-  (return-type "const-GstQueryType*")
+(define-vfunc delay
+  (of-object "GstAudioSrc")
+  (return-type "guint")
 )
 
-(define-vfunc query
-  (of-object "GstElement")
-  (return-type "gboolean")
-  (parameters
-   '("GstQuery*" "query")
-  )
+(define-vfunc reset
+  (of-object "GstAudioSrc")
+  (return-type "void")
 )
 
-; GstImplementsInterface
+; GstBaseAudioSink
 
-(define-vfunc supported
-  (of-object "GstImplementsInterface")
-  (return-type "gboolean")
-  (parameters
-   '("GType" "iface_type")
-  )
+(define-vfunc create_ringbuffer
+  (of-object "GstBaseAudioSink")
+  (return-type "GstRingBuffer*")
 )
 
-; GstIndex
+; GstBaseAudioSrc
 
-(define-vfunc get_writer_id
-  (of-object "GstIndex")
-  (return-type "gboolean")
-  (parameters
-   '("gint*" "writer_id")
-   '("gchar*" "writer_string")
-  )
+(define-vfunc create_ringbuffer
+  (of-object "GstBaseAudioSrc")
+  (return-type "GstRingBuffer*")
 )
 
-(define-vfunc commit
-  (of-object "GstIndex")
-  (return-type "void")
-  (parameters
-   '("gint" "id")
-  )
-)
+; GstBaseSink
 
-(define-vfunc add_entry
-  (of-object "GstIndex")
-  (return-type "void")
-  (parameters
-   '("GstIndexEntry*" "entry")
-  )
+(define-vfunc get_caps
+  (of-object "GstBaseSink")
+  (return-type "GstCaps*")
 )
 
-(define-vfunc get_assoc_entry
-  (of-object "GstIndex")
-  (return-type "GstIndexEntry*")
+(define-vfunc set_caps
+  (of-object "GstBaseSink")
+  (return-type "gboolean")
   (parameters
-   '("guint" "id")
-   '("GstIndexLookupMethod" "method")
-   '("GstAssocFlags" "flags")
-   '("GstFormat" "format")
-   '("gint64" "value")
-   '("GCompareDataFunc" "func")
-   '("gpointer" "user_data")
+   '("GstCaps*" "caps")
   )
 )
 
-; GstObject
-
-(define-vfunc save_thyself
-  (of-object "GstObject")
-  (return-type "GstXmlNodePtr")
+(define-vfunc buffer_alloc
+  (of-object "GstBaseSink")
+  (return-type "GstFlowReturn")
   (parameters
-   '("GstXmlNodePtr" "parent")
+   '("guint64" "offset")
+   '("guint" "size")
+   '("GstCaps*" "caps")
+   '("GstBuffer**" "buf")
   )
 )
 
-(define-vfunc restore_thyself
-  (of-object "GstObject")
+(define-vfunc get_times
+  (of-object "GstBaseSink")
   (return-type "void")
   (parameters
-   '("GstXmlNodePtr" "self_node")
-  )
-)
-
-; GstPreset
-
-(define-vfunc get_preset_names
-  (of-object "GstPreset")
-  (return-type "gchar**")
-)
-
-(define-vfunc get_property_names
-  (of-object "GstPreset")
-  (return-type "gchar**")
-)
-
-(define-vfunc load_preset
-  (of-object "GstPreset")
-  (return-type "gboolean")
-  (parameters
-   '("const-gchar*" "name")
+   '("GstBuffer*" "buffer")
+   '("GstClockTime*" "start")
+   '("GstClockTime*" "end")
   )
 )
 
-(define-vfunc save_preset
-  (of-object "GstPreset")
+(define-vfunc start
+  (of-object "GstBaseSink")
   (return-type "gboolean")
-  (parameters
-   '("const-gchar*" "name")
-  )
 )
 
-(define-vfunc rename_preset
-  (of-object "GstPreset")
+(define-vfunc stop
+  (of-object "GstBaseSink")
   (return-type "gboolean")
-  (parameters
-   '("const-gchar*" "old_name")
-   '("const-gchar*" "new_name")
-  )
 )
 
-(define-vfunc delete_preset
-  (of-object "GstPreset")
+(define-vfunc unlock
+  (of-object "GstBaseSink")
   (return-type "gboolean")
-  (parameters
-   '("const-gchar*" "name")
-  )
 )
 
-(define-vfunc set_meta
-  (of-object "GstPreset")
+(define-vfunc event
+  (of-object "GstBaseSink")
   (return-type "gboolean")
   (parameters
-   '("const-gchar*" "name")
-   '("const-gchar*" "tag")
-   '("const-gchar*" "value")
+   '("GstEvent*" "event")
   )
 )
 
-(define-vfunc get_meta
-  (of-object "GstPreset")
-  (return-type "gboolean")
+(define-vfunc preroll
+  (of-object "GstBaseSink")
+  (return-type "GstFlowReturn")
   (parameters
-   '("const-gchar*" "name")
-   '("const-gchar*" "tag")
-   '("gchar**" "value")
+   '("GstBuffer*" "buffer")
   )
 )
 
-; GstTaskPool
-
-(define-vfunc prepare
-  (of-object "GstTaskPool")
-  (return-type "void")
+(define-vfunc render
+  (of-object "GstBaseSink")
+  (return-type "GstFlowReturn")
   (parameters
-   '("GError**" "error")
+   '("GstBuffer*" "buffer")
   )
 )
 
-(define-vfunc cleanup
-  (of-object "GstTaskPool")
-  (return-type "void")
+(define-vfunc async_play
+  (of-object "GstBaseSink")
+  (return-type "GstStateChangeReturn")
 )
 
-(define-vfunc push
-  (of-object "GstTaskPool")
-  (return-type "gpointer")
+(define-vfunc activate_pull
+  (of-object "GstBaseSink")
+  (return-type "gboolean")
   (parameters
-   '("GstTaskPoolFunction" "func")
-   '("gpointer" "user_data")
-   '("GError**" "error")
+   '("gboolean" "active")
   )
 )
 
-(define-vfunc join
-  (of-object "GstTaskPool")
+(define-vfunc fixate
+  (of-object "GstBaseSink")
   (return-type "void")
   (parameters
-   '("gpointer" "id")
+   '("GstCaps*" "caps")
   )
 )
 
-; GstURIHandler
-
-(define-vfunc get_uri
-  (of-object "GstURIHandler")
-  (return-type "const-gchar*")
-)
-
-(define-vfunc set_uri
-  (of-object "GstURIHandler")
+(define-vfunc unlock_stop
+  (of-object "GstBaseSink")
   (return-type "gboolean")
-  (parameters
-   '("const-gchar*" "uri")
-  )
 )
 
 ; GstBaseSrc
@@ -504,107 +340,6 @@
   )
 )
 
-; GstBaseSink
-
-(define-vfunc get_caps
-  (of-object "GstBaseSink")
-  (return-type "GstCaps*")
-)
-
-(define-vfunc set_caps
-  (of-object "GstBaseSink")
-  (return-type "gboolean")
-  (parameters
-   '("GstCaps*" "caps")
-  )
-)
-
-(define-vfunc buffer_alloc
-  (of-object "GstBaseSink")
-  (return-type "GstFlowReturn")
-  (parameters
-   '("guint64" "offset")
-   '("guint" "size")
-   '("GstCaps*" "caps")
-   '("GstBuffer**" "buf")
-  )
-)
-
-(define-vfunc get_times
-  (of-object "GstBaseSink")
-  (return-type "void")
-  (parameters
-   '("GstBuffer*" "buffer")
-   '("GstClockTime*" "start")
-   '("GstClockTime*" "end")
-  )
-)
-
-(define-vfunc start
-  (of-object "GstBaseSink")
-  (return-type "gboolean")
-)
-
-(define-vfunc stop
-  (of-object "GstBaseSink")
-  (return-type "gboolean")
-)
-
-(define-vfunc unlock
-  (of-object "GstBaseSink")
-  (return-type "gboolean")
-)
-
-(define-vfunc event
-  (of-object "GstBaseSink")
-  (return-type "gboolean")
-  (parameters
-   '("GstEvent*" "event")
-  )
-)
-
-(define-vfunc preroll
-  (of-object "GstBaseSink")
-  (return-type "GstFlowReturn")
-  (parameters
-   '("GstBuffer*" "buffer")
-  )
-)
-
-(define-vfunc render
-  (of-object "GstBaseSink")
-  (return-type "GstFlowReturn")
-  (parameters
-   '("GstBuffer*" "buffer")
-  )
-)
-
-(define-vfunc async_play
-  (of-object "GstBaseSink")
-  (return-type "GstStateChangeReturn")
-)
-
-(define-vfunc activate_pull
-  (of-object "GstBaseSink")
-  (return-type "gboolean")
-  (parameters
-   '("gboolean" "active")
-  )
-)
-
-(define-vfunc fixate
-  (of-object "GstBaseSink")
-  (return-type "void")
-  (parameters
-   '("GstCaps*" "caps")
-  )
-)
-
-(define-vfunc unlock_stop
-  (of-object "GstBaseSink")
-  (return-type "gboolean")
-)
-
 ; GstBaseTransform
 
 (define-vfunc transform_caps
@@ -717,172 +452,306 @@
   )
 )
 
-; GstAudioFilter
+; GstBin
 
-(define-vfunc setup
-  (of-object "GstAudioFilter")
+(define-vfunc add_element
+  (of-object "GstBin")
   (return-type "gboolean")
   (parameters
-   '("GstRingBufferSpec*" "format")
+   '("GstElement*" "element")
   )
 )
 
-; GstAudioSink
-
-(define-vfunc open
-  (of-object "GstAudioSink")
+(define-vfunc remove_element
+  (of-object "GstBin")
   (return-type "gboolean")
+  (parameters
+   '("GstElement*" "element")
+  )
 )
 
-(define-vfunc prepare
-  (of-object "GstAudioSink")
-  (return-type "gboolean")
+(define-vfunc handle_message
+  (of-object "GstBin")
+  (return-type "void")
   (parameters
-   '("GstRingBufferSpec*" "spec")
+   '("GstMessage*" "message")
   )
 )
 
-(define-vfunc unprepare
-  (of-object "GstAudioSink")
+; GstCddaBaseSrc
+
+(define-vfunc open
+  (of-object "GstCddaBaseSrc")
   (return-type "gboolean")
+  (parameters
+   '("const-gchar*" "device")
+  )
 )
 
 (define-vfunc close
-  (of-object "GstAudioSink")
-  (return-type "gboolean")
+  (of-object "GstCddaBaseSrc")
+  (return-type "void")
 )
 
-(define-vfunc write
-  (of-object "GstAudioSink")
-  (return-type "guint")
+(define-vfunc read_sector
+  (of-object "GstCddaBaseSrc")
+  (return-type "GstBuffer*")
   (parameters
-   '("gpointer" "data")
-   '("guint" "length")
+   '("gint" "sector")
   )
 )
 
-(define-vfunc delay
-  (of-object "GstAudioSink")
+(define-vfunc get_default_device
+  (of-object "GstCddaBaseSrc")
+  (return-type "gchar*")
+)
+
+(define-vfunc probe_devices
+  (of-object "GstCddaBaseSrc")
+  (return-type "gchar**")
+)
+
+; GstChildProxy
+
+(define-vfunc get_child_by_index
+  (of-object "GstChildProxy")
+  (return-type "GstObject*")
+  (parameters
+   '("guint" "index")
+  )
+)
+
+(define-vfunc get_children_count
+  (of-object "GstChildProxy")
   (return-type "guint")
 )
 
-(define-vfunc reset
-  (of-object "GstAudioSink")
-  (return-type "void")
+; GstClock
+
+(define-vfunc change_resolution
+  (of-object "GstClock")
+  (return-type "GstClockTime")
+  (parameters
+   '("GstClockTime" "old_resolution")
+   '("GstClockTime" "new_resolution")
+  )
 )
 
-; GstAudioSrc
+(define-vfunc get_resolution
+  (of-object "GstClock")
+  (return-type "GstClockTime")
+)
 
-(define-vfunc open
-  (of-object "GstAudioSrc")
-  (return-type "gboolean")
+(define-vfunc get_internal_time
+  (of-object "GstClock")
+  (return-type "GstClockTime")
 )
 
-(define-vfunc prepare
-  (of-object "GstAudioSrc")
-  (return-type "gboolean")
+(define-vfunc wait
+  (of-object "GstClock")
+  (return-type "GstClockReturn")
   (parameters
-   '("GstRingBufferSpec*" "spec")
+   '("GstClockEntry*" "entry")
   )
 )
 
-(define-vfunc unprepare
-  (of-object "GstAudioSrc")
-  (return-type "gboolean")
+(define-vfunc wait_async
+  (of-object "GstClock")
+  (return-type "GstClockReturn")
+  (parameters
+   '("GstClockEntry*" "entry")
+  )
 )
 
-(define-vfunc close
-  (of-object "GstAudioSrc")
-  (return-type "gboolean")
+(define-vfunc unschedule
+  (of-object "GstClock")
+  (return-type "void")
+  (parameters
+   '("GstClockEntry*" "entry")
+  )
 )
 
-(define-vfunc read
-  (of-object "GstAudioSrc")
-  (return-type "guint")
+(define-vfunc wait_jitter
+  (of-object "GstClock")
+  (return-type "GstClockReturn")
   (parameters
-   '("gpointer" "data")
-   '("guint" "length")
+   '("GstClockEntry*" "entry")
+   '("GstClockTimeDiff*" "jitter")
   )
 )
 
-(define-vfunc delay
-  (of-object "GstAudioSrc")
-  (return-type "guint")
+; GstColorBalance
+
+(define-vfunc list_channels
+  (of-object "GstColorBalance")
+  (return-type "const-GList*")
 )
 
-(define-vfunc reset
-  (of-object "GstAudioSrc")
+(define-vfunc set_value
+  (of-object "GstColorBalance")
   (return-type "void")
+  (parameters
+   '("GstColorBalanceChannel*" "balance")
+   '("gint" "value")
+  )
 )
 
-; GstBaseAudioSink
+(define-vfunc get_value
+  (of-object "GstColorBalance")
+  (return-type "gint")
+  (parameters
+   '("GstColorBalanceChannel*" "balance")
+  )
+)
 
-(define-vfunc create_ringbuffer
-  (of-object "GstBaseAudioSink")
-  (return-type "GstRingBuffer*")
+; GstElement
+
+(define-vfunc request_new_pad
+  (of-object "GstElement")
+  (return-type "GstPad*")
+  (parameters
+   '("GstPadTemplate*" "templ")
+   '("const-gchar*" "name")
+  )
 )
 
-; GstBaseAudioSrc
+(define-vfunc release_pad
+  (of-object "GstElement")
+  (return-type "void")
+  (parameters
+   '("GstPad*" "pad")
+  )
+)
 
-(define-vfunc create_ringbuffer
-  (of-object "GstBaseAudioSrc")
-  (return-type "GstRingBuffer*")
+(define-vfunc get_state
+  (of-object "GstElement")
+  (return-type "GstStateChangeReturn")
+  (parameters
+   '("GstState*" "state")
+   '("GstState*" "pending")
+   '("GstClockTime" "timeout")
+  )
 )
 
-; GstCddaBaseSrc
+(define-vfunc set_state
+  (of-object "GstElement")
+  (return-type "GstStateChangeReturn")
+  (parameters
+   '("GstState" "state")
+  )
+)
 
-(define-vfunc open
-  (of-object "GstCddaBaseSrc")
+(define-vfunc change_state
+  (of-object "GstElement")
+  (return-type "GstStateChangeReturn")
+  (parameters
+   '("GstStateChange" "transition")
+  )
+)
+
+(define-vfunc set_bus
+  (of-object "GstElement")
+  (return-type "void")
+  (parameters
+   '("GstBus*" "bus")
+  )
+)
+
+(define-vfunc provide_clock
+  (of-object "GstElement")
+  (return-type "GstClock*")
+)
+
+(define-vfunc set_clock
+  (of-object "GstElement")
   (return-type "gboolean")
   (parameters
-   '("const-gchar*" "device")
+   '("GstClock*" "clock")
   )
 )
 
-(define-vfunc close
-  (of-object "GstCddaBaseSrc")
+(define-vfunc get_index
+  (of-object "GstElement")
+  (return-type "GstIndex*")
+)
+
+(define-vfunc set_index
+  (of-object "GstElement")
   (return-type "void")
+  (parameters
+   '("GstIndex*" "index")
+  )
 )
 
-(define-vfunc read_sector
-  (of-object "GstCddaBaseSrc")
-  (return-type "GstBuffer*")
+(define-vfunc send_event
+  (of-object "GstElement")
+  (return-type "gboolean")
   (parameters
-   '("gint" "sector")
+   '("GstEvent*" "event")
   )
 )
 
-(define-vfunc get_default_device
-  (of-object "GstCddaBaseSrc")
-  (return-type "gchar*")
+(define-vfunc get_query_types
+  (of-object "GstElement")
+  (return-type "const-GstQueryType*")
 )
 
-(define-vfunc probe_devices
-  (of-object "GstCddaBaseSrc")
-  (return-type "gchar**")
+(define-vfunc query
+  (of-object "GstElement")
+  (return-type "gboolean")
+  (parameters
+   '("GstQuery*" "query")
+  )
 )
 
-; GstColorBalance
+; GstImplementsInterface
 
-(define-vfunc list_channels
-  (of-object "GstColorBalance")
-  (return-type "const-GList*")
+(define-vfunc supported
+  (of-object "GstImplementsInterface")
+  (return-type "gboolean")
+  (parameters
+   '("GType" "iface_type")
+  )
 )
 
-(define-vfunc set_value
-  (of-object "GstColorBalance")
+; GstIndex
+
+(define-vfunc get_writer_id
+  (of-object "GstIndex")
+  (return-type "gboolean")
+  (parameters
+   '("gint*" "writer_id")
+   '("gchar*" "writer_string")
+  )
+)
+
+(define-vfunc commit
+  (of-object "GstIndex")
   (return-type "void")
   (parameters
-   '("GstColorBalanceChannel*" "balance")
-   '("gint" "value")
+   '("gint" "id")
   )
 )
 
-(define-vfunc get_value
-  (of-object "GstColorBalance")
-  (return-type "gint")
+(define-vfunc add_entry
+  (of-object "GstIndex")
+  (return-type "void")
   (parameters
-   '("GstColorBalanceChannel*" "balance")
+   '("GstIndexEntry*" "entry")
+  )
+)
+
+(define-vfunc get_assoc_entry
+  (of-object "GstIndex")
+  (return-type "GstIndexEntry*")
+  (parameters
+   '("guint" "id")
+   '("GstIndexLookupMethod" "method")
+   '("GstAssocFlags" "flags")
+   '("GstFormat" "format")
+   '("gint64" "value")
+   '("GCompareDataFunc" "func")
+   '("gpointer" "user_data")
   )
 )
 
@@ -961,6 +830,89 @@
   )
 )
 
+; GstObject
+
+(define-vfunc save_thyself
+  (of-object "GstObject")
+  (return-type "GstXmlNodePtr")
+  (parameters
+   '("GstXmlNodePtr" "parent")
+  )
+)
+
+(define-vfunc restore_thyself
+  (of-object "GstObject")
+  (return-type "void")
+  (parameters
+   '("GstXmlNodePtr" "self_node")
+  )
+)
+
+; GstPreset
+
+(define-vfunc get_preset_names
+  (of-object "GstPreset")
+  (return-type "gchar**")
+)
+
+(define-vfunc get_property_names
+  (of-object "GstPreset")
+  (return-type "gchar**")
+)
+
+(define-vfunc load_preset
+  (of-object "GstPreset")
+  (return-type "gboolean")
+  (parameters
+   '("const-gchar*" "name")
+  )
+)
+
+(define-vfunc save_preset
+  (of-object "GstPreset")
+  (return-type "gboolean")
+  (parameters
+   '("const-gchar*" "name")
+  )
+)
+
+(define-vfunc rename_preset
+  (of-object "GstPreset")
+  (return-type "gboolean")
+  (parameters
+   '("const-gchar*" "old_name")
+   '("const-gchar*" "new_name")
+  )
+)
+
+(define-vfunc delete_preset
+  (of-object "GstPreset")
+  (return-type "gboolean")
+  (parameters
+   '("const-gchar*" "name")
+  )
+)
+
+(define-vfunc set_meta
+  (of-object "GstPreset")
+  (return-type "gboolean")
+  (parameters
+   '("const-gchar*" "name")
+   '("const-gchar*" "tag")
+   '("const-gchar*" "value")
+  )
+)
+
+(define-vfunc get_meta
+  (of-object "GstPreset")
+  (return-type "gboolean")
+  (parameters
+   '("const-gchar*" "name")
+   '("const-gchar*" "tag")
+   '("gchar**" "value")
+  )
+)
+
 ; GstPropertyProbe
 
 (define-vfunc get_properties
@@ -995,6 +947,114 @@
   )
 )
 
+; GstRingBuffer
+
+(define-vfunc open_device
+  (of-object "GstRingBuffer")
+  (return-type "gboolean")
+)
+
+(define-vfunc acquire
+  (of-object "GstRingBuffer")
+  (return-type "gboolean")
+  (parameters
+   '("GstRingBufferSpec*" "spec")
+  )
+)
+
+(define-vfunc release
+  (of-object "GstRingBuffer")
+  (return-type "gboolean")
+)
+
+(define-vfunc close_device
+  (of-object "GstRingBuffer")
+  (return-type "gboolean")
+)
+
+(define-vfunc start
+  (of-object "GstRingBuffer")
+  (return-type "gboolean")
+)
+
+(define-vfunc pause
+  (of-object "GstRingBuffer")
+  (return-type "gboolean")
+)
+
+(define-vfunc resume
+  (of-object "GstRingBuffer")
+  (return-type "gboolean")
+)
+
+(define-vfunc stop
+  (of-object "GstRingBuffer")
+  (return-type "gboolean")
+)
+
+(define-vfunc delay
+  (of-object "GstRingBuffer")
+  (return-type "guint")
+)
+
+(define-vfunc activate
+  (of-object "GstRingBuffer")
+  (return-type "gboolean")
+  (parameters
+   '("gboolean" "active")
+  )
+)
+
+(define-vfunc commit
+  (of-object "GstRingBuffer")
+  (return-type "guint")
+  (parameters
+   '("guint64*" "sample")
+   '("guchar*" "data")
+   '("gint" "in_samples")
+   '("gint" "out_samples")
+   '("gint*" "accum")
+  )
+)
+
+(define-vfunc clear_all
+  (of-object "GstRingBuffer")
+  (return-type "void")
+)
+
+; GstTaskPool
+
+(define-vfunc prepare
+  (of-object "GstTaskPool")
+  (return-type "void")
+  (parameters
+   '("GError**" "error")
+  )
+)
+
+(define-vfunc cleanup
+  (of-object "GstTaskPool")
+  (return-type "void")
+)
+
+(define-vfunc push
+  (of-object "GstTaskPool")
+  (return-type "gpointer")
+  (parameters
+   '("GstTaskPoolFunction" "func")
+   '("gpointer" "user_data")
+   '("GError**" "error")
+  )
+)
+
+(define-vfunc join
+  (of-object "GstTaskPool")
+  (return-type "void")
+  (parameters
+   '("gpointer" "id")
+  )
+)
+
 ; GstTuner
 
 (define-vfunc list_channels
@@ -1058,6 +1118,21 @@
   )
 )
 
+; GstURIHandler
+
+(define-vfunc get_uri
+  (of-object "GstURIHandler")
+  (return-type "const-gchar*")
+)
+
+(define-vfunc set_uri
+  (of-object "GstURIHandler")
+  (return-type "gboolean")
+  (parameters
+   '("const-gchar*" "uri")
+  )
+)
+
 ; GstVideoOrientation
 
 (define-vfunc get_hflip
diff --git a/gstreamer/src/ringbuffer.ccg b/gstreamer/src/ringbuffer.ccg
index 5b1345f..d4c35a0 100644
--- a/gstreamer/src/ringbuffer.ccg
+++ b/gstreamer/src/ringbuffer.ccg
@@ -36,7 +36,8 @@ static void RingBuffer_Fill_gstreamermm_callback(GstRingBuffer*, guint8* data, g
   try
 #endif
   {
-    slot_fill(data, len);
+    Glib::ArrayHandle<guint8> cpp_data(data, len, Glib::OWNERSHIP_NONE);
+    slot_fill(cpp_data, len);
   }
 #ifdef GLIBMM_EXCEPTIONS_ENABLED
   catch (...)
@@ -53,18 +54,7 @@ static void RingBuffer_Fill_gstreamermm_callback(GstRingBuffer*, guint8* data, g
 namespace Gst
 {
 
-RingBufferSpec::RingBufferSpec(const GstRingBufferSpec* castitem)
-{
-  if(castitem)
-    copy_fields_from(*castitem);
-  else
-  {
-    GstRingBufferSpec empty;
-    copy_fields_from(empty);
-  }
-}
-
-void RingBufferSpec::copy_fields_from(const GstRingBufferSpec& spec)
+void RingBufferSpec::copy_from(const GstRingBufferSpec& spec)
 {
   caps = Glib::wrap(spec.caps);
 
@@ -83,10 +73,10 @@ void RingBufferSpec::copy_fields_from(const GstRingBufferSpec& spec)
   bytes_per_sample = spec.bytes_per_sample;
   seglatency = spec.seglatency;
 
-  std::memcpy(silence_sample, spec.silence_sample, sizeof(silence_sample));
+  silence_sample.assign(spec.silence_sample, spec.silence_sample + 32);
 }
 
-void RingBufferSpec::copy_fields_to(GstRingBufferSpec& spec) const
+void RingBufferSpec::copy_to(GstRingBufferSpec& spec) const
 {
   spec.caps = Glib::unwrap(caps);
   spec.type = static_cast<GstBufferFormatType>(type);
@@ -104,58 +94,181 @@ void RingBufferSpec::copy_fields_to(GstRingBufferSpec& spec) const
   spec.bytes_per_sample = bytes_per_sample;
   spec.seglatency = seglatency;
 
-  std::memcpy(spec.silence_sample, silence_sample, sizeof(spec.silence_sample));
+  std::copy(silence_sample.begin(), silence_sample.end(), spec.silence_sample);
 }
 
-RingBuffer::RingBuffer(const Glib::ConstructParams& construct_params)
-:
-  Gst::Object(construct_params),
-  _slot_set(false)
-{}
+void RingBuffer::set_fill_slot(const SlotFill& slot)
+{
+  // The slot is dynamically allocated because according to the
+  // gst_ring_buffer_set_callback() docs, the slot may be called several times.
+  // A copy is hence created to avoid losing the slot.  The copy is kept in an
+  // auto_ptr<> so that is released upon the ring buffer's destruction.
+  m_slot.reset(new SlotFill(slot));
 
-RingBuffer::RingBuffer(GstRingBuffer* castitem)
-:
-  Gst::Object(reinterpret_cast<GstObject*>(castitem)),
-  _slot_set(false)
-{}
+  gst_ring_buffer_set_callback(gobj(), &RingBuffer_Fill_gstreamermm_callback,
+    m_slot.get());
+}
 
-void RingBuffer::set_fill_slot(const SlotFill& slot)
+bool RingBuffer::prepare_read(int& segment, std::vector<guint8>& readptr,
+  int& len)
 {
-  // TODO: Not safe against self assignment, and not exception-safe.  Is the
-  // separate _slot_set flag really needed?  Is dynamic allocation actually
-  // needed at all?  This would not have to be a member at all if there were
-  // an accessor to the callback user data in the C API.
-  if(_slot_set)
-    delete this->slot;
+  guint8* c_readptr = 0;
 
-  this->slot = new SlotFill(slot);
-  _slot_set = true;
+  const bool result = static_cast<bool>(gst_ring_buffer_prepare_read(gobj(), &segment, &c_readptr, &len));
+  readptr.assign(c_readptr, c_readptr + len);
 
-  gst_ring_buffer_set_callback(gobj(), &RingBuffer_Fill_gstreamermm_callback,
-    this->slot);
+  if (c_readptr)
+    g_free(c_readptr);
+
+  return result;
 }
 
 bool RingBuffer::acquire(const Gst::RingBufferSpec& spec)
 {
   GstRingBufferSpec gst_spec;
-  spec.copy_fields_to(gst_spec);
+  spec.copy_to(gst_spec);
   return gst_ring_buffer_acquire(gobj(), &gst_spec);
 }
 
 bool RingBuffer::parse_caps(Gst::RingBufferSpec& spec, const Glib::RefPtr<Gst::Caps>& caps)
 {
   GstRingBufferSpec gst_spec;
-  spec.copy_fields_to(gst_spec);
+  spec.copy_to(gst_spec);
   gboolean const result = gst_ring_buffer_parse_caps(&gst_spec, Glib::unwrap(caps));
-  spec.copy_fields_from(gst_spec);
+  spec.copy_from(gst_spec);
   return (result != 0);
 }
 
-RingBuffer::~RingBuffer()
+#ifdef GLIBMM_VFUNCS_ENABLED
+gboolean RingBuffer_Class::acquire_vfunc_callback(GstRingBuffer* self, GstRingBufferSpec* spec)
+{
+  Glib::ObjectBase *const obj_base = static_cast<Glib::ObjectBase*>(
+      Glib::ObjectBase::_get_current_wrapper((GObject*)self));
+
+  // Non-gtkmmproc-generated custom classes implicitly call the default
+  // Glib::ObjectBase constructor, which sets is_derived_. But gtkmmproc-
+  // generated classes can use this optimisation, which avoids the unnecessary
+  // parameter conversions if there is no possibility of the virtual function
+  // being overridden:
+  if(obj_base && obj_base->is_derived_())
+  {
+    CppObjectType *const obj = dynamic_cast<CppObjectType* const>(obj_base);
+    if(obj) // This can be NULL during destruction.
+    {
+      #ifdef GLIBMM_EXCEPTIONS_ENABLED
+      try // Trap C++ exceptions which would normally be lost because this is a C callback.
+      {
+      #endif //GLIBMM_EXCEPTIONS_ENABLED
+        Gst::RingBufferSpec cpp_spec;
+        cpp_spec.copy_from(*spec);
+        // Call the virtual member method, which derived classes might override.
+        const gboolean result = static_cast<int>(obj->acquire_vfunc(cpp_spec));
+        cpp_spec.copy_to(*spec);
+        return result;
+
+      #ifdef GLIBMM_EXCEPTIONS_ENABLED
+      }
+      catch(...)
+      {
+        Glib::exception_handlers_invoke();
+      }
+      #endif //GLIBMM_EXCEPTIONS_ENABLED
+    }
+  }
+  
+  BaseClassType *const base = static_cast<BaseClassType*>(
+      g_type_class_peek_parent(G_OBJECT_GET_CLASS(self)) // Get the parent class of the object class (The original underlying C class).
+  );
+
+  // Call the original underlying C function:
+  if(base && base->acquire)
+    return (*base->acquire)(self, spec);
+
+
+  typedef gboolean RType;
+  return RType();
+}
+bool Gst::RingBuffer::acquire_vfunc(Gst::RingBufferSpec& spec) 
+{
+  BaseClassType *const base = static_cast<BaseClassType*>(
+      g_type_class_peek_parent(G_OBJECT_GET_CLASS(gobject_)) // Get the parent class of the object class (The original underlying C class).
+  );
+
+  if(base && base->acquire)
+  {
+    GstRingBufferSpec c_spec;
+    spec.copy_to(c_spec);
+    const bool result = static_cast<bool>((*base->acquire)(gobj(), &c_spec));
+    spec.copy_from(c_spec);
+    return result;
+  }
+
+  typedef bool RType;
+  return RType();
+}
+guint RingBuffer_Class::commit_vfunc_callback(GstRingBuffer* self, guint64* sample, guchar* data, gint in_samples, gint out_samples, gint* accum)
 {
-    // Delete ringbuffer's slot upon destruction
-  if(_slot_set)
-    delete slot;
+  Glib::ObjectBase *const obj_base = static_cast<Glib::ObjectBase*>(
+      Glib::ObjectBase::_get_current_wrapper((GObject*)self));
+
+  // Non-gtkmmproc-generated custom classes implicitly call the default
+  // Glib::ObjectBase constructor, which sets is_derived_. But gtkmmproc-
+  // generated classes can use this optimisation, which avoids the unnecessary
+  // parameter conversions if there is no possibility of the virtual function
+  // being overridden:
+  if(obj_base && obj_base->is_derived_())
+  {
+    CppObjectType *const obj = dynamic_cast<CppObjectType* const>(obj_base);
+    if(obj) // This can be NULL during destruction.
+    {
+      #ifdef GLIBMM_EXCEPTIONS_ENABLED
+      try // Trap C++ exceptions which would normally be lost because this is a C callback.
+      {
+      #endif //GLIBMM_EXCEPTIONS_ENABLED
+        // This formula is obtained from the definition of the data_end
+        // variable in the default_commit() function of the C API
+        // gstringbuffer.c file.
+        size_t data_length = (self->spec.bytes_per_sample * in_samples);
+
+        // Declare the ArrayHandle for the C++ vfunc.
+        Glib::ArrayHandle<guchar> cpp_data(data, data_length, Glib::OWNERSHIP_NONE);
+        // Call the virtual member method, which derived classes might override.
+        return obj->commit_vfunc(*(sample), cpp_data, in_samples, out_samples,
+          *(accum));
+      #ifdef GLIBMM_EXCEPTIONS_ENABLED
+      }
+      catch(...)
+      {
+        Glib::exception_handlers_invoke();
+      }
+      #endif //GLIBMM_EXCEPTIONS_ENABLED
+    }
+  }
+  
+  BaseClassType *const base = static_cast<BaseClassType*>(
+      g_type_class_peek_parent(G_OBJECT_GET_CLASS(self)) // Get the parent class of the object class (The original underlying C class).
+  );
+
+  // Call the original underlying C function:
+  if(base && base->commit)
+    return (*base->commit)(self, sample, data, in_samples, out_samples, accum);
+
+
+  typedef guint RType;
+  return RType();
+}
+guint Gst::RingBuffer::commit_vfunc(guint64& sample, const Glib::ArrayHandle<guchar>& data, int in_samples, int out_samples, int& accum) 
+{
+  BaseClassType *const base = static_cast<BaseClassType*>(
+      g_type_class_peek_parent(G_OBJECT_GET_CLASS(gobject_)) // Get the parent class of the object class (The original underlying C class).
+  );
+
+  if(base && base->commit)
+    return (*base->commit)(gobj(),&sample,const_cast<guchar*>(data.data()),in_samples,out_samples,&accum);
+
+  typedef guint RType;
+  return RType();
 }
+#endif //GLIBMM_VFUNCS_ENABLED
 
 } // namespace Gst
diff --git a/gstreamer/src/ringbuffer.hg b/gstreamer/src/ringbuffer.hg
index c29d7ae..1d2521f 100644
--- a/gstreamer/src/ringbuffer.hg
+++ b/gstreamer/src/ringbuffer.hg
@@ -21,6 +21,7 @@
 #include <gstreamermm/caps.h>
 #include <gstreamermm/object.h>
 #include <gstreamermm/format.h>
+#include <memory>
 
 _DEFS(gstreamermm,gst)
 
@@ -32,87 +33,95 @@ _WRAP_ENUM(RingBufferState, GstRingBufferState)
 _WRAP_ENUM(BufferFormat, GstBufferFormat)
 _WRAP_ENUM(BufferFormatType, GstBufferFormatType)
 
-// TODO: Rewrite at next API break, either as a real class with accessors
-// instead of public data members, or alternatively as a plain struct
-// accompanied by a justification.
+// The reason that this is implemented as just a struct with public members
+// and not a class is that it is only used in two methods:
+// 1) In Gst::RingBuffer::acquire() to acquire a ring buffer (some members
+// should be set while acquire() modifies others).
+// 2) In Gst::RingBuffer::parse_caps() by attempting to merge the given caps
+// in to the spec (with some existing members already set).
+// It doesn't seem necessary to implement a full blown class for this yet.
+
 /** The structure containing the format specification of a Gst::RingBuffer.
+ * The "in" members should be specified by the caller of the
+ * Gst::RingBuffer::acquire() method while the "in/out" members may be set by
+ * the caller but are also modifiable by Gst::RingBuffer::acquire().  The
+ * "out" members are generated as a result of the call to
+ * Gst::RingBuffer::acquire().
  * @see Gst::RingBuffer::acquire().
  */
-class RingBufferSpec
+struct RingBufferSpec
 {
-  _CLASS_GENERIC(RingBufferSpec, GstRingBufferSpec)
-public:
-  /// Construct a Gst::RingBufferSpec from a GstRingBufferSpec.
-  RingBufferSpec(const GstRingBufferSpec* castitem);
-
-  /** The caps that generated the Spec. */
+  /** The caps of the buffer (in). */
   Glib::RefPtr<Gst::Caps> caps;
 
-  /** The sample type.
+  /** The sample type (in/out).
    */
   Gst::BufferFormatType type;
 
-  /** The sample format.
+  /** The sample format (in/out).
    */
   Gst::BufferFormat format;
 
-  /** The sample sign.
+  /** The sample sign (in/out).
    */
   bool          sign;
 
-  /** The endianness of the samples.
+  /** The endianness of the samples (in/out).
    */
   bool          bigend;
 
-  /** The width of the samples.
+  /** The width of the samples (in/out).
    */
   int           width;
 
-  /** The depth of the samples.
+  /** The depth of the samples (in/out).
    */
   int           depth;
 
-  /** The samplerate.
+  /** The samplerate (in/out).
    */
   int           rate;
 
-  /** The number of channels.
+  /** The number of channels (in/out).
    */
   int           channels;
 
-  /** The latency in microseconds.
+  /** The latency in microseconds (in/out).
    */
   guint64       latency_time;
 
-  /**  The total buffer size in microseconds.
+  /**  The total buffer size in microseconds (in/out).
    */
   guint64       buffer_time;
 
-  /** The size of one segment in bytes.
+  /** The size of one segment in bytes (in/out).
    */
   int           segsize;
 
-  /** The total number of segments.
+  /** The total number of segments (in/out).
    */
   int           segtotal;
 
-  /** Number of bytes of one sample.
+  /** Number of segments queued in the lower level device, defaults to
+   * segtotal (in/out).
    */
-  int           bytes_per_sample;
+  int           seglatency;
 
-  // TODO: Ouch.  No way.
-  /** Bytes representing one sample of silence.
+  /** Number of bytes of one sample (out).  This is set by the call to
+   * Gst::RingBuffer::acquire().
    */
-  guint8        silence_sample[32];
+  int           bytes_per_sample;
 
-  /** Number of segments queued in the lower level device, defaults to
-   * segtotal.
+  // TODO: Ouch.  No way.
+  /** Bytes representing one sample of silence (out).  This is set by the call
+   * to Gst::RingBuffer::acquire().
    */
-  int           seglatency;
+  // I hope this is what the TODO means:
+  std::vector<guint8> silence_sample;
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
-  void copy_fields_from(const GstRingBufferSpec& spec);
-  void copy_fields_to(GstRingBufferSpec& spec) const;
+  void copy_from(const GstRingBufferSpec& spec);
+  void copy_to(GstRingBufferSpec& spec) const;
 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
 };
 
@@ -122,8 +131,8 @@ public:
  *
  * The ringbuffer abstracts a circular buffer of data. One reader and one
  * writer can operate on the data from different threads in a lockfree manner.
- * The base class is sufficiently flexible to be used as an abstraction for DMA
- * based ringbuffers as well as a pure software implementations.
+ * The base class is sufficiently flexible to be used as an abstraction for
+ * DMA based ringbuffers as well as a pure software implementations.
  *
  * Last reviewed on 2006-02-02 (0.10.4).
  * @ingroup GstBaseClasses
@@ -131,17 +140,15 @@ public:
 class RingBuffer : public Gst::Object
 {
   _CLASS_GOBJECT(RingBuffer, GstRingBuffer, GST_RING_BUFFER, Gst::Object, GstObject)
-  _CUSTOM_DTOR()
-  _CUSTOM_CTOR_CAST()
 
 public:
   /** For example,
-   * bool on_fill(const Glib::RefPtr<Gst::RingBuffer>& rbuf, guint8* data,
-   * guint len);.
+   * bool on_fill(const Glib::RefPtr<Gst::RingBuffer>& rbuf,
+   * const std::vector<guint8>& data, guint len);.
    * This slot is set with set_fill_slot() and is called to fill the memory at
    * data with len bytes of samples.
    */
-  typedef sigc::slot<void, guint8*, guint> SlotFill;
+  typedef sigc::slot<void, const Glib::ArrayHandle<guint8>&, guint> SlotFill;
 
   //TODO: _MEMBER_GET(cond, cond, Glib::Cond, GCond*)
 
@@ -176,11 +183,18 @@ public:
   _WRAP_METHOD(guint get_delay() const, gst_ring_buffer_delay)
   _WRAP_METHOD(guint64 get_samples_done() const, gst_ring_buffer_samples_done)
   _WRAP_METHOD(void set_sample(guint64 sample), gst_ring_buffer_set_sample)
-  _WRAP_METHOD(guint commit(guint64 sample, guchar* data, guint len), gst_ring_buffer_commit)
-  _WRAP_METHOD(guint commit(guint64& sample, guchar* data, int in_samples, int out_samples, int& accum), gst_ring_buffer_commit_full)
+
+#m4 _CONVERSION(`const Glib::ArrayHandle<guchar>&', `guchar*', `const_cast<guchar*>($3.data())')
+  _WRAP_METHOD(guint commit(guint64 sample, const Glib::ArrayHandle<guchar>& data, guint len), gst_ring_buffer_commit)
+  _WRAP_METHOD(guint commit(guint64& sample, const Glib::ArrayHandle<guchar>& data, int in_samples, int out_samples, int& accum), gst_ring_buffer_commit_full)
+
   _WRAP_METHOD(bool convert(Gst::Format src_fmt, gint64 src_val, Gst::Format dest_fmt, gint64& dest_val) const, gst_ring_buffer_convert)
-  _WRAP_METHOD(bool prepare_read(int& segment, guint8*& readptr, int& len), gst_ring_buffer_prepare_read)
-  _WRAP_METHOD(guint read(guint64 sample, guchar* data, guint len), gst_ring_buffer_read)
+
+  _WRAP_METHOD_DOCS_ONLY(gst_ring_buffer_prepare_read)
+  bool prepare_read(int& segment, std::vector<guint8>& readptr, int& len);
+
+  _WRAP_METHOD(guint read(guint64 sample, const Glib::ArrayHandle<guchar>& data, guint len), gst_ring_buffer_read)
+
   _WRAP_METHOD(void clear(int segment), gst_ring_buffer_clear)
   _WRAP_METHOD(void clear_all(), gst_ring_buffer_clear_all)
   _WRAP_METHOD(void advance(guint advance), gst_ring_buffer_advance)
@@ -199,13 +213,75 @@ public:
 
   _WRAP_METHOD(void set_flushing(bool flushing), gst_ring_buffer_set_flushing)
 
-  //TODO: Wrap vfuncs.
+  /** Virtual function to open the device.  Don't set any params or allocate
+   * anything.
+   */
+  _WRAP_VFUNC(bool open_device(), "open_device")
+
+#ifdef GLIBMM_VFUNCS_ENABLED
+  /** Virtual function to allocate the resources for the ring buffer using the
+   * given spec.
+   */
+  virtual bool acquire_vfunc(Gst::RingBufferSpec& spec);
+#endif //GLIBMM_VFUNCS_ENABLED
+
+  /** Virtual function to free resources of the ring buffer.
+   */
+  _WRAP_VFUNC(bool release(), "release")
+
+  /** Virtual function to close the device.
+   */
+  _WRAP_VFUNC(bool close_device(), "close_device")
+
+  /** Virtual function to start processing of samples.
+   */
+  _WRAP_VFUNC(bool start(), "start")
+
+  /** Virtual function to pause processing of samples.
+   */
+  _WRAP_VFUNC(bool pause(), "pause")
+
+  /** Virtual function to resume processing of samples after pause.
+   */
+  _WRAP_VFUNC(bool resume(), "resume")
+
+  /** Virtual function to stop processing of samples.
+   */
+  _WRAP_VFUNC(bool stop(), "stop")
+
+  /** Virtual function to get number of samples queued in device.
+   */
+  _WRAP_VFUNC(guint delay(), "delay")
+
+  /** Virtual function to activate the thread that starts pulling and
+   * monitoring the consumed segments in the device. Since 0.10.22.
+   */
+  _WRAP_VFUNC(bool activate(bool active), "activate")
+
+#ifdef GLIBMM_VFUNCS_ENABLED
+  /** Virtual function to write samples into the ring buffer.
+   */
+  virtual guint commit_vfunc(guint64& sample, const Glib::ArrayHandle<guchar>& data, int in_samples, int out_samples, int& accum);
+#endif //GLIBMM_VFUNCS_ENABLED
+
+  /** Virtual function to clear the entire ringbuffer Since 0.10.24.
+   */
+  _WRAP_VFUNC(void clear_all(), "clear_all")
+
+protected:
+#m4begin
+  _PUSH(SECTION_PCC_CLASS_INIT_VFUNCS)
+  klass->acquire = &acquire_vfunc_callback;
+  klass->commit = &commit_vfunc_callback;
+  _SECTION(SECTION_PH_VFUNCS)
+  static gboolean acquire_vfunc_callback(GstRingBuffer* self, GstRingBufferSpec* spec);
+  static guint commit_vfunc_callback(GstRingBuffer* self, guint64* sample, guchar* data, gint in_samples, gint out_samples, gint* accum);
+  _POP()
+#m4end
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 private:
-  // TODO: Follow naming conventions and use std::auto_ptr<SlotFill>.
-  SlotFill* slot;
-  bool _slot_set;
+  std::auto_ptr<SlotFill> m_slot;
 #endif
 };
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]