opensles: refactor to behave more like other sinks
authorJosep Torra <n770galaxy@gmail.com>
Thu, 27 Sep 2012 02:00:28 +0000 (04:00 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 18 Oct 2012 12:03:09 +0000 (14:03 +0200)
Reflect the queue in our own data buffer.
Drop the _commit hook that wasn't usefull.
Don't mess with the segsize/segtotal.

sys/opensles/openslesringbuffer.c
sys/opensles/openslesringbuffer.h

index 30a5954..9601b53 100644 (file)
@@ -38,7 +38,6 @@ _do_init (GType type)
 GST_BOILERPLATE_FULL (GstOpenSLESRingBuffer, gst_opensles_ringbuffer,
     GstRingBuffer, GST_TYPE_RING_BUFFER, _do_init);
 
-#define PLAYER_QUEUE_SIZE 2
 #define RECORDER_QUEUE_SIZE 2
 
 /* Some generic helper functions */
@@ -115,36 +114,6 @@ _opensles_player_read_position (GstOpenSLESRingBuffer * thiz)
   }
 }
 
-static void
-_opensles_enqueue_cb (SLAndroidSimpleBufferQueueItf bufferQueue, void *context)
-{
-  GstRingBuffer *rb = GST_RING_BUFFER_CAST (context);
-  GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
-  SLresult result;
-  guint8 *ptr;
-  gint seg;
-  gint len;
-
-  _opensles_player_read_position (thiz);
-
-  if (!gst_ring_buffer_prepare_read (rb, &seg, &ptr, &len)) {
-    GST_WARNING_OBJECT (rb, "No segment available");
-    return;
-  }
-
-  /* Enqueue a buffer */
-  GST_LOG_OBJECT (thiz, "enqueue: %p size %d segment: %d", ptr, len, seg);
-  result = (*thiz->bufferQueue)->Enqueue (thiz->bufferQueue, ptr, len);
-
-  if (result != SL_RESULT_SUCCESS) {
-    GST_ERROR_OBJECT (thiz, "bufferQueue.Enqueue failed(0x%08x)",
-        (guint32) result);
-    return;
-  }
-
-  gst_ring_buffer_advance (rb, 1);
-}
-
 /* Recorder related functions */
 
 static gboolean
@@ -220,6 +189,36 @@ failed:
   return FALSE;
 }
 
+static void
+_opensles_recorder_cb (SLAndroidSimpleBufferQueueItf bufferQueue, void *context)
+{
+  GstRingBuffer *rb = GST_RING_BUFFER_CAST (context);
+  GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
+  SLresult result;
+  guint8 *ptr;
+  gint seg;
+  gint len;
+
+  _opensles_player_read_position (thiz);
+
+  if (!gst_ring_buffer_prepare_read (rb, &seg, &ptr, &len)) {
+    GST_WARNING_OBJECT (rb, "No segment available");
+    return;
+  }
+
+  /* Enqueue a buffer */
+  GST_LOG_OBJECT (thiz, "enqueue: %p size %d segment: %d", ptr, len, seg);
+  result = (*thiz->bufferQueue)->Enqueue (thiz->bufferQueue, ptr, len);
+
+  if (result != SL_RESULT_SUCCESS) {
+    GST_ERROR_OBJECT (thiz, "bufferQueue.Enqueue failed(0x%08x)",
+        (guint32) result);
+    return;
+  }
+
+  gst_ring_buffer_advance (rb, 1);
+}
+
 static gboolean
 _opensles_recorder_start (GstRingBuffer * rb)
 {
@@ -229,7 +228,7 @@ _opensles_recorder_start (GstRingBuffer * rb)
 
   /* Register callback on the buffer queue */
   result = (*thiz->bufferQueue)->RegisterCallback (thiz->bufferQueue,
-      _opensles_enqueue_cb, rb);
+      _opensles_recorder_cb, rb);
   if (result != SL_RESULT_SUCCESS) {
     GST_ERROR_OBJECT (thiz, "bufferQueue.RegisterCallback failed(0x%08x)",
         (guint32) result);
@@ -238,7 +237,7 @@ _opensles_recorder_start (GstRingBuffer * rb)
 
   /* Fill the queue by enqueing buffers */
   for (i = 0; i < RECORDER_QUEUE_SIZE; i++) {
-    _opensles_enqueue_cb (NULL, rb);
+    _opensles_recorder_cb (NULL, rb);
   }
 
   /* Start recording */
@@ -344,7 +343,7 @@ _opensles_player_acquire (GstRingBuffer * rb, GstRingBufferSpec * spec)
 
   /* Configure audio source */
   SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
-    SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, PLAYER_QUEUE_SIZE
+    SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, spec->segtotal
   };
   SLDataSource audioSrc = { &loc_bufq, &format };
 
@@ -408,9 +407,10 @@ _opensles_player_acquire (GstRingBuffer * rb, GstRingBufferSpec * spec)
   _opensles_player_change_volume (rb);
   _opensles_player_change_mute (rb);
 
-  /* Define our ringbuffer in terms of number of buffers and buffer size. */
-  spec->segsize = (spec->rate >> 4) * spec->bytes_per_sample;
-  spec->segtotal = 2 << 4;
+  /* Define our queue data buffer */
+  thiz->data_segtotal = spec->segtotal + 1;
+  thiz->data = g_malloc (spec->segsize * thiz->data_segtotal);
+  thiz->cursor = 0;
 
   return TRUE;
 
@@ -418,6 +418,42 @@ failed:
   return FALSE;
 }
 
+static void
+_opensles_player_cb (SLAndroidSimpleBufferQueueItf bufferQueue, void *context)
+{
+  GstRingBuffer *rb = GST_RING_BUFFER_CAST (context);
+  GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
+  SLresult result;
+  guint8 *ptr, *cur;
+  gint seg;
+  gint len;
+
+  _opensles_player_read_position (thiz);
+
+  if (!gst_ring_buffer_prepare_read (rb, &seg, &ptr, &len)) {
+    GST_WARNING_OBJECT (rb, "No segment available");
+    return;
+  }
+
+  /* copy data to our queue ringbuffer */
+  cur = thiz->data + (thiz->cursor * rb->spec.segsize);
+  thiz->cursor = (thiz->cursor + 1) % thiz->data_segtotal;
+  memcpy (cur, ptr, len);
+
+  /* Enqueue a buffer */
+  GST_LOG_OBJECT (thiz, "enqueue: %p size %d segment: %d", cur, len, seg);
+  result = (*thiz->bufferQueue)->Enqueue (thiz->bufferQueue, cur, len);
+
+  if (result != SL_RESULT_SUCCESS) {
+    GST_ERROR_OBJECT (thiz, "bufferQueue.Enqueue failed(0x%08x)",
+        (guint32) result);
+    return;
+  }
+
+  gst_ring_buffer_clear (rb, seg);
+  gst_ring_buffer_advance (rb, 1);
+}
+
 static gboolean
 _opensles_player_start (GstRingBuffer * rb)
 {
@@ -427,7 +463,7 @@ _opensles_player_start (GstRingBuffer * rb)
 
   /* Register callback on the buffer queue */
   result = (*thiz->bufferQueue)->RegisterCallback (thiz->bufferQueue,
-      _opensles_enqueue_cb, rb);
+      _opensles_player_cb, rb);
   if (result != SL_RESULT_SUCCESS) {
     GST_ERROR_OBJECT (thiz, "bufferQueue.RegisterCallback failed(0x%08x)",
         (guint32) result);
@@ -435,8 +471,8 @@ _opensles_player_start (GstRingBuffer * rb)
   }
 
   /* Fill the queue by enqueing buffers */
-  for (i = 0; i < PLAYER_QUEUE_SIZE; i++) {
-    _opensles_enqueue_cb (NULL, rb);
+  for (i = 0; i < rb->spec.segtotal; i++) {
+    _opensles_player_cb (NULL, rb);
   }
 
   /* Change player state into PLAYING */
@@ -693,6 +729,11 @@ gst_opensles_ringbuffer_release (GstRingBuffer * rb)
     thiz->recorderRecord = NULL;
   }
 
+  if (thiz->data) {
+    g_free (thiz->data);
+    thiz->data = NULL;
+  }
+
   if (rb->data) {
     gst_buffer_unref (rb->data);
     rb->data = NULL;
@@ -746,23 +787,6 @@ gst_opensles_ringbuffer_delay (GstRingBuffer * rb)
   return 0;
 }
 
-static guint
-gst_opensles_ringbuffer_commit (GstRingBuffer * rb, guint64 * sample,
-    guchar * data, gint in_samples, gint out_samples, gint * accum)
-{
-  GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb);
-  guint result;
-
-  _opensles_player_read_position (thiz);
-
-  result =
-      GST_CALL_PARENT_WITH_DEFAULT (GST_RING_BUFFER_CLASS, commit, (rb, sample,
-          data, in_samples, out_samples, accum), 0);
-  GST_LOG_OBJECT (thiz, "wrote %d samples", result);
-
-  return result;
-}
-
 static void
 gst_opensles_ringbuffer_dispose (GObject * object)
 {
@@ -812,9 +836,6 @@ gst_opensles_ringbuffer_class_init (GstOpenSLESRingBufferClass * klass)
   gstringbuffer_class->stop = GST_DEBUG_FUNCPTR (gst_opensles_ringbuffer_stop);
   gstringbuffer_class->delay =
       GST_DEBUG_FUNCPTR (gst_opensles_ringbuffer_delay);
-  gstringbuffer_class->commit =
-      GST_DEBUG_FUNCPTR (gst_opensles_ringbuffer_commit);
-
 }
 
 static void
index 7f8a088..81adf15 100644 (file)
@@ -84,6 +84,9 @@ struct _GstOpenSLESRingBuffer
 
   /* buffer queue */
   SLAndroidSimpleBufferQueueItf bufferQueue;
+  guint data_segtotal;
+  guint8 * data;
+  guint cursor;
 
   /* vmethods */
   AcquireFunc acquire;