ext/alsa/: - add debugging info
authorThomas Vander Stichele <thomas@apestaart.org>
Thu, 8 Jul 2004 13:40:37 +0000 (13:40 +0000)
committerThomas Vander Stichele <thomas@apestaart.org>
Thu, 8 Jul 2004 13:40:37 +0000 (13:40 +0000)
Original commit message from CVS:
* ext/alsa/gstalsa.c: (gst_alsa_drain_audio):
* ext/alsa/gstalsasink.c: (gst_alsa_sink_flush_one_pad),
(gst_alsa_sink_check_event), (gst_alsa_sink_mmap),
(gst_alsa_sink_write), (gst_alsa_sink_loop):
* ext/alsa/gstalsasink.h:
- add debugging info
- clean up schizophrenia of data/buffer/event
- fix double event unref error

ChangeLog
ext/alsa/gstalsa.c
ext/alsa/gstalsasink.c
ext/alsa/gstalsasink.h

index ce0400c..462566e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2004-07-08  Thomas Vander Stichele  <thomas (at) apestaart (dot) org>
+
+       * ext/alsa/gstalsa.c: (gst_alsa_drain_audio):
+       * ext/alsa/gstalsasink.c: (gst_alsa_sink_flush_one_pad),
+       (gst_alsa_sink_check_event), (gst_alsa_sink_mmap),
+       (gst_alsa_sink_write), (gst_alsa_sink_loop):
+       * ext/alsa/gstalsasink.h:
+       - add debugging info
+       - clean up schizophrenia of data/buffer/event
+       - fix double event unref error
+
 2004-07-08  Wim Taymans  <wim@fluendo.com>
 
        * gst/playback/Makefile.am:
index ea5266c..1fbcbde 100644 (file)
@@ -1579,6 +1579,7 @@ gst_alsa_drain_audio (GstAlsa * this)
       break;
   }
 
+  GST_DEBUG ("stopped alsa");
   GST_FLAG_UNSET (this, GST_ALSA_RUNNING);
   return TRUE;
 }
index 1147f14..68adf93 100644 (file)
@@ -160,18 +160,21 @@ gst_alsa_sink_init (GstAlsaSink * sink)
 static inline void
 gst_alsa_sink_flush_one_pad (GstAlsaSink * sink, gint i)
 {
+  GST_DEBUG_OBJECT (sink, "flushing pad %d", i);
   switch (sink->behaviour[i]) {
     case 0:
-      if (sink->buf[i])
-        gst_data_unref (GST_DATA (sink->buf[i]));
-      sink->buf[i] = NULL;
-      sink->data[i] = NULL;
+      if (sink->gst_data[i]) {
+        GST_DEBUG_OBJECT (sink, "unreffing gst data %p", sink->gst_data[i]);
+        gst_data_unref (GST_DATA (sink->gst_data[i]));
+      }
+      sink->gst_data[i] = NULL;
+      sink->buf_data[i] = NULL;
       sink->behaviour[i] = 0;
       sink->size[i] = 0;
       break;
     case 1:
-      g_free (sink->data[i]);
-      sink->data[i] = NULL;
+      g_free (sink->buf_data[i]);
+      sink->buf_data[i] = NULL;
       sink->behaviour[i] = 0;
       sink->size[i] = 0;
       break;
@@ -196,9 +199,14 @@ static gboolean
 gst_alsa_sink_check_event (GstAlsaSink * sink, gint pad_nr)
 {
   gboolean cont = TRUE;
-  GstEvent *event = GST_EVENT (sink->buf[pad_nr]);
+  GstEvent *event;
   GstAlsa *this = GST_ALSA (sink);
 
+  /* we get the event from our internal buffer and clear the internal one */
+  event = GST_EVENT (sink->gst_data[pad_nr]);
+  sink->gst_data[pad_nr] = 0;
+  GST_LOG_OBJECT (sink, "checking event %p of type %d on sink pad %d",
+      event, GST_EVENT_TYPE (event), pad_nr);
   if (event) {
     switch (GST_EVENT_TYPE (event)) {
       case GST_EVENT_EOS:
@@ -241,8 +249,10 @@ gst_alsa_sink_check_event (GstAlsaSink * sink, gint pad_nr)
             GST_EVENT_TYPE (event));
         break;
     }
+    GST_LOG_OBJECT (sink, "unreffing event %p of type %d with refcount %d",
+        event, GST_EVENT_TYPE (event), GST_DATA_REFCOUNT (event));
     gst_event_unref (event);
-    sink->buf[pad_nr] = NULL;
+    sink->gst_data[pad_nr] = NULL;
   } else {
     /* the element at the top of the chain did not emit an event. */
     g_assert_not_reached ();
@@ -266,14 +276,14 @@ gst_alsa_sink_mmap (GstAlsa * this, snd_pcm_sframes_t * avail)
   if (((GstElement *) this)->numpads == 1) {
     /* interleaved */
     for (i = 0; i < this->format->channels; i++) {
-      src[i].addr = sink->data[0];
+      src[i].addr = sink->buf_data[0];
       src[i].first = i * width;
       src[i].step = this->format->channels * width;
     }
   } else {
     /* noninterleaved */
     for (i = 0; i < this->format->channels; i++) {
-      src[i].addr = sink->data[i];
+      src[i].addr = sink->buf_data[i];
       src[i].first = 0;
       src[i].step = width;
     }
@@ -309,11 +319,11 @@ gst_alsa_sink_write (GstAlsa * this, snd_pcm_sframes_t * avail)
 
   if (((GstElement *) this)->numpads == 1) {
     /* interleaved */
-    err = snd_pcm_writei (this->handle, sink->data[0], *avail);
+    err = snd_pcm_writei (this->handle, sink->buf_data[0], *avail);
   } else {
     /* noninterleaved */
     for (i = 0; i < this->format->channels; i++) {
-      channels[i] = sink->data[i];
+      channels[i] = sink->buf_data[i];
     }
     err = snd_pcm_writen (this->handle, channels, *avail);
   }
@@ -354,36 +364,47 @@ sink_restart:
     }
 
     /* check how many bytes we still have in all our bytestreams */
-    /* initialize this value to a somewhat sane state, we might alloc this much data below (which would be a bug, but who knows)... */
+    /* initialize this value to a somewhat sane state, we might alloc
+     * this much data below (which would be a bug, but who knows)... */
     bytes = this->period_size * this->period_count * element->numpads * 8;      /* must be > max sample size in bytes */
     for (i = 0; i < element->numpads; i++) {
+      GstBuffer *buf;
+
       g_assert (this->pad[i] != NULL);
       while (sink->size[i] == 0) {
-        if (!sink->buf[i])
-          sink->buf[i] = GST_BUFFER (gst_pad_pull (this->pad[i]));
-        if (GST_IS_EVENT (sink->buf[i])) {
+        if (!sink->gst_data[i]) {
+          sink->gst_data[i] = gst_pad_pull (this->pad[i]);
+          GST_LOG_OBJECT (sink, "pulled data %p from pad %d",
+              sink->gst_data[i], i);
+        }
+
+        if (GST_IS_EVENT (sink->gst_data[i])) {
+          GST_LOG_OBJECT (sink, "pulled data %p is an event, checking",
+              sink->gst_data[i]);
           if (gst_alsa_sink_check_event (sink, i))
             continue;
           return;
         }
-        /* caps nego failed somewhere */
+        /* it's a buffer */
+        g_return_if_fail (GST_IS_BUFFER (sink->gst_data[i]));
+        buf = GST_BUFFER (sink->gst_data[i]);
+        /* check if caps nego failed somewhere */
         if (this->format == NULL) {
           GST_ELEMENT_ERROR (this, CORE, NEGOTIATION, (NULL),
               ("ALSA format not negotiated"));
         }
-        samplestamp =
-            gst_alsa_timestamp_to_samples (this,
-            GST_BUFFER_TIMESTAMP (sink->buf[i]));
+        samplestamp = gst_alsa_timestamp_to_samples (this,
+            GST_BUFFER_TIMESTAMP (buf));
         max_discont = gst_alsa_timestamp_to_samples (this, this->max_discont);
         /* optimization: check if we're using our own clock
-         * This optimization is important because if we're using our own clock 
-         * gst_element_get_time calls snd_pcm_delay and the following code assumes
-         * that both calls return the same value. However they can be wildly 
-         * different, since snd_pcm_delay goes deep into the kernel.
+         * This optimization is important because if we're using our own clock
+         * gst_element_get_time calls snd_pcm_delay and the following code
+         * assumes that both calls return the same value. However they can be
+         * wildly different, since snd_pcm_delay goes deep into the kernel.
          */
         if (gst_element_get_clock (element) == GST_CLOCK (this->clock)) {
-          /* FIXME: this is ugly because of the variables it uses but I don't know a 
-           * better way to get this info */
+          /* FIXME: this is ugly because of the variables it uses but I
+           * don't know a better way to get this info */
           if (element->base_time > this->clock->start_time) {
             expected =
                 this->played - gst_alsa_timestamp_to_samples (this,
@@ -404,13 +425,13 @@ sink_restart:
         }
         sample_diff = samplestamp - expected;
 
-        if ((!GST_BUFFER_TIMESTAMP_IS_VALID (sink->buf[i])) ||
+        if ((!GST_BUFFER_TIMESTAMP_IS_VALID (buf)) ||
             (-max_discont <= sample_diff && sample_diff <= max_discont)) {
 
           /* difference between expected and current is < GST_ALSA_DEVIATION */
         no_difference:
-          sink->size[i] = sink->buf[i]->size;
-          sink->data[i] = sink->buf[i]->data;
+          sink->size[i] = GST_BUFFER_SIZE (buf);
+          sink->buf_data[i] = GST_BUFFER_DATA (buf);
           sink->behaviour[i] = 0;
         } else if (sample_diff > 0) {
           /* there are empty samples in front of us, fill them with silence */
@@ -422,28 +443,28 @@ sink_restart:
           GST_INFO_OBJECT (this,
               "Allocating %d bytes (%ld samples) now to resync: sample %lu expected, but got %ld",
               size, MIN (bytes, sample_diff), expected, samplestamp);
-          sink->data[i] = g_try_malloc (size);
-          if (!sink->data[i]) {
+          sink->buf_data[i] = g_try_malloc (size);
+          if (!sink->buf_data[i]) {
             GST_WARNING_OBJECT (this,
                 "error allocating %d bytes, buffers unsynced now.", size);
             goto no_difference;
           }
           sink->size[i] = size;
           if (0 != snd_pcm_format_set_silence (this->format->format,
-                  sink->data[i], samples)) {
+                  sink->buf_data[i], samples)) {
             GST_WARNING_OBJECT (this,
                 "error silencing buffer, enjoy the noise.");
           }
           sink->behaviour[i] = 1;
-        } else if (gst_alsa_samples_to_bytes (this,
-                -sample_diff) >= sink->buf[i]->size) {
+        } else if (gst_alsa_samples_to_bytes (this, -sample_diff) >=
+            GST_BUFFER_SIZE (buf)) {
           GST_INFO_OBJECT (this,
               "Skipping %lu samples to resync (complete buffer): sample %lu expected, but got %ld",
-              gst_alsa_bytes_to_samples (this, sink->buf[i]->size), expected,
+              gst_alsa_bytes_to_samples (this, GST_BUFFER_SIZE (buf)), expected,
               samplestamp);
           /* this buffer is way behind */
-          gst_buffer_unref (sink->buf[i]);
-          sink->buf[i] = NULL;
+          gst_buffer_unref (buf);
+          sink->gst_data[i] = NULL;
           continue;
         } else if (sample_diff < 0) {
           gint difference = gst_alsa_samples_to_bytes (this, -sample_diff);
@@ -452,8 +473,8 @@ sink_restart:
               "Skipping %lu samples to resync: sample %lu expected, but got %ld",
               (gulong) - sample_diff, expected, samplestamp);
           /* this buffer is only a bit behind */
-          sink->size[i] = sink->buf[i]->size - difference;
-          sink->data[i] = sink->buf[i]->data + difference;
+          sink->size[i] = GST_BUFFER_SIZE (buf) - difference;
+          sink->buf_data[i] = GST_BUFFER_DATA (buf) + difference;
           sink->behaviour[i] = 0;
         } else {
           g_assert_not_reached ();
@@ -479,7 +500,8 @@ sink_restart:
         return;
     }
 
-    /* FIXME: lotsa stuff can have happened while fetching data. Do we need to check something? */
+    /* FIXME: lotsa stuff can have happened while fetching data.
+     * Do we need to check something? */
 
     /* put this data into alsa */
     if ((copied = this->transmit (this, &avail)) < 0)
@@ -495,7 +517,7 @@ sink_restart:
       }
       g_assert (sink->size[i] > 0);
       if (sink->behaviour[i] != 1)
-        sink->data[i] += bytes;
+        sink->buf_data[i] += bytes;
     }
   }
 
index c6e2bf3..b032916 100644 (file)
@@ -39,9 +39,9 @@ struct _GstAlsaSink {
   GstAlsaMixer parent;
 
   /* array of the data on the channels */
-  guint8    *data[GST_ALSA_MAX_TRACKS];      /* pointer into buffer */
+  guint8    *buf_data[GST_ALSA_MAX_TRACKS];  /* pointer into buffer */
   guint      size[GST_ALSA_MAX_TRACKS];      /* sink: bytes left in buffer */
-  GstBuffer *buf[GST_ALSA_MAX_TRACKS];       /* current buffer */
+  GstData   *gst_data[GST_ALSA_MAX_TRACKS];  /* current data */
   guint      behaviour[GST_ALSA_MAX_TRACKS]; /* 0 = data points into buffer (so unref when size == 0),
                                                   1 = data should be freed, use buffer after that */
 };