[gstreamermm] Gst::RingBufferSpec: Avoid copying between it and its C counterpart.



commit 0bc8ba5c106901c37f03c6b49c925f98b92f1cd4
Author: José Alburquerque <jaalburqu svn gnome org>
Date:   Wed Dec 16 14:23:20 2009 -0500

    	Gst::RingBufferSpec: Avoid copying between it and its C counterpart.
    
    	* gstreamer/src/ringbuffer.ccg:
    	* gstreamer/src/ringbuffer.hg (RingBufferSpec): Re-implement as a
    	class with an underlying GstRingBufferSpec* instead of a struct so
    	that copying to and from the C object is not necessary in the
    	implementation of virtual functions.  Also, functions with
    	GstRingBufferSpec* parameters can be wrapped with _WRAP_METHOD.
    	(acquire):
    	(parse_caps): Wrapped with _WRAP_METHOD.
    	* gstreamer/src/audiofilter.ccg (setup_vfunc):
    	* gstreamer/src/audiosink.ccg (prepare_vfunc):
    	* gstreamer/src/audiosrc.ccg (prepare_vfunc): Modified usage of
    	Gst::RingBufferSpec in virtual functions and their callbacks so that
    	copying is now not done because it is no longer necessary.
    	* tools/m4/convert_gst.m4: Added a conversion from
    	Gst::RingBufferSpec& to GstRingBufferSpec*.

 ChangeLog                     |   20 +++
 gstreamer/src/audiofilter.ccg |   16 +--
 gstreamer/src/audiosink.ccg   |   16 +--
 gstreamer/src/audiosrc.ccg    |   16 +--
 gstreamer/src/ringbuffer.ccg  |  346 +++++++++++++++++++++++++++++++++--------
 gstreamer/src/ringbuffer.hg   |  227 +++++++++++++++++++--------
 tools/m4/convert_gst.m4       |    3 +
 7 files changed, 478 insertions(+), 166 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index aa44ac7..2afc0fb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2009-12-10  José Alburquerque  <jaalburqu svn gnome org>
+
+	Gst::RingBufferSpec: Avoid copying between it and its C counterpart.
+
+	* gstreamer/src/ringbuffer.ccg:
+	* gstreamer/src/ringbuffer.hg (RingBufferSpec): Re-implement as a
+	class with an underlying GstRingBufferSpec* instead of a struct so
+	that copying to and from the C object is not necessary in the
+	implementation of virtual functions.  Also, functions with
+	GstRingBufferSpec* parameters can be wrapped with _WRAP_METHOD.
+	(acquire):
+	(parse_caps): Wrapped with _WRAP_METHOD.
+	* gstreamer/src/audiofilter.ccg (setup_vfunc):
+	* gstreamer/src/audiosink.ccg (prepare_vfunc):
+	* gstreamer/src/audiosrc.ccg (prepare_vfunc): Modified usage of
+	Gst::RingBufferSpec in virtual functions and their callbacks so that
+	copying is now not done because it is no longer necessary.
+	* tools/m4/convert_gst.m4: Added a conversion from
+	Gst::RingBufferSpec& to GstRingBufferSpec*.
+
 2009-12-09  José Alburquerque  <jaalburqu svn gnome org>
 
 	RingBuffer: Wrap virtual functions.
diff --git a/gstreamer/src/audiofilter.ccg b/gstreamer/src/audiofilter.ccg
index 9fdb97c..df61cf5 100644
--- a/gstreamer/src/audiofilter.ccg
+++ b/gstreamer/src/audiofilter.ccg
@@ -44,12 +44,10 @@ 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;
-        spec.copy_from(*format);
+        Gst::RingBufferSpec spec(*format);
+
         // Call the virtual member method, which derived classes might override.
-        const gboolean result = static_cast<int>(obj->setup_vfunc(spec));
-        spec.copy_to(*format);
-        return result;
+        return static_cast<int>(obj->setup_vfunc(spec));
       #ifdef GLIBMM_EXCEPTIONS_ENABLED
       }
       catch(...)
@@ -79,13 +77,7 @@ bool Gst::AudioFilter::setup_vfunc(Gst::RingBufferSpec& format)
   );
 
   if(base && base->setup)
-  {
-    GstRingBufferSpec 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;
-  }
+    return static_cast<bool>((*base->setup)(gobj(), format.gobj()));
 
   typedef bool RType;
   return RType();
diff --git a/gstreamer/src/audiosink.ccg b/gstreamer/src/audiosink.ccg
index 6e623ee..15bf7d4 100644
--- a/gstreamer/src/audiosink.ccg
+++ b/gstreamer/src/audiosink.ccg
@@ -43,12 +43,10 @@ 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);
+        Gst::RingBufferSpec cpp_spec(*spec);
+
         // Call the virtual member method, which derived classes might override.
-        const gboolean result = static_cast<int>(obj->prepare_vfunc(cpp_spec));
-        cpp_spec.copy_to(*spec);
-        return result;
+        return static_cast<int>(obj->prepare_vfunc(cpp_spec));
       #ifdef GLIBMM_EXCEPTIONS_ENABLED
       }
       catch(...)
@@ -78,13 +76,7 @@ bool Gst::AudioSink::prepare_vfunc(Gst::RingBufferSpec& spec)
   );
 
   if(base && base->prepare)
-  {
-    GstRingBufferSpec 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;
-  }
+    return static_cast<bool>((*base->prepare)(gobj(),spec.gobj()));
 
   typedef bool RType;
   return RType();
diff --git a/gstreamer/src/audiosrc.ccg b/gstreamer/src/audiosrc.ccg
index d22c7b6..e3fb5fd 100644
--- a/gstreamer/src/audiosrc.ccg
+++ b/gstreamer/src/audiosrc.ccg
@@ -43,12 +43,10 @@ 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);
+        Gst::RingBufferSpec cpp_spec(*spec);
+
         // Call the virtual member method, which derived classes might override.
-        const gboolean result = static_cast<int>(obj->prepare_vfunc(cpp_spec));
-        cpp_spec.copy_to(*spec);
-        return result;
+        return static_cast<int>(obj->prepare_vfunc(cpp_spec));
       #ifdef GLIBMM_EXCEPTIONS_ENABLED
       }
       catch(...)
@@ -78,13 +76,7 @@ bool Gst::AudioSrc::prepare_vfunc(Gst::RingBufferSpec& spec)
   );
 
   if(base && base->prepare)
-  {
-    GstRingBufferSpec 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;
-  }
+    return static_cast<bool>((*base->prepare)(gobj(), spec.gobj()));
 
   typedef bool RType;
   return RType();
diff --git a/gstreamer/src/ringbuffer.ccg b/gstreamer/src/ringbuffer.ccg
index d4c35a0..1cb6bcb 100644
--- a/gstreamer/src/ringbuffer.ccg
+++ b/gstreamer/src/ringbuffer.ccg
@@ -21,6 +21,10 @@
 #include <gst/audio/audio-enumtypes.h>
 _PINCLUDE(gstreamermm/private/object_p.h)
 
+// This constant is obtained from the "silence_sample" member in the
+// GstRingBufferSpec structure definition.
+#define GSTREAMERMM_RING_BUFFER_SPEC_SILENCE_SAMPLE 32
+
 namespace
 {
 
@@ -54,47 +58,289 @@ static void RingBuffer_Fill_gstreamermm_callback(GstRingBuffer*, guint8* data, g
 namespace Gst
 {
 
-void RingBufferSpec::copy_from(const GstRingBufferSpec& spec)
+RingBufferSpec::RingBufferSpec()
+: m_spec(g_new(GstRingBufferSpec, 1)),
+  take_ownership(true)
+{}
+
+RingBufferSpec::RingBufferSpec(const Glib::RefPtr<Gst::Caps>& caps,
+  Gst::BufferFormatType type, Gst::BufferFormat format, bool sign,
+  bool bigend, int width, int depth, int rate, int channels,
+  guint64 latency_time, guint64 buffer_time, int segsize, int segtotal,
+  int seglatency)
+: m_spec(g_new(GstRingBufferSpec, 1)),
+  take_ownership(true)
+  
+{
+  GstRingBufferSpec* spec = gobj();
+
+  spec->caps = Glib::unwrap(caps);
+
+  // Keep a copy of the caps (it will be unreferenced in the destructor).
+  if (caps)
+    caps->reference();
+
+  spec->type = static_cast<GstBufferFormatType>(type);
+  spec->format = static_cast<GstBufferFormat>(format);
+  spec->sign = static_cast<int>(sign);
+  spec->bigend = static_cast<int>(bigend);
+  spec->width = width;
+  spec->depth = depth;
+  spec->rate = rate;
+  spec->channels = channels;
+  spec->latency_time = latency_time;
+  spec->buffer_time = buffer_time;
+  spec->segsize = segsize;
+  spec->segtotal = segtotal;
+  spec->seglatency = seglatency;
+}
+
+
+RingBufferSpec::RingBufferSpec(GstRingBufferSpec& castitem, bool take_ownership)
+: m_spec(&castitem),
+  take_ownership(take_ownership)
+{
+  // Keep a copy of the caps (it will be unreferenced in the destructor).
+  if(castitem.caps)
+      gst_caps_ref(castitem.caps);
+}
+
+RingBufferSpec::RingBufferSpec(const RingBufferSpec& other)
+: m_spec(g_new(GstRingBufferSpec, 1)),
+  take_ownership(true)
+{
+  m_spec->caps = other.m_spec->caps;
+
+  // Keep a copy of the caps (it will be unreferenced in the destructor).
+  if(m_spec->caps)
+    gst_caps_ref(m_spec->caps);
+
+  m_spec->type = other.m_spec->type;
+  m_spec->format = other.m_spec->format;
+  m_spec->sign = other.m_spec->sign;
+  m_spec->bigend = other.m_spec->bigend;
+  m_spec->width = other.m_spec->width;
+  m_spec->depth = other.m_spec->depth;
+  m_spec->rate = other.m_spec->rate;
+  m_spec->channels = other.m_spec->channels;
+  m_spec->latency_time = other.m_spec->latency_time;
+  m_spec->buffer_time = other.m_spec->buffer_time;
+  m_spec->segsize = other.m_spec->segsize;
+  m_spec->segtotal = other.m_spec->segtotal;
+  m_spec->bytes_per_sample = other.m_spec->bytes_per_sample;
+  m_spec->seglatency = other.m_spec->seglatency;
+
+  std::copy(other.m_spec->silence_sample, other.m_spec->silence_sample + GSTREAMERMM_RING_BUFFER_SPEC_SILENCE_SAMPLE, m_spec->silence_sample);
+}
+
+RingBufferSpec& RingBufferSpec::operator=(const RingBufferSpec& other)
+{
+  RingBufferSpec temp(other);
+  swap(temp);
+  return *this;
+}
+
+RingBufferSpec::~RingBufferSpec()
+{
+  // Unref existing reference to caps.
+  if(m_spec->caps)
+    gst_caps_unref(m_spec->caps);
+
+  // Release the underlying m_spec if it is owned.
+  if(take_ownership)
+    g_free(m_spec);
+}
+
+void RingBufferSpec::swap(RingBufferSpec& other)
+{
+  GstRingBufferSpec* spec_temp = m_spec;
+  m_spec = other.m_spec;
+  other.m_spec = spec_temp;
+
+  const bool take_temp = take_ownership;
+  take_ownership = other.take_ownership;
+  other.take_ownership = take_temp;
+}
+
+GstRingBufferSpec* RingBufferSpec::gobj()
+{
+  return m_spec;
+}
+
+const GstRingBufferSpec* RingBufferSpec::gobj() const
+{
+  return m_spec;
+}
+
+Glib::RefPtr<Gst::Caps> RingBufferSpec::qet_caps()
+{
+  return Glib::wrap(m_spec->caps);
+}
+
+void RingBufferSpec::set_caps(const Glib::RefPtr<Gst::Caps>& caps)
+{
+  // Unrefence possible previous caps.
+  if(m_spec->caps)
+    gst_caps_unref(m_spec->caps);
+
+  m_spec->caps = Glib::unwrap(caps);
+
+  // Keep a copy of the new caps (it will be unreferenced in the destructor).
+  if(m_spec->caps)
+    gst_caps_ref(m_spec->caps);
+}
+
+Gst::BufferFormatType RingBufferSpec::qet_type()
+{
+  return static_cast<Gst::BufferFormatType>(m_spec->type);
+}
+
+void RingBufferSpec::set_type(Gst::BufferFormatType type)
+{
+  m_spec->type = static_cast<GstBufferFormatType>(type);
+}
+
+Gst::BufferFormat RingBufferSpec::qet_format()
+{
+  return static_cast<Gst::BufferFormat>(m_spec->format);
+}
+
+void RingBufferSpec::set_format(Gst::BufferFormat format)
+{
+  m_spec->format = static_cast<GstBufferFormat>(format);
+}
+
+bool RingBufferSpec::qet_sign()
+{
+  return static_cast<bool>(m_spec->sign);
+}
+
+void RingBufferSpec::set_sign(bool sign)
+{
+  m_spec->sign = static_cast<gboolean>(sign);
+}
+
+bool RingBufferSpec::qet_bigend()
+{
+  return static_cast<bool>(m_spec->bigend);
+}
+
+void RingBufferSpec::set_bigend(bool bigend)
 {
-  caps = Glib::wrap(spec.caps);
+  m_spec->sign = static_cast<gboolean>(bigend);
+}
 
-  type = static_cast<Gst::BufferFormatType>(spec.type);
-  format = static_cast<Gst::BufferFormat>(spec.format);
-  sign = spec.sign;
-  bigend = spec.bigend;
-  width = spec.width;
-  depth = spec.depth;
-  rate = spec.rate;
-  channels = spec.channels;
-  latency_time = spec.latency_time;
-  buffer_time = spec.buffer_time;
-  segsize = spec.segsize;
-  segtotal = spec.segtotal;
-  bytes_per_sample = spec.bytes_per_sample;
-  seglatency = spec.seglatency;
+int RingBufferSpec::qet_width()
+{
+  return m_spec->width;
+}
 
-  silence_sample.assign(spec.silence_sample, spec.silence_sample + 32);
+void RingBufferSpec::set_width(int width)
+{
+  m_spec->width = width;
 }
 
-void RingBufferSpec::copy_to(GstRingBufferSpec& spec) const
+int RingBufferSpec::qet_depth()
 {
-  spec.caps = Glib::unwrap(caps);
-  spec.type = static_cast<GstBufferFormatType>(type);
-  spec.format = static_cast<GstBufferFormat>(format);
-  spec.sign = sign;
-  spec.bigend = bigend;
-  spec.width = width;
-  spec.depth = depth;
-  spec.rate = rate;
-  spec.channels = channels;
-  spec.latency_time = latency_time;
-  spec.buffer_time = buffer_time;
-  spec.segsize = segsize;
-  spec.segtotal = segtotal;
-  spec.bytes_per_sample = bytes_per_sample;
-  spec.seglatency = seglatency;
+  return m_spec->depth;
+}
 
-  std::copy(silence_sample.begin(), silence_sample.end(), spec.silence_sample);
+void RingBufferSpec::set_depth(int depth)
+{
+  m_spec->depth = depth;
+}
+
+int RingBufferSpec::qet_rate()
+{
+  return m_spec->rate;
+}
+
+void RingBufferSpec::set_rate(int rate)
+{
+  m_spec->rate = rate;
+}
+
+int RingBufferSpec::qet_channels()
+{
+  return m_spec->channels;
+}
+
+void RingBufferSpec::set_channels(int channels)
+{
+  m_spec->channels = channels;
+}
+
+guint64 RingBufferSpec::qet_latency_time()
+{
+  return m_spec->latency_time;
+}
+
+void RingBufferSpec::set_latency_time(guint64 latency_time)
+{
+  m_spec->latency_time = latency_time;
+}
+
+guint64 RingBufferSpec::qet_buffer_time()
+{
+  return m_spec->buffer_time;
+}
+
+void RingBufferSpec::set_buffer_time(guint64 buffer_time)
+{
+  m_spec->buffer_time = buffer_time;
+}
+
+int RingBufferSpec::qet_segsize()
+{
+  return m_spec->segsize;
+}
+
+void RingBufferSpec::set_segsize(int segsize)
+{
+  m_spec->segsize = segsize;
+}
+
+int RingBufferSpec::qet_segtotal()
+{
+  return m_spec->segtotal;
+}
+
+void RingBufferSpec::set_segtotal(int segtotal)
+{
+  m_spec->segtotal = segtotal;
+}
+
+int RingBufferSpec::qet_seglatency()
+{
+  return m_spec->seglatency;
+}
+
+void RingBufferSpec::set_seglatency(int seglatency)
+{
+  m_spec->seglatency = seglatency;
+}
+
+int RingBufferSpec::qet_bytes_per_sample()
+{
+  return m_spec->bytes_per_sample;
+}
+
+void RingBufferSpec::set_bytes_per_sample(int bytes_per_sample)
+{
+  m_spec->bytes_per_sample = bytes_per_sample;
+}
+
+Glib::ArrayHandle<guint8> RingBufferSpec::get_silence_sample()
+{
+  return Glib::ArrayHandle<guint8>(m_spec->silence_sample,
+    GSTREAMERMM_RING_BUFFER_SPEC_SILENCE_SAMPLE, Glib::OWNERSHIP_NONE);
+}
+
+void RingBufferSpec::set_silence_sample(const Glib::ArrayHandle<guint8>& silence_sample)
+{
+  std::copy(silence_sample.data(),
+    silence_sample.data() + GSTREAMERMM_RING_BUFFER_SPEC_SILENCE_SAMPLE,
+    m_spec->silence_sample);
 }
 
 void RingBuffer::set_fill_slot(const SlotFill& slot)
@@ -123,22 +369,6 @@ bool RingBuffer::prepare_read(int& segment, std::vector<guint8>& readptr,
   return result;
 }
 
-bool RingBuffer::acquire(const Gst::RingBufferSpec& spec)
-{
-  GstRingBufferSpec 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_to(gst_spec);
-  gboolean const result = gst_ring_buffer_parse_caps(&gst_spec, Glib::unwrap(caps));
-  spec.copy_from(gst_spec);
-  return (result != 0);
-}
-
 #ifdef GLIBMM_VFUNCS_ENABLED
 gboolean RingBuffer_Class::acquire_vfunc_callback(GstRingBuffer* self, GstRingBufferSpec* spec)
 {
@@ -159,12 +389,10 @@ gboolean RingBuffer_Class::acquire_vfunc_callback(GstRingBuffer* self, GstRingBu
       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);
+        Gst::RingBufferSpec cpp_spec(*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;
+        return static_cast<int>(obj->acquire_vfunc(cpp_spec));
 
       #ifdef GLIBMM_EXCEPTIONS_ENABLED
       }
@@ -195,13 +423,7 @@ bool Gst::RingBuffer::acquire_vfunc(Gst::RingBufferSpec& spec)
   );
 
   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;
-  }
+    return static_cast<bool>((*base->acquire)(gobj(), spec.gobj()));
 
   typedef bool RType;
   return RType();
diff --git a/gstreamer/src/ringbuffer.hg b/gstreamer/src/ringbuffer.hg
index 1d2521f..66655b0 100644
--- a/gstreamer/src/ringbuffer.hg
+++ b/gstreamer/src/ringbuffer.hg
@@ -33,95 +33,204 @@ _WRAP_ENUM(RingBufferState, GstRingBufferState)
 _WRAP_ENUM(BufferFormat, GstBufferFormat)
 _WRAP_ENUM(BufferFormatType, GstBufferFormatType)
 
-// 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
+/** The class 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().
  */
-struct RingBufferSpec
+class RingBufferSpec
 {
-  /** The caps of the buffer (in). */
-  Glib::RefPtr<Gst::Caps> caps;
+    _CLASS_GENERIC(RingBufferSpec, GstRingBufferSpec)
+public:
+  /// Default constructor.
+  RingBufferSpec();
+
+  /** Fully construct a Gst::RingBufferSpec.  Only the "(in)" parameters are
+   * required.  The "(in/out)" parameters are optional and may be modified by
+   * the call to the Gst::RingBuffer::acquire() method.
+   * @param caps The caps of the buffer (in).
+   * @param type The sample type (in/out).
+   * @param format The sample format (in/out).
+   * @param sign The sample sign (in/out).
+   * @param bigend The endianness of the samples (in/out).
+   * @param width The width of the samples (in/out).
+   * @param depth The depth of the samples (in/out).
+   * @param rate The sample rate (in/out).
+   * @param channels The number of channels (in/out).
+   * @param latency_time The latency in microseconds (in/out).
+   * @param buffer_time The total buffer size in microseconds (in/out).
+   * @param segsize The size of one segment in bytes (in/out).
+   * @param segtotal The total number of segments (in/out).
+   * @param seglatency Number of segments queued in the lower level device,
+   * defaults to @a segtotal in the C API (in/out).
+   */
+  RingBufferSpec(const Glib::RefPtr<Gst::Caps>& caps,
+    Gst::BufferFormatType type = Gst::BUFTYPE_LINEAR,
+    Gst::BufferFormat format = Gst::UNKNOWN, bool sign = false,
+    bool bigend = false, int width = 0, int depth = 0, int rate = 0,
+    int channels = 0, guint64 latency_time = 0, guint64 buffer_time = 0,
+    int segsize = 0, int segtotal = 0, int seglatency = 0);
+
+  /// Construct a Gst::RingBufferSpec from a GstRingBufferSpec.
+  RingBufferSpec(GstRingBufferSpec& castitem, bool take_ownership = false);
+
+  /// Copy constructor.
+  RingBufferSpec(const RingBufferSpec& other);
+
+  /// Assignment operator.
+  RingBufferSpec& operator=(const RingBufferSpec& other);
+
+  /// Destructor.
+  virtual ~RingBufferSpec();
+
+  void swap(RingBufferSpec& other);
+
+  /// Gets the underlying gobject.
+  GstRingBufferSpec* gobj();
+
+  /// Gets the underlying gobject.
+  const GstRingBufferSpec* gobj() const;
+
+  /** Get the caps of the buffer (in). */
+  Glib::RefPtr<Gst::Caps> qet_caps();
+
+  /** Set the caps of the buffer (in). */
+  void set_caps(const Glib::RefPtr<Gst::Caps>& caps);
+
+  /** Get the sample type (in/out).
+   */
+  Gst::BufferFormatType qet_type();
 
-  /** The sample type (in/out).
+  /** Set the sample type (in/out).
    */
-  Gst::BufferFormatType type;
+  void set_type(Gst::BufferFormatType type);
 
-  /** The sample format (in/out).
+  /** Get the sample format (in/out).
    */
-  Gst::BufferFormat format;
+  Gst::BufferFormat qet_format();
 
-  /** The sample sign (in/out).
+  /** Set the sample format (in/out).
    */
-  bool          sign;
+  void set_format(Gst::BufferFormat format);
 
-  /** The endianness of the samples (in/out).
+  /** Get the sample sign (in/out).
    */
-  bool          bigend;
+  bool qet_sign();
 
-  /** The width of the samples (in/out).
+  /** Set the sample sign (in/out).
    */
-  int           width;
+  void set_sign(bool sign);
 
-  /** The depth of the samples (in/out).
+  /** Get the endianness of the samples (in/out).
    */
-  int           depth;
+  bool qet_bigend();
 
-  /** The samplerate (in/out).
+  /** Set the endianness of the samples (in/out).
    */
-  int           rate;
+  void set_bigend(bool bigend);
 
-  /** The number of channels (in/out).
+  /** Get the width of the samples (in/out).
    */
-  int           channels;
+  int qet_width();
 
-  /** The latency in microseconds (in/out).
+  /** Set the width of the samples (in/out).
    */
-  guint64       latency_time;
+  void set_width(int width);
 
-  /**  The total buffer size in microseconds (in/out).
+  /** Get the depth of the samples (in/out).
    */
-  guint64       buffer_time;
+  int qet_depth();
 
-  /** The size of one segment in bytes (in/out).
+  /** Set the depth of the samples (in/out).
    */
-  int           segsize;
+  void set_depth(int depth);
 
-  /** The total number of segments (in/out).
+  /** Get the samplerate (in/out).
    */
-  int           segtotal;
+  int qet_rate();
 
-  /** Number of segments queued in the lower level device, defaults to
+  /** Set the samplerate (in/out).
+   */
+  void set_rate(int rate);
+
+  /** Get the number of channels (in/out).
+   */
+  int qet_channels();
+
+  /** Set the number of channels (in/out).
+   */
+  void set_channels(int channels);
+
+  /** Get the latency in microseconds (in/out).
+   */
+  guint64 qet_latency_time();
+
+  /** Set the latency in microseconds (in/out).
+   */
+  void set_latency_time(guint64 latency_time);
+
+  /** Get the total buffer size in microseconds (in/out).
+   */
+  guint64 qet_buffer_time();
+
+  /** Set the total buffer size in microseconds (in/out).
+   */
+  void set_buffer_time(guint64 buffer_time);
+
+  /** Get the size of one segment in bytes (in/out).
+   */
+  int qet_segsize();
+
+  /** Set the size of one segment in bytes (in/out).
+   */
+  void set_segsize(int segsize);
+
+  /** Get the total number of segments (in/out).
+   */
+  int qet_segtotal();
+
+  /** Set the total number of segments (in/out).
+   */
+  void set_segtotal(int segtotal);
+
+  /** Get the number of segments queued in the lower level device, defaults to
+   * segtotal (in/out).
+   */
+  int qet_seglatency();
+
+  /** Set the number of segments queued in the lower level device, defaults to
    * segtotal (in/out).
    */
-  int           seglatency;
+  void set_seglatency(int seglatency);
 
-  /** Number of bytes of one sample (out).  This is set by the call to
+  /** Get the number of bytes of one sample (out).  This is set by the call to
    * Gst::RingBuffer::acquire().
    */
-  int           bytes_per_sample;
+  int qet_bytes_per_sample();
 
-  // TODO: Ouch.  No way.
-  /** Bytes representing one sample of silence (out).  This is set by the call
-   * to Gst::RingBuffer::acquire().
+  /** Set the number of bytes of one sample (out).  This is set by the call to
+   * Gst::RingBuffer::acquire() and should probably not be set.
    */
-  // I hope this is what the TODO means:
-  std::vector<guint8> silence_sample;
+  void set_bytes_per_sample(int bytes_per_sample);
 
+  /** Get the bytes representing one sample of silence (out).  This is set by
+   * the call to Gst::RingBuffer::acquire().
+   */
+  Glib::ArrayHandle<guint8> get_silence_sample();
+
+  /** Sets the bytes representing one sample of silence (out).  This is set by
+   * the call to Gst::RingBuffer::acquire() and probably should not be set.
+   */
+  void set_silence_sample(const Glib::ArrayHandle<guint8>& silence_sample);
+
+protected:
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
-  void copy_from(const GstRingBufferSpec& spec);
-  void copy_to(GstRingBufferSpec& spec) const;
+  GstRingBufferSpec* m_spec;
+  // Tells whether the m_spec member should be freed upon destruction.
+  bool take_ownership;
 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
 };
 
@@ -162,17 +271,7 @@ public:
   void set_fill_slot(const SlotFill& slot);
   _IGNORE(gst_ring_buffer_set_callback)
 
-  /** Allocate the resources for the ringbuffer. This function fills in the
-   * data pointer of the ring buffer with a valid Gst::Buffer to which samples
-   * can be written.
-   *
-   * @param spec The specs of the buffer.
-   *
-   * @return true if the device could be acquired, false on error. MT safe.
-   */
-  bool acquire(const Gst::RingBufferSpec& spec);
-  _IGNORE(gst_ring_buffer_acquire)
-
+  _WRAP_METHOD(bool acquire(Gst::RingBufferSpec& spec), gst_ring_buffer_acquire)
   _WRAP_METHOD(bool release(), gst_ring_buffer_release)
   _WRAP_METHOD(bool is_acquired() const, gst_ring_buffer_is_acquired)
   _WRAP_METHOD(bool activate(bool active), gst_ring_buffer_activate)
@@ -202,15 +301,7 @@ public:
   _WRAP_METHOD(bool open_device(), gst_ring_buffer_open_device)
   _WRAP_METHOD(bool device_is_open() const, gst_ring_buffer_device_is_open)
   _WRAP_METHOD(void set_may_start(bool allowed), gst_ring_buffer_may_start)
-
-  /** Parse caps into a Gst::RingBufferSpec.
-   *
-   * @param spec A Gst::RingBufferSpec.
-   * @param caps the Gst::Caps to parse.
-   * @return true if the caps could be parsed.
-   */
-  static bool parse_caps(Gst::RingBufferSpec& spec, const Glib::RefPtr<Gst::Caps>& caps);
-
+  _WRAP_METHOD(static bool parse_caps(Gst::RingBufferSpec&, const Glib::RefPtr<Gst::Caps>& caps), gst_ring_buffer_parse_caps)
   _WRAP_METHOD(void set_flushing(bool flushing), gst_ring_buffer_set_flushing)
 
   /** Virtual function to open the device.  Don't set any params or allocate
diff --git a/tools/m4/convert_gst.m4 b/tools/m4/convert_gst.m4
index 60ce02c..f7f4d53 100644
--- a/tools/m4/convert_gst.m4
+++ b/tools/m4/convert_gst.m4
@@ -160,6 +160,9 @@ dnl RingBuffer
 _CONVERSION(`GstRingBuffer*',`Glib::RefPtr<Gst::RingBuffer>',`Glib::wrap($3)')
 _CONVERSION(`Glib::RefPtr<Gst::RingBuffer>',`GstRingBuffer*',`Glib::unwrap($3)')
 
+dnl RingBufferSpec
+_CONVERSION(`Gst::RingBufferSpec&', `GstRingBufferSpec*', `$3.gobj()')
+
 dnl Structure
 _CONVERSION(`Gst::Structure&',`GstStructure*',`$3.gobj()')
 



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