From: Andy W. <wi...@us...> - 2001-10-27 01:29:50
|
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); |