[gst-cvs] CVS: gstreamer/plugins/alsa alsa.c,1.11,1.12

Andy Wingo wingo at users.sourceforge.net
Fri Oct 26 18:30:11 PDT 2001


Update of /cvsroot/gstreamer/gstreamer/plugins/alsa
In directory usw-pr-cvs1:/tmp/cvs-serv4006

Modified Files:
	alsa.c 
Log Message:
* preliminary event support on alsasink.
* implementation of the "paused" state.


Index: alsa.c
===================================================================
RCS file: /cvsroot/gstreamer/gstreamer/plugins/alsa/alsa.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- alsa.c	2001/10/26 20:41:21	1.11
+++ alsa.c	2001/10/27 01:29:47	1.12
@@ -463,25 +463,44 @@
 gst_alsa_change_state(GstElement *element)
 {
     GstAlsa *this;
+    guint chn;
     
     g_return_val_if_fail(element != NULL, FALSE);
     this = GST_ALSA (element);
-
-    if (GST_STATE_PENDING(element) == GST_STATE_NULL) {
+    
+    switch (GST_STATE_PENDING(element)) {
+    case GST_STATE_NULL:
         if (GST_FLAG_IS_SET(element, GST_ALSA_RUNNING))
             gst_alsa_stop_audio((GstAlsa *)element);
         if (GST_FLAG_IS_SET(element, GST_ALSA_OPEN))
             gst_alsa_close_audio((GstAlsa *)element);
         /* FIXME: clean up bytestreams, etc */
-    } else if (GST_STATE_PENDING(element) == GST_STATE_PLAYING) {
+        break;
+        
+    case GST_STATE_READY:
+        break;
+        
+    case GST_STATE_PAUSED:
         if (GST_FLAG_IS_SET(element, GST_ALSA_OPEN) == FALSE)
             if (gst_alsa_open_audio((GstAlsa *)element) == FALSE)
                 return GST_STATE_FAILURE;
+        if (GST_FLAG_IS_SET(element, GST_ALSA_RUNNING)) {
+            if (this->stream == SND_PCM_STREAM_PLAYBACK) {
+                for (chn = 0; chn < this->channels; chn++) {
+                    gst_alsa_sink_silence_on_channel (this, chn, this->buffer_frames);
+                }
+            }
+            gst_alsa_stop_audio((GstAlsa *)element);
+        }
+        break;
+        
+    case GST_STATE_PLAYING:
         if (GST_FLAG_IS_SET(element, GST_ALSA_RUNNING) == FALSE)
             if (gst_alsa_start_audio((GstAlsa *)element) == FALSE)
                 return GST_STATE_FAILURE;
+        break;
     }
-
+    
     if (GST_ELEMENT_CLASS(parent_class)->change_state)
         return GST_ELEMENT_CLASS(parent_class)->change_state(element);
 
@@ -832,8 +851,10 @@
                 g_warning("alsa: something happened while processing audio");
                 return;
             }
-        
-            gst_alsa_release_channel_addresses(this);
+            
+            /* we could have released the mmap regions on a state change */
+            if (this->mmap_open)
+                gst_alsa_release_channel_addresses(this);
         }
     } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
 }
@@ -916,7 +937,8 @@
 gst_alsa_sink_process (GstAlsa *this, snd_pcm_uframes_t frames)
 {
     guint8 *peeked;
-    guint32 len;
+    guint32 len, avail;
+    GstEvent *event = NULL;
     GList *l;
     
     /* this is necessary because the sample_bytes will change, probably, when
@@ -928,7 +950,11 @@
         if (!GST_ALSA_PAD(this->pads)->bs)
             GST_ALSA_PAD(this->pads)->bs = gst_bytestream_new(GST_ALSA_PAD(this->pads)->pad);
         
-        peeked = gst_bytestream_peek_bytes(GST_ALSA_PAD(this->pads)->bs, frames);
+        if (!(peeked = gst_bytestream_peek_bytes(GST_ALSA_PAD(this->pads)->bs, frames))) {
+            g_warning("initial pull on pad %s returned NULL", GST_OBJECT_NAME(GST_ALSA_PAD(this->pads)->pad));
+            gst_element_set_state(GST_ELEMENT(this), GST_STATE_PAUSED);
+            return FALSE;
+        }
         
         if (!this->sample_bytes) {
             g_critical ("alsa plugin requires a pipeline that can adequately set caps.");
@@ -943,7 +969,26 @@
         if (!GST_ALSA_PAD(this->pads)->bs)
             GST_ALSA_PAD(this->pads)->bs = gst_bytestream_new(GST_ALSA_PAD(this->pads)->pad);
         
-        peeked = gst_bytestream_peek_bytes(GST_ALSA_PAD(this->pads)->bs, len);
+        if (!(peeked = gst_bytestream_peek_bytes(GST_ALSA_PAD(this->pads)->bs, len))) {
+            gst_bytestream_get_status(GST_ALSA_PAD(this->pads)->bs, &avail, &event);
+            if (event) {
+                g_warning("got an event on alsasink");
+                if (GST_EVENT_TYPE(event) == GST_EVENT_EOS) {
+                    /* really, we should just cut this pad out of the graph. let
+                     * me know when this is needed ;)
+                     * also, for sample accuracy etc, we should play avail
+                     * bytes, but hey. */
+                    gst_element_set_state(GST_ELEMENT(this), GST_STATE_PAUSED);
+                    gst_event_free(event);
+                    return TRUE;
+                }
+            } else {
+                /* the element at the top of the chain did not emit an eos
+                 * event. this is a Bug(tm) */
+                g_assert_not_reached();
+            }
+        }
+        
         memcpy(GST_ALSA_PAD(this->pads)->access_addr, peeked, len);
         gst_bytestream_flush(GST_ALSA_PAD(this->pads)->bs, len);
         





More information about the Gstreamer-commits mailing list