From: <rb...@fr...> - 2004-09-13 18:24:07
|
CVS Root: /home/cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Mon Sep 13 2004 11:24:01 PDT Log message: * gst/playback/gstplaybasebin.c: (gst_play_base_bin_dispose), (gst_play_base_bin_set_property): Handle double disposals, and proper change of URIs. Modified files: . : ChangeLog gst/playback : gstplaybasebin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1052&r2=1.1053 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.7&r2=1.8 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /home/cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1052 retrieving revision 1.1053 diff -u -d -r1.1052 -r1.1053 --- ChangeLog 13 Sep 2004 17:33:18 -0000 1.1052 +++ ChangeLog 13 Sep 2004 18:23:49 -0000 1.1053 @@ -1,5 +1,11 @@ 2004-09-13 Ronald S. Bultje <rb...@ro...> + * gst/playback/gstplaybasebin.c: + (gst_play_base_bin_dispose), (gst_play_base_bin_set_property): + Handle double disposals, and proper change of URIs. + +2004-09-13 Ronald S. Bultje <rb...@ro...> * ext/gnomevfs/Makefile.am: * ext/gnomevfs/gstgnomevfs.c: (plugin_init): * ext/gnomevfs/gstgnomevfssink.c: (gst_gnomevfssink_get_type), Index: gstplaybasebin.c RCS file: /home/cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- gstplaybasebin.c 29 Jul 2004 14:08:11 -0000 1.7 +++ gstplaybasebin.c 13 Sep 2004 18:23:49 -0000 1.8 @@ -186,6 +186,7 @@ play_base_bin = GST_PLAY_BASE_BIN (object); g_free (play_base_bin->uri); + play_base_bin->uri = NULL; if (G_OBJECT_CLASS (parent_class)->dispose) { G_OBJECT_CLASS (parent_class)->dispose (object); @@ -415,7 +416,7 @@ g_warning ("cannot set NULL uri"); return; } - if (!play_base_bin->uri || !strcmp (play_base_bin->uri, uri)) { + if (!play_base_bin->uri || strcmp (play_base_bin->uri, uri) != 0) { g_free (play_base_bin->uri); play_base_bin->uri = g_strdup (uri); |
From: <rb...@fr...> - 2004-09-15 08:35:37
|
CVS Root: /home/cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Wed Sep 15 2004 01:35:32 PDT Log message: * gst/playback/gstplaybasebin.c: (state_change), (setup_source), (gst_play_base_bin_change_state): Handle the case where we failed to setup a clear pipeline. This will throw an error (or EOS, another nice case) and if you don't catch that, the app will wait for the signal forever (and thus hang). Modified files: . : ChangeLog gst/playback : gstplaybasebin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1060&r2=1.1061 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.10&r2=1.11 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /home/cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1060 retrieving revision 1.1061 diff -u -d -r1.1060 -r1.1061 --- ChangeLog 15 Sep 2004 06:33:43 -0000 1.1060 +++ ChangeLog 15 Sep 2004 08:35:17 -0000 1.1061 @@ -1,5 +1,14 @@ 2004-09-15 Ronald S. Bultje <rb...@ro...> + * gst/playback/gstplaybasebin.c: (state_change), (setup_source), + (gst_play_base_bin_change_state): + Handle the case where we failed to setup a clear pipeline. This + will throw an error (or EOS, another nice case) and if you don't + catch that, the app will wait for the signal forever (and thus + hang). + +2004-09-15 Ronald S. Bultje <rb...@ro...> * ext/gnomevfs/gstgnomevfssink.c: (gst_gnomevfssink_uri_get_protocols): * ext/gnomevfs/gstgnomevfssrc.c: Index: gstplaybasebin.c RCS file: /home/cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- gstplaybasebin.c 15 Sep 2004 06:33:44 -0000 1.10 +++ gstplaybasebin.c 15 Sep 2004 08:35:18 -0000 1.11 @@ -325,6 +325,24 @@ play_base_bin->streaminfo = g_list_append (play_base_bin->streaminfo, info); } +static void +state_change (GstElement * element, + GstElementState old_state, GstElementState new_state, gpointer data) +{ + GstPlayBaseBin *play_base_bin = GST_PLAY_BASE_BIN (data); + if (old_state > new_state) { + /* EOS or error occurred */ + GST_DEBUG ("state changed downwards"); + g_mutex_lock (play_base_bin->preroll_lock); + GST_DEBUG ("signal preroll done"); + g_cond_signal (play_base_bin->preroll_cond); + GST_DEBUG ("signaled preroll done"); + g_mutex_unlock (play_base_bin->preroll_lock); + } +} static gboolean setup_source (GstPlayBaseBin * play_base_bin) { @@ -351,7 +369,7 @@ { gboolean res; - gint sig1, sig2, sig3; + gint sig1, sig2, sig3, sig4; GstElement *old_dec; old_dec = play_base_bin->decoder; @@ -385,6 +403,8 @@ G_CALLBACK (no_more_pads), play_base_bin); sig3 = g_signal_connect (G_OBJECT (play_base_bin->decoder), "unknown-type", G_CALLBACK (unknown_type), play_base_bin); + sig4 = g_signal_connect (G_OBJECT (play_base_bin->decoder), + "state-change", G_CALLBACK (state_change), play_base_bin); /* either when the queues are filled or when the decoder element has no more * dynamic streams, the cond is unlocked. We can remove the signal handlers then @@ -396,6 +416,7 @@ GST_DEBUG ("preroll done !"); g_mutex_unlock (play_base_bin->preroll_lock); + g_signal_handler_disconnect (G_OBJECT (play_base_bin->decoder), sig4); g_signal_handler_disconnect (G_OBJECT (play_base_bin->decoder), sig3); g_signal_handler_disconnect (G_OBJECT (play_base_bin->decoder), sig2); g_signal_handler_disconnect (G_OBJECT (play_base_bin->decoder), sig1); @@ -403,7 +424,7 @@ play_base_bin->need_rebuild = FALSE; } - return TRUE; + return (GST_STATE (play_base_bin->thread) == GST_STATE_PLAYING); static void @@ -519,8 +540,9 @@ case GST_STATE_READY_TO_PAUSED: { if (!setup_source (play_base_bin)) { - GST_ELEMENT_ERROR (GST_ELEMENT (play_base_bin), LIBRARY, TOO_LAZY, - (NULL), ("cannot handle uri \"%s\"", play_base_bin->uri)); + GST_ELEMENT_ERROR (GST_ELEMENT (play_base_bin), STREAM, + CODEC_NOT_FOUND, + ("cannot open file \"%s\"", play_base_bin->uri), (NULL)); ret = GST_STATE_FAILURE; } else { ret = gst_element_set_state (play_base_bin->thread, GST_STATE_PAUSED); |
From: <rb...@fr...> - 2004-09-15 16:48:56
|
CVS Root: /home/cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Wed Sep 15 2004 09:48:55 PDT Log message: * gst/playback/gstplaybin.c: (gst_play_bin_get_property): Volume is a double not a float. Modified files: . : ChangeLog gst/playback : gstplaybin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1063&r2=1.1064 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybin.c.diff?r1=1.11&r2=1.12 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /home/cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1063 retrieving revision 1.1064 diff -u -d -r1.1063 -r1.1064 --- ChangeLog 15 Sep 2004 16:03:14 -0000 1.1063 +++ ChangeLog 15 Sep 2004 16:48:43 -0000 1.1064 @@ -1,3 +1,8 @@ +2004-09-15 Ronald S. Bultje <rb...@ro...> + + * gst/playback/gstplaybin.c: (gst_play_bin_get_property): + Volume is a double not a float. 2004-09-15 Wim Taymans <wi...@fl...> * gst/tcp/gstmultifdsink.c: (gst_multifdsink_remove_client_link), Index: gstplaybin.c RCS file: /home/cvs/gstreamer/gst-plugins/gst/playback/gstplaybin.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- gstplaybin.c 14 Sep 2004 16:54:14 -0000 1.11 +++ gstplaybin.c 15 Sep 2004 16:48:43 -0000 1.12 @@ -264,7 +264,7 @@ g_value_set_object (value, play_bin->visualisation); break; case ARG_VOLUME: - g_value_set_float (value, play_bin->volume); + g_value_set_double (value, play_bin->volume); default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
From: <rb...@fr...> - 2004-10-09 13:50:49
|
CVS Root: /home/cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Sat Oct 09 2004 06:50:45 PDT Log message: * gst/playback/gstplaybasebin.c: (setup_source), (gst_play_base_bin_change_state): Actually clean up streaminfo if output fails. This would trigger if, for example, there was no CD in the drive. No preroll, so a streaminfo structure is created, but the subsequent state change of the thread fails. * gst/playback/gstplaybin.c: (gst_play_bin_change_state): Don't change state if parent failed. Modified files: . : ChangeLog gst/playback : gstplaybasebin.c gstplaybin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1148&r2=1.1149 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.22&r2=1.23 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybin.c.diff?r1=1.19&r2=1.20 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /home/cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1148 retrieving revision 1.1149 diff -u -d -r1.1148 -r1.1149 --- ChangeLog 8 Oct 2004 18:05:39 -0000 1.1148 +++ ChangeLog 9 Oct 2004 13:50:33 -0000 1.1149 @@ -1,3 +1,14 @@ +2004-10-09 Ronald S. Bultje <rb...@ro...> + + * gst/playback/gstplaybasebin.c: (setup_source), + (gst_play_base_bin_change_state): + Actually clean up streaminfo if output fails. This would trigger + if, for example, there was no CD in the drive. No preroll, so + a streaminfo structure is created, but the subsequent state change + of the thread fails. + * gst/playback/gstplaybin.c: (gst_play_bin_change_state): + Don't change state if parent failed. 2004-10-08 Ronald S. Bultje <rb...@ro...> * gst/playback/gstplaybin.c: (gst_play_bin_class_init), Index: gstplaybasebin.c RCS file: /home/cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.22 retrieving revision 1.23 diff -u -d -r1.22 -r1.23 --- gstplaybasebin.c 8 Oct 2004 17:10:16 -0000 1.22 +++ gstplaybasebin.c 9 Oct 2004 13:50:33 -0000 1.23 @@ -403,6 +403,10 @@ gst_bin_remove (GST_BIN (play_base_bin->thread), old_src); } gst_bin_add (GST_BIN (play_base_bin->thread), play_base_bin->source); + if (gst_bin_sync_children_state (GST_BIN (play_base_bin->thread)) == + GST_STATE_FAILURE) { + return FALSE; + } } /* now see if the source element emits raw audio/video all by itself, @@ -670,6 +674,12 @@ * because one stream was unrecognized. */ g_signal_connect (play_base_bin->thread, "error", G_CALLBACK (gst_play_base_bin_error), play_base_bin); + } else { + /* in case of no preroll, we might have streaminfo already... */ + g_list_foreach (play_base_bin->streaminfo, + (GFunc) g_object_unref, NULL); + g_list_free (play_base_bin->streaminfo); + play_base_bin->streaminfo = NULL; } break; Index: gstplaybin.c RCS file: /home/cvs/gstreamer/gst-plugins/gst/playback/gstplaybin.c,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -r1.19 -r1.20 --- gstplaybin.c 8 Oct 2004 18:05:39 -0000 1.19 +++ gstplaybin.c 9 Oct 2004 13:50:33 -0000 1.20 @@ -527,6 +527,8 @@ transition = GST_STATE_TRANSITION (element); ret = GST_ELEMENT_CLASS (parent_class)->change_state (element); + if (ret == GST_STATE_FAILURE) + return ret; switch (transition) { case GST_STATE_NULL_TO_READY: |
From: <rb...@fr...> - 2004-10-29 08:40:44
|
CVS Root: /home/cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Fri Oct 29 2004 01:40:41 PDT Log message: * gst/playback/gstplaybasebin.c: (thread_error), (setup_source), (gst_play_base_bin_change_state): Improve error reporting. Modified files: . : ChangeLog gst/playback : gstplaybasebin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1226&r2=1.1227 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.27&r2=1.28 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /home/cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1226 retrieving revision 1.1227 diff -u -d -r1.1226 -r1.1227 --- ChangeLog 28 Oct 2004 14:22:14 -0000 1.1226 +++ ChangeLog 29 Oct 2004 08:40:28 -0000 1.1227 @@ -1,3 +1,9 @@ +2004-10-29 Ronald S. Bultje <rb...@ro...> + + * gst/playback/gstplaybasebin.c: (thread_error), (setup_source), + (gst_play_base_bin_change_state): + Improve error reporting. 2004-10-28 Wim Taymans <wi...@fl...> * gst/tcp/Makefile.am: Index: gstplaybasebin.c RCS file: /home/cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.27 retrieving revision 1.28 diff -u -d -r1.27 -r1.28 --- gstplaybasebin.c 20 Oct 2004 12:02:20 -0000 1.27 +++ gstplaybasebin.c 29 Oct 2004 08:40:28 -0000 1.28 @@ -398,6 +398,20 @@ no_more_pads (NULL, play_base_bin); } +/* + * Cache errors... + */ +static void +thread_error (GstElement * element, + GstElement * orig, GError * error, const gchar * debug, gpointer data) +{ + GError **_error = data; + if (!*_error) + *_error = g_error_copy (error); +} /* signal fired when the internal thread performed an unexpected * state change. This usually indicated an error occured. We stop the * preroll stage. @@ -423,7 +437,7 @@ * all the streams or until a preroll queue has been filled. */ static gboolean -setup_source (GstPlayBaseBin * play_base_bin) +setup_source (GstPlayBaseBin * play_base_bin, GError ** error) { GstElement *old_src; GstElement *old_dec; @@ -521,7 +535,7 @@ { gboolean res; - gint sig1, sig2, sig3, sig4; + gint sig1, sig2, sig3, sig4, sig5; /* now create the decoder element */ play_base_bin->decoder = gst_element_factory_make ("decodebin", "decoder"); @@ -547,6 +561,8 @@ G_CALLBACK (no_more_pads), play_base_bin); sig3 = g_signal_connect (G_OBJECT (play_base_bin->decoder), "unknown-type", G_CALLBACK (unknown_type), play_base_bin); + sig4 = 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 * dynamic streams, the cond is unlocked. We can remove the signal handlers then @@ -557,7 +573,7 @@ GList *prerolls; GST_DEBUG ("waiting for preroll..."); - sig4 = g_signal_connect (G_OBJECT (play_base_bin->thread), + sig5 = g_signal_connect (G_OBJECT (play_base_bin->thread), "state-change", G_CALLBACK (state_change), play_base_bin); g_cond_wait (play_base_bin->preroll_cond, play_base_bin->preroll_lock); GST_DEBUG ("preroll done !"); @@ -577,12 +593,13 @@ } } else { GST_DEBUG ("state change failed, media cannot be loaded"); - sig4 = 0; + sig5 = 0; } g_mutex_unlock (play_base_bin->preroll_lock); - if (sig4 != 0) - g_signal_handler_disconnect (G_OBJECT (play_base_bin->thread), sig4); + if (sig5 != 0) + g_signal_handler_disconnect (G_OBJECT (play_base_bin->thread), sig5); + g_signal_handler_disconnect (G_OBJECT (play_base_bin->thread), sig4); g_signal_handler_disconnect (G_OBJECT (play_base_bin->decoder), sig3); g_signal_handler_disconnect (G_OBJECT (play_base_bin->decoder), sig2); g_signal_handler_disconnect (G_OBJECT (play_base_bin->decoder), sig1); @@ -707,19 +724,72 @@ case GST_STATE_READY_TO_PAUSED: { - if (!setup_source (play_base_bin)) { - GST_ELEMENT_ERROR (GST_ELEMENT (play_base_bin), STREAM, - CODEC_NOT_FOUND, - ("cannot open file \"%s\"", play_base_bin->uri), (NULL)); - ret = GST_STATE_FAILURE; - } else if (!play_base_bin->streaminfo) { - ("Failed to find any supported stream in file \"%s\"", - play_base_bin->uri), (NULL)); + GError *error = NULL; + if (!setup_source (play_base_bin, &error) || error != NULL) { + if (!error) { + /* opening failed but no error - hellup */ + GST_ELEMENT_ERROR (GST_ELEMENT (play_base_bin), STREAM, + NOT_IMPLEMENTED, + ("cannot open file \"%s\"", play_base_bin->uri), (NULL)); + } else { + /* just copy the cached error - type doesn't matter */ + GST_ELEMENT_ERROR (play_base_bin, STREAM, TOO_LAZY, + (error->message), (NULL)); + g_error_free (error); + } ret = GST_STATE_FAILURE; } else { - ret = gst_element_set_state (play_base_bin->thread, GST_STATE_PAUSED); + const GList *item; + gboolean stream_found = FALSE, no_media = FALSE; + /* check if we found any supported stream... if not, then + * we detected stream type (or the above would've failed), + * but linking/decoding failed - plugin probably missing. */ + for (item = play_base_bin->streaminfo; item != NULL; item = item->next) { + GstStreamInfo *info = GST_STREAM_INFO (item->data); + if (info->type != GST_STREAM_TYPE_UNKNOWN) { + stream_found = TRUE; + break; + } else if (!item->prev && !item->next) { + /* We're no audio/video and the only stream... We could + * be something not-media that's detected because then our + * typefind doesn't mess up with mp3 (bz2, gz, elf, ...) */ + if (GST_IS_PAD (info->object)) { + const GstCaps *caps = GST_PAD_CAPS (GST_PAD (info->object)); + if (caps) { + const gchar *mime = + gst_structure_get_name (gst_caps_get_structure (caps, 0)); + if (!strcmp (mime, "application/x-executable") || + !strcmp (mime, "application/x-bzip") || + !strcmp (mime, "application/x-gzip") || + !strcmp (mime, "application/zip") || + !strcmp (mime, "application/x-compress")) { + no_media = TRUE; + } + } + } + } + if (!stream_found) { + if (!no_media) { + GST_ELEMENT_ERROR (play_base_bin, STREAM, CODEC_NOT_FOUND, + ("There were no decoders found to handle the stream in file " + "\"%s\", you might need to install the corresponding plugins", + play_base_bin->uri), (NULL)); + } else { + GST_ELEMENT_ERROR (play_base_bin, STREAM, WRONG_TYPE, + ("File \"%s\" is not a media file", play_base_bin->uri), + (NULL)); + ret = GST_STATE_FAILURE; + ret = gst_element_set_state (play_base_bin->thread, GST_STATE_PAUSED); if (ret == GST_STATE_SUCCESS) { /* error forwarding: |
From: <rb...@fr...> - 2004-10-31 13:37:40
|
CVS Root: /home/cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Sun Oct 31 2004 05:37:38 PST Log message: * gst/playback/Makefile.am: We need the marshallers for decodebin, too. Modified files: . : ChangeLog gst/playback : Makefile.am Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1236&r2=1.1237 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/Makefile.am.diff?r1=1.5&r2=1.6 ====Begin Diffs==== Index: Makefile.am =================================================================== RCS file: /home/cvs/gstreamer/gst-plugins/gst/playback/Makefile.am,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- Makefile.am 20 Oct 2004 12:02:20 -0000 1.5 +++ Makefile.am 31 Oct 2004 13:37:26 -0000 1.6 @@ -19,6 +19,7 @@ libgstplaybin_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstdecodebin_la_SOURCES = gstdecodebin.c +nodist_libgstdecodebin_la_SOURCES = $(built_sources) libgstdecodebin_la_CFLAGS = $(GST_CFLAGS) libgstdecodebin_la_LIBADD = libgstdecodebin_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) Index: ChangeLog RCS file: /home/cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1236 retrieving revision 1.1237 diff -u -d -r1.1236 -r1.1237 --- ChangeLog 31 Oct 2004 02:09:40 -0000 1.1236 +++ ChangeLog 31 Oct 2004 13:37:25 -0000 1.1237 @@ -1,3 +1,8 @@ +2004-10-31 Ronald S. Bultje <rb...@ro...> + + * gst/playback/Makefile.am: + We need the marshallers for decodebin, too. 2004-10-30 David Schleef <ds...@sc...> * gst/typefind/gsttypefindfunctions.c: (qt_type_find): Make |
From: <rb...@fr...> - 2004-11-01 16:08:47
|
CVS Root: /home/cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Mon Nov 01 2004 08:08:44 PST Log message: * gst/playback/gstdecodebin.c: (gst_decode_bin_class_init), (get_unconnected_element), (remove_starting_from), (pad_removed), (close_link): Implement support for dynamic pad changing. We listen to "live" pad removals (i.e. while playing) and re-setup autoplugging after that. Playbasebin/playbin need some more work for this to finally work, but decodebin supports (and replugs) chained ogg now. Modified files: . : ChangeLog gst/playback : gstdecodebin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1246&r2=1.1247 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstdecodebin.c.diff?r1=1.14&r2=1.15 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /home/cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1246 retrieving revision 1.1247 diff -u -d -r1.1246 -r1.1247 --- ChangeLog 1 Nov 2004 14:43:34 -0000 1.1246 +++ ChangeLog 1 Nov 2004 16:08:32 -0000 1.1247 @@ -1,3 +1,14 @@ +2004-11-01 Ronald S. Bultje <rb...@ro...> + + * gst/playback/gstdecodebin.c: (gst_decode_bin_class_init), + (get_unconnected_element), (remove_starting_from), (pad_removed), + (close_link): + Implement support for dynamic pad changing. We listen to "live" + pad removals (i.e. while playing) and re-setup autoplugging + after that. Playbasebin/playbin need some more work for this + to finally work, but decodebin supports (and replugs) chained + ogg now. 2004-11-02 Jan Schmidt <th...@ma...> * ext/alsa/gstalsa.c: (gst_alsa_class_init), (gst_alsa_dispose), (gst_alsa_finalize): Index: gstdecodebin.c RCS file: /home/cvs/gstreamer/gst-plugins/gst/playback/gstdecodebin.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- gstdecodebin.c 20 Oct 2004 12:02:20 -0000 1.14 +++ gstdecodebin.c 1 Nov 2004 16:08:32 -0000 1.15 @@ -76,6 +76,8 @@ void (*new_decoded_pad) (GstElement * element, GstPad * pad, gboolean last); /* signal fired when we found a pad that we cannot decode */ void (*unknown_type) (GstElement * element, GstPad * pad, GstCaps * caps); + /* called on dynamic pad removal */ + void (*removed_decoded_pad) (GstElement * element, GstPad * pad); }; /* props */ @@ -90,6 +92,7 @@ { SIGNAL_NEW_DECODED_PAD, SIGNAL_UNKNOWN_TYPE, + SIGNAL_REMOVED_DECODED_PAD, LAST_SIGNAL @@ -191,6 +194,11 @@ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, unknown_type), NULL, NULL, gst_marshal_VOID__OBJECT_BOXED, G_TYPE_NONE, 2, GST_TYPE_PAD, GST_TYPE_CAPS); + gst_decode_bin_signals[SIGNAL_REMOVED_DECODED_PAD] = + g_signal_new ("removed-decoded-pad", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstDecodeBinClass, removed_decoded_pad), NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD); gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_decode_bin_dispose); @@ -550,6 +558,110 @@ } } +/* get unconnected element (after unlink/pad-remove). */ +static GstElement * +get_unconnected_element (GstDecodeBin * decode_bin) +{ + const GList *walk; + for (walk = gst_bin_get_list (GST_BIN (decode_bin)); + walk != NULL; walk = walk->next) { + GstElement *element = walk->data; + const GList *pwalk; + for (pwalk = gst_element_get_pad_list (GST_ELEMENT (element)); + pwalk != NULL; pwalk = pwalk->next) { + GstPad *pad = pwalk->data; + if (GST_PAD_IS_SINK (pad) && GST_PAD_PEER (pad) == NULL) + return element; + } + } + return NULL; +} +/* remove all elements linked forward from this element on from the bin */ +static void +remove_starting_from (GstDecodeBin * decode_bin, GstElement * start) + const GList *pwalk; + for (pwalk = gst_element_get_pad_list (start); + pwalk != NULL; pwalk = pwalk->next) { + GstPad *pad = pwalk->data; + if (GST_PAD_IS_SRC (pad)) { + GstPad *peer = GST_PAD_PEER (pad); + GstElement *peer_parent = NULL; + if (peer) + peer_parent = gst_pad_get_parent (peer); + /* be recursive */ + if (peer_parent != NULL) { + if (gst_object_get_parent (GST_OBJECT (peer_parent)) + == GST_OBJECT (decode_bin)) { + remove_starting_from (decode_bin, peer_parent); + } else { + /* linked outside us - signal pad removal */ + g_signal_emit (decode_bin, + gst_decode_bin_signals[SIGNAL_REMOVED_DECODED_PAD], 0, pad); + } + } + /* now remove ourselves */ + gst_bin_remove (GST_BIN (decode_bin), start); +/* This function will be called for elements with dynamic elements when + * they remove pads. This might just be because they're disposed, in + * which case we don't care. It might also be because they're changing + * chain, in which case we want to re-plug afterwards. */ +pad_removed (GstElement * element, GstPad * pad, GstDecodeBin * decode_bin) + GList *walk; + GstElement *peer; + GstDynamic *dyn; + /* don't care about disposal - it's really only for replugging. + * We only need to check for pending is ready because if pending + * is NULL, then state is READY. */ + if (GST_STATE (element) <= GST_STATE_READY || + GST_STATE_PENDING (element) == GST_STATE_READY) + return; + /* clean up. FIXME: getting peer of removed pad is dirty. */ + peer = get_unconnected_element (decode_bin); + g_assert (peer); + remove_starting_from (decode_bin, peer); + /* if an element removes two pads, then we don't want this twice */ + for (walk = decode_bin->dynamics; walk != NULL; walk = walk->next) { + dyn = walk->data; + if (dyn->element == element) + return; + GST_DEBUG_OBJECT (decode_bin, "pad removal while alive - chained?"); + /* re-setup dynamic plugging */ + dyn = g_new0 (GstDynamic, 1); + dyn->np_sig_id = g_signal_connect (G_OBJECT (element), "new-pad", + G_CALLBACK (new_pad), dyn); + dyn->nmp_sig_id = g_signal_connect (G_OBJECT (element), "no-more-pads", + G_CALLBACK (no_more_pads), dyn); + dyn->element = element; + dyn->decode_bin = decode_bin; + /* and add this element to the dynamic elements */ + decode_bin->dynamics = g_list_prepend (decode_bin->dynamics, dyn); /* this function inspects the given element and tries to connect something * on the srcpads. If there are dynamic pads, it sets up a signal handler to * continue autoplugging when they become available */ @@ -639,6 +751,10 @@ /* and add this element to the dynamic elements */ decode_bin->dynamics = g_list_prepend (decode_bin->dynamics, dyn); + /* let's keep this one around longer than the lifetime of dynamicity */ + g_signal_connect (G_OBJECT (element), "pad-removed", + G_CALLBACK (pad_removed), decode_bin); /* Check if this is an element with more than 1 pad. If this element |
From: <rb...@fr...> - 2004-11-10 16:05:30
|
CVS Root: /home/cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Wed Nov 10 2004 08:05:29 PST Log message: * gst/playback/gstplaybasebin.c: (gst_play_base_bin_change_state): Don't assert (#157853). Modified files: . : ChangeLog gst/playback : gstplaybasebin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1285&r2=1.1286 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.34&r2=1.35 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /home/cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1285 retrieving revision 1.1286 diff -u -d -r1.1285 -r1.1286 --- ChangeLog 10 Nov 2004 14:53:49 -0000 1.1285 +++ ChangeLog 10 Nov 2004 16:05:17 -0000 1.1286 @@ -1,5 +1,10 @@ 2004-11-10 Ronald S. Bultje <rb...@ro...> + * gst/playback/gstplaybasebin.c: (gst_play_base_bin_change_state): + Don't assert (#157853). + +2004-11-10 Ronald S. Bultje <rb...@ro...> * ext/alsa/gstalsasink.c: (gst_alsa_sink_check_event), Fix bytes/samples confustion. (gst_alsa_sink_mmap), (gst_alsa_sink_loop): Index: gstplaybasebin.c RCS file: /home/cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.34 retrieving revision 1.35 diff -u -d -r1.34 -r1.35 --- gstplaybasebin.c 9 Nov 2004 12:10:28 -0000 1.34 +++ gstplaybasebin.c 10 Nov 2004 16:05:17 -0000 1.35 @@ -1069,15 +1069,11 @@ group = get_active_group (play_base_bin); - /* FIXME for now... The group can be NULL if the setup_source - * function somehow returned TRUE but did not commit the group. - * Actually I don't think this can happen but need to recheck. */ - g_assert (group); - /* check if we found any supported stream... if not, then * we detected stream type (or the above would've failed), * but linking/decoding failed - plugin probably missing. */ - for (item = group->streaminfo; item != NULL; item = item->next) { + for (item = group ? group->streaminfo : NULL; + item != NULL; item = item->next) { GstStreamInfo *info = GST_STREAM_INFO (item->data); if (info->type != GST_STREAM_TYPE_UNKNOWN) { |
From: <rb...@fr...> - 2004-11-13 15:20:24
|
CVS Root: /home/cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Sat Nov 13 2004 07:20:22 PST Log message: * gst/playback/gstplaybasebin.c: (gst_play_base_bin_add_element): Re-add clock distribution hack (until new core is released). Fixes #158125. Modified files: . : ChangeLog gst/playback : gstplaybasebin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1302&r2=1.1303 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.35&r2=1.36 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /home/cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1302 retrieving revision 1.1303 diff -u -d -r1.1302 -r1.1303 --- ChangeLog 13 Nov 2004 14:13:26 -0000 1.1302 +++ ChangeLog 13 Nov 2004 15:20:09 -0000 1.1303 @@ -1,3 +1,9 @@ +2004-11-13 Ronald S. Bultje <rb...@ro...> + + * gst/playback/gstplaybasebin.c: (gst_play_base_bin_add_element): + Re-add clock distribution hack (until new core is released). + Fixes #158125. 2004-11-13 Arwed v. Merkatz <v.m...@gm...> * configure.ac: fix mplex configure check segfaulting on some systems (bug #140994) Index: gstplaybasebin.c RCS file: /home/cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.35 retrieving revision 1.36 diff -u -d -r1.35 -r1.36 --- gstplaybasebin.c 10 Nov 2004 16:05:17 -0000 1.35 +++ gstplaybasebin.c 13 Nov 2004 15:20:10 -0000 1.36 @@ -1169,6 +1169,9 @@ play_base_bin = GST_PLAY_BASE_BIN (bin); if (play_base_bin->thread) { + GstScheduler *sched; + GstClock *clock; if (play_base_bin->threaded) { gchar *name; GstElement *thread; @@ -1181,6 +1184,16 @@ element = thread; } gst_bin_add (GST_BIN (play_base_bin->thread), element); + /* hack, the clock is not correctly distributed in the core */ + sched = gst_element_get_scheduler (GST_ELEMENT (play_base_bin->thread)); + clock = gst_scheduler_get_clock (sched); + gst_scheduler_set_clock (sched, clock); + /* FIXME set element to READY so that negotiation can happen. This + * currently fails because of weird negotiation problems. */ + //gst_element_set_state (element, GST_STATE_PLAYING); } else { g_warning ("adding elements is not allowed in NULL"); } |
From: <rb...@fr...> - 2004-11-25 20:22:06
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Thu Nov 25 2004 12:22:25 PST Log message: * gst/playback/gstdecodebin.c: (gst_decode_bin_factory_filter): We sometimes need parsers for playback, so add those too. Modified files: . : ChangeLog gst/playback : gstdecodebin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1318&r2=1.1319 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstdecodebin.c.diff?r1=1.19&r2=1.20 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1318 retrieving revision 1.1319 diff -u -d -r1.1318 -r1.1319 --- ChangeLog 25 Nov 2004 20:14:32 -0000 1.1318 +++ ChangeLog 25 Nov 2004 20:22:12 -0000 1.1319 @@ -1,5 +1,10 @@ 2004-11-25 Ronald S. Bultje <rb...@ro...> + * gst/playback/gstdecodebin.c: (gst_decode_bin_factory_filter): + We sometimes need parsers for playback, so add those too. + +2004-11-25 Ronald S. Bultje <rb...@ro...> * configure.ac: * gst/apetag/Makefile.am: * gst/apetag/apedemux.c: (gst_ape_demux_get_type), Index: gstdecodebin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstdecodebin.c,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -r1.19 -r1.20 --- gstdecodebin.c 9 Nov 2004 14:37:51 -0000 1.19 +++ gstdecodebin.c 25 Nov 2004 20:22:13 -0000 1.20 @@ -242,7 +242,8 @@ klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature)); /* only demuxers and decoders can play */ - if (strstr (klass, "Demux") == NULL && strstr (klass, "Decoder") == NULL) { + if (strstr (klass, "Demux") == NULL && + strstr (klass, "Decoder") == NULL && strstr (klass, "Parse") == NULL) { return FALSE; } |
From: <rb...@fr...> - 2004-11-25 20:47:02
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Thu Nov 25 2004 12:47:07 PST Log message: * gst/playback/gstplaybin.c: (gen_video_element), (gen_audio_element), (setup_sinks), (gst_play_bin_change_state): Don't reference all sinks, but only the video- and audiosinks. The vis. element should be disposed when we're done with it. We don't have any reason to keep it around. This fixes warnings when reusing playbin for playing multiple audio files with vis. enabled. Also release audio device on pause - idea stolen from Rhythmbox. Modified files: . : ChangeLog gst/playback : gstplaybin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1321&r2=1.1322 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybin.c.diff?r1=1.25&r2=1.26 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1321 retrieving revision 1.1322 diff -u -d -r1.1321 -r1.1322 --- ChangeLog 25 Nov 2004 20:36:28 -0000 1.1321 +++ ChangeLog 25 Nov 2004 20:46:55 -0000 1.1322 @@ -1,5 +1,16 @@ 2004-11-25 Ronald S. Bultje <rb...@ro...> + * gst/playback/gstplaybin.c: (gen_video_element), + (gen_audio_element), (setup_sinks), (gst_play_bin_change_state): + Don't reference all sinks, but only the video- and audiosinks. + The vis. element should be disposed when we're done with it. + We don't have any reason to keep it around. This fixes warnings + when reusing playbin for playing multiple audio files with + vis. enabled. Also release audio device on pause - idea stolen + from Rhythmbox. + +2004-11-25 Ronald S. Bultje <rb...@ro...> * ext/a52dec/gsta52dec.c: (gst_a52dec_channels), (gst_a52dec_push), (gst_a52dec_reneg), (gst_a52dec_loop), (plugin_init): * ext/alsa/gstalsa.c: (gst_alsa_get_caps): Index: gstplaybin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybin.c,v retrieving revision 1.25 retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- gstplaybin.c 9 Nov 2004 14:37:51 -0000 1.25 +++ gstplaybin.c 25 Nov 2004 20:46:55 -0000 1.26 @@ -387,6 +387,10 @@ done: play_bin->seekables = g_list_append (play_bin->seekables, sink); + /* since we're gonna add it to a bin but don't want to lose it, + * we keep a reference. */ + gst_object_ref (GST_OBJECT (element)); return element; } @@ -455,6 +459,10 @@ play_bin->seekables = g_list_prepend (play_bin->seekables, sink); @@ -695,7 +703,6 @@ /* we found a sink for this stream, now try to install it */ if (sink != NULL) { - gst_object_ref (GST_OBJECT (sink)); gst_bin_add (GST_BIN (play_bin), sink); GST_DEBUG ("Adding sink with state %d (parent: %d, peer: %d)\n", GST_STATE (sink), GST_STATE (play_bin), @@ -743,19 +750,16 @@ return ret; switch (transition) { - case GST_STATE_NULL_TO_READY: - break; - case GST_STATE_READY_TO_PAUSED: - case GST_STATE_PAUSED_TO_PLAYING: case GST_STATE_PLAYING_TO_PAUSED: + /* Set audio sink state to NULL to release the sound device, + * but only if we own it (else we might be in chain-transition). */ + if (GST_STATE (play_bin->audio_sink) == GST_STATE_PAUSED) { + gst_element_set_state (play_bin->audio_sink, GST_STATE_NULL); + } break; case GST_STATE_PAUSED_TO_READY: remove_sinks (play_bin); - case GST_STATE_READY_TO_NULL: default: } |
From: <rb...@fr...> - 2004-11-25 20:52:35
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Thu Nov 25 2004 12:52:29 PST Log message: Reviewed by: Ronald S. Bultje <rb...@ro...> * gst/playback/gstplaybin.c: (gst_play_bin_dispose), (gst_play_bin_set_property), (gen_video_element), (gen_audio_element): Refcounting fixes for provided audio-/videosinks. Modified files: . : ChangeLog gst/playback : gstplaybin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1322&r2=1.1323 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybin.c.diff?r1=1.26&r2=1.27 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1322 retrieving revision 1.1323 diff -u -d -r1.1322 -r1.1323 --- ChangeLog 25 Nov 2004 20:46:55 -0000 1.1322 +++ ChangeLog 25 Nov 2004 20:52:14 -0000 1.1323 @@ -1,3 +1,12 @@ +2004-11-25 Christophe Fergeau <te...@gn...> + + Reviewed by: Ronald S. Bultje <rb...@ro...> + * gst/playback/gstplaybin.c: (gst_play_bin_dispose), + (gst_play_bin_set_property), (gen_video_element), + (gen_audio_element): + Refcounting fixes for provided audio-/videosinks. 2004-11-25 Ronald S. Bultje <rb...@ro...> * gst/playback/gstplaybin.c: (gen_video_element), Index: gstplaybin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybin.c,v retrieving revision 1.26 retrieving revision 1.27 diff -u -d -r1.26 -r1.27 --- gstplaybin.c 25 Nov 2004 20:46:55 -0000 1.26 +++ gstplaybin.c 25 Nov 2004 20:52:16 -0000 1.27 @@ -229,14 +229,32 @@ play_bin = GST_PLAY_BIN (object); - remove_sinks (play_bin); - g_hash_table_destroy (play_bin->cache); + if (play_bin->cache != NULL) { + remove_sinks (play_bin); + g_hash_table_destroy (play_bin->cache); + play_bin->cache = NULL; + } + if (play_bin->audio_sink != NULL) { + gst_object_unref (GST_OBJECT (play_bin->audio_sink)); + play_bin->audio_sink = NULL; + if (play_bin->video_sink != NULL) { + gst_object_unref (GST_OBJECT (play_bin->video_sink)); + play_bin->video_sink = NULL; + if (play_bin->visualisation != NULL) { + gst_object_unref (GST_OBJECT (play_bin->visualisation)); + play_bin->visualisation = NULL; if (G_OBJECT_CLASS (parent_class)->dispose) { G_OBJECT_CLASS (parent_class)->dispose (object); } } static void gst_play_bin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -249,18 +267,39 @@ switch (prop_id) { case ARG_VIDEO_SINK: + if (play_bin->video_sink != NULL) { + gst_object_unref (GST_OBJECT (play_bin->video_sink)); + } play_bin->video_sink = g_value_get_object (value); + gst_object_ref (GST_OBJECT (play_bin->video_sink)); + gst_object_sink (GST_OBJECT (play_bin->video_sink)); /* when changing the videosink, we just remove the * video pipeline from the cache so that it will be * regenerated with the new sink element */ g_hash_table_remove (play_bin->cache, "vbin"); break; case ARG_AUDIO_SINK: + if (play_bin->audio_sink != NULL) { + gst_object_unref (GST_OBJECT (play_bin->audio_sink)); play_bin->audio_sink = g_value_get_object (value); + gst_object_ref (GST_OBJECT (play_bin->audio_sink)); + gst_object_sink (GST_OBJECT (play_bin->audio_sink)); g_hash_table_remove (play_bin->cache, "abin"); case ARG_VIS_PLUGIN: + if (play_bin->visualisation != NULL) { + gst_object_unref (GST_OBJECT (play_bin->visualisation)); play_bin->visualisation = g_value_get_object (value); + gst_object_ref (GST_OBJECT (play_bin->visualisation)); + gst_object_sink (GST_OBJECT (play_bin->visualisation)); case ARG_VOLUME: if (play_bin->volume_element) { @@ -381,7 +420,6 @@ gst_element_set_state (element, GST_STATE_READY); /* ref before adding to the cache */ - g_object_ref (G_OBJECT (element)); g_hash_table_insert (play_bin->cache, "vbin", element); done: @@ -453,7 +491,6 @@ g_hash_table_insert (play_bin->cache, "abin", element); |
From: <rb...@fr...> - 2004-11-26 12:30:57
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Fri Nov 26 2004 04:31:17 PST Log message: * gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init), (probe_triggered), (check_queue), (buffer_underrun), (buffer_running), (buffer_overrun), (gen_source_element), (setup_source): * gst/playback/gstplaybasebin.h: Implement buffering. Needs some more work. Modified files: . : ChangeLog gst/playback : gstplaybasebin.c gstplaybasebin.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1327&r2=1.1328 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.38&r2=1.39 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.h.diff?r1=1.6&r2=1.7 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1327 retrieving revision 1.1328 diff -u -d -r1.1327 -r1.1328 --- ChangeLog 26 Nov 2004 12:25:43 -0000 1.1327 +++ ChangeLog 26 Nov 2004 12:31:04 -0000 1.1328 @@ -1,5 +1,14 @@ 2004-11-26 Ronald S. Bultje <rb...@ro...> + * gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init), + (probe_triggered), (check_queue), (buffer_underrun), + (buffer_running), (buffer_overrun), (gen_source_element), + (setup_source): + * gst/playback/gstplaybasebin.h: + Implement buffering. Needs some more work. + +2004-11-26 Ronald S. Bultje <rb...@ro...> * ext/theora/theoradec.c: (theora_dec_chain): Fix ilog mask range overflow. Index: gstplaybasebin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.38 retrieving revision 1.39 diff -u -d -r1.38 -r1.39 --- gstplaybasebin.c 25 Nov 2004 20:09:53 -0000 1.38 +++ gstplaybasebin.c 26 Nov 2004 12:31:05 -0000 1.39 @@ -46,6 +46,7 @@ { SETUP_OUTPUT_PADS_SIGNAL, REMOVED_OUTPUT_PAD_SIGNAL, + BUFFERING_SIGNAL, LINK_STREAM_SIGNAL, UNLINK_STREAM_SIGNAL, LAST_SIGNAL @@ -149,6 +150,11 @@ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstPlayBaseBinClass, removed_output_pad), NULL, NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); + gst_play_base_bin_signals[BUFFERING_SIGNAL] = + g_signal_new ("buffering", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstPlayBaseBinClass, buffering), + NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); /* action signals */ gst_play_base_bin_signals[LINK_STREAM_SIGNAL] = @@ -557,6 +563,7 @@ g_signal_emit (play_base_bin, gst_play_base_bin_signals[SETUP_OUTPUT_PADS_SIGNAL], 0); + GST_DEBUG ("Syncing state from %d", GST_STATE (play_base_bin->thread)); gst_element_set_state (play_base_bin->thread, GST_STATE_PLAYING); /* get rid of the EOS event */ @@ -759,6 +766,113 @@ } } +/* + * Buffer/cache checking. FIXME: make configurable. + * Note that we could also do this (buffering) at the + * preroll-level. The advantage there is that it'd + * allow us to cache in time-units rather than byte- + * units. Ohwell... + */ +static gboolean +check_queue (GstProbe * probe, GstData ** data, gpointer user_data) +{ + GstElement *queue = GST_ELEMENT (user_data); + GstPlayBaseBin *play_base_bin = g_object_get_data (G_OBJECT (queue), "pbb"); + guint level = 0; + g_object_get (G_OBJECT (queue), "current-level-bytes", &level, NULL); + GST_DEBUG ("Queue size: %u bytes", level); + g_signal_emit (play_base_bin, + gst_play_base_bin_signals[BUFFERING_SIGNAL], 0, + level * 100 / (512 * 1024)); + /* continue! */ + return TRUE; +} +static void +buffer_underrun (GstElement * queue, GstPlayBaseBin * play_base_bin) + GST_DEBUG ("Underrun, re-caching"); + /* On underrun, we want to temoprarily pause playback, set a "min-size" + * treshold and wait for the running signal and then play again. Take + * care of possible deadlocks and so on, */ + g_object_set (queue, "min-threshold-bytes", 64 * 1024, NULL); + gst_play_base_bin_signals[BUFFERING_SIGNAL], 0, 0); +buffer_running (GstElement * queue, GstPlayBaseBin * play_base_bin) + GST_DEBUG ("Running"); + /* When we had an underrun, we now want to play again. */ + g_object_set (queue, "min-threshold-bytes", 0, + "max-size-bytes", 512 * 1024, NULL); +buffer_overrun (GstElement * queue, GstPlayBaseBin * play_base_bin) + GST_DEBUG ("Overrun, leaking upstream and flushing next few buffers"); + /* we want to decrease max-size here so the next few bytes are flushed */ + g_object_set (queue, "max-size-bytes", 448 * 1024, NULL); + gst_play_base_bin_signals[BUFFERING_SIGNAL], 0, 100); + * Generate a source element that does caching for network streams. +static GstElement * +gen_source_element (GstPlayBaseBin * play_base_bin) + GstElement *source, *queue, *bin; + GstProbe *probe; + gboolean is_stream; + source = + gst_element_make_from_uri (GST_URI_SRC, play_base_bin->uri, "source"); + if (!source) + return NULL; + /* lame - FIXME, maybe we can use seek_types/mask here? */ + is_stream = !strncmp (play_base_bin->uri, "http://", 7); + if (!is_stream) + return source; + /* buffer */ + bin = gst_thread_new ("sourcebin"); + queue = gst_element_factory_make ("queue", "buffer"); + g_object_set (queue, "max-size-bytes", 512 * 1024, + "max-size-buffers", 0, NULL); + /* I'd like it to be leaky too, but only for live sources. How? */ + g_signal_connect (queue, "underrun", G_CALLBACK (buffer_underrun), + play_base_bin); + g_signal_connect (queue, "running", G_CALLBACK (buffer_running), + g_signal_connect (queue, "overrun", G_CALLBACK (buffer_overrun), + /* give updates on queue size */ + probe = gst_probe_new (FALSE, check_queue, queue); + gst_pad_add_probe (gst_element_get_pad (source, "src"), probe); + g_object_set_data (G_OBJECT (queue), "pbb", play_base_bin); + gst_element_link (source, queue); + gst_bin_add_many (GST_BIN (bin), source, queue, NULL); + gst_element_add_ghost_pad (bin, gst_element_get_pad (queue, "src"), "src"); + return bin; /* construct and run the source and decoder elements until we found * all the streams or until a preroll queue has been filled. */ @@ -778,12 +892,13 @@ old_src = play_base_bin->source; /* create and configure an element that can handle the uri */ - play_base_bin->source = - gst_element_make_from_uri (GST_URI_SRC, play_base_bin->uri, "source"); + play_base_bin->source = gen_source_element (play_base_bin); if (!play_base_bin->source) { /* whoops, could not create the source element */ - g_warning ("don't know how to read %s", play_base_bin->uri); + g_set_error (error, 0, 0, + "No URI handler implemented for \"%s\"", play_base_bin->uri); + GST_WARNING ("don't know how to read %s", play_base_bin->uri); play_base_bin->source = old_src; return FALSE; } else { Index: gstplaybasebin.h RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.h,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- gstplaybasebin.h 8 Nov 2004 09:46:17 -0000 1.6 +++ gstplaybasebin.h 26 Nov 2004 12:31:05 -0000 1.7 @@ -91,6 +91,11 @@ void (*removed_output_pad) (GstPlayBaseBin *play_base_bin, GstStreamInfo *info); + /* 0: buf=empty (underrun) - will re-cache, + * 100: buf=full (overrun) - will flush head of cache (latency) */ + void (*buffering) (GstPlayBaseBin *play_base_bin, + gint percentage); gboolean (*link_stream) (GstPlayBaseBin *play_base_bin, GstStreamInfo *info, |
From: <rb...@fr...> - 2004-11-29 17:01:18
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Mon Nov 29 2004 09:01:46 PST Log message: * gst/playback/gststreaminfo.c: (stream_info_mute_pad): On mute of an unlinked stream, check for pad availability so we don't crash on unlinked pad. Modified files: . : ChangeLog gst/playback : gststreaminfo.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1345&r2=1.1346 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gststreaminfo.c.diff?r1=1.7&r2=1.8 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1345 retrieving revision 1.1346 diff -u -d -r1.1345 -r1.1346 --- ChangeLog 29 Nov 2004 12:41:03 -0000 1.1345 +++ ChangeLog 29 Nov 2004 17:01:34 -0000 1.1346 @@ -1,5 +1,11 @@ 2004-11-29 Ronald S. Bultje <rb...@ro...> + * gst/playback/gststreaminfo.c: (stream_info_mute_pad): + On mute of an unlinked stream, check for pad availability so + we don't crash on unlinked pad. + +2004-11-29 Ronald S. Bultje <rb...@ro...> * gst/avi/gstavidemux.c: (gst_avi_demux_stream_index), (gst_avi_demux_massage_index): Fix quite humiliating bug in omitting 0-sized index chunks but Index: gststreaminfo.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gststreaminfo.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- gststreaminfo.c 9 Nov 2004 12:10:28 -0000 1.7 +++ gststreaminfo.c 29 Nov 2004 17:01:34 -0000 1.8 @@ -212,18 +212,18 @@ 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 = gst_pad_get_parent (peer); + 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->numsrcpads == 1) { + 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 { + } 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); |
From: <rb...@fr...> - 2004-12-01 13:14:35
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Wed Dec 01 2004 05:15:09 PST Log message: * gst/playback/gstplaybin.c: (remove_sinks), (setup_sinks): Unlink manually since sometimes bin disposal (and therefore pad unlinking) is delayed, which will cause a new media file to not be able to start playing instantly. Modified files: . : ChangeLog gst/playback : gstplaybin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1346&r2=1.1347 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybin.c.diff?r1=1.29&r2=1.30 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1346 retrieving revision 1.1347 diff -u -d -r1.1346 -r1.1347 --- ChangeLog 29 Nov 2004 17:01:34 -0000 1.1346 +++ ChangeLog 1 Dec 2004 13:14:56 -0000 1.1347 @@ -1,3 +1,10 @@ +2004-12-01 Ronald S. Bultje <rb...@ro...> + + * gst/playback/gstplaybin.c: (remove_sinks), (setup_sinks): + Unlink manually since sometimes bin disposal (and therefore + pad unlinking) is delayed, which will cause a new media file + to not be able to start playing instantly. 2004-11-29 Ronald S. Bultje <rb...@ro...> * gst/playback/gststreaminfo.c: (stream_info_mute_pad): Index: gstplaybin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybin.c,v retrieving revision 1.29 retrieving revision 1.30 diff -u -d -r1.29 -r1.30 --- gstplaybin.c 27 Nov 2004 20:28:27 -0000 1.29 +++ gstplaybin.c 1 Dec 2004 13:14:57 -0000 1.30 @@ -606,8 +606,11 @@ for (sinks = play_bin->sinks; sinks; sinks = g_list_next (sinks)) { GstElement *element = GST_ELEMENT (sinks->data); + GstPad *pad = gst_element_get_pad (element, "sink"); GST_LOG ("removing sink %p", element); + if (GST_PAD_PEER (pad)) + gst_pad_unlink (GST_PAD_PEER (pad), pad); gst_bin_remove (GST_BIN (play_bin), element); } g_list_free (play_bin->sinks); @@ -741,6 +744,7 @@ GST_STATE (sink), GST_STATE (play_bin), GST_STATE (gst_pad_get_parent (srcpad))); sinkpad = gst_element_get_pad (sink, "sink"); /* try to link the pad of the sink to the stream */ res = gst_pad_link (srcpad, sinkpad); if (!res) { |
From: <rb...@fr...> - 2004-12-01 17:57:58
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Wed Dec 01 2004 09:58:32 PST Log message: * gst/playback/gstplaybasebin.c: (gst_play_base_bin_change_state): Don't crash on EMPTY caps (e.g. when the demuxer didn't recognize the contained stream). Modified files: . : ChangeLog gst/playback : gstplaybasebin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1351&r2=1.1352 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.40&r2=1.41 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1351 retrieving revision 1.1352 diff -u -d -r1.1351 -r1.1352 --- ChangeLog 1 Dec 2004 16:07:43 -0000 1.1351 +++ ChangeLog 1 Dec 2004 17:58:19 -0000 1.1352 @@ -1,5 +1,11 @@ 2004-12-01 Ronald S. Bultje <rb...@ro...> + * gst/playback/gstplaybasebin.c: (gst_play_base_bin_change_state): + Don't crash on EMPTY caps (e.g. when the demuxer didn't recognize + the contained stream). + +2004-12-01 Ronald S. Bultje <rb...@ro...> * ext/faad/gstfaad.c: (gst_faad_srcconnect), (gst_faad_chain): Oops, remove debug. Index: gstplaybasebin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.40 retrieving revision 1.41 diff -u -d -r1.40 -r1.41 --- gstplaybasebin.c 27 Nov 2004 20:28:27 -0000 1.40 +++ gstplaybasebin.c 1 Dec 2004 17:58:19 -0000 1.41 @@ -1207,7 +1207,7 @@ /* We're no audio/video and the only stream... We could * be something not-media that's detected because then our * typefind doesn't mess up with mp3 (bz2, gz, elf, ...) */ - if (info->caps) { + if (info->caps && !gst_caps_is_empty (info->caps)) { const gchar *mime = gst_structure_get_name (gst_caps_get_structure (info->caps, 0)); |
From: <rb...@fr...> - 2004-12-16 11:55:07
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Thu Dec 16 2004 03:55:05 PST Log message: Reviewed by: Ronald S. Bultje <rb...@ro...> * gst/playback/gstdecodebin.c: (new_pad), (close_link): * gst/playback/gstplaybasebin.c: (new_decoded_pad): Fix memleaks (#157233). Modified files: . : ChangeLog gst/playback : gstdecodebin.c gstplaybasebin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1390&r2=1.1391 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstdecodebin.c.diff?r1=1.20&r2=1.21 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.42&r2=1.43 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1390 retrieving revision 1.1391 diff -u -d -r1.1390 -r1.1391 --- ChangeLog 16 Dec 2004 11:39:00 -0000 1.1390 +++ ChangeLog 16 Dec 2004 11:54:53 -0000 1.1391 @@ -1,3 +1,11 @@ +2004-12-16 Christophe Fergeau <te...@gn...> + + Reviewed by: Ronald S. Bultje <rb...@ro...> + * gst/playback/gstdecodebin.c: (new_pad), (close_link): + * gst/playback/gstplaybasebin.c: (new_decoded_pad): + Fix memleaks (#157233). 2004-12-16 Sebastien Cote <sc...@he...> Reviewed by: Ronald S. Bultje <rb...@ro...> Index: gstdecodebin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstdecodebin.c,v retrieving revision 1.20 retrieving revision 1.21 diff -u -d -r1.20 -r1.21 --- gstdecodebin.c 25 Nov 2004 20:22:13 -0000 1.20 +++ gstdecodebin.c 16 Dec 2004 11:54:53 -0000 1.21 @@ -637,11 +637,15 @@ new_pad (GstElement * element, GstPad * pad, GstDynamic * dynamic) { GstDecodeBin *decode_bin = dynamic->decode_bin; + GstCaps *caps; /* see if any more pending dynamic connections exist */ gboolean more = gst_decode_bin_is_dynamic (decode_bin); - close_pad_link (element, pad, gst_pad_get_caps (pad), decode_bin, more); + caps = gst_pad_get_caps (pad); + close_pad_link (element, pad, caps, decode_bin, more); + if (caps) + gst_caps_free (caps); } /* this signal is fired when an element signals the no_more_pads signal. @@ -813,6 +817,7 @@ /* now loop over all the pads we need to connect */ for (pads = to_connect; pads; pads = g_list_next (pads)) { GstPad *pad = GST_PAD (pads->data); + GstCaps *caps; /* we have more pads if we have more than 1 pad to connect or * dynamics. If we have only 1 pad and no dynamics, more will be @@ -824,7 +829,10 @@ gst_pad_get_name (pad)); /* continue autoplugging on the pads */ - close_pad_link (element, pad, gst_pad_get_caps (pad), decode_bin, more); + caps = gst_pad_get_caps (pad); + close_pad_link (element, pad, caps, decode_bin, more); + if (caps) + gst_caps_free (caps); } g_list_free (to_connect); Index: gstplaybasebin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.42 retrieving revision 1.43 diff -u -d -r1.42 -r1.43 --- gstplaybasebin.c 9 Dec 2004 12:57:29 -0000 1.42 +++ gstplaybasebin.c 16 Dec 2004 11:54:53 -0000 1.43 @@ -657,6 +657,8 @@ caps = gst_pad_get_caps (pad); if (caps == NULL || gst_caps_is_empty (caps)) { g_warning ("no type on pad %s:%s", GST_DEBUG_PAD_NAME (pad)); return; @@ -717,6 +719,7 @@ /* add the stream to the list */ info = gst_stream_info_new (GST_OBJECT (srcpad), type, NULL, caps); + gst_caps_free (caps); info->origin = GST_OBJECT (pad); add_stream (group, info); |
From: <rb...@fr...> - 2005-01-08 18:31:36
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Sat Jan 08 2005 10:31:34 PST Log message: * gst/playback/Makefile.am: * gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init), (group_destroy), (group_commit), (group_is_muted), (gen_preroll_element), (add_stream), (unknown_type), (probe_triggered), (preroll_unlinked), (mute_stream), (silence_stream), (new_decoded_pad), (setup_substreams), (setup_source), (get_active_source), (mute_group_type), (muted_group_change_state), (set_active_source), (gst_play_base_bin_set_property), (gst_play_base_bin_get_property), (play_base_eos), (gst_play_base_bin_change_state): * gst/playback/gstplaybasebin.h: * gst/playback/gstplaybin.c: (add_sink), (setup_sinks): * gst/playback/gststreaminfo.c: (gst_stream_info_class_init), (gst_stream_info_dispose), (stream_info_mute_pad), (stream_info_change_state), (gst_stream_info_set_mute): * gst/playback/gststreamselector.c: (gst_stream_selector_get_type), (gst_stream_selector_base_init), (gst_stream_selector_class_init), (gst_stream_selector_init), (gst_stream_selector_dispose), (gst_stream_selector_get_linked_pad), (gst_stream_selector_get_caps), (gst_stream_selector_link), (gst_stream_selector_get_linked_pads), (gst_stream_selector_request_new_pad), (gst_stream_selector_chain): * gst/playback/gststreamselector.h: Adding stream selection support plus required properties for applications to use this. Fully fixes #100931. Modified files: . : ChangeLog gst/playback : Makefile.am gstplaybasebin.c gstplaybasebin.h gstplaybin.c gststreaminfo.c Added files: gst/playback : gststreamselector.c gststreamselector.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1473&r2=1.1474 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/Makefile.am.diff?r1=1.6&r2=1.7 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.47&r2=1.48 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.h.diff?r1=1.8&r2=1.9 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybin.c.diff?r1=1.32&r2=1.33 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gststreaminfo.c.diff?r1=1.8&r2=1.9 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gststreamselector.c?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gststreamselector.h?rev=1.1&content-type=text/vnd.viewcvs-markup ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1473 retrieving revision 1.1474 diff -u -d -r1.1473 -r1.1474 --- ChangeLog 8 Jan 2005 18:27:07 -0000 1.1473 +++ ChangeLog 8 Jan 2005 18:31:22 -0000 1.1474 @@ -1,3 +1,31 @@ +2005-01-08 Ronald S. Bultje <rb...@ro...> + + * gst/playback/Makefile.am: + * gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init), + (group_destroy), (group_commit), (group_is_muted), + (gen_preroll_element), (add_stream), (unknown_type), + (probe_triggered), (preroll_unlinked), (mute_stream), + (silence_stream), (new_decoded_pad), (setup_substreams), + (setup_source), (get_active_source), (mute_group_type), + (muted_group_change_state), (set_active_source), + (gst_play_base_bin_set_property), (gst_play_base_bin_get_property), + (play_base_eos), (gst_play_base_bin_change_state): + * gst/playback/gstplaybasebin.h: + * gst/playback/gstplaybin.c: (add_sink), (setup_sinks): + * gst/playback/gststreaminfo.c: (gst_stream_info_class_init), + (gst_stream_info_dispose), (stream_info_mute_pad), + (stream_info_change_state), (gst_stream_info_set_mute): + * gst/playback/gststreamselector.c: (gst_stream_selector_get_type), + (gst_stream_selector_base_init), (gst_stream_selector_class_init), + (gst_stream_selector_init), (gst_stream_selector_dispose), + (gst_stream_selector_get_linked_pad), + (gst_stream_selector_get_caps), (gst_stream_selector_link), + (gst_stream_selector_get_linked_pads), + (gst_stream_selector_request_new_pad), (gst_stream_selector_chain): + * gst/playback/gststreamselector.h: + Adding stream selection support plus required properties for + applications to use this. Fully fixes #100931. 2005-01-08 Benjamin Otte <ot...@gn...> * gst/games/gstpuzzle.c: (nav_event_handler): Index: Makefile.am RCS file: /cvs/gstreamer/gst-plugins/gst/playback/Makefile.am,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- Makefile.am 31 Oct 2004 13:37:26 -0000 1.6 +++ Makefile.am 8 Jan 2005 18:31:22 -0000 1.7 @@ -12,7 +12,9 @@ libgstplaybin_la_SOURCES = \ gstplaybin.c \ gstplaybasebin.c \ - gststreaminfo.c + gststreaminfo.c \ + gststreamselector.c nodist_libgstplaybin_la_SOURCES = $(built_sources) libgstplaybin_la_CFLAGS = $(GST_CFLAGS) libgstplaybin_la_LIBADD = @@ -24,7 +26,10 @@ libgstdecodebin_la_LIBADD = libgstdecodebin_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -noinst_HEADERS = gstplaybasebin.h gststreaminfo.h +noinst_HEADERS = \ + gstplaybasebin.h \ + gststreaminfo.h \ + gststreamselector.h noinst_PROGRAMS = test decodetest test2 test3 test4 Index: gstplaybasebin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.47 retrieving revision 1.48 diff -u -d -r1.47 -r1.48 --- gstplaybasebin.c 8 Jan 2005 18:22:41 -0000 1.47 +++ gstplaybasebin.c 8 Jan 2005 18:31:22 -0000 1.48 @@ -23,6 +23,7 @@ #include <string.h> #include "gstplaybasebin.h" +#include "gststreamselector.h" #include "gstplay-marshal.h" GST_DEBUG_CATEGORY_STATIC (gst_play_base_bin_debug); @@ -39,7 +40,10 @@ ARG_NSTREAMS, ARG_QUEUE_SIZE, ARG_STREAMINFO, - ARG_SOURCE + ARG_SOURCE, + ARG_VIDEO, + ARG_AUDIO, + ARG_TEXT }; /* signals */ @@ -76,6 +80,12 @@ static void gst_play_base_bin_found_tag (GstElement * element, GstElement * source, const GstTagList * taglist, gpointer data); +static void set_active_source (GstPlayBaseBin * play_base_bin, + GstStreamType type, gint source_num); +static gboolean probe_triggered (GstProbe * probe, GstData ** data, + gpointer user_data); +static void setup_substreams (GstPlayBaseBin * play_base_bin); static GstElementClass *element_class; static GstElementClass *parent_class; static guint gst_play_base_bin_signals[LAST_SIGNAL] = { 0 }; @@ -140,6 +150,19 @@ g_param_spec_object ("source", "Source", "Source element", GST_TYPE_ELEMENT, G_PARAM_READABLE)); + g_object_class_install_property (gobject_klass, ARG_VIDEO, + g_param_spec_int ("current-video", "Current video", + "Currently playing video stream (-1 = none)", + -1, G_MAXINT, -1, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_klass, ARG_AUDIO, + g_param_spec_int ("current-audio", "Current audio", + "Currently playing audio stream (-1 = none)", + g_object_class_install_property (gobject_klass, ARG_TEXT, + g_param_spec_int ("current-text", "Current text", + "Currently playing text stream (-1 = none)", GST_DEBUG_CATEGORY_INIT (gst_play_base_bin_debug, "playbasebin", 0, "playbasebin"); @@ -263,17 +286,21 @@ group_destroy (GstPlayBaseGroup * group) { GstPlayBaseBin *play_base_bin = group->bin; - GList *prerolls, *infos; + GList *infos; + gint n; GST_LOG ("removing group %p", group); /* remove the preroll queues */ - for (prerolls = group->preroll_elems; prerolls; - prerolls = g_list_next (prerolls)) { - GstElement *element = GST_ELEMENT (prerolls->data); + for (n = 0; n < NUM_TYPES; n++) { + GstElement *element = group->type[n].preroll; GstPad *pad; guint sig_id; GstElement *fakesrc; + const GList *item; + if (!element) + continue; /* have to unlink the unlink handler first because else we * are going to link an element in the finalize handler */ @@ -288,10 +315,20 @@ } /* remove any fakesrc elements for this preroll element */ - fakesrc = (GstElement *) g_object_get_data (G_OBJECT (element), "fakesrc"); - if (fakesrc != NULL) { - GST_LOG ("removing fakesrc"); - gst_bin_remove (GST_BIN (play_base_bin->thread), fakesrc); + for (item = gst_element_get_pad_list (group->type[n].selector); + item != NULL; item = item->next) { + GstPad *pad = item->data; + if (GST_PAD_DIRECTION (pad) != GST_PAD_SINK) + continue; + fakesrc = (GstElement *) g_object_get_data (G_OBJECT (pad), "fakesrc"); + if (fakesrc != NULL) { + GST_LOG ("removing fakesrc from %s:%s", + gst_pad_get_name (pad), + GST_ELEMENT_NAME (gst_pad_get_parent (pad))); + gst_bin_remove (GST_BIN (play_base_bin->thread), fakesrc); + } /* if the group is currently being played, we have to remove the element @@ -299,12 +336,15 @@ if (get_active_group (play_base_bin) == group) { GST_LOG ("removing preroll element %s", gst_element_get_name (element)); gst_bin_remove (GST_BIN (play_base_bin->thread), element); + gst_bin_remove (GST_BIN (play_base_bin->thread), group->type[n].selector); } else { /* else we can just unref it */ gst_object_unref (GST_OBJECT (element)); + gst_object_unref (GST_OBJECT (group->type[n].selector)); + group->type[n].preroll = NULL; } - g_list_free (group->preroll_elems); /* free the streaminfo too */ for (infos = group->streaminfo; infos; infos = g_list_next (infos)) { @@ -323,7 +363,6 @@ group_commit (GstPlayBaseBin * play_base_bin, gboolean fatal) GstPlayBaseGroup *group = play_base_bin->building_group; - GList *prerolls; /* if an element signalled a no-more-pads after we stopped due * to preroll, the group is NULL. This is not an error */ @@ -334,6 +373,8 @@ GST_DEBUG ("Group loading failed, bailing out"); } else { + gint n; GST_DEBUG ("group %p done", group); play_base_bin->queued_groups = g_list_append (play_base_bin->queued_groups, @@ -343,11 +384,13 @@ /* remove signals. We don't want anymore signals from the preroll * elements at this stage. */ - for (prerolls = group->preroll_elems; prerolls; - prerolls = g_list_next (prerolls)) { - GstElement *element = GST_ELEMENT (prerolls->data); + for (n = 0; n < NUM_TYPES; n++) { + GstElement *element = group->type[n].preroll; guint sig_id; + if (!element) sig_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (element), "signal_id")); @@ -367,15 +410,13 @@ static gboolean group_is_muted (GstPlayBaseGroup * group) - GList *infos; - - for (infos = group->streaminfo; infos; infos = g_list_next (infos)) { - GstStreamInfo *info = GST_STREAM_INFO (infos->data); - /* if we find a non muded group we can return FALSE */ - if (!info->mute) + if (group->type[n].preroll && !group->type[n].done) return FALSE; return TRUE; } @@ -394,26 +435,62 @@ * of the queues to fill. The assumption is that all the dynamic * streams will be detected by that time. */ -static GstElement * -gen_preroll_element (GstPlayBaseBin * play_base_bin, GstPad * pad) +static void +gen_preroll_element (GstPlayBaseBin * play_base_bin, + GstPlayBaseGroup * group, GstStreamType type, GstPad * pad, + GstStreamInfo * info) - GstElement *element; + GstElement *selector, *preroll; gchar *name; + const gchar *prename; guint sig; + GstPad *preroll_pad; + GstProbe *probe; - name = g_strdup_printf ("preroll_%s", gst_pad_get_name (pad)); - element = gst_element_factory_make ("queue", name); - g_object_set (G_OBJECT (element), + if (type == GST_STREAM_TYPE_VIDEO) + prename = "video"; + else if (type == GST_STREAM_TYPE_TEXT) + prename = "text"; + else if (type == GST_STREAM_TYPE_AUDIO) + prename = "audio"; + else + g_return_if_reached (); + /* create stream selector */ + name = g_strdup_printf ("selector_%s_%s", prename, gst_pad_get_name (pad)); + selector = g_object_new (GST_TYPE_STREAM_SELECTOR, NULL); + gst_object_set_name (GST_OBJECT (selector), name); + g_free (name); + /* create preroll queue */ + name = g_strdup_printf ("preroll_%s_%s", prename, gst_pad_get_name (pad)); + preroll = gst_element_factory_make ("queue", name); + g_object_set (G_OBJECT (preroll), "max-size-buffers", 0, "max-size-bytes", 10 * 1024 * 1024, "max-size-time", play_base_bin->queue_size, NULL); - sig = g_signal_connect (G_OBJECT (element), "overrun", + sig = g_signal_connect (G_OBJECT (preroll), "overrun", G_CALLBACK (queue_overrun), play_base_bin); /* keep a ref to the signal id so that we can disconnect the signal callback * when we are done with the preroll */ - g_object_set_data (G_OBJECT (element), "signal_id", GINT_TO_POINTER (sig)); + g_object_set_data (G_OBJECT (preroll), "signal_id", GINT_TO_POINTER (sig)); g_free (name); - return element; + /* listen for EOS */ + preroll_pad = gst_element_get_pad (preroll, "src"); + probe = gst_probe_new (FALSE, probe_triggered, info); + /* have to REALIZE the pad as we cannot attach a padprobe to a ghostpad */ + gst_pad_add_probe (preroll_pad, probe); + /* add to group list */ + gst_element_link (selector, preroll); + group->type[type - 1].selector = selector; + group->type[type - 1].preroll = preroll; + gst_bin_add (GST_BIN (play_base_bin->thread), selector); + gst_element_set_state (selector, GST_STATE_PLAYING); + gst_bin_add (GST_BIN (play_base_bin->thread), preroll); + gst_element_set_state (preroll, GST_STATE_PAUSED); + play_base_bin->threaded = TRUE; static void @@ -456,19 +533,8 @@ g_object_set_data (G_OBJECT (info), "group", group); group->streaminfo = g_list_append (group->streaminfo, info); - switch (info->type) { - case GST_STREAM_TYPE_AUDIO: - group->naudiopads++; - break; - case GST_STREAM_TYPE_VIDEO: - group->nvideopads++; - case GST_STREAM_TYPE_TEXT: - group->ntextpads++; - default: - group->nunknownpads++; + if (info->type > 0 && info->type <= NUM_TYPES) { + group->type[info->type - 1].npads++; @@ -484,7 +550,7 @@ GstPlayBaseGroup *group = get_building_group (play_base_bin); capsstr = gst_caps_to_string (caps); - g_warning ("don't know how to handle %s", capsstr); + g_message /*warning */ ("don't know how to handle %s", capsstr); /* add the stream to the list */ info = gst_stream_info_new (GST_OBJECT (pad), GST_STREAM_TYPE_UNKNOWN, @@ -540,15 +606,21 @@ GstEvent *event = GST_EVENT (*data); if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) { + gint num_groups = 0; gboolean have_left; GST_DEBUG ("probe got EOS in group %p", group); /* mute this stream */ - g_object_set (G_OBJECT (info), "mute", TRUE, NULL); + //g_object_set (G_OBJECT (info), "mute", TRUE, NULL); + if (info->type > 0 && info->type <= NUM_TYPES) + group->type[info->type - 1].done = TRUE; /* see if we have some more groups left to play */ - have_left = (g_list_length (play_base_bin->queued_groups) > 1); + num_groups = g_list_length (play_base_bin->queued_groups); + if (play_base_bin->building_group) + num_groups++; + have_left = (num_groups > 1); /* see if the complete group is muted */ if (!group_is_muted (group)) { @@ -561,14 +633,15 @@ } if (have_left) { + GST_DEBUG ("changing state for group change"); gst_element_set_state (play_base_bin->thread, GST_STATE_PAUSED); /* ok, get rid of the current group then */ group_destroy (group); /* removing the current group brings the next group * active */ play_base_bin->queued_groups = - g_list_delete_link (play_base_bin->queued_groups, - play_base_bin->queued_groups); + g_list_remove (play_base_bin->queued_groups, group); + setup_substreams (play_base_bin); GST_DEBUG ("switching to next group %p", play_base_bin->queued_groups->data); /* and signal the new group */ @@ -578,9 +651,12 @@ GST_DEBUG ("Syncing state from %d", GST_STATE (play_base_bin->thread)); gst_element_set_state (play_base_bin->thread, GST_STATE_PLAYING); + GST_DEBUG ("done"); /* get rid of the EOS event */ return FALSE; + } else { + GST_LOG ("Last group done, EOS"); } else if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) { GstTagList *taglist; @@ -616,7 +692,7 @@ preroll_unlinked (GstPad * pad, GstPad * peerpad, GstPlayBaseBin * play_base_bin) - GstElement *fakesrc, *queue; + GstElement *fakesrc; guint sig_id; /* make a fakesrc that will just emit one EOS */ @@ -629,8 +705,7 @@ gst_bin_add (GST_BIN (play_base_bin->thread), fakesrc); /* keep track of these patch elements */ - queue = GST_ELEMENT (gst_object_get_parent (GST_OBJECT (pad))); - g_object_set_data (G_OBJECT (queue), "fakesrc", fakesrc); + g_object_set_data (G_OBJECT (pad), "fakesrc", fakesrc); /* now unlink the unlinked signal so that it is not called again when * we destroy the queue */ @@ -641,6 +716,30 @@ +/* Mute stream on first data - for header-is-in-stream-stuff + * (vorbis, ogmtext). */ +static gboolean +mute_stream (GstProbe * probe, GstData ** d, gpointer data) +{ + GstStreamInfo *info = GST_STREAM_INFO (data); + if (GST_IS_BUFFER (*d)) { + g_object_set (G_OBJECT (info), "mute", TRUE, NULL); + gst_pad_remove_probe ((GstPad *) GST_PAD_REALIZE (info->object), probe); + gst_probe_destroy (probe); + } + /* no data */ + return FALSE; +} +/* Eat data. */ +silence_stream (GstProbe * probe, GstData ** d, gpointer data) /* signal fired when decodebin has found a new raw pad. We create * a preroll element if needed and the appropriate streaminfo. @@ -652,13 +751,12 @@ GstStructure *structure; const gchar *mimetype; GstCaps *caps; - GstElement *new_element = NULL; GstStreamInfo *info; GstStreamType type; - GstPad *srcpad; - gboolean need_preroll; + GstPad *sinkpad; GstPlayBaseGroup *group; GstProbe *probe; + guint sig; GST_DEBUG ("play base: new decoded pad %d", last); @@ -679,69 +777,46 @@ group->nstreams++; - need_preroll = FALSE; if (g_str_has_prefix (mimetype, "audio/")) { type = GST_STREAM_TYPE_AUDIO; - /* first audio pad gets a preroll element */ - if (group->naudiopads == 0) { - need_preroll = TRUE; - } } else if (g_str_has_prefix (mimetype, "video/")) { type = GST_STREAM_TYPE_VIDEO; - /* first video pad gets a preroll element */ - if (group->nvideopads == 0) { } else if (g_str_has_prefix (mimetype, "text/")) { type = GST_STREAM_TYPE_TEXT; - /* first text pad gets a preroll element */ - if (group->ntextpads == 0) { type = GST_STREAM_TYPE_UNKNOWN; - if (last || !need_preroll) { - GST_DEBUG ("play base: pad does not need preroll"); - srcpad = pad; - } else { - guint sig; - GstPad *sinkpad; - GST_DEBUG ("play base: pad needs preroll"); - new_element = gen_preroll_element (play_base_bin, pad); - srcpad = gst_element_get_pad (new_element, "src"); - gst_bin_add (GST_BIN (play_base_bin->thread), new_element); - play_base_bin->threaded = TRUE; - group->preroll_elems = g_list_prepend (group->preroll_elems, new_element); - gst_element_set_state (new_element, GST_STATE_READY); + info = gst_stream_info_new (GST_OBJECT (pad), type, NULL, caps); + if (type > 0 && type <= NUM_TYPES) { + /* first pad of each type gets a selector + preroll queue */ + if (group->type[type - 1].npads == 0) { + GST_DEBUG ("play base: pad needs new preroll"); + gen_preroll_element (play_base_bin, group, type, pad, info); + } - sinkpad = gst_element_get_pad (new_element, "sink"); - gst_pad_link (pad, sinkpad); - /* make sure we catch unlink signals */ - sig = g_signal_connect (G_OBJECT (sinkpad), "unlinked", - G_CALLBACK (preroll_unlinked), play_base_bin); - /* keep a ref to the signal id so that we can disconnect the signal callback */ - g_object_set_data (G_OBJECT (sinkpad), "unlinked_id", - GINT_TO_POINTER (sig)); + /* add to stream selector */ + sinkpad = gst_element_get_pad (group->type[type - 1].selector, "sink%d"); + /* make sure we catch unlink signals */ + sig = g_signal_connect (G_OBJECT (sinkpad), "unlinked", + G_CALLBACK (preroll_unlinked), play_base_bin); + /* keep a ref to the signal id so that we can disconnect the signal callback */ + g_object_set_data (G_OBJECT (sinkpad), "unlinked_id", GINT_TO_POINTER (sig)); + gst_pad_link (pad, sinkpad); - gst_element_set_state (new_element, GST_STATE_PAUSED); - } - info = gst_stream_info_new (GST_OBJECT (srcpad), type, NULL, caps); gst_caps_free (caps); info->origin = GST_OBJECT (pad); - add_stream (group, info); - /* install a probe so that we know when this group has ended */ - probe = gst_probe_new (FALSE, probe_triggered, info); - /* have to REALIZE the pad as we cannot attach a padprobe to a ghostpad */ - gst_pad_add_probe (GST_PAD_REALIZE (srcpad), probe); + /* select 1st for now - we'll select a preferred one after preroll */ + if (type == GST_STREAM_TYPE_UNKNOWN || group->type[type - 1].npads > 0) { + probe = gst_probe_new (FALSE, silence_stream, info); + gst_pad_add_probe (GST_PAD_REALIZE (pad), probe); + g_object_set_data (G_OBJECT (pad), "eat_probe", probe); + add_stream (group, info); /* signal the no more pads after adding the stream */ if (last) @@ -942,6 +1017,48 @@ return bin; +/* Setup the substreams (to be called right after group_commit ()) */ +setup_substreams (GstPlayBaseBin * play_base_bin) + GstPlayBaseGroup *group = get_active_group (play_base_bin); + const GList *item; + /* Remove the eat probes */ + for (item = group->streaminfo; item; item = item->next) { + GstStreamInfo *info = item->data; + probe = g_object_get_data (G_OBJECT (info->object), "eat_probe"); + if (probe) { + gst_pad_remove_probe (GST_PAD_REALIZE (info->object), probe); + gst_probe_destroy (probe); + /* now remove unknown pads */ + if (info->type == GST_STREAM_TYPE_UNKNOWN) { + GstProbe *probe; + probe = gst_probe_new (FALSE, mute_stream, info); + gst_pad_add_probe (GST_PAD_REALIZE (info->object), probe); + /* now check if the requested current streams exist */ + if (play_base_bin->current[n] >= group->type[n].npads) { + play_base_bin->current[n] = group->type[n].npads > 0 ? 0 : -1; + /* now acticate the right sources. Don't forget that during preroll, + * we set the first source to forwarding and ignored the rest. */ + set_active_source (play_base_bin, n + 1, play_base_bin->current[n]); /* construct and run the source and decoder elements until we found * all the streams or until a preroll queue has been filled. @@ -1133,14 +1250,125 @@ play_base_bin->need_rebuild = FALSE; - /* make subs iterate from now on */ - for (item = play_base_bin->subtitles; item; item = item->next) { - gst_bin_add (GST_BIN (play_base_bin->thread), item->data); + if (get_active_group (play_base_bin) != NULL) { + /* make subs iterate from now on */ + for (item = play_base_bin->subtitles; item; item = item->next) { + gst_bin_add (GST_BIN (play_base_bin->thread), item->data); + setup_substreams (play_base_bin); +/* + * Multi-stream management. -1 = none. + */ +static gint +get_active_source (GstPlayBaseBin * play_base_bin, GstStreamType type) + GstPlayBaseGroup *group; + GList *s; + gint num = 0; + group = get_active_group (play_base_bin); + if (!group) + return -1; + for (s = group->streaminfo; s; s = s->next) { + GstStreamInfo *info = s->data; + if (info->type == type) { + if (!info->mute) { + return num; + num++; + return -1; +/* Kill pad reactivation on state change. */ +static void muted_group_change_state (GstElement * element, + gint old_state, gint new_state, gpointer data); +mute_group_type (GstPlayBaseGroup * group, GstStreamType type, gboolean mute) + gboolean active = !mute; + gst_pad_set_active (gst_element_get_pad (group->type[type - 1].preroll, + "src"), active); + "sink"), active); + gst_pad_set_active (gst_element_get_pad (group->type[type - 1].selector, + if (mute) { + g_signal_connect (group->type[type - 1].preroll, "state-change", + G_CALLBACK (muted_group_change_state), group); + } else { + g_signal_handlers_disconnect_by_func (group->type[type - 1].preroll, +muted_group_change_state (GstElement * element, + gint old_state, gint new_state, gpointer data) + GstPlayBaseGroup *group = data; + if (new_state == GST_STATE_PLAYING) { + if (group->type[n].selector == element) { + mute_group_type (group, n + 1, TRUE); +set_active_source (GstPlayBaseBin * play_base_bin, + GstStreamType type, gint source_num) + gboolean have_active = FALSE; + GST_LOG ("Changing active source of type %d to %d", type, source_num); + play_base_bin->current[type - 1] = source_num; + if (!group || !group->type[type - 1].preroll) + return; + if (num == source_num) { + g_object_set (s->data, "mute", FALSE, NULL); + have_active = TRUE; + GstProbe *probe; + probe = gst_probe_new (FALSE, mute_stream, info); + gst_pad_add_probe (GST_PAD_REALIZE (info->object), probe); + num++; + mute_group_type (group, type, !have_active); gst_play_base_bin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -1175,6 +1403,18 @@ case ARG_QUEUE_SIZE: play_base_bin->queue_size = g_value_get_uint64 (value); break; + case ARG_VIDEO: + set_active_source (play_base_bin, + GST_STREAM_TYPE_VIDEO, g_value_get_int (value)); + break; + case ARG_AUDIO: + GST_STREAM_TYPE_AUDIO, g_value_get_int (value)); + case ARG_TEXT: + GST_STREAM_TYPE_TEXT, g_value_get_int (value)); default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1222,6 +1462,18 @@ } else g_value_set_object (value, play_base_bin->source); + g_value_set_int (value, get_active_source (play_base_bin, + GST_STREAM_TYPE_VIDEO)); + GST_STREAM_TYPE_AUDIO)); + GST_STREAM_TYPE_TEXT)); @@ -1233,6 +1485,8 @@ no_more_pads (GST_ELEMENT (bin), play_base_bin); + GST_LOG ("forwarding EOS"); gst_element_set_eos (GST_ELEMENT (play_base_bin)); @@ -1349,6 +1603,7 @@ GST_DEBUG ("emit signal"); g_signal_emit (play_base_bin, gst_play_base_bin_signals[SETUP_OUTPUT_PADS_SIGNAL], 0); } else { /* clean up leftover groups */ remove_groups (play_base_bin); Index: gstplaybasebin.h RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.h,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- gstplaybasebin.h 8 Jan 2005 18:22:41 -0000 1.8 +++ gstplaybasebin.h 8 Jan 2005 18:31:22 -0000 1.9 @@ -52,12 +52,13 @@ gint nstreams; GList *streaminfo; - gint naudiopads; - gint nvideopads; - gint ntextpads; - gint nunknownpads; - GList *preroll_elems; + struct { + gint npads; + GstElement *preroll; + GstElement *selector; + gboolean done; +#define NUM_TYPES 3 + } type[NUM_TYPES]; /* AUDIO, VIDEO, TEXT */ } GstPlayBaseGroup; struct _GstPlayBaseBin { @@ -67,6 +68,8 @@ gboolean threaded; guint64 queue_size; + gint current[NUM_TYPES]; /* internal thread */ GstElement *thread; gchar *uri; Index: gstplaybin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybin.c,v retrieving revision 1.32 retrieving revision 1.33 diff -u -d -r1.32 -r1.33 --- gstplaybin.c 8 Jan 2005 18:22:41 -0000 1.32 +++ gstplaybin.c 8 Jan 2005 18:31:22 -0000 1.33 @@ -671,74 +671,72 @@ * this should eventually be handled with a tuner interface so that * one can switch the streams. +add_sink (GstPlayBin * play_bin, GstElement * sink, GstPad * srcpad) + gboolean res; + /* we found a sink for this stream, now try to install it */ + gst_bin_add (GST_BIN (play_bin), sink); + GST_DEBUG ("Adding sink with state %d (parent: %d, peer: %d)\n", + GST_STATE (sink), GST_STATE (play_bin), + GST_STATE (gst_pad_get_parent (srcpad))); + sinkpad = gst_element_get_pad (sink, "sink"); + /* try to link the pad of the sink to the stream */ + res = gst_pad_link (srcpad, sinkpad); + if (!res) { + gchar *capsstr; + /* could not link this stream */ + capsstr = gst_caps_to_string (gst_pad_get_caps (srcpad)); + g_warning ("could not link %s", capsstr); + g_free (capsstr); + GST_LOG ("removing sink %p", sink); + gst_bin_remove (GST_BIN (play_bin), sink); + /* we got the sink succesfully linked, now keep the sink + * in out internal list */ + play_bin->sinks = g_list_prepend (play_bin->sinks, sink); + return res; setup_sinks (GstPlayBaseBin * play_base_bin) GstPlayBin *play_bin = GST_PLAY_BIN (play_base_bin); - GList *streaminfo; - GList *s; - gint num_audio = 0; - gint num_video = 0; - gint num_text = 0; + GList *streaminfo = NULL, *s; gboolean need_vis = FALSE; gboolean need_text = FALSE; GstPad *textsrcpad = NULL, *textsinkpad = NULL; + GstElement *sink; - /* FIXME: do this nicer, like taking a look at the installed - * bins and figuring out if we can simply reconnect them, remove - * or add them. */ - if (GST_STATE (play_base_bin) == GST_STATE_PLAYING) { + /* get rid of existing sinks */ + if (play_bin->sinks) { remove_sinks (play_bin); GST_DEBUG ("setupsinks"); - /* get info about the stream */ - g_object_get (G_OBJECT (play_bin), "stream-info", &streaminfo, NULL); - /* first examine the streams we have */ - for (s = streaminfo; s; s = g_list_next (s)) { - GObject *obj = G_OBJECT (s->data); - gint type; - GstPad *srcpad; - g_object_get (obj, "type", &type, NULL); - /* we don't care about streams with their own sink */ - if (type == 4) - continue; - /* else we need to get the pad */ - g_object_get (obj, "object", &srcpad, NULL); - /* hmm.. pad is allready linked */ - if (gst_pad_is_linked (srcpad)) - if (type == 1) { - num_audio++; - } else if (type == 2) { - num_video++; - } else if (type == 3) { - num_text++; - /* no video, use vis */ - if (num_video == 0 && num_audio > 0 && play_bin->visualisation) { - need_vis = TRUE; - } else if (num_video > 0 && num_text > 0) { + /* find out what to do */ + group = play_base_bin->queued_groups->data; + if (group->type[GST_STREAM_TYPE_VIDEO - 1].npads > 0 && + group->type[GST_STREAM_TYPE_TEXT - 1].npads > 0) { need_text = TRUE; + } else if (group->type[GST_STREAM_TYPE_VIDEO - 1].npads == 0 && + group->type[GST_STREAM_TYPE_AUDIO - 1].npads > 0 && + play_bin->visualisation != NULL) { + need_vis = TRUE; - num_audio = 0; - num_video = 0; - num_text = 0; /* now actually connect everything */ + g_object_get (G_OBJECT (play_base_bin), "stream-info", &streaminfo, NULL); for (s = streaminfo; s; s = g_list_next (s)) { GObject *obj = G_OBJECT (s->data); gint type; - GstPad *srcpad, *sinkpad; - GstElement *sink = NULL; - gboolean res; - gboolean mute = FALSE; GstObject *object; g_object_get (obj, "type", &type, NULL); @@ -747,91 +745,41 @@ /* use the sink elements as seek entry point */ if (type == 4) { play_bin->seekables = g_list_prepend (play_bin->seekables, object); - srcpad = GST_PAD (object); - /* pas is allready linked, go to the next pad */ - if (num_audio > 0) { - g_warning ("two audio streams found, playing first one"); - mute = TRUE; - } else { - if (need_vis) { - sink = gen_vis_element (play_bin); - } else { - sink = gen_audio_element (play_bin); - } - num_audio++; - } - if (num_video > 0) { - g_warning ("two video streams found, playing first one"); - if (need_text) { - sink = gen_text_element (play_bin); - textsinkpad = gst_element_get_pad (sink, "text_sink"); - sink = gen_video_element (play_bin); - num_video++; - if (num_text > 0) { - g_warning ("two subtitle streams found, playing first one"); - textsrcpad = srcpad; - num_text++; - } else if (type == 4) { - /* we can ignore these streams here */ + /* link audio */ + if (group->type[GST_STREAM_TYPE_AUDIO - 1].npads > 0) { + if (need_vis) { + sink = gen_vis_element (play_bin); - g_warning ("unknown stream found"); - mute = TRUE; + sink = gen_audio_element (play_bin); + //gst_element_link (group->type[GST_STREAM_TYPE_AUDIO - 1].preroll, sink); + add_sink (play_bin, sink, + gst_element_get_pad (group->type[GST_STREAM_TYPE_AUDIO - 1].preroll, + "src")); - /* we found a sink for this stream, now try to install it */ - if (sink != NULL) { - gst_bin_add (GST_BIN (play_bin), sink); - GST_DEBUG ("Adding sink with state %d (parent: %d, peer: %d)\n", - GST_STATE (sink), GST_STATE (play_bin), - GST_STATE (gst_pad_get_parent (srcpad))); - sinkpad = gst_element_get_pad (sink, "sink"); - /* try to link the pad of the sink to the stream */ - res = gst_pad_link (srcpad, sinkpad); - if (!res) { - gchar *capsstr; + /* link video */ + if (group->type[GST_STREAM_TYPE_VIDEO - 1].npads > 0) { + if (need_text) { + sink = gen_text_element (play_bin); - /* could not link this stream */ - capsstr = gst_caps_to_string (gst_pad_get_caps (srcpad)); - g_warning ("could not link %s", capsstr); - g_free (capsstr); - GST_LOG ("removing sink %p", sink); - gst_bin_remove (GST_BIN (play_bin), sink); - /* we got the sink succesfully linked, now keep the sink - * in out internal list */ - play_bin->sinks = g_list_prepend (play_bin->sinks, sink); + textsinkpad = gst_element_get_pad (sink, "text_sink"); + textsrcpad = + gst_element_get_pad (group->type[GST_STREAM_TYPE_TEXT - 1].preroll, + "src"); + if (textsinkpad && textsrcpad) { + gst_pad_link (textsrcpad, textsinkpad); + } else { + sink = gen_video_element (play_bin); - if (mute) { - /* no sink found/needed for this stream. We mute the stream - * so that it does not take any resources */ - g_object_set (G_OBJECT (obj), "mute", TRUE, NULL); - /* if subtitles, link */ - if (textsrcpad && num_video > 0) { - gst_pad_link (textsrcpad, textsinkpad); + //gst_element_link (group->type[GST_STREAM_TYPE_VIDEO - 1].preroll, sink); + gst_element_get_pad (group->type[GST_STREAM_TYPE_VIDEO - 1].preroll, Index: gststreaminfo.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gststreaminfo.c,v --- gststreaminfo.c 29 Nov 2004 17:01:34 -0000 1.8 +++ gststreaminfo.c 8 Jan 2005 18:31:22 -0000 1.9 @@ -25,6 +25,9 @@ #include <gst/gst.h> #include "gststreaminfo.h" +GST_DEBUG_CATEGORY_STATIC (gst_streaminfo_debug); +#define GST_CAT_DEFAULT gst_streaminfo_debug /* props */ enum @@ -70,6 +73,9 @@ static void gst_stream_info_init (GstStreamInfo * stream_info); static void gst_stream_info_dispose (GObject * object); +static void stream_info_change_state (GstElement * element, static void gst_stream_info_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * spec); static void gst_stream_info_get_property (GObject * object, guint prop_id, @@ -140,6 +146,9 @@ gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_stream_info_dispose); + GST_DEBUG_CATEGORY_INIT (gst_streaminfo_debug, "streaminfo", 0, + "Playbin Stream Info"); @@ -181,8 +190,16 @@ stream_info = GST_STREAM_INFO (object); - gst_object_unref (stream_info->object); - stream_info->object = NULL; + if (stream_info->object) { + if (GST_PAD_REALIZE (stream_info->object)) { + g_signal_handlers_disconnect_by_func (gst_pad_get_parent ((GstPad *) + GST_PAD_REALIZE (stream_info->object)), + G_CALLBACK (stream_info_change_state), stream_info); + gst_object_unref (stream_info->object); + stream_info->object = NULL; stream_info->origin = NULL; stream_info->type = GST_STREAM_TYPE_UNKNOWN; g_free (stream_info->decoder); @@ -207,6 +224,8 @@ 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) for (int_links = gst_pad_get_internal_links (pad); int_links; int_links = g_list_next (int_links)) { @@ -231,6 +250,20 @@ +stream_info_change_state (GstElement * element, + GstStreamInfo *stream_info = data; + /* state change will annoy us */ + g_return_if_fail (stream_info->mute == TRUE); + GST_DEBUG_OBJECT (stream_info, "Re-muting pads after state-change"); + stream_info_mute_pad (stream_info, GST_PAD (stream_info->object), TRUE); gboolean gst_stream_info_set_mute (GstStreamInfo * stream_info, gboolean mute) @@ -243,7 +276,18 @@ if (mute != stream_info->mute) { stream_info->mute = mute; - stream_info_mute_pad (stream_info, GST_PAD (stream_info->object), mute); + stream_info_mute_pad (stream_info, + (GstPad *) GST_PAD_REALIZE (stream_info->object), mute); + if (mute) { + g_signal_connect (gst_pad_get_parent ((GstPad *) + GST_PAD_REALIZE (stream_info->object)), "state-change", --- NEW FILE: gststreamselector.c --- /* GStreamer * Copyright (C) 2003 Julien Moutte <ju...@mo...> * Copyright (C) 2005 Ronald S. Bultje <rb...@ro...> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* * !!!!!!!!!!!!!!!!! Big phat warning. !!!!!!!!!!!!!!!!!!!!!! * The pads on the sinkside can be filled and the application is * supposed to enable/disable them. The plugin will receive input * data over the currently active pad and take care of data * forwarding and negotiation. This plugin does nothing fancy. It * exists to be light-weight and simple. * This is not a generic switch element. This is not to be used for * any such purpose. Patches to make it do that will be rejected. #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "gststreamselector.h" GST_DEBUG_CATEGORY_STATIC (stream_selector_debug); #define GST_CAT_DEFAULT stream_selector_debug static GstStaticPadTemplate gst_stream_selector_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink%d", GST_PAD_SINK, GST_PAD_REQUEST, GST_STATIC_CAPS_ANY); static GstStaticPadTemplate gst_stream_selector_src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, static void gst_stream_selector_dispose (GObject * object); static void gst_stream_selector_init (GstStreamSelector * sel); static void gst_stream_selector_base_init (GstStreamSelectorClass * klass); static void gst_stream_selector_class_init (GstStreamSelectorClass * klass); static GstCaps *gst_stream_selector_get_caps (GstPad * pad); static GstPadLinkReturn gst_stream_selector_link (GstPad * pad, const GstCaps * caps); static GList *gst_stream_selector_get_linked_pads (GstPad * pad); static GstPad *gst_stream_selector_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * unused); static void gst_stream_selector_chain (GstPad * pad, GstData * data); static GstElementClass *parent_class = NULL; GType gst_stream_selector_get_type (void) { static GType stream_selector_type = 0; if (!stream_selector_type) { static const GTypeInfo stream_selector_info = { sizeof (GstStreamSelectorClass), (GBaseInitFunc) gst_stream_selector_base_init, NULL, (GClassInitFunc) gst_stream_selector_class_init, sizeof (GstStreamSelector), 0, (GInstanceInitFunc) gst_stream_selector_init, }; stream_selector_type = g_type_register_static (GST_TYPE_ELEMENT, "GstStreamSelector", &stream_selector_info, 0); GST_DEBUG_CATEGORY_INIT (stream_selector_debug, "streamselector", 0, "A stream-selector element"); } return stream_selector_type; } static void gst_stream_selector_base_init (GstStreamSelectorClass * klass) GstElementClass *element_class = GST_ELEMENT_CLASS (klass); static GstElementDetails gst_stream_selector_details = GST_ELEMENT_DETAILS ("StreamSelector", "Generic", "N-to-1 input stream_selectoring", "Julien Moutte <ju...@mo...>\n" "Ronald S. Bultje <rb...@ro...>"); gst_element_class_set_details (element_class, &gst_stream_selector_details); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&gst_stream_selector_sink_factory)); gst_static_pad_template_get (&gst_stream_selector_src_factory)); gst_stream_selector_class_init (GstStreamSelectorClass * klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); parent_class = g_type_class_ref (GST_TYPE_ELEMENT); gobject_class->dispose = gst_stream_selector_dispose; gstelement_class->request_new_pad = gst_stream_selector_request_new_pad; gst_stream_selector_init (GstStreamSelector * sel) sel->srcpad = gst_pad_new ("src", GST_PAD_SRC); gst_pad_set_internal_link_function (sel->srcpad, GST_DEBUG_FUNCPTR (gst_stream_selector_get_linked_pads)); gst_pad_set_link_function (sel->srcpad, GST_DEBUG_FUNCPTR (gst_stream_selector_link)); gst_pad_set_getcaps_function (sel->srcpad, GST_DEBUG_FUNCPTR (gst_stream_selector_get_caps)); gst_element_add_pad (GST_ELEMENT (sel), sel->srcpad); /* sinkpad management */ sel->last_active_sinkpad = NULL; sel->nb_sinkpads = 0; gst_stream_selector_dispose (GObject * object) GstStreamSelector *sel = GST_STREAM_SELECTOR (object); G_OBJECT_CLASS (parent_class)->dispose (object); static GstPad * gst_stream_selector_get_linked_pad (GstPad * pad) GstStreamSelector *sel = GST_STREAM_SELECTOR (gst_pad_get_parent (pad)); GstPad *otherpad = NULL; if (pad == sel->srcpad) otherpad = sel->last_active_sinkpad; else if (pad == sel->last_active_sinkpad) otherpad = sel->srcpad; return otherpad; static GstCaps * gst_stream_selector_get_caps (GstPad * pad) GstPad *otherpad = gst_stream_selector_get_linked_pad (pad); if (!otherpad) { GST_DEBUG_OBJECT (gst_pad_get_parent (pad), "Pad %s not linked, returning ANY", gst_pad_get_name (pad)); return gst_caps_new_any (); GST_DEBUG_OBJECT (gst_pad_get_parent (pad), "Pad %s is linked (to %s), returning allowed-caps", gst_pad_get_name (pad), gst_pad_get_name (otherpad)); return gst_pad_get_allowed_caps (otherpad); static GstPadLinkReturn gst_stream_selector_link (GstPad * pad, const GstCaps * caps) "Pad %s not linked, returning %s", gst_pad_get_name (pad), GST_PAD_IS_SINK (pad) ? "ok" : "delayed"); return GST_PAD_IS_SINK (pad) ? GST_PAD_LINK_OK : GST_PAD_LINK_DELAYED; "Pad %s is linked (to %s), returning other-trysetcaps", return gst_pad_try_set_caps (otherpad, caps); static GList * gst_stream_selector_get_linked_pads (GstPad * pad) if (!otherpad) return NULL; return g_list_append (NULL, otherpad); gst_stream_selector_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * unused) GstStreamSelector *sel = GST_STREAM_SELECTOR (element); gchar *name = NULL; GstPad *sinkpad = NULL; g_return_val_if_fail (templ->direction == GST_PAD_SINK, NULL); GST_LOG_OBJECT (sel, "Creating new pad %d", sel->nb_sinkpads); name = g_strdup_printf ("sink%d", sel->nb_sinkpads++); sinkpad = gst_pad_new_from_template (templ, name); g_free (name); gst_pad_set_link_function (sinkpad, gst_pad_set_getcaps_function (sinkpad, gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (gst_stream_selector_chain)); gst_pad_set_internal_link_function (sinkpad, gst_element_add_pad (GST_ELEMENT (sel), sinkpad); return sinkpad; gst_stream_selector_chain (GstPad * pad, GstData * data) /* first, check if the active pad changed. If so, redo * negotiation and fail if that fails. */ if (pad != sel->last_active_sinkpad) { GstPadLinkReturn ret; GST_LOG_OBJECT (sel, "stream change detected, switching from %s to %s", sel->last_active_sinkpad ? gst_pad_get_name (sel->last_active_sinkpad) : "none", gst_pad_get_name (pad)); sel->last_active_sinkpad = pad; ret = gst_pad_renegotiate (pad); if (GST_PAD_LINK_FAILED (ret)) { GST_ELEMENT_ERROR (sel, CORE, NEGOTIATION, (NULL), (NULL)); sel->last_active_sinkpad = NULL; return; } /* forward */ GST_DEBUG_OBJECT (sel, "Forwarding %s %p from pad %s", GST_IS_EVENT (data) ? "event" : "buffer", data, gst_pad_get_name (pad)); gst_pad_push (sel->srcpad, data); --- NEW FILE: gststreamselector.h --- #ifndef __GST_STREAM_SELECTOR_H__ #define __GST_STREAM_SELECTOR_H__ #include <gst/gst.h> G_BEGIN_DECLS #define GST_TYPE_STREAM_SELECTOR \ (gst_stream_selector_get_type()) #define GST_STREAM_SELECTOR(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_STREAM_SELECTOR, GstStreamSelector)) #define GST_STREAM_SELECTOR_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_STREAM_SELECTOR, GstStreamSelector)) #define GST_IS_STREAM_SELECTOR(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_STREAM_SELECTOR)) #define GST_IS_STREAM_SELECTOR_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_STREAM_SELECTOR)) typedef struct _GstStreamSelector GstStreamSelector; typedef struct _GstStreamSelectorClass GstStreamSelectorClass; struct _GstStreamSelector { GstElement element; GstPad *last_active_sinkpad; GstPad *srcpad; guint nb_sinkpads; }; struct _GstStreamSelectorClass { GstElementClass parent_class; GType gst_stream_selector_get_type (void); G_END_DECLS #endif /* __GST_STREAM_SELECTOR_H__ */ |
From: <rb...@fr...> - 2005-01-09 18:03:56
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Sun Jan 09 2005 10:03:52 PST Log message: * gst/playback/gstplaybasebin.c: (gst_play_base_bin_init), (gen_preroll_element), (remove_groups), (setup_subtitle), (gen_source_element), (setup_source): * gst/playback/gstplaybasebin.h: Multiple .sub files is just a stupid idea... Fix some threading mistakes. Interestingly, external .sub files cause playbin to hang, I don't know why... Parsing fixes contributed by Felix Kooman <fk...@tu...>. Modified files: . : ChangeLog gst/playback : gstplaybasebin.c gstplaybasebin.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1487&r2=1.1488 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.50&r2=1.51 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.h.diff?r1=1.9&r2=1.10 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1487 retrieving revision 1.1488 diff -u -d -r1.1487 -r1.1488 --- ChangeLog 9 Jan 2005 16:32:06 -0000 1.1487 +++ ChangeLog 9 Jan 2005 18:03:40 -0000 1.1488 @@ -1,5 +1,16 @@ 2005-01-09 Ronald S. Bultje <rb...@ro...> + * gst/playback/gstplaybasebin.c: (gst_play_base_bin_init), + (gen_preroll_element), (remove_groups), (setup_subtitle), + (gen_source_element), (setup_source): + * gst/playback/gstplaybasebin.h: + Multiple .sub files is just a stupid idea... Fix some threading + mistakes. Interestingly, external .sub files cause playbin to + hang, I don't know why... Parsing fixes contributed by Felix + Kooman <fk...@tu...>. + +2005-01-09 Ronald S. Bultje <rb...@ro...> * testsuite/embed/Makefile.am: Fix buildbot. Index: gstplaybasebin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.50 retrieving revision 1.51 diff -u -d -r1.50 -r1.51 --- gstplaybasebin.c 9 Jan 2005 14:53:59 -0000 1.50 +++ gstplaybasebin.c 9 Jan 2005 18:03:40 -0000 1.51 @@ -218,7 +218,7 @@ play_base_bin->need_rebuild = TRUE; play_base_bin->source = NULL; play_base_bin->decoder = NULL; - play_base_bin->subtitles = NULL; + play_base_bin->subtitle = NULL; play_base_bin->group_lock = g_mutex_new (); play_base_bin->group_cond = g_cond_new (); @@ -488,9 +488,15 @@ gst_element_link (selector, preroll); group->type[type - 1].selector = selector; group->type[type - 1].preroll = preroll; - gst_bin_add (GST_BIN (play_base_bin->thread), selector); - gst_element_set_state (selector, GST_STATE_PLAYING); - gst_bin_add (GST_BIN (play_base_bin->thread), preroll); + if (type == GST_STREAM_TYPE_TEXT && play_base_bin->subtitle) { + gst_bin_add (GST_BIN (play_base_bin->subtitle), selector); + gst_bin_add (GST_BIN (play_base_bin->subtitle), preroll); + gst_element_set_state (selector, GST_STATE_PAUSED); + } else { + gst_bin_add (GST_BIN (play_base_bin->thread), selector); + gst_bin_add (GST_BIN (play_base_bin->thread), preroll); + gst_element_set_state (selector, GST_STATE_PLAYING); + } gst_element_set_state (preroll, GST_STATE_PAUSED); play_base_bin->threaded = TRUE; @@ -499,7 +505,7 @@ static void remove_groups (GstPlayBaseBin * play_base_bin) { - GList *groups, *item; + GList *groups; /* first destroy the group we were building if any */ if (play_base_bin->building_group) { @@ -518,11 +524,10 @@ play_base_bin->queued_groups = NULL; /* clear subs */ - for (item = play_base_bin->subtitles; item; item = item->next) { - gst_bin_remove (GST_BIN (play_base_bin->thread), item->data); + if (play_base_bin->subtitle) { + gst_bin_remove (GST_BIN (play_base_bin->thread), play_base_bin->subtitle); + play_base_bin->subtitle = NULL; } - g_list_free (play_base_bin->subtitles); } /* Add/remove a single stream to current building group. @@ -931,32 +936,28 @@ * Generate source ! subparse bins. */ -static GList * -setup_subtitles (GstPlayBaseBin * play_base_bin, gchar * sub_uri[]) +static GstElement * +setup_subtitle (GstPlayBaseBin * play_base_bin, gchar * sub_uri) - GstElement *source, *subparse, *bin; - gint n; + GstElement *source, *subparse, *subbin; gchar *name; - GList *subtitles = NULL; - for (n = 0; sub_uri[n]; n++) { - source = gst_element_make_from_uri (GST_URI_SRC, sub_uri[n], NULL); - if (!source) - continue; + source = gst_element_make_from_uri (GST_URI_SRC, sub_uri, NULL); + if (!source) + return NULL; - subparse = gst_element_factory_make ("subparse", NULL); - name = g_strdup_printf ("subbin%d", n); - bin = gst_thread_new (name); - g_free (name); + subparse = gst_element_factory_make ("subparse", NULL); + name = g_strdup_printf ("subbin"); + subbin = gst_thread_new (name); + g_free (name); - gst_bin_add_many (GST_BIN (bin), source, subparse, NULL); - gst_element_link (source, subparse); - gst_element_add_ghost_pad (bin, - gst_element_get_pad (subparse, "src"), "src"); - subtitles = g_list_append (subtitles, bin); - } + gst_bin_add_many (GST_BIN (subbin), source, subparse, NULL); + gst_element_link (source, subparse); + gst_element_add_ghost_pad (subbin, + gst_element_get_pad (subparse, "src"), "src"); - return subtitles; + /* return the subtitle GstElement object */ + return subbin; /* @@ -964,23 +965,23 @@ static GstElement * -gen_source_element (GstPlayBaseBin * play_base_bin, GList ** subbins) +gen_source_element (GstPlayBaseBin * play_base_bin, GstElement ** subbin) GstElement *source, *queue, *bin; GstProbe *probe; gboolean is_stream; - gchar **src, **subs, *uri; + gchar **src, *uri; - /* create subtitle elements */ + /* stip subtitle from uri */ src = g_strsplit (play_base_bin->uri, "#", 2); if (!src[0]) return NULL; if (src[1]) { - subs = g_strsplit (src[1], ",", 8); - *subbins = setup_subtitles (play_base_bin, subs); - g_strfreev (subs); + /* subtitle specified */ + *subbin = setup_subtitle (play_base_bin, src[1]); } else { - *subbins = NULL; + /* no subtitle specified */ + *subbin = NULL; uri = src[0]; src[0] = NULL; @@ -1072,7 +1073,7 @@ GstElement *old_src; GstElement *old_dec; GstPad *srcpad = NULL; - GList *new_subs, *item; + GstElement *subbin; if (!play_base_bin->need_rebuild) return TRUE; @@ -1083,7 +1084,7 @@ old_src = play_base_bin->source; /* create and configure an element that can handle the uri */ - play_base_bin->source = gen_source_element (play_base_bin, &new_subs); + play_base_bin->source = gen_source_element (play_base_bin, &subbin); if (!play_base_bin->source) { /* whoops, could not create the source element */ @@ -1120,17 +1121,14 @@ remove_groups (play_base_bin); /* do subs */ - if (new_subs) { - play_base_bin->subtitles = new_subs; - for (item = play_base_bin->subtitles; item; item = item->next) { - GstElement *bin = item->data; + if (subbin) { + play_base_bin->subtitle = subbin; - /* don't add yet, because we will preroll, and subs shouldn't - * preroll (we shouldn't preroll more than once source). */ - new_decoded_pad (bin, gst_element_get_pad (bin, "src"), FALSE, - play_base_bin); - gst_element_set_state (bin, GST_STATE_PAUSED); - } + /* don't add yet, because we will preroll, and subs shouldn't + * preroll (we shouldn't preroll more than once source). */ + new_decoded_pad (subbin, gst_element_get_pad (subbin, "src"), FALSE, + play_base_bin); + gst_element_set_state (subbin, GST_STATE_PAUSED); /* now see if the source element emits raw audio/video all by itself, @@ -1255,9 +1253,9 @@ if (get_active_group (play_base_bin) != NULL) { - /* make subs iterate from now on */ - gst_bin_add (GST_BIN (play_base_bin->thread), item->data); + if (play_base_bin->subtitle) { + /* make subs iterate from now on */ + gst_bin_add (GST_BIN (play_base_bin->thread), play_base_bin->subtitle); } setup_substreams (play_base_bin); Index: gstplaybasebin.h RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- gstplaybasebin.h 8 Jan 2005 18:31:22 -0000 1.9 +++ gstplaybasebin.h 9 Jan 2005 18:03:40 -0000 1.10 @@ -75,7 +75,7 @@ gchar *uri; GstElement *source; GstElement *decoder; - GList *subtitles; /* additional filesrc ! subparse bins */ + GstElement *subtitle; /* additional filesrc ! subparse bin */ gboolean need_rebuild; /* group management */ |
From: <rb...@fr...> - 2005-01-09 18:33:53
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Sun Jan 09 2005 10:33:50 PST Log message: * gst/playback/gstplaybasebin.c: (setup_source): Fix hanging subs. Modified files: . : ChangeLog gst/playback : gstplaybasebin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1489&r2=1.1490 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.51&r2=1.52 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1489 retrieving revision 1.1490 diff -u -d -r1.1489 -r1.1490 --- ChangeLog 9 Jan 2005 18:13:57 -0000 1.1489 +++ ChangeLog 9 Jan 2005 18:33:37 -0000 1.1490 @@ -1,5 +1,10 @@ 2005-01-09 Ronald S. Bultje <rb...@ro...> + * gst/playback/gstplaybasebin.c: (setup_source): + Fix hanging subs. + +2005-01-09 Ronald S. Bultje <rb...@ro...> * gst/playback/gstplaybasebin.c: (gst_play_base_bin_init), (gen_preroll_element), (remove_groups), (setup_subtitle), (gen_source_element), (setup_source): Index: gstplaybasebin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.51 retrieving revision 1.52 diff -u -d -r1.51 -r1.52 --- gstplaybasebin.c 9 Jan 2005 18:03:40 -0000 1.51 +++ gstplaybasebin.c 9 Jan 2005 18:33:38 -0000 1.52 @@ -1126,9 +1126,9 @@ /* don't add yet, because we will preroll, and subs shouldn't * preroll (we shouldn't preroll more than once source). */ + gst_element_set_state (subbin, GST_STATE_PAUSED); new_decoded_pad (subbin, gst_element_get_pad (subbin, "src"), FALSE, play_base_bin); - gst_element_set_state (subbin, GST_STATE_PAUSED); } /* now see if the source element emits raw audio/video all by itself, |
From: <rb...@fr...> - 2005-01-09 19:29:23
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Sun Jan 09 2005 11:29:18 PST Log message: * gst/playback/gstplaybasebin.c: (setup_source): Set source to NULL so that resources are free'ed. Fixes issues with playback of CDDA and similar device-accessing things. Modified files: . : ChangeLog gst/playback : gstplaybasebin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1492&r2=1.1493 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.52&r2=1.53 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1492 retrieving revision 1.1493 diff -u -d -r1.1492 -r1.1493 --- ChangeLog 9 Jan 2005 19:02:31 -0000 1.1492 +++ ChangeLog 9 Jan 2005 19:29:06 -0000 1.1493 @@ -1,5 +1,11 @@ 2005-01-09 Ronald S. Bultje <rb...@ro...> + * gst/playback/gstplaybasebin.c: (setup_source): + Set source to NULL so that resources are free'ed. Fixes issues + with playback of CDDA and similar device-accessing things. + +2005-01-09 Ronald S. Bultje <rb...@ro...> * testsuite/embed/Makefile.am: test->noinst, fix make test in buildbot. Index: gstplaybasebin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.52 retrieving revision 1.53 diff -u -d -r1.52 -r1.53 --- gstplaybasebin.c 9 Jan 2005 18:33:38 -0000 1.52 +++ gstplaybasebin.c 9 Jan 2005 19:29:06 -0000 1.53 @@ -1096,6 +1096,7 @@ } else { if (old_src) { GST_LOG ("removing old src element %s", gst_element_get_name (old_src)); + gst_element_set_state (old_src, GST_STATE_NULL); gst_bin_remove (GST_BIN (play_base_bin->thread), old_src); } gst_bin_add (GST_BIN (play_base_bin->thread), play_base_bin->source); |
From: <rb...@fr...> - 2005-01-09 19:41:22
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Sun Jan 09 2005 11:41:19 PST Log message: * gst/playback/gstplaybasebin.c: (group_destroy): Remove hack to get rid of assert and get rid of unlinked signals properly. Modified files: . : ChangeLog gst/playback : gstplaybasebin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1493&r2=1.1494 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.53&r2=1.54 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1493 retrieving revision 1.1494 diff -u -d -r1.1493 -r1.1494 --- ChangeLog 9 Jan 2005 19:29:06 -0000 1.1493 +++ ChangeLog 9 Jan 2005 19:41:07 -0000 1.1494 @@ -1,5 +1,11 @@ 2005-01-09 Ronald S. Bultje <rb...@ro...> + * gst/playback/gstplaybasebin.c: (group_destroy): + Remove hack to get rid of assert and get rid of unlinked + signals properly. + +2005-01-09 Ronald S. Bultje <rb...@ro...> * gst/playback/gstplaybasebin.c: (setup_source): Set source to NULL so that resources are free'ed. Fixes issues with playback of CDDA and similar device-accessing things. Index: gstplaybasebin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.53 retrieving revision 1.54 diff -u -d -r1.53 -r1.54 --- gstplaybasebin.c 9 Jan 2005 19:29:06 -0000 1.53 +++ gstplaybasebin.c 9 Jan 2005 19:41:07 -0000 1.54 @@ -294,42 +294,36 @@ /* remove the preroll queues */ for (n = 0; n < NUM_TYPES; n++) { GstElement *element = group->type[n].preroll; - GstPad *pad; - guint sig_id; GstElement *fakesrc; const GList *item; if (!element) continue; - /* have to unlink the unlink handler first because else we - * are going to link an element in the finalize handler */ - pad = gst_element_get_pad (element, "sink"); - sig_id = - GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pad), "unlinked_id")); - - if (sig_id != 0) { - GST_LOG ("removing unlink signal %s:%s", GST_DEBUG_PAD_NAME (pad)); - g_signal_handler_disconnect (G_OBJECT (pad), sig_id); - g_object_set_data (G_OBJECT (pad), "unlinked_id", GINT_TO_POINTER (0)); - } /* remove any fakesrc elements for this preroll element */ for (item = gst_element_get_pad_list (group->type[n].selector); item != NULL; item = item->next) { - GstPad *pad = item->data; + GstPad *pad = GST_PAD (item->data); + guint sig_id; if (GST_PAD_DIRECTION (pad) != GST_PAD_SINK) continue; + sig_id = + GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pad), "unlinked_id")); + if (sig_id != 0) { + GST_LOG ("removing unlink signal %s:%s", GST_DEBUG_PAD_NAME (pad)); + g_signal_handler_disconnect (G_OBJECT (pad), sig_id); + g_object_set_data (G_OBJECT (pad), "unlinked_id", GINT_TO_POINTER (0)); + } fakesrc = (GstElement *) g_object_get_data (G_OBJECT (pad), "fakesrc"); if (fakesrc != NULL) { GST_LOG ("removing fakesrc from %s:%s", gst_pad_get_name (pad), GST_ELEMENT_NAME (gst_pad_get_parent (pad))); gst_bin_remove (GST_BIN (play_base_bin->thread), fakesrc); - } else if (GST_PAD_PEER (pad)) { - gst_pad_unlink (GST_PAD_PEER (pad), pad); } } |
From: <rb...@fr...> - 2005-01-10 13:15:26
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Mon Jan 10 2005 05:15:23 PST Log message: * gst/playback/gstplaybasebin.c: (setup_substreams): Don't disable streamtype if the stream doesn't exist, since then playing a video after audio will disable both and nothing will happen. Fixes the testsuite. Modified files: . : ChangeLog gst/playback : gstplaybasebin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1500&r2=1.1501 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.54&r2=1.55 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1500 retrieving revision 1.1501 diff -u -d -r1.1500 -r1.1501 --- ChangeLog 10 Jan 2005 11:16:13 -0000 1.1500 +++ ChangeLog 10 Jan 2005 13:15:11 -0000 1.1501 @@ -1,5 +1,12 @@ 2005-01-10 Ronald S. Bultje <rb...@ro...> + * gst/playback/gstplaybasebin.c: (setup_substreams): + Don't disable streamtype if the stream doesn't exist, since + then playing a video after audio will disable both and nothing + will happen. Fixes the testsuite. + +2005-01-10 Ronald S. Bultje <rb...@ro...> * sys/v4l/gstv4lxoverlay.c: (gst_v4l_xoverlay_interface_init), (gst_v4l_xoverlay_set_xwindow_id): * sys/v4l2/gstv4l2xoverlay.c: (gst_v4l2_xoverlay_interface_init), Index: gstplaybasebin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.54 retrieving revision 1.55 diff -u -d -r1.54 -r1.55 --- gstplaybasebin.c 9 Jan 2005 19:41:07 -0000 1.54 +++ gstplaybasebin.c 10 Jan 2005 13:15:11 -0000 1.55 @@ -1044,10 +1044,12 @@ } } - /* now check if the requested current streams exist */ + /* now check if the requested current streams exist. If + * current >= num_streams, decrease current so at least + * we have output. Always keep it enabled. */ for (n = 0; n < NUM_TYPES; n++) { if (play_base_bin->current[n] >= group->type[n].npads) { - play_base_bin->current[n] = group->type[n].npads > 0 ? 0 : -1; + play_base_bin->current[n] = 0; |
From: <rb...@fr...> - 2005-01-11 12:03:41
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Tue Jan 11 2005 04:03:36 PST Log message: * gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init), (gst_play_base_bin_init), (gst_play_base_bin_dispose), (probe_triggered), (new_decoded_pad), (gen_source_element), (gst_play_base_bin_set_property), (gst_play_base_bin_get_property): * gst/playback/gstplaybasebin.h: * gst/playback/gstplaybin.c: (gst_play_bin_class_init), (gst_play_bin_init), (group_switch), (remove_sinks), (setup_sinks), (gst_play_bin_change_state): Implement group-switch signal for use in apps to clear metadata cache, clean up subtitle, add suburi property instead of # hack, some error-out fixes. Modified files: . : ChangeLog gst/playback : gstplaybasebin.c gstplaybasebin.h gstplaybin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1509&r2=1.1510 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.55&r2=1.56 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.h.diff?r1=1.10&r2=1.11 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybin.c.diff?r1=1.33&r2=1.34 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1509 retrieving revision 1.1510 diff -u -d -r1.1509 -r1.1510 --- ChangeLog 11 Jan 2005 00:26:13 -0000 1.1509 +++ ChangeLog 11 Jan 2005 12:03:23 -0000 1.1510 @@ -1,5 +1,19 @@ 2005-01-11 Ronald S. Bultje <rb...@ro...> + * gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init), + (gst_play_base_bin_init), (gst_play_base_bin_dispose), + (probe_triggered), (new_decoded_pad), (gen_source_element), + (gst_play_base_bin_set_property), (gst_play_base_bin_get_property): + * gst/playback/gstplaybasebin.h: + * gst/playback/gstplaybin.c: (gst_play_bin_class_init), + (gst_play_bin_init), (group_switch), (remove_sinks), (setup_sinks), + (gst_play_bin_change_state): + Implement group-switch signal for use in apps to clear metadata + cache, clean up subtitle, add suburi property instead of # hack, + some error-out fixes. + +2005-01-11 Ronald S. Bultje <rb...@ro...> * ext/vorbis/vorbisdec.c: (vorbis_dec_chain): Debug. * sys/v4l/v4lsrc_calls.c: (gst_v4lsrc_grab_frame): Index: gstplaybasebin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.55 retrieving revision 1.56 diff -u -d -r1.55 -r1.56 --- gstplaybasebin.c 10 Jan 2005 13:15:11 -0000 1.55 +++ gstplaybasebin.c 11 Jan 2005 12:03:24 -0000 1.56 @@ -36,6 +36,7 @@ { ARG_0, ARG_URI, + ARG_SUBURI, ARG_THREADED, ARG_NSTREAMS, ARG_QUEUE_SIZE, @@ -52,6 +53,7 @@ SETUP_OUTPUT_PADS_SIGNAL, REMOVED_OUTPUT_PAD_SIGNAL, BUFFERING_SIGNAL, + GROUP_SWITCH_SIGNAL, LINK_STREAM_SIGNAL, UNLINK_STREAM_SIGNAL, LAST_SIGNAL @@ -136,6 +138,9 @@ g_object_class_install_property (gobject_klass, ARG_URI, g_param_spec_string ("uri", "URI", "URI of the media to play", NULL, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_klass, ARG_SUBURI, + g_param_spec_string ("suburi", ".sub-URI", "Optional URI of a subtitle", + NULL, G_PARAM_READWRITE)); g_object_class_install_property (gobject_klass, ARG_NSTREAMS, g_param_spec_int ("nstreams", "NStreams", "number of streams", 0, G_MAXINT, 0, G_PARAM_READABLE)); @@ -182,6 +187,11 @@ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstPlayBaseBinClass, buffering), NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + gst_play_base_bin_signals[GROUP_SWITCH_SIGNAL] = + g_signal_new ("group-switch", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstPlayBaseBinClass, group_switch), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); /* action signals */ gst_play_base_bin_signals[LINK_STREAM_SIGNAL] = @@ -215,6 +225,7 @@ gst_play_base_bin_init (GstPlayBaseBin * play_base_bin) play_base_bin->uri = NULL; + play_base_bin->suburi = NULL; play_base_bin->need_rebuild = TRUE; play_base_bin->source = NULL; play_base_bin->decoder = NULL; @@ -239,6 +250,8 @@ play_base_bin = GST_PLAY_BASE_BIN (object); g_free (play_base_bin->uri); + g_free (play_base_bin->suburi); if (G_OBJECT_CLASS (parent_class)->dispose) { G_OBJECT_CLASS (parent_class)->dispose (object); @@ -639,6 +652,8 @@ gst_element_set_state (play_base_bin->thread, GST_STATE_PAUSED); /* ok, get rid of the current group then */ group_destroy (group); + g_signal_emit (play_base_bin, + gst_play_base_bin_signals[GROUP_SWITCH_SIGNAL], 0); /* removing the current group brings the next group * active */ play_base_bin->queued_groups = @@ -764,8 +779,9 @@ /* first see if this pad has interesting caps */ caps = gst_pad_get_caps (pad); - if (caps == NULL || gst_caps_is_empty (caps)) { - g_warning ("no type on pad %s:%s", GST_DEBUG_PAD_NAME (pad)); + if (caps == NULL || gst_caps_is_empty (caps) || gst_caps_is_any (caps)) { + g_warning ("no type on pad %s:%s", + GST_DEBUG_PAD_NAME (GST_PAD_REALIZE (pad))); if (caps) gst_caps_free (caps); return; @@ -964,24 +980,20 @@ GstElement *source, *queue, *bin; GstProbe *probe; gboolean is_stream; - gchar **src, *uri; /* stip subtitle from uri */ - src = g_strsplit (play_base_bin->uri, "#", 2); - if (!src[0]) + if (!play_base_bin->uri) return NULL; - if (src[1]) { + if (play_base_bin->suburi) { /* subtitle specified */ - *subbin = setup_subtitle (play_base_bin, src[1]); + *subbin = setup_subtitle (play_base_bin, play_base_bin->suburi); } else { /* no subtitle specified */ *subbin = NULL; } - uri = src[0]; - src[0] = NULL; - g_strfreev (src); - source = gst_element_make_from_uri (GST_URI_SRC, uri, "source"); + source = gst_element_make_from_uri (GST_URI_SRC, play_base_bin->uri, + "source"); if (!source) @@ -1399,6 +1411,19 @@ } break; } + case ARG_SUBURI:{ + const gchar *suburi = g_value_get_string (value); + if ((!suburi && !play_base_bin->suburi) || + (suburi && play_base_bin->suburi && + !strcmp (play_base_bin->suburi, suburi))) + return; + g_free (play_base_bin->suburi); + play_base_bin->suburi = g_strdup (suburi); + GST_DEBUG ("setting new .sub uri to %s", suburi); + play_base_bin->need_rebuild = TRUE; + break; + } case ARG_QUEUE_SIZE: play_base_bin->queue_size = g_value_get_uint64 (value); @@ -1434,6 +1459,9 @@ case ARG_URI: g_value_set_string (value, play_base_bin->uri); + case ARG_SUBURI: + g_value_set_string (value, play_base_bin->suburi); case ARG_NSTREAMS: { GstPlayBaseGroup *group = get_active_group (play_base_bin); Index: gstplaybasebin.h RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.h,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- gstplaybasebin.h 9 Jan 2005 18:03:40 -0000 1.10 +++ gstplaybasebin.h 11 Jan 2005 12:03:24 -0000 1.11 @@ -72,7 +72,7 @@ /* internal thread */ GstElement *thread; - gchar *uri; + gchar *uri, *suburi; GstElement *source; GstElement *decoder; GstElement *subtitle; /* additional filesrc ! subparse bin */ @@ -100,6 +100,7 @@ * 100: buf=full (overrun) - will flush head of cache (latency) */ void (*buffering) (GstPlayBaseBin *play_base_bin, gint percentage); + void (*group_switch) (GstPlayBaseBin *play_base_bin); gboolean (*link_stream) (GstPlayBaseBin *play_base_bin, Index: gstplaybin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybin.c,v retrieving revision 1.33 retrieving revision 1.34 diff -u -d -r1.33 -r1.34 --- gstplaybin.c 8 Jan 2005 18:31:22 -0000 1.33 +++ gstplaybin.c 11 Jan 2005 12:03:24 -0000 1.34 @@ -62,6 +62,9 @@ /* our cache for the sinks */ GHashTable *cache; + /* boolean to see if we're currently switching groups */ + gboolean group_switch; }; struct _GstPlayBinClass @@ -90,6 +93,7 @@ static void gst_play_bin_init (GstPlayBin * play_bin); static void gst_play_bin_dispose (GObject * object); +static void group_switch (GstPlayBaseBin * play_base_bin); static void setup_sinks (GstPlayBaseBin * play_base_bin); static void remove_sinks (GstPlayBin * play_bin); @@ -202,6 +206,7 @@ gstelement_klass->query = GST_DEBUG_FUNCPTR (gst_play_bin_query); playbasebin_klass->setup_output_pads = setup_sinks; + playbasebin_klass->group_switch = group_switch; } static void @@ -217,6 +222,7 @@ play_bin->frame = NULL; play_bin->cache = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) gst_object_unref); + play_bin->group_switch = FALSE; /* no iterate is needed */ GST_FLAG_SET (play_bin, GST_BIN_SELF_SCHEDULABLE); @@ -615,6 +621,13 @@ return element; +/* set for group switch */ +static void +group_switch (GstPlayBaseBin * play_base_bin) +{ + GST_PLAY_BIN (play_base_bin)->group_switch = TRUE; +} /* get rid of all installed sinks */ remove_sinks (GstPlayBin * play_bin) @@ -624,6 +637,7 @@ GstElement *element; GST_DEBUG ("removesinks"); element = g_hash_table_lookup (play_bin->cache, "abin"); if (element != NULL) { parent = gst_element_get_parent (element); @@ -755,7 +769,6 @@ } else { sink = gen_audio_element (play_bin); - //gst_element_link (group->type[GST_STREAM_TYPE_AUDIO - 1].preroll, sink); add_sink (play_bin, sink, gst_element_get_pad (group->type[GST_STREAM_TYPE_AUDIO - 1].preroll, "src")); @@ -776,7 +789,6 @@ sink = gen_video_element (play_bin); - //gst_element_link (group->type[GST_STREAM_TYPE_VIDEO - 1].preroll, sink); gst_element_get_pad (group->type[GST_STREAM_TYPE_VIDEO - 1].preroll, @@ -802,7 +814,7 @@ case GST_STATE_PLAYING_TO_PAUSED: /* Set audio sink state to NULL to release the sound device, * but only if we own it (else we might be in chain-transition). */ - if (play_bin->audio_sink != NULL && + if (play_bin->audio_sink != NULL && !play_bin->group_switch && GST_STATE (play_bin->audio_sink) == GST_STATE_PAUSED) { gst_element_set_state (play_bin->audio_sink, GST_STATE_NULL); |
From: <rb...@fr...> - 2005-01-16 14:38:58
|
CVS Root: /cvs/gstreamer Module: gst-plugins Changes by: rbultje Date: Sun Jan 16 2005 06:38:52 PST Log message: * gst/playback/gstplaybasebin.c: (probe_triggered): Thread safety. Modified files: . : ChangeLog gst/playback : gstplaybasebin.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1524&r2=1.1525 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c.diff?r1=1.56&r2=1.57 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1524 retrieving revision 1.1525 diff -u -d -r1.1524 -r1.1525 --- ChangeLog 16 Jan 2005 11:07:45 -0000 1.1524 +++ ChangeLog 16 Jan 2005 14:38:39 -0000 1.1525 @@ -1,3 +1,8 @@ +2005-01-16 Ronald S. Bultje <rb...@ro...> + + * gst/playback/gstplaybasebin.c: (probe_triggered): + Thread safety. 2005-01-16 Jan Schmidt <th...@ma...> * ext/swfdec/gstswfdec.c: (gst_swfdec_change_state): Index: gstplaybasebin.c RCS file: /cvs/gstreamer/gst-plugins/gst/playback/gstplaybasebin.c,v retrieving revision 1.56 retrieving revision 1.57 diff -u -d -r1.56 -r1.57 --- gstplaybasebin.c 11 Jan 2005 12:03:24 -0000 1.56 +++ gstplaybasebin.c 16 Jan 2005 14:38:40 -0000 1.57 @@ -656,8 +656,15 @@ gst_play_base_bin_signals[GROUP_SWITCH_SIGNAL], 0); /* removing the current group brings the next group * active */ + g_mutex_lock (play_base_bin->group_lock); play_base_bin->queued_groups = g_list_remove (play_base_bin->queued_groups, group); + while (!play_base_bin->queued_groups) { + 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); setup_substreams (play_base_bin); GST_DEBUG ("switching to next group %p", play_base_bin->queued_groups->data); |