Add some synchronization for more robustness
authorMikko Rasa <mikko.rasa@movial.fi>
Tue, 18 Nov 2008 12:41:45 +0000 (14:41 +0200)
committerMikko Rasa <mikko.rasa@movial.fi>
Tue, 18 Nov 2008 12:41:45 +0000 (14:41 +0200)
Clear have_type flag on mapping change
Do nothing in play/pause/stop if the route already was in the correct state

src/octopus-backend-gst.c
src/octopus-route.c

index a8da44b..c555e63 100644 (file)
@@ -258,23 +258,24 @@ clear_bin(GstBin *bin)
 {
   GstIterator *iter;
   gpointer    eptr;
-  GSList      *elems = NULL;
-  GSList      *iter2;
 
   iter = gst_bin_iterate_elements(bin);
-  while(gst_iterator_next(iter, &eptr) == GST_ITERATOR_OK) {
-    elems = g_slist_prepend(elems, eptr);
-  }
-  gst_iterator_free(iter);
+  while(1) {
+    GstIteratorResult result;
 
-  for(iter2 = elems; iter2; iter2 = iter2->next) {
-    GstElement *elem=(GstElement *)iter2->data;
+    result = gst_iterator_next(iter, &eptr);
+    if(result == GST_ITERATOR_RESYNC) {
+      gst_iterator_resync(iter);
+    } else if(result == GST_ITERATOR_OK) {
+      GstElement *elem=(GstElement *)eptr;
 
-    gst_element_set_state(elem, GST_STATE_NULL);
-    gst_bin_remove(bin, elem);
-    gst_object_unref(elem);
+      gst_bin_remove(bin, elem);
+      gst_object_unref(elem);
+    }
+    else
+      break;
   }
-  g_slist_free(elems);
+  gst_iterator_free(iter);
 }
 
 /*
@@ -379,11 +380,16 @@ play_route(OctopusBackend *backend,
            OctopusRoute   *route)
 {
   RouteDataGst         *data;
+  GstState             state;
   GstStateChangeReturn ret;
   gint                 hook_ret;
 
   data = (RouteDataGst *)g_object_get_data(G_OBJECT(route), "data");
 
+  gst_element_get_state(data->pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
+  if(state==GST_STATE_PLAYING)
+    return TRUE;
+
   g_signal_emit(backend, hooks[HOOK_PLAY], 0, route, &hook_ret);
   if(hook_ret)
     return hook_ret > 0;
@@ -413,6 +419,7 @@ pause_route(OctopusBackend *backend,
             OctopusRoute   *route)
 {
   RouteDataGst         *data;
+  GstState             state;
   GstStateChangeReturn ret;
 
   data = (RouteDataGst *)g_object_get_data(G_OBJECT(route), "data");
@@ -422,6 +429,10 @@ pause_route(OctopusBackend *backend,
     data->timeout_tag = 0;
   }
 
+  gst_element_get_state(data->pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
+  if(state==GST_STATE_PAUSED)
+    return TRUE;
+
   ret = gst_element_set_state(GST_ELEMENT(data->pipeline), GST_STATE_PAUSED);
   if(ret == GST_STATE_CHANGE_FAILURE) {
     g_debug("Pipeline failed to pause playback");
@@ -438,6 +449,7 @@ stop_route(OctopusBackend *backend,
            OctopusRoute   *route)
 {
   RouteDataGst         *data;
+  GstState             state;
   GstStateChangeReturn ret;
   int                  hook_ret;
 
@@ -448,6 +460,10 @@ stop_route(OctopusBackend *backend,
     data->timeout_tag = 0;
   }
 
+  gst_element_get_state(data->pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
+  if(state==GST_STATE_NULL)
+    return TRUE;
+
   g_signal_emit(backend, hooks[HOOK_STOP], 0, route, &hook_ret);
   if(hook_ret)
     return hook_ret > 0;
@@ -751,7 +767,9 @@ route_mapping_changed(OctopusRoute *route,
       g_warning("Pipeline is invalid: %s", err->message);
 
   } else {
+    octopus_route_stop(route);
     clear_bin(GST_BIN(data->pipeline));
+    data->have_type = FALSE;
 
     for(i = 0; sources[i]; ++i) {
       GSList   *chain = NULL;
@@ -793,13 +811,10 @@ route_endpoint_changed(OctopusRoute    *route,
     GstState state;
 
     g_debug("Changed endpoint is a source, rebuilding route");
-    data->have_type = FALSE;
 
     gst_element_get_state(data->pipeline, &state, NULL, 0);
-    if(state!=GST_STATE_NULL) {
-      octopus_route_stop(route);
-      route_mapping_changed(route, NULL);
-    }
+    route_mapping_changed(route, NULL);
+
     if(state==GST_STATE_PLAYING) {
       octopus_route_play(route);
     }
index 922fff3..c3571f4 100644 (file)
@@ -377,18 +377,21 @@ octopus_route_get_endpoint(OctopusRoute *route,
 gboolean
 octopus_route_play(OctopusRoute *route)
 {
+  g_debug("Starting playback");
   return octopus_backend_play_route(route->priv->backend, route);
 }
 
 gboolean
 octopus_route_pause(OctopusRoute *route)
 {
+  g_debug("Pausing playback");
   return octopus_backend_pause_route(route->priv->backend, route);
 }
 
 gboolean
 octopus_route_stop(OctopusRoute *route)
 {
+  g_debug("Stopping playback");
   return octopus_backend_stop_route(route->priv->backend, route);
 }