mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-03 05:59:10 +00:00
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:
parent
180b4346fd
commit
e62a79939e
3 changed files with 93 additions and 91 deletions
11
ChangeLog
11
ChangeLog
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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 *)
|
||||||
|
|
Loading…
Reference in a new issue