playsink: keep both raw and non raw pipelines at all times

and switch between them as needed.

https://bugzilla.gnome.org/show_bug.cgi?id=661262
This commit is contained in:
Vincent Penquerc'h 2011-10-17 17:26:48 +00:00 committed by Sebastian Dröge
parent 69d98d08c1
commit 6925c02bc2

View file

@ -137,18 +137,21 @@ gst_play_sink_convert_bin_add_identity (GstPlaySinkConvertBin * self)
); );
} else { } else {
gst_bin_add (GST_BIN_CAST (self), self->identity); gst_bin_add (GST_BIN_CAST (self), self->identity);
gst_element_sync_state_with_parent (self->identity);
distribute_running_time (self->identity, &self->segment);
} }
} }
static void static void
gst_play_sink_convert_bin_set_targets (GstPlaySinkConvertBin * self) gst_play_sink_convert_bin_set_targets (GstPlaySinkConvertBin * self,
gboolean passthrough)
{ {
GstPad *pad; GstPad *pad;
GstElement *head, *tail; GstElement *head, *tail;
if (self->conversion_elements == NULL) { if (self->conversion_elements == NULL || passthrough) {
if (!passthrough) {
GST_WARNING_OBJECT (self,
"Doing passthrough as no converter elements were added");
}
head = tail = self->identity; head = tail = self->identity;
} else { } else {
head = GST_ELEMENT (g_list_first (self->conversion_elements)->data); head = GST_ELEMENT (g_list_first (self->conversion_elements)->data);
@ -208,45 +211,23 @@ pad_blocked_cb (GstPad * pad, gboolean blocked, GstPlaySinkConvertBin * self)
goto unblock; goto unblock;
self->raw = raw; self->raw = raw;
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->sinkpad), NULL);
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL);
if (raw) { if (raw) {
GST_DEBUG_OBJECT (self, "Creating raw conversion pipeline"); GST_DEBUG_OBJECT (self, "Switching to raw conversion pipeline");
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->sinkpad), NULL);
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL);
g_assert (self->add_conversion_elements);
if (!(*self->add_conversion_elements) (self)) {
goto link_failed;
}
if (self->conversion_elements) if (self->conversion_elements)
g_list_foreach (self->conversion_elements, g_list_foreach (self->conversion_elements,
(GFunc) gst_play_sink_convert_bin_on_element_added, self); (GFunc) gst_play_sink_convert_bin_on_element_added, self);
GST_DEBUG_OBJECT (self, "Raw conversion pipeline created");
} else { } else {
GST_DEBUG_OBJECT (self, "Removing raw conversion pipeline"); GST_DEBUG_OBJECT (self, "Switch to passthrough pipeline");
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->sinkpad), NULL); gst_play_sink_convert_bin_on_element_added (self->identity, self);
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL);
if (self->conversion_elements) {
g_list_foreach (self->conversion_elements,
(GFunc) gst_play_sink_convert_bin_remove_element, self);
g_list_free (self->conversion_elements);
self->conversion_elements = NULL;
}
GST_DEBUG_OBJECT (self, "Raw conversion pipeline removed");
} }
/* to make things simple and avoid counterintuitive pad juggling, gst_play_sink_convert_bin_set_targets (self, !raw);
ensure there is at least one element in the list */
if (!self->conversion_elements) {
gst_play_sink_convert_bin_add_identity (self);
}
gst_play_sink_convert_bin_set_targets (self);
unblock: unblock:
gst_pad_set_blocked_async_full (self->sink_proxypad, FALSE, gst_pad_set_blocked_async_full (self->sink_proxypad, FALSE,
@ -256,23 +237,6 @@ unblock:
done: done:
GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self); GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
return; return;
link_failed:
{
GST_ELEMENT_ERROR (self, CORE, PAD,
(NULL), ("Failed to configure the converter bin."));
/* use a simple identity, better than nothing */
gst_play_sink_convert_bin_add_identity (self);
gst_play_sink_convert_bin_set_targets (self);
gst_pad_set_blocked_async_full (self->sink_proxypad, FALSE,
(GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self),
(GDestroyNotify) gst_object_unref);
GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
return;
}
} }
static gboolean static gboolean
@ -430,6 +394,16 @@ gst_play_sink_convert_bin_change_state (GstElement * element,
GstPlaySinkConvertBin *self = GST_PLAY_SINK_CONVERT_BIN_CAST (element); GstPlaySinkConvertBin *self = GST_PLAY_SINK_CONVERT_BIN_CAST (element);
switch (transition) { switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
g_assert (self->add_conversion_elements);
if (!(*self->add_conversion_elements) (self)) {
GST_ELEMENT_ERROR (self, CORE, PAD,
(NULL), ("Failed to configure the converter bin."));
}
gst_play_sink_convert_bin_add_identity (self);
GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
break;
case GST_STATE_CHANGE_PAUSED_TO_READY: case GST_STATE_CHANGE_PAUSED_TO_READY:
GST_PLAY_SINK_CONVERT_BIN_LOCK (self); GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
if (gst_pad_is_blocked (self->sink_proxypad)) if (gst_pad_is_blocked (self->sink_proxypad))
@ -450,16 +424,7 @@ gst_play_sink_convert_bin_change_state (GstElement * element,
case GST_STATE_CHANGE_PAUSED_TO_READY: case GST_STATE_CHANGE_PAUSED_TO_READY:
GST_PLAY_SINK_CONVERT_BIN_LOCK (self); GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED); gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);
if (self->conversion_elements) { gst_play_sink_convert_bin_set_targets (self, TRUE);
g_list_foreach (self->conversion_elements,
(GFunc) gst_play_sink_convert_bin_remove_element, self);
g_list_free (self->conversion_elements);
self->conversion_elements = NULL;
}
if (!self->identity) {
gst_play_sink_convert_bin_add_identity (self);
}
gst_play_sink_convert_bin_set_targets (self);
self->raw = FALSE; self->raw = FALSE;
GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self); GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
break; break;
@ -472,11 +437,19 @@ gst_play_sink_convert_bin_change_state (GstElement * element,
GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self); GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
break; break;
case GST_STATE_CHANGE_READY_TO_NULL: case GST_STATE_CHANGE_READY_TO_NULL:
GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
if (self->conversion_elements) {
g_list_foreach (self->conversion_elements,
(GFunc) gst_play_sink_convert_bin_remove_element, self);
g_list_free (self->conversion_elements);
self->conversion_elements = NULL;
}
if (self->identity) { if (self->identity) {
gst_element_set_state (self->identity, GST_STATE_NULL); gst_element_set_state (self->identity, GST_STATE_NULL);
gst_bin_remove (GST_BIN_CAST (self), self->identity); gst_bin_remove (GST_BIN_CAST (self), self->identity);
self->identity = NULL; self->identity = NULL;
} }
GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);
break; break;
default: default:
break; break;