gst/playback/gstplaybasebin.c: Don't block for streams.

Original commit message from CVS:
* gst/playback/gstplaybasebin.c: (group_commit),
(gen_preroll_element), (probe_triggered), (gen_source_element),
(setup_source), (gst_play_base_bin_change_state),
(gst_play_base_bin_add_element):
Don't block for streams.
* gst/playback/gststreaminfo.c: (stream_info_change_state),
(gst_stream_info_set_mute):
Use gst_pad_set_active_recursive.
This commit is contained in:
Ronald S. Bultje 2005-01-25 10:51:48 +00:00
parent 180b4346fd
commit e62a79939e
3 changed files with 93 additions and 91 deletions

View file

@ -1,3 +1,14 @@
2005-01-25 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* gst/playback/gstplaybasebin.c: (group_commit),
(gen_preroll_element), (probe_triggered), (gen_source_element),
(setup_source), (gst_play_base_bin_change_state),
(gst_play_base_bin_add_element):
Don't block for streams.
* gst/playback/gststreaminfo.c: (stream_info_change_state),
(gst_stream_info_set_mute):
Use gst_pad_set_active_recursive.
2005-01-25 Andy Wingo <wingo@pobox.com> 2005-01-25 Andy Wingo <wingo@pobox.com>
* sys/v4l/gstv4lelement.c (gst_v4l_iface_supported): Fix compile * sys/v4l/gstv4lelement.c (gst_v4l_iface_supported): Fix compile

View file

@ -373,6 +373,7 @@ static void
group_commit (GstPlayBaseBin * play_base_bin, gboolean fatal) group_commit (GstPlayBaseBin * play_base_bin, gboolean fatal)
{ {
GstPlayBaseGroup *group = play_base_bin->building_group; GstPlayBaseGroup *group = play_base_bin->building_group;
gboolean had_active_group = (get_active_group (play_base_bin) != NULL);
/* if an element signalled a no-more-pads after we stopped due /* if an element signalled a no-more-pads after we stopped due
* to preroll, the group is NULL. This is not an error */ * to preroll, the group is NULL. This is not an error */
@ -414,6 +415,14 @@ group_commit (GstPlayBaseBin * play_base_bin, gboolean fatal)
g_cond_signal (play_base_bin->group_cond); g_cond_signal (play_base_bin->group_cond);
GST_DEBUG ("signaled group done"); GST_DEBUG ("signaled group done");
g_mutex_unlock (play_base_bin->group_lock); g_mutex_unlock (play_base_bin->group_lock);
if (!had_active_group && GST_STATE (play_base_bin) > GST_STATE_READY) {
setup_substreams (play_base_bin);
GST_DEBUG ("Emitting signal");
g_signal_emit (play_base_bin,
gst_play_base_bin_signals[SETUP_OUTPUT_PADS_SIGNAL], 0);
GST_DEBUG ("done");
}
} }
/* check if there are streams in the group that are not muted */ /* check if there are streams in the group that are not muted */
@ -504,7 +513,12 @@ gen_preroll_element (GstPlayBaseBin * play_base_bin,
gst_bin_add (GST_BIN (play_base_bin->thread), preroll); gst_bin_add (GST_BIN (play_base_bin->thread), preroll);
gst_element_set_state (selector, GST_STATE_PLAYING); gst_element_set_state (selector, GST_STATE_PLAYING);
} }
gst_element_set_state (preroll, GST_STATE_PAUSED); if (GST_STATE (play_base_bin) == GST_STATE_PLAYING &&
!get_active_group (play_base_bin)) {
gst_element_set_state (preroll, GST_STATE_PLAYING);
} else {
gst_element_set_state (preroll, GST_STATE_PAUSED);
}
play_base_bin->threaded = TRUE; play_base_bin->threaded = TRUE;
} }
@ -648,15 +662,6 @@ probe_triggered (GstProbe * probe, GstData ** data, gpointer user_data)
} }
if (have_left) { if (have_left) {
g_mutex_lock (play_base_bin->group_lock);
while (g_list_length (play_base_bin->queued_groups) < 2 &&
GST_STATE (play_base_bin->thread) == GST_STATE_PLAYING) {
GST_DEBUG ("Waiting for new groups");
g_cond_wait (play_base_bin->group_cond, play_base_bin->group_lock);
GST_DEBUG ("done");
}
g_mutex_unlock (play_base_bin->group_lock);
/* error? */ /* error? */
if (GST_STATE (play_base_bin->thread) != GST_STATE_PLAYING) if (GST_STATE (play_base_bin->thread) != GST_STATE_PLAYING)
return TRUE; return TRUE;
@ -671,14 +676,16 @@ probe_triggered (GstProbe * probe, GstData ** data, gpointer user_data)
* active */ * active */
play_base_bin->queued_groups = play_base_bin->queued_groups =
g_list_remove (play_base_bin->queued_groups, group); g_list_remove (play_base_bin->queued_groups, group);
setup_substreams (play_base_bin); if (play_base_bin->queued_groups) {
GST_DEBUG ("switching to next group %p", setup_substreams (play_base_bin);
play_base_bin->queued_groups->data); GST_DEBUG ("switching to next group %p",
/* and signal the new group */ play_base_bin->queued_groups->data);
GST_DEBUG ("emit signal"); /* and signal the new group */
g_signal_emit (play_base_bin, GST_DEBUG ("emit signal");
gst_play_base_bin_signals[SETUP_OUTPUT_PADS_SIGNAL], 0); g_signal_emit (play_base_bin,
gst_play_base_bin_signals[SETUP_OUTPUT_PADS_SIGNAL], 0);
}
/* else, it'll be handled in commit_group */
GST_DEBUG ("Syncing state from %d", GST_STATE (play_base_bin->thread)); GST_DEBUG ("Syncing state from %d", GST_STATE (play_base_bin->thread));
gst_element_set_state (play_base_bin->thread, GST_STATE_PLAYING); gst_element_set_state (play_base_bin->thread, GST_STATE_PLAYING);
GST_DEBUG ("done"); GST_DEBUG ("done");
@ -988,7 +995,8 @@ setup_subtitle (GstPlayBaseBin * play_base_bin, gchar * sub_uri)
*/ */
static GstElement * static GstElement *
gen_source_element (GstPlayBaseBin * play_base_bin, GstElement ** subbin) gen_source_element (GstPlayBaseBin * play_base_bin,
GstElement ** subbin, gboolean * _is_stream)
{ {
GstElement *source, *queue, *bin; GstElement *source, *queue, *bin;
GstProbe *probe; GstProbe *probe;
@ -1011,7 +1019,7 @@ gen_source_element (GstPlayBaseBin * play_base_bin, GstElement ** subbin)
return NULL; return NULL;
/* lame - FIXME, maybe we can use seek_types/mask here? */ /* lame - FIXME, maybe we can use seek_types/mask here? */
is_stream = !strncmp (play_base_bin->uri, "http://", 7) || *_is_stream = is_stream = !strncmp (play_base_bin->uri, "http://", 7) ||
!strncmp (play_base_bin->uri, "mms://", 6); !strncmp (play_base_bin->uri, "mms://", 6);
if (!is_stream) if (!is_stream)
return source; return source;
@ -1089,12 +1097,14 @@ setup_substreams (GstPlayBaseBin * play_base_bin)
* all the streams or until a preroll queue has been filled. * all the streams or until a preroll queue has been filled.
*/ */
static gboolean static gboolean
setup_source (GstPlayBaseBin * play_base_bin, GError ** error) setup_source (GstPlayBaseBin * play_base_bin,
gboolean * _stream, GError ** error)
{ {
GstElement *old_src; GstElement *old_src;
GstElement *old_dec; GstElement *old_dec;
GstPad *srcpad = NULL; GstPad *srcpad = NULL;
GstElement *subbin; GstElement *subbin;
gboolean stream;
if (!play_base_bin->need_rebuild) if (!play_base_bin->need_rebuild)
return TRUE; return TRUE;
@ -1105,7 +1115,8 @@ setup_source (GstPlayBaseBin * play_base_bin, GError ** error)
old_src = play_base_bin->source; old_src = play_base_bin->source;
/* create and configure an element that can handle the uri */ /* create and configure an element that can handle the uri */
play_base_bin->source = gen_source_element (play_base_bin, &subbin); play_base_bin->source = gen_source_element (play_base_bin, &subbin, &stream);
*_stream = stream;
if (!play_base_bin->source) { if (!play_base_bin->source) {
/* whoops, could not create the source element */ /* whoops, could not create the source element */
@ -1243,33 +1254,39 @@ setup_source (GstPlayBaseBin * play_base_bin, GError ** error)
"removed-decoded-pad", G_CALLBACK (removed_decoded_pad), play_base_bin); "removed-decoded-pad", G_CALLBACK (removed_decoded_pad), play_base_bin);
sig3 = g_signal_connect (G_OBJECT (play_base_bin->decoder), "no-more-pads", sig3 = g_signal_connect (G_OBJECT (play_base_bin->decoder), "no-more-pads",
G_CALLBACK (no_more_pads), play_base_bin); G_CALLBACK (no_more_pads), play_base_bin);
sig4 = g_signal_connect (G_OBJECT (play_base_bin->decoder), "unknown-type",
G_CALLBACK (unknown_type), play_base_bin);
sig5 = g_signal_connect (G_OBJECT (play_base_bin->thread), "error",
G_CALLBACK (thread_error), error);
/* either when the queues are filled or when the decoder element has no more if (!stream) {
* dynamic streams, the cond is unlocked. We can remove the signal handlers then sig4 = g_signal_connect (G_OBJECT (play_base_bin->decoder),
*/ "unknown-type", G_CALLBACK (unknown_type), play_base_bin);
g_mutex_lock (play_base_bin->group_lock); sig5 = g_signal_connect (G_OBJECT (play_base_bin->thread), "error",
if (gst_element_set_state (play_base_bin->thread, GST_STATE_PLAYING) == G_CALLBACK (thread_error), error);
GST_STATE_SUCCESS) {
GST_DEBUG ("waiting for first group..."); /* either when the queues are filled or when the decoder element
sig6 = g_signal_connect (G_OBJECT (play_base_bin->thread), * has no more dynamic streams, the cond is unlocked. We can remove
"state-change", G_CALLBACK (state_change), play_base_bin); * the signal handlers then
g_cond_wait (play_base_bin->group_cond, play_base_bin->group_lock); */
GST_DEBUG ("group done !"); g_mutex_lock (play_base_bin->group_lock);
if (gst_element_set_state (play_base_bin->thread, GST_STATE_PLAYING) ==
GST_STATE_SUCCESS) {
GST_DEBUG ("waiting for first group...");
sig6 = g_signal_connect (G_OBJECT (play_base_bin->thread),
"state-change", G_CALLBACK (state_change), play_base_bin);
g_cond_wait (play_base_bin->group_cond, play_base_bin->group_lock);
GST_DEBUG ("group done !");
} else {
GST_DEBUG ("state change failed, media cannot be loaded");
sig6 = 0;
}
g_mutex_unlock (play_base_bin->group_lock);
if (sig6 != 0)
g_signal_handler_disconnect (G_OBJECT (play_base_bin->thread), sig6);
g_signal_handler_disconnect (G_OBJECT (play_base_bin->thread), sig5);
g_signal_handler_disconnect (G_OBJECT (play_base_bin->decoder), sig4);
} else { } else {
GST_DEBUG ("state change failed, media cannot be loaded"); GST_DEBUG ("Source is a stream, delaying stream initialization");
sig6 = 0;
} }
g_mutex_unlock (play_base_bin->group_lock);
if (sig6 != 0)
g_signal_handler_disconnect (G_OBJECT (play_base_bin->thread), sig6);
g_signal_handler_disconnect (G_OBJECT (play_base_bin->thread), sig5);
g_signal_handler_disconnect (G_OBJECT (play_base_bin->decoder), sig4);
play_base_bin->need_rebuild = FALSE; play_base_bin->need_rebuild = FALSE;
} }
@ -1279,7 +1296,9 @@ setup_source (GstPlayBaseBin * play_base_bin, GError ** error)
/* make subs iterate from now on */ /* make subs iterate from now on */
gst_bin_add (GST_BIN (play_base_bin->thread), play_base_bin->subtitle); gst_bin_add (GST_BIN (play_base_bin->thread), play_base_bin->subtitle);
} }
setup_substreams (play_base_bin); if (!stream) {
setup_substreams (play_base_bin);
}
} }
return TRUE; return TRUE;
@ -1564,8 +1583,9 @@ gst_play_base_bin_change_state (GstElement * element)
case GST_STATE_READY_TO_PAUSED: case GST_STATE_READY_TO_PAUSED:
{ {
GError *error = NULL; GError *error = NULL;
gboolean stream;
if (!setup_source (play_base_bin, &error) || error != NULL) { if (!setup_source (play_base_bin, &stream, &error) || error != NULL) {
if (!error) { if (!error) {
/* opening failed but no error - hellup */ /* opening failed but no error - hellup */
GST_ELEMENT_ERROR (GST_ELEMENT (play_base_bin), STREAM, GST_ELEMENT_ERROR (GST_ELEMENT (play_base_bin), STREAM,
@ -1578,6 +1598,8 @@ gst_play_base_bin_change_state (GstElement * element)
g_error_free (error); g_error_free (error);
} }
ret = GST_STATE_FAILURE; ret = GST_STATE_FAILURE;
} else if (stream) {
ret = gst_element_set_state (play_base_bin->thread, GST_STATE_PAUSED);
} else { } else {
const GList *item; const GList *item;
gboolean stream_found = FALSE, no_media = FALSE; gboolean stream_found = FALSE, no_media = FALSE;
@ -1640,10 +1662,12 @@ gst_play_base_bin_change_state (GstElement * element)
G_CALLBACK (gst_play_base_bin_error), play_base_bin); G_CALLBACK (gst_play_base_bin_error), play_base_bin);
g_signal_connect (G_OBJECT (play_base_bin->thread), "eos", g_signal_connect (G_OBJECT (play_base_bin->thread), "eos",
G_CALLBACK (play_base_eos), play_base_bin); G_CALLBACK (play_base_eos), play_base_bin);
GST_DEBUG ("emit signal"); if (!stream) {
g_signal_emit (play_base_bin, GST_DEBUG ("emit signal");
gst_play_base_bin_signals[SETUP_OUTPUT_PADS_SIGNAL], 0); g_signal_emit (play_base_bin,
GST_DEBUG ("done"); gst_play_base_bin_signals[SETUP_OUTPUT_PADS_SIGNAL], 0);
GST_DEBUG ("done");
}
} else { } else {
/* clean up leftover groups */ /* clean up leftover groups */
remove_groups (play_base_bin); remove_groups (play_base_bin);
@ -1708,6 +1732,9 @@ gst_play_base_bin_add_element (GstBin * bin, GstElement * element)
element = thread; element = thread;
} }
gst_bin_add (GST_BIN (play_base_bin->thread), element); gst_bin_add (GST_BIN (play_base_bin->thread), element);
if (GST_STATE (play_base_bin) > GST_STATE_READY) {
gst_element_set_state (element, GST_STATE (play_base_bin));
}
/* hack, the clock is not correctly distributed in the core */ /* hack, the clock is not correctly distributed in the core */
sched = gst_element_get_scheduler (GST_ELEMENT (play_base_bin->thread)); sched = gst_element_get_scheduler (GST_ELEMENT (play_base_bin->thread));

View file

@ -215,42 +215,6 @@ gst_stream_info_dispose (GObject * object)
} }
} }
static void
stream_info_mute_pad (GstStreamInfo * stream_info, GstPad * pad, gboolean mute)
{
GList *int_links;
gboolean activate = !mute;
gchar *debug_str = (activate ? "activate" : "inactivate");
GST_DEBUG_OBJECT (stream_info, "%s %s:%s", debug_str,
GST_DEBUG_PAD_NAME (pad));
gst_pad_set_active (pad, activate);
if (gst_pad_get_parent (pad)->numsrcpads > 1)
return;
for (int_links = gst_pad_get_internal_links (pad);
int_links; int_links = g_list_next (int_links)) {
GstPad *pad = GST_PAD (int_links->data);
GstPad *peer = gst_pad_get_peer (pad);
GstElement *peer_elem = peer ? gst_pad_get_parent (peer) : NULL;
GST_DEBUG_OBJECT (stream_info, "%s internal pad %s:%s",
debug_str, GST_DEBUG_PAD_NAME (pad));
gst_pad_set_active (pad, activate);
if (peer_elem && peer_elem->numsrcpads == 1) {
GST_DEBUG_OBJECT (stream_info, "recursing element %s on pad %s:%s",
gst_element_get_name (peer_elem), GST_DEBUG_PAD_NAME (peer));
stream_info_mute_pad (stream_info, peer, mute);
} else if (peer) {
GST_DEBUG_OBJECT (stream_info, "%s final pad %s:%s",
debug_str, GST_DEBUG_PAD_NAME (peer));
gst_pad_set_active (peer, activate);
}
}
}
static void static void
stream_info_change_state (GstElement * element, stream_info_change_state (GstElement * element,
gint old_state, gint new_state, gpointer data) gint old_state, gint new_state, gpointer data)
@ -261,7 +225,7 @@ stream_info_change_state (GstElement * element,
/* state change will annoy us */ /* state change will annoy us */
g_return_if_fail (stream_info->mute == TRUE); g_return_if_fail (stream_info->mute == TRUE);
GST_DEBUG_OBJECT (stream_info, "Re-muting pads after state-change"); GST_DEBUG_OBJECT (stream_info, "Re-muting pads after state-change");
stream_info_mute_pad (stream_info, GST_PAD (stream_info->object), TRUE); gst_pad_set_active_recursive (GST_PAD (stream_info->object), FALSE);
} }
} }
@ -277,8 +241,8 @@ gst_stream_info_set_mute (GstStreamInfo * stream_info, gboolean mute)
if (mute != stream_info->mute) { if (mute != stream_info->mute) {
stream_info->mute = mute; stream_info->mute = mute;
stream_info_mute_pad (stream_info, gst_pad_set_active_recursive ((GstPad *)
(GstPad *) GST_PAD_REALIZE (stream_info->object), mute); GST_PAD_REALIZE (stream_info->object), !mute);
if (mute) { if (mute) {
g_signal_connect (gst_pad_get_parent ((GstPad *) g_signal_connect (gst_pad_get_parent ((GstPad *)