playsink/streamsynchronizer: Remove and deactivate pads after calling the change_state function of the parent class

Fixes some deadlocks.
This commit is contained in:
Sebastian Dröge 2010-07-16 18:51:35 +02:00
parent 1605bef4b9
commit a16024d9fb
2 changed files with 42 additions and 44 deletions

View file

@ -3078,36 +3078,7 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition)
do_async_start (playsink); do_async_start (playsink);
ret = GST_STATE_CHANGE_ASYNC; ret = GST_STATE_CHANGE_ASYNC;
break; break;
case GST_STATE_CHANGE_PAUSED_TO_READY:{ case GST_STATE_CHANGE_PAUSED_TO_READY:
if (playsink->video_sinkpad_stream_synchronizer) {
gst_element_release_request_pad (GST_ELEMENT_CAST
(playsink->stream_synchronizer),
playsink->video_sinkpad_stream_synchronizer);
gst_object_unref (playsink->video_sinkpad_stream_synchronizer);
playsink->video_sinkpad_stream_synchronizer = NULL;
gst_object_unref (playsink->video_srcpad_stream_synchronizer);
playsink->video_srcpad_stream_synchronizer = NULL;
}
if (playsink->audio_sinkpad_stream_synchronizer) {
gst_element_release_request_pad (GST_ELEMENT_CAST
(playsink->stream_synchronizer),
playsink->audio_sinkpad_stream_synchronizer);
gst_object_unref (playsink->audio_sinkpad_stream_synchronizer);
playsink->audio_sinkpad_stream_synchronizer = NULL;
gst_object_unref (playsink->audio_srcpad_stream_synchronizer);
playsink->audio_srcpad_stream_synchronizer = NULL;
}
if (playsink->text_sinkpad_stream_synchronizer) {
gst_element_release_request_pad (GST_ELEMENT_CAST
(playsink->stream_synchronizer),
playsink->text_sinkpad_stream_synchronizer);
gst_object_unref (playsink->text_sinkpad_stream_synchronizer);
playsink->text_sinkpad_stream_synchronizer = NULL;
gst_object_unref (playsink->text_srcpad_stream_synchronizer);
playsink->text_srcpad_stream_synchronizer = NULL;
}
}
/* fall through */
case GST_STATE_CHANGE_READY_TO_NULL: case GST_STATE_CHANGE_READY_TO_NULL:
if (playsink->audiochain && playsink->audiochain->sink_volume) { if (playsink->audiochain && playsink->audiochain->sink_volume) {
/* remove our links to the mute and volume elements when they were /* remove our links to the mute and volume elements when they were
@ -3157,7 +3128,36 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition)
/* FIXME Release audio device when we implement that */ /* FIXME Release audio device when we implement that */
playsink->need_async_start = TRUE; playsink->need_async_start = TRUE;
break; break;
case GST_STATE_CHANGE_PAUSED_TO_READY: case GST_STATE_CHANGE_PAUSED_TO_READY:{
if (playsink->video_sinkpad_stream_synchronizer) {
gst_element_release_request_pad (GST_ELEMENT_CAST
(playsink->stream_synchronizer),
playsink->video_sinkpad_stream_synchronizer);
gst_object_unref (playsink->video_sinkpad_stream_synchronizer);
playsink->video_sinkpad_stream_synchronizer = NULL;
gst_object_unref (playsink->video_srcpad_stream_synchronizer);
playsink->video_srcpad_stream_synchronizer = NULL;
}
if (playsink->audio_sinkpad_stream_synchronizer) {
gst_element_release_request_pad (GST_ELEMENT_CAST
(playsink->stream_synchronizer),
playsink->audio_sinkpad_stream_synchronizer);
gst_object_unref (playsink->audio_sinkpad_stream_synchronizer);
playsink->audio_sinkpad_stream_synchronizer = NULL;
gst_object_unref (playsink->audio_srcpad_stream_synchronizer);
playsink->audio_srcpad_stream_synchronizer = NULL;
}
if (playsink->text_sinkpad_stream_synchronizer) {
gst_element_release_request_pad (GST_ELEMENT_CAST
(playsink->stream_synchronizer),
playsink->text_sinkpad_stream_synchronizer);
gst_object_unref (playsink->text_sinkpad_stream_synchronizer);
playsink->text_sinkpad_stream_synchronizer = NULL;
gst_object_unref (playsink->text_srcpad_stream_synchronizer);
playsink->text_srcpad_stream_synchronizer = NULL;
}
}
/* fall through */
case GST_STATE_CHANGE_READY_TO_NULL: case GST_STATE_CHANGE_READY_TO_NULL:
/* remove sinks we added */ /* remove sinks we added */
if (playsink->videodeinterlacechain) { if (playsink->videodeinterlacechain) {

View file

@ -417,7 +417,8 @@ gst_stream_synchronizer_sink_event (GstPad * pad, GstEvent * event)
GST_TIME_ARGS (stream->segment.accum)); GST_TIME_ARGS (stream->segment.accum));
stream->running_time_diff = stream->segment.accum; stream->running_time_diff = stream->segment.accum;
} else if (stream) { } else if (stream) {
GST_ERROR_OBJECT (pad, "Non-TIME segment"); GST_WARNING_OBJECT (pad, "Non-TIME segment: %s",
gst_format_get_name (format));
gst_segment_init (&stream->segment, GST_FORMAT_UNDEFINED); gst_segment_init (&stream->segment, GST_FORMAT_UNDEFINED);
} }
GST_STREAM_SYNCHRONIZER_UNLOCK (self); GST_STREAM_SYNCHRONIZER_UNLOCK (self);
@ -634,8 +635,8 @@ gst_stream_synchronizer_release_stream (GstStreamSynchronizer * self,
gst_pad_set_element_private (stream->srcpad, NULL); gst_pad_set_element_private (stream->srcpad, NULL);
gst_pad_set_element_private (stream->sinkpad, NULL); gst_pad_set_element_private (stream->sinkpad, NULL);
gst_pad_set_active (stream->srcpad, FALSE); gst_pad_set_active (stream->srcpad, FALSE);
gst_pad_set_active (stream->sinkpad, FALSE);
gst_element_remove_pad (GST_ELEMENT_CAST (self), stream->srcpad); gst_element_remove_pad (GST_ELEMENT_CAST (self), stream->srcpad);
gst_pad_set_active (stream->sinkpad, FALSE);
gst_element_remove_pad (GST_ELEMENT_CAST (self), stream->sinkpad); gst_element_remove_pad (GST_ELEMENT_CAST (self), stream->sinkpad);
if (stream->segment.format == GST_FORMAT_TIME) { if (stream->segment.format == GST_FORMAT_TIME) {
@ -689,21 +690,11 @@ gst_stream_synchronizer_change_state (GstElement * element,
break; break;
case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_READY_TO_PAUSED:
GST_DEBUG_OBJECT (self, "State change READY->PAUSED"); GST_DEBUG_OBJECT (self, "State change READY->PAUSED");
self->group_start_time = 0;
break; break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING: case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
GST_DEBUG_OBJECT (self, "State change PAUSED->PLAYING"); GST_DEBUG_OBJECT (self, "State change PAUSED->PLAYING");
break; break;
case GST_STATE_CHANGE_READY_TO_NULL:{
GST_DEBUG_OBJECT (self, "State change READY->NULL");
GST_STREAM_SYNCHRONIZER_LOCK (self);
g_cond_broadcast (self->stream_finish_cond);
while (self->streams)
gst_stream_synchronizer_release_stream (self, self->streams->data);
self->current_stream_number = 0;
GST_STREAM_SYNCHRONIZER_UNLOCK (self);
break;
}
default: default:
break; break;
} }
@ -741,6 +732,13 @@ gst_stream_synchronizer_change_state (GstElement * element,
} }
case GST_STATE_CHANGE_READY_TO_NULL:{ case GST_STATE_CHANGE_READY_TO_NULL:{
GST_DEBUG_OBJECT (self, "State change READY->NULL"); GST_DEBUG_OBJECT (self, "State change READY->NULL");
GST_STREAM_SYNCHRONIZER_LOCK (self);
g_cond_broadcast (self->stream_finish_cond);
while (self->streams)
gst_stream_synchronizer_release_stream (self, self->streams->data);
self->current_stream_number = 0;
GST_STREAM_SYNCHRONIZER_UNLOCK (self);
break; break;
} }
default: default: