+2005-10-11 Michael Smith <msmith@fluendo.com>
+
+ * gst/playback/gstplaybin.c: (gst_play_bin_send_event_to_sink),
+ (do_playbin_seek), (gst_play_bin_send_event):
+ Override send_event differently, so that we can takes bits of
+ functionality from GstPipeline (special handling for seeks,
+ including pausing/resuming, and resetting stream time) and still get
+ the appropriate behaviour of only forwarding event to a single sink,
+ rather than all of them.
+ Unfortunately requires a lot of code duplication, but the
+ alternatives are equally ugly in the end.
+
2005-10-11 Thomas Vander Stichele <thomas at apestaart dot org>
* check/elements/audioconvert.c: (setup_audioconvert),
}
}
+/* Send an event to our sinks until one of them works; don't then send to the
+ * remaining sinks (unlike GstBin)
+ */
static gboolean
-gst_play_bin_send_event (GstElement * element, GstEvent * event)
+gst_play_bin_send_event_to_sink (GstPlayBin * play_bin, GstEvent * event)
{
- GstPlayBin *play_bin;
- GList *sinks;
- gboolean res = FALSE;
+ GList *sinks = play_bin->sinks;
+ gboolean res = TRUE;
- play_bin = GST_PLAY_BIN (element);
-
- sinks = play_bin->sinks;
while (sinks) {
GstElement *sink = GST_ELEMENT_CAST (sinks->data);
return res;
}
+static gboolean
+do_playbin_seek (GstElement * element, GstEvent * event)
+{
+ gdouble rate;
+ GstSeekFlags flags;
+ gboolean flush;
+ gboolean was_playing = FALSE;
+ gboolean res;
+
+ gst_event_parse_seek (event, &rate, NULL, &flags, NULL, NULL, NULL, NULL);
+
+ flush = flags & GST_SEEK_FLAG_FLUSH;
+
+ if (flush) {
+ GstState state;
+ GTimeVal timeout;
+
+ GST_TIME_TO_TIMEVAL (0, timeout);
+ /* need to call _get_state() since a bin state is only updated
+ * with this call. */
+ gst_element_get_state (element, &state, NULL, &timeout);
+ was_playing = state == GST_STATE_PLAYING;
+
+ if (was_playing) {
+ gst_element_set_state (element, GST_STATE_PAUSED);
+ }
+ }
+
+ res = gst_play_bin_send_event_to_sink (GST_PLAY_BIN (element), event);
+
+ if (flush && res) {
+ /* need to reset the stream time to 0 after a flushing seek */
+ gst_pipeline_set_new_stream_time (GST_PIPELINE (element), 0);
+ if (was_playing)
+ /* and continue playing */
+ gst_element_set_state (element, GST_STATE_PLAYING);
+ }
+ return res;
+}
+
+/* We only want to send the event to a single sink (overriding GstBin's
+ * behaviour), but we want to keep GstPipeline's behaviour - wrapping seek
+ * events appropriately. So, this is a messy duplication of code. */
+static gboolean
+gst_play_bin_send_event (GstElement * element, GstEvent * event)
+{
+ gboolean res = FALSE;
+ GstEventType event_type = GST_EVENT_TYPE (event);
+
+
+ switch (event_type) {
+ case GST_EVENT_SEEK:
+ res = do_playbin_seek (element, event);
+ break;
+ default:
+ res = gst_play_bin_send_event_to_sink (GST_PLAY_BIN (element), event);
+ break;
+ }
+
+ return res;
+}
+
static GstStateChangeReturn
gst_play_bin_change_state (GstElement * element, GstStateChange transition)
{