gst-libs/gst/audio/: Cleanups.
authorWim Taymans <wim.taymans@gmail.com>
Tue, 11 Oct 2005 18:32:01 +0000 (18:32 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Tue, 11 Oct 2005 18:32:01 +0000 (18:32 +0000)
Original commit message from CVS:
* gst-libs/gst/audio/gstbaseaudiosink.c:
(gst_base_audio_sink_render):
* gst-libs/gst/audio/gstbaseaudiosrc.c:
(gst_base_audio_src_create):
* gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_commit),
(gst_ring_buffer_read):
Cleanups.
Commit and read from ringbuffer in samples rather than bytes.

ChangeLog
gst-libs/gst/audio/gstbaseaudiosink.c
gst-libs/gst/audio/gstbaseaudiosrc.c
gst-libs/gst/audio/gstringbuffer.c

index 702f32d..3e513ed 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,17 @@
 
        * gst-libs/gst/audio/gstbaseaudiosink.c:
        (gst_base_audio_sink_render):
+       * gst-libs/gst/audio/gstbaseaudiosrc.c:
+       (gst_base_audio_src_create):
+       * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_commit),
+       (gst_ring_buffer_read):
+       Cleanups.
+       Commit and read from ringbuffer in samples rather than bytes.
+
+2005-10-11  Wim Taymans  <wim@fluendo.com>
+
+       * gst-libs/gst/audio/gstbaseaudiosink.c:
+       (gst_base_audio_sink_render):
        Respect segment rate and accum when scheduling samples.
 
 2005-10-11  Julien MOUTTE  <julien@moutte.net>
index 1fc7957..69ecda2 100644 (file)
@@ -340,21 +340,36 @@ static GstFlowReturn
 gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
 {
   guint64 render_offset, in_offset;
-  GstClockTime time, render_time;
+  GstClockTime time, render_time, duration;
   GstClockTimeDiff render_diff;
-  GstBaseAudioSink *sink = GST_BASE_AUDIO_SINK (bsink);
+  GstBaseAudioSink *sink;
+  GstRingBuffer *ringbuf;
   gint64 diff;
   guint8 *data;
   guint size;
+  guint samples;
+  gint bps;
+
+  sink = GST_BASE_AUDIO_SINK (bsink);
+
+  ringbuf = sink->ringbuffer;
 
   /* can't do anything when we don't have the device */
-  if (!gst_ring_buffer_is_acquired (sink->ringbuffer))
+  if (!gst_ring_buffer_is_acquired (ringbuf))
     goto wrong_state;
 
+  bps = ringbuf->spec.bytes_per_sample;
+
+  size = GST_BUFFER_SIZE (buf);
+  if (size % bps != 0)
+    goto wrong_size;
+
+  samples = size / bps;
+
   in_offset = GST_BUFFER_OFFSET (buf);
   time = GST_BUFFER_TIMESTAMP (buf);
+  duration = GST_BUFFER_DURATION (buf);
   data = GST_BUFFER_DATA (buf);
-  size = GST_BUFFER_SIZE (buf);
 
   GST_DEBUG ("time %" GST_TIME_FORMAT ", offset %llu, start %" GST_TIME_FORMAT,
       GST_TIME_ARGS (time), in_offset, GST_TIME_ARGS (bsink->segment_start));
@@ -376,34 +391,42 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
   /* add base time to get absolute clock time */
   render_time += gst_element_get_base_time (GST_ELEMENT (bsink));
   /* and bring the time to the offset in the buffer */
-  render_offset = render_time * sink->ringbuffer->spec.rate / GST_SECOND;
+  render_offset = render_time * ringbuf->spec.rate / GST_SECOND;
 
   /* roundoff errors in timestamp conversion */
   if (sink->next_sample != -1)
     diff = ABS ((gint64) render_offset - (gint64) sink->next_sample);
   else
-    diff = sink->ringbuffer->spec.rate;
+    diff = ringbuf->spec.rate;
 
   GST_DEBUG ("render time %" GST_TIME_FORMAT
-      ", render offset %llu, diff %lld, size %lu", GST_TIME_ARGS (render_time),
-      render_offset, diff, size);
+      ", render offset %llu, diff %lld, samples %lu",
+      GST_TIME_ARGS (render_time), render_offset, diff, samples);
 
   /* we tollerate a 10th of a second diff before we start resyncing. This
    * should be enough to compensate for various rounding errors in the timestamp
    * and sample offset position. */
-  if (diff < sink->ringbuffer->spec.rate / DIFF_TOLERANCE) {
+  if (diff < ringbuf->spec.rate / DIFF_TOLERANCE) {
     GST_DEBUG ("align with prev sample, %" G_GINT64_FORMAT " < %lu", diff,
-        sink->ringbuffer->spec.rate / DIFF_TOLERANCE);
+        ringbuf->spec.rate / DIFF_TOLERANCE);
     /* just align with previous sample then */
     render_offset = sink->next_sample;
   } else {
     GST_DEBUG ("resync");
   }
-  gst_ring_buffer_commit (sink->ringbuffer, render_offset, data, size);
+
+  /* clip length based on rate */
+  samples /= ABS (bsink->segment_rate);
 
   /* the next sample should be current sample and its length */
-  sink->next_sample =
-      render_offset + size / sink->ringbuffer->spec.bytes_per_sample;
+  sink->next_sample = render_offset + samples;
+
+  gst_ring_buffer_commit (ringbuf, render_offset, data, samples);
+
+  if (time + duration >= bsink->segment_stop) {
+    GST_DEBUG ("start playback because we are at the end of segment");
+    gst_ring_buffer_start (ringbuf);
+  }
 
   return GST_FLOW_OK;
 
@@ -414,6 +437,14 @@ wrong_state:
         ("sink not negotiated."), ("sink not negotiated."));
     return GST_FLOW_NOT_NEGOTIATED;
   }
+wrong_size:
+  {
+    GST_DEBUG ("wrong size");
+    GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
+        ("sink received buffer of wrong size."),
+        ("sink received buffer of wrong size."));
+    return GST_FLOW_ERROR;
+  }
 }
 
 GstRingBuffer *
index 0dc25ad..a579eee 100644 (file)
@@ -308,7 +308,7 @@ gst_base_audio_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
   GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (psrc);
   GstBuffer *buf;
   guchar *data;
-  guint len;
+  guint len, samples;
   guint res;
   guint64 sample;
 
@@ -326,11 +326,13 @@ gst_base_audio_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
     sample = 0;
   }
 
-  res = gst_ring_buffer_read (src->ringbuffer, sample, data, len);
+  samples = len / src->ringbuffer->spec.bytes_per_sample;
+
+  res = gst_ring_buffer_read (src->ringbuffer, sample, data, samples);
   if (res == -1)
     goto stopped;
 
-  src->next_sample = sample + len / src->ringbuffer->spec.bytes_per_sample;
+  src->next_sample = sample + samples;
 
   gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (psrc)));
 
index daa1027..274d326 100644 (file)
@@ -904,7 +904,7 @@ not_started:
  * @buf: the #GstRingBuffer to commit
  * @sample: the sample position of the data
  * @data: the data to commit
- * @len: the length of the data to commit
+ * @len: the number of samples in the data to commit
  *
  * Commit @len samples pointed to by @data to the ringbuffer
  * @buf. The first sample should be written at position @sample in
@@ -936,15 +936,15 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
   bps = buf->spec.bytes_per_sample;
   sps = buf->samples_per_seg;
 
-  /* write out all bytes */
+  /* write out all samples */
   while (len > 0) {
-    gint writelen;
-    gint writeseg, writeoff;
+    gint sampleslen;
+    gint writeseg, sampleoff;
 
     /* figure out the segment and the offset inside the segment where
      * the sample should be written. */
     writeseg = sample / sps;
-    writeoff = (sample % sps) * bps;
+    sampleoff = (sample % sps);
 
     while (TRUE) {
       gint diff;
@@ -957,13 +957,13 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
 
       GST_DEBUG
           ("pointer at %d, sample %llu, write to %d-%d, len %d, diff %d, segtotal %d, segsize %d",
-          segdone, sample, writeseg, writeoff, len, diff, segtotal, segsize);
+          segdone, sample, writeseg, sampleoff, len, diff, segtotal, sps);
 
       /* segment too far ahead, we need to drop */
       if (diff < 0) {
         /* we need to drop one segment at a time, pretend we wrote a
          * segment. */
-        writelen = MIN (segsize, len);
+        sampleslen = MIN (sps, len);
         goto next;
       }
 
@@ -979,17 +979,18 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
 
     /* we can write now */
     writeseg = writeseg % segtotal;
-    writelen = MIN (segsize - writeoff, len);
+    sampleslen = MIN (sps - sampleoff, len);
 
     GST_DEBUG ("write @%p seg %d, off %d, len %d",
-        dest + writeseg * segsize, writeseg, writeoff, writelen);
+        dest + writeseg * segsize, writeseg, sampleoff, sampleslen);
 
-    memcpy (dest + writeseg * segsize + writeoff, data, writelen);
+    memcpy (dest + (writeseg * segsize) + (sampleoff * bps), data,
+        (sampleslen * bps));
 
   next:
-    len -= writelen;
-    data += writelen;
-    sample += writelen / bps;
+    len -= sampleslen;
+    sample += sampleslen;
+    data += sampleslen * bps;
   }
 
   return len;
@@ -1007,9 +1008,9 @@ not_started:
  * @buf: the #GstRingBuffer to read from
  * @sample: the sample position of the data
  * @data: where the data should be read
- * @len: the length of the data to read
+ * @len: the number of samples in data to read
  *
- * Read @length samples from the ringbuffer into the memory pointed 
+ * Read @len samples from the ringbuffer into the memory pointed 
  * to by @data.
  * The first sample should be read from position @sample in
  * the ringbuffer.
@@ -1040,15 +1041,15 @@ gst_ring_buffer_read (GstRingBuffer * buf, guint64 sample, guchar * data,
   bps = buf->spec.bytes_per_sample;
   sps = buf->samples_per_seg;
 
-  /* read enough bytes */
+  /* read enough samples */
   while (len > 0) {
-    gint readlen;
-    gint readseg, readoff;
+    gint sampleslen;
+    gint readseg, sampleoff;
 
     /* figure out the segment and the offset inside the segment where
      * the sample should be written. */
     readseg = sample / sps;
-    readoff = (sample % sps) * bps;
+    sampleoff = (sample % sps);
 
     while (TRUE) {
       gint diff;
@@ -1061,14 +1062,14 @@ gst_ring_buffer_read (GstRingBuffer * buf, guint64 sample, guchar * data,
 
       GST_DEBUG
           ("pointer at %d, sample %llu, read from %d-%d, len %d, diff %d, segtotal %d, segsize %d",
-          segdone, sample, readseg, readoff, len, diff, segtotal, segsize);
+          segdone, sample, readseg, sampleoff, len, diff, segtotal, segsize);
 
       /* segment too far ahead, we need to drop */
       if (diff < 0) {
         /* we need to drop one segment at a time, pretend we read an
          * empty segment. */
-        readlen = MIN (segsize, len);
-        memcpy (data, buf->empty_seg, readlen);
+        sampleslen = MIN (sps, len);
+        memcpy (data, buf->empty_seg, sampleslen * bps);
         goto next;
       }
 
@@ -1084,17 +1085,18 @@ gst_ring_buffer_read (GstRingBuffer * buf, guint64 sample, guchar * data,
 
     /* we can read now */
     readseg = readseg % segtotal;
-    readlen = MIN (segsize - readoff, len);
+    sampleslen = MIN (sps - sampleoff, len);
 
     GST_DEBUG ("read @%p seg %d, off %d, len %d",
-        dest + readseg * segsize, readseg, readoff, readlen);
+        dest + readseg * segsize, readseg, sampleoff, sampleslen);
 
-    memcpy (data, dest + readseg * segsize + readoff, readlen);
+    memcpy (data, dest + (readseg * segsize) + (sampleoff * bps),
+        (sampleslen * bps));
 
   next:
-    len -= readlen;
-    data += readlen;
-    sample += readlen / bps;
+    len -= sampleslen;
+    sample += sampleslen;
+    data += sampleslen * bps;
   }
 
   return len;