Add methods to more accuratly control the pulling thread of a ringbuffer.
authorWim Taymans <wim.taymans@gmail.com>
Fri, 17 Oct 2008 13:19:05 +0000 (13:19 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Fri, 17 Oct 2008 13:19:05 +0000 (13:19 +0000)
Original commit message from CVS:
* docs/libs/gst-plugins-base-libs-sections.txt:
* gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_convert),
(gst_ring_buffer_activate), (gst_ring_buffer_is_active):
* gst-libs/gst/audio/gstringbuffer.h:
Add methods to more accuratly control the pulling thread of a
ringbuffer.
Add format conversion helper code to the ringbuffer.
API: GstRingBuffer:gst_ring_buffer_activate()
API: GstRingBuffer:gst_ring_buffer_is_active()
API: GstRingBuffer:gst_ring_buffer_convert()

ChangeLog
docs/libs/gst-plugins-base-libs-sections.txt
gst-libs/gst/audio/gstringbuffer.c
gst-libs/gst/audio/gstringbuffer.h

index 14a2e81..6a506d4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2008-10-17  Wim Taymans  <wim.taymans@collabora.co.uk>
+
+       * docs/libs/gst-plugins-base-libs-sections.txt:
+       * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_convert),
+       (gst_ring_buffer_activate), (gst_ring_buffer_is_active):
+       * gst-libs/gst/audio/gstringbuffer.h:
+       Add methods to more accuratly control the pulling thread of a
+       ringbuffer.
+       Add format conversion helper code to the ringbuffer.
+       API: GstRingBuffer:gst_ring_buffer_activate()
+       API: GstRingBuffer:gst_ring_buffer_is_active()
+       API: GstRingBuffer:gst_ring_buffer_convert()
+
 2008-10-16  Wim Taymans  <wim.taymans@collabora.co.uk>
 
        * gst-libs/gst/audio/gstaudiosink.c: (audioringbuffer_thread_func),
index 3a0dc9b..4a08e9f 100644 (file)
@@ -172,6 +172,9 @@ gst_ring_buffer_acquire
 gst_ring_buffer_release
 gst_ring_buffer_is_acquired
 
+gst_ring_buffer_activate
+gst_ring_buffer_is_active
+
 gst_ring_buffer_start
 gst_ring_buffer_pause
 gst_ring_buffer_stop
@@ -181,6 +184,7 @@ gst_ring_buffer_samples_done
 gst_ring_buffer_set_sample
 gst_ring_buffer_commit
 gst_ring_buffer_commit_full
+gst_ring_buffer_convert
 
 gst_ring_buffer_prepare_read
 gst_ring_buffer_read
index 7312436..e9023c8 100644 (file)
@@ -433,6 +433,101 @@ parse_error:
 }
 
 /**
+ * gst_ring_buffer_convert:
+ * @buf: the #GstRingBuffer
+ * @src_fmt: the source format
+ * @src_val: the source value
+ * @dest_fmt: the destination format
+ * @dest_val: a location to store the converted value
+ *
+ * Convert @src_val in @src_fmt to the equivalent value in @dest_fmt. The result
+ * will be put in @dest_val.
+ *
+ * Returns: TRUE if the conversion succeeded.
+ *
+ * Since: 0.10.22.
+ */
+gboolean
+gst_ring_buffer_convert (GstRingBuffer * buf,
+    GstFormat src_fmt, gint64 src_val, GstFormat dest_fmt, gint64 * dest_val)
+{
+  gboolean res = TRUE;
+  gint bps, rate;
+
+  GST_DEBUG ("converting value %" G_GINT64_FORMAT " from %s (%d) to %s (%d)",
+      src_val, gst_format_get_name (src_fmt), src_fmt,
+      gst_format_get_name (dest_fmt), dest_fmt);
+
+  if (src_fmt == dest_fmt || src_val == -1) {
+    *dest_val = src_val;
+    goto done;
+  }
+
+  /* get important info */
+  GST_OBJECT_LOCK (buf);
+  bps = buf->spec.bytes_per_sample;
+  rate = buf->spec.rate;
+  GST_OBJECT_UNLOCK (buf);
+
+  if (bps == 0 || rate == 0) {
+    GST_DEBUG ("no rate or bps configured");
+    res = FALSE;
+    goto done;
+  }
+
+  switch (src_fmt) {
+    case GST_FORMAT_BYTES:
+      switch (dest_fmt) {
+        case GST_FORMAT_TIME:
+          *dest_val = gst_util_uint64_scale_int (src_val / bps, GST_SECOND,
+              rate);
+          break;
+        case GST_FORMAT_DEFAULT:
+          *dest_val = src_val / bps;
+          break;
+        default:
+          res = FALSE;
+          break;
+      }
+      break;
+    case GST_FORMAT_DEFAULT:
+      switch (dest_fmt) {
+        case GST_FORMAT_TIME:
+          *dest_val = gst_util_uint64_scale_int (src_val, GST_SECOND, rate);
+          break;
+        case GST_FORMAT_BYTES:
+          *dest_val = src_val * bps;
+          break;
+        default:
+          res = FALSE;
+          break;
+      }
+      break;
+    case GST_FORMAT_TIME:
+      switch (dest_fmt) {
+        case GST_FORMAT_DEFAULT:
+          *dest_val = gst_util_uint64_scale_int (src_val, rate, GST_SECOND);
+          break;
+        case GST_FORMAT_BYTES:
+          *dest_val = gst_util_uint64_scale_int (src_val, rate, GST_SECOND);
+          *dest_val *= bps;
+          break;
+        default:
+          res = FALSE;
+          break;
+      }
+      break;
+    default:
+      res = FALSE;
+      break;
+  }
+done:
+  GST_DEBUG ("ret=%d result %" G_GINT64_FORMAT, res, *dest_val);
+
+  return res;
+}
+
+/**
  * gst_ring_buffer_set_callback:
  * @buf: the #GstRingBuffer to set the callback on
  * @cb: the callback to set
@@ -608,7 +703,6 @@ gst_ring_buffer_device_is_open (GstRingBuffer * buf)
   return res;
 }
 
-
 /**
  * gst_ring_buffer_acquire:
  * @buf: the #GstRingBuffer to acquire
@@ -801,6 +895,103 @@ gst_ring_buffer_is_acquired (GstRingBuffer * buf)
 }
 
 /**
+ * gst_ring_buffer_activate:
+ * @buf: the #GstRingBuffer to activate
+ * @active: the new mode
+ *
+ * Activate @buf to start or stop pulling data.
+ *
+ * Returns: TRUE if the device could be activated in the requested mode,
+ * FALSE on error.
+ *
+ * Since: 0.10.22.
+ *
+ * MT safe.
+ */
+gboolean
+gst_ring_buffer_activate (GstRingBuffer * buf, gboolean active)
+{
+  gboolean res = FALSE;
+  GstRingBufferClass *rclass;
+
+  g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
+
+  GST_DEBUG_OBJECT (buf, "activate device");
+
+  GST_OBJECT_LOCK (buf);
+  if (G_UNLIKELY (active && !buf->acquired))
+    goto not_acquired;
+
+  if (G_UNLIKELY (buf->abidata.ABI.active == active))
+    goto was_active;
+
+  rclass = GST_RING_BUFFER_GET_CLASS (buf);
+  /* if there is no activate function we assume it was started/released
+   * in the acquire method */
+  if (G_LIKELY (rclass->activate))
+    res = rclass->activate (buf, active);
+  else
+    res = TRUE;
+
+  if (G_UNLIKELY (!res))
+    goto activate_failed;
+
+  buf->abidata.ABI.active = active;
+
+done:
+  GST_OBJECT_UNLOCK (buf);
+
+  return res;
+
+  /* ERRORS */
+not_acquired:
+  {
+    GST_DEBUG_OBJECT (buf, "device not acquired");
+    g_critical ("Device for %p not acquired", buf);
+    res = FALSE;
+    goto done;
+  }
+was_active:
+  {
+    res = TRUE;
+    GST_DEBUG_OBJECT (buf, "device was active in mode %d", active);
+    goto done;
+  }
+activate_failed:
+  {
+    GST_DEBUG_OBJECT (buf, "failed to activate device");
+    goto done;
+  }
+}
+
+/**
+ * gst_ring_buffer_is_active:
+ * @buf: the #GstRingBuffer
+ *
+ * Check if @buf is activated.
+ *
+ * Returns: TRUE if the device is active.
+ *
+ * Since: 0.10.22.
+ *
+ * MT safe.
+ */
+gboolean
+gst_ring_buffer_is_active (GstRingBuffer * buf)
+{
+  gboolean res;
+
+  g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
+
+  GST_OBJECT_LOCK (buf);
+  res = buf->abidata.ABI.active;
+  GST_OBJECT_UNLOCK (buf);
+
+  return res;
+}
+
+
+/**
  * gst_ring_buffer_set_flushing:
  * @buf: the #GstRingBuffer to flush
  * @flushing: the new mode
index 8d2a40f..be0b27c 100644 (file)
@@ -279,6 +279,7 @@ struct _GstRingBuffer {
       gboolean           flushing;
       /* ATOMIC */
       gint               may_start;
+      gboolean           active;
     } ABI;
     /* adding + 0 to mark ABI change to be undone later */
     gpointer _gst_reserved[GST_PADDING + 0];
@@ -297,6 +298,7 @@ struct _GstRingBuffer {
  * @resume: resume processing of samples after pause
  * @stop: stop processing of samples
  * @delay: get number of samples queued in device
+ * @activate: activate the thread that starts pulling. Since 0.10.22
  *
  * The vmethods that subclasses can override to implement the ringbuffer.
  */
@@ -316,8 +318,11 @@ struct _GstRingBufferClass {
 
   guint        (*delay)        (GstRingBuffer *buf);
 
+  /* ABI added */
+  gboolean     (*activate)     (GstRingBuffer *buf, gboolean active);
+
   /*< private >*/
-  gpointer _gst_reserved[GST_PADDING];
+  gpointer _gst_reserved[GST_PADDING - 1];
 };
 
 GType gst_ring_buffer_get_type(void);
@@ -330,6 +335,10 @@ gboolean        gst_ring_buffer_parse_caps      (GstRingBufferSpec *spec, GstCap
 void            gst_ring_buffer_debug_spec_caps (GstRingBufferSpec *spec);
 void            gst_ring_buffer_debug_spec_buff (GstRingBufferSpec *spec);
 
+gboolean        gst_ring_buffer_convert         (GstRingBuffer * buf, GstFormat src_fmt,
+                                                 gint64 src_val, GstFormat dest_fmt,
+                                                gint64 * dest_val);
+
 /* device state */
 gboolean        gst_ring_buffer_open_device     (GstRingBuffer *buf);
 gboolean        gst_ring_buffer_close_device    (GstRingBuffer *buf);
@@ -342,6 +351,10 @@ gboolean        gst_ring_buffer_release         (GstRingBuffer *buf);
 
 gboolean        gst_ring_buffer_is_acquired     (GstRingBuffer *buf);
 
+/* activating */
+gboolean        gst_ring_buffer_activate        (GstRingBuffer *buf, gboolean active);
+gboolean        gst_ring_buffer_is_active       (GstRingBuffer *buf);
+
 /* flushing */
 void            gst_ring_buffer_set_flushing    (GstRingBuffer *buf, gboolean flushing);