mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
ext/pulse/pulsesink.*: Use a mutex to protect the current stream pointer, and ignore callbacks for stream objects tha...
Original commit message from CVS: * ext/pulse/pulsesink.c: * ext/pulse/pulsesink.h: Use a mutex to protect the current stream pointer, and ignore callbacks for stream objects that have been destroyed already. Fixes problems with unprepare/prepare cycles caused by the input caps changing, without reintroducing bug #556986.
This commit is contained in:
parent
90e9d8e0e1
commit
3e380b488d
3 changed files with 43 additions and 5 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2009-01-07 Jan Schmidt <jan.schmidt@sun.com>
|
||||||
|
|
||||||
|
* ext/pulse/pulsesink.c:
|
||||||
|
* ext/pulse/pulsesink.h:
|
||||||
|
Use a mutex to protect the current stream pointer, and ignore
|
||||||
|
callbacks for stream objects that have been destroyed already.
|
||||||
|
Fixes problems with unprepare/prepare cycles caused by the input
|
||||||
|
caps changing, without reintroducing bug #556986.
|
||||||
|
|
||||||
2009-01-07 Jan Schmidt <jan.schmidt@sun.com>
|
2009-01-07 Jan Schmidt <jan.schmidt@sun.com>
|
||||||
|
|
||||||
* sys/v4l2/gstv4l2src.c:
|
* sys/v4l2/gstv4l2src.c:
|
||||||
|
|
|
@ -264,6 +264,8 @@ gst_pulsesink_init (GstPulseSink * pulsesink, GstPulseSinkClass * klass)
|
||||||
pulsesink->context = NULL;
|
pulsesink->context = NULL;
|
||||||
pulsesink->stream = NULL;
|
pulsesink->stream = NULL;
|
||||||
|
|
||||||
|
pulsesink->stream_mutex = g_mutex_new ();
|
||||||
|
|
||||||
pulsesink->mainloop = pa_threaded_mainloop_new ();
|
pulsesink->mainloop = pa_threaded_mainloop_new ();
|
||||||
g_assert (pulsesink->mainloop);
|
g_assert (pulsesink->mainloop);
|
||||||
|
|
||||||
|
@ -277,11 +279,13 @@ gst_pulsesink_init (GstPulseSink * pulsesink, GstPulseSinkClass * klass)
|
||||||
static void
|
static void
|
||||||
gst_pulsesink_destroy_stream (GstPulseSink * pulsesink)
|
gst_pulsesink_destroy_stream (GstPulseSink * pulsesink)
|
||||||
{
|
{
|
||||||
|
g_mutex_lock (pulsesink->stream_mutex);
|
||||||
if (pulsesink->stream) {
|
if (pulsesink->stream) {
|
||||||
pa_stream_disconnect (pulsesink->stream);
|
pa_stream_disconnect (pulsesink->stream);
|
||||||
pa_stream_unref (pulsesink->stream);
|
pa_stream_unref (pulsesink->stream);
|
||||||
pulsesink->stream = NULL;
|
pulsesink->stream = NULL;
|
||||||
}
|
}
|
||||||
|
g_mutex_unlock (pulsesink->stream_mutex);
|
||||||
|
|
||||||
g_free (pulsesink->stream_name);
|
g_free (pulsesink->stream_name);
|
||||||
pulsesink->stream_name = NULL;
|
pulsesink->stream_name = NULL;
|
||||||
|
@ -290,7 +294,6 @@ gst_pulsesink_destroy_stream (GstPulseSink * pulsesink)
|
||||||
static void
|
static void
|
||||||
gst_pulsesink_destroy_context (GstPulseSink * pulsesink)
|
gst_pulsesink_destroy_context (GstPulseSink * pulsesink)
|
||||||
{
|
{
|
||||||
|
|
||||||
gst_pulsesink_destroy_stream (pulsesink);
|
gst_pulsesink_destroy_stream (pulsesink);
|
||||||
|
|
||||||
if (pulsesink->context) {
|
if (pulsesink->context) {
|
||||||
|
@ -313,6 +316,8 @@ gst_pulsesink_finalize (GObject * object)
|
||||||
g_free (pulsesink->device);
|
g_free (pulsesink->device);
|
||||||
g_free (pulsesink->stream_name);
|
g_free (pulsesink->stream_name);
|
||||||
|
|
||||||
|
g_mutex_free (pulsesink->stream_mutex);
|
||||||
|
|
||||||
pa_threaded_mainloop_free (pulsesink->mainloop);
|
pa_threaded_mainloop_free (pulsesink->mainloop);
|
||||||
|
|
||||||
if (pulsesink->probe) {
|
if (pulsesink->probe) {
|
||||||
|
@ -482,8 +487,16 @@ gst_pulsesink_stream_state_cb (pa_stream * s, void *userdata)
|
||||||
|
|
||||||
case PA_STREAM_READY:
|
case PA_STREAM_READY:
|
||||||
case PA_STREAM_FAILED:
|
case PA_STREAM_FAILED:
|
||||||
case PA_STREAM_TERMINATED:
|
case PA_STREAM_TERMINATED:{
|
||||||
|
pa_stream *cur_stream;
|
||||||
|
|
||||||
|
g_mutex_lock (pulsesink->stream_mutex);
|
||||||
|
cur_stream = pulsesink->stream;
|
||||||
|
g_mutex_unlock (pulsesink->stream_mutex);
|
||||||
|
|
||||||
|
if (cur_stream == s)
|
||||||
pa_threaded_mainloop_signal (pulsesink->mainloop, 0);
|
pa_threaded_mainloop_signal (pulsesink->mainloop, 0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PA_STREAM_UNCONNECTED:
|
case PA_STREAM_UNCONNECTED:
|
||||||
|
@ -496,7 +509,13 @@ static void
|
||||||
gst_pulsesink_stream_request_cb (pa_stream * s, size_t length, void *userdata)
|
gst_pulsesink_stream_request_cb (pa_stream * s, size_t length, void *userdata)
|
||||||
{
|
{
|
||||||
GstPulseSink *pulsesink = GST_PULSESINK (userdata);
|
GstPulseSink *pulsesink = GST_PULSESINK (userdata);
|
||||||
|
pa_stream *cur_stream;
|
||||||
|
|
||||||
|
g_mutex_lock (pulsesink->stream_mutex);
|
||||||
|
cur_stream = pulsesink->stream;
|
||||||
|
g_mutex_unlock (pulsesink->stream_mutex);
|
||||||
|
|
||||||
|
if (cur_stream == s)
|
||||||
pa_threaded_mainloop_signal (pulsesink->mainloop, 0);
|
pa_threaded_mainloop_signal (pulsesink->mainloop, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,7 +523,13 @@ static void
|
||||||
gst_pulsesink_stream_latency_update_cb (pa_stream * s, void *userdata)
|
gst_pulsesink_stream_latency_update_cb (pa_stream * s, void *userdata)
|
||||||
{
|
{
|
||||||
GstPulseSink *pulsesink = GST_PULSESINK (userdata);
|
GstPulseSink *pulsesink = GST_PULSESINK (userdata);
|
||||||
|
pa_stream *cur_stream;
|
||||||
|
|
||||||
|
g_mutex_lock (pulsesink->stream_mutex);
|
||||||
|
cur_stream = pulsesink->stream;
|
||||||
|
g_mutex_unlock (pulsesink->stream_mutex);
|
||||||
|
|
||||||
|
if (cur_stream == s)
|
||||||
pa_threaded_mainloop_signal (pulsesink->mainloop, 0);
|
pa_threaded_mainloop_signal (pulsesink->mainloop, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,15 +617,18 @@ gst_pulsesink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
|
||||||
goto unlock_and_fail;
|
goto unlock_and_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_mutex_lock (pulsesink->stream_mutex);
|
||||||
if (!(pulsesink->stream = pa_stream_new (pulsesink->context,
|
if (!(pulsesink->stream = pa_stream_new (pulsesink->context,
|
||||||
pulsesink->stream_name ? pulsesink->
|
pulsesink->stream_name ? pulsesink->
|
||||||
stream_name : "Playback Stream", &pulsesink->sample_spec,
|
stream_name : "Playback Stream", &pulsesink->sample_spec,
|
||||||
gst_pulse_gst_to_channel_map (&channel_map, spec)))) {
|
gst_pulse_gst_to_channel_map (&channel_map, spec)))) {
|
||||||
|
g_mutex_unlock (pulsesink->stream_mutex);
|
||||||
GST_ELEMENT_ERROR (pulsesink, RESOURCE, FAILED,
|
GST_ELEMENT_ERROR (pulsesink, RESOURCE, FAILED,
|
||||||
("Failed to create stream: %s",
|
("Failed to create stream: %s",
|
||||||
pa_strerror (pa_context_errno (pulsesink->context))), (NULL));
|
pa_strerror (pa_context_errno (pulsesink->context))), (NULL));
|
||||||
goto unlock_and_fail;
|
goto unlock_and_fail;
|
||||||
}
|
}
|
||||||
|
g_mutex_unlock (pulsesink->stream_mutex);
|
||||||
|
|
||||||
pa_stream_set_state_callback (pulsesink->stream,
|
pa_stream_set_state_callback (pulsesink->stream,
|
||||||
gst_pulsesink_stream_state_cb, pulsesink);
|
gst_pulsesink_stream_state_cb, pulsesink);
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct _GstPulseSink
|
||||||
|
|
||||||
pa_context *context;
|
pa_context *context;
|
||||||
pa_stream *stream;
|
pa_stream *stream;
|
||||||
|
GMutex *stream_mutex;
|
||||||
|
|
||||||
pa_sample_spec sample_spec;
|
pa_sample_spec sample_spec;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue