Properly handle setting source endpoint URI while the route is playing
authorMikko Rasa <mikko.rasa@movial.fi>
Thu, 30 Oct 2008 14:43:26 +0000 (16:43 +0200)
committerMikko Rasa <mikko.rasa@movial.fi>
Thu, 30 Oct 2008 14:43:26 +0000 (16:43 +0200)
src/octopus-backend-gst.c
src/octopus-backend-gst.h

index ce28279..a322079 100644 (file)
@@ -219,12 +219,37 @@ set_property_all(OctopusRoute *route,
       g_object_set_property(G_OBJECT(elem), prop_name, value);
       ret = TRUE;
     }
+    gst_object_unref(GST_OBJECT(elem));
   }
   gst_iterator_free(iter);
 
   return ret;
 }
 
+static void
+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);
+
+  for(iter2 = elems; iter2; iter2 = iter2->next) {
+    GstElement *elem=(GstElement *)iter2->data;
+
+    gst_element_set_state(elem, GST_STATE_NULL);
+    gst_bin_remove(bin, elem);
+    gst_object_unref(elem);
+  }
+  g_slist_free(elems);
+}
+
 /*
  * OctopusBackend implementation
  */
@@ -642,6 +667,7 @@ static void
 route_mapping_changed(OctopusRoute *route,
                       gpointer user_data)
 {
+  RouteDataGst     *data;
   OctopusBackend   *backend;
   OctopusComponent *component;
   gchar            **sources;
@@ -651,6 +677,7 @@ route_mapping_changed(OctopusRoute *route,
 
   g_debug("Route mapping changed");
 
+  data = (RouteDataGst *)g_object_get_data(G_OBJECT(route), "data");
   g_object_get(G_OBJECT(route), "backend", &backend,
                                 "sources", &sources,
                                 "sinks", &sinks,
@@ -658,12 +685,10 @@ route_mapping_changed(OctopusRoute *route,
   g_assert(OCTOPUS_IS_BACKEND_GST(backend));
 
   if(pipeline_desc) {
-    RouteDataGst *data;
-    GError       *err;
+    GError *err;
 
     g_debug("Using forced pipeline description: %s", pipeline_desc);
 
-    data = (RouteDataGst *)g_object_get_data(G_OBJECT(route), "data");
     if(data->pipeline) {
       gst_element_set_state(data->pipeline, GST_STATE_NULL);
       gst_object_unref(data->pipeline);
@@ -676,6 +701,8 @@ route_mapping_changed(OctopusRoute *route,
       g_warning("Pipeline is invalid: %s", err->message);
 
   } else {
+    clear_bin(GST_BIN(data->pipeline));
+
     for(i = 0; sources[i]; ++i) {
       GSList   *chain = NULL;
       unsigned j;
@@ -700,14 +727,35 @@ route_endpoint_changed(OctopusRoute    *route,
                        OctopusEndpoint *endpoint,
                        gpointer        user_data)
 {
-  RouteDataGst *data;
-  GstIterator  *iter;
-  gpointer     element;
-  gboolean     found = FALSE;
+  RouteDataGst   *data;
+  OctopusBackend *backend;
+  GstIterator    *iter;
+  gpointer       element;
+  gboolean       found = FALSE;
 
   g_debug("Route endpoint '%s' changed", endpoint->name);
 
   data = (RouteDataGst *)g_object_get_data(G_OBJECT(route), "data");
+  g_object_get(G_OBJECT(route), "backend", &backend, NULL);
+  g_assert(OCTOPUS_IS_BACKEND_GST(backend));
+
+  if(data->have_type && octopus_backend_get_component_by_endpoint(backend, endpoint->name, OCTOPUS_ENDPOINT_SOURCE)) {
+    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);
+    }
+    if(state==GST_STATE_PLAYING) {
+      octopus_route_play(route);
+    }
+
+    return;
+  }
 
   iter = gst_bin_iterate_recurse(GST_BIN(data->pipeline));
   while(!found && gst_iterator_next(iter, &element) == GST_ITERATOR_OK) {
@@ -732,11 +780,18 @@ have_type(GstTypeFind *typefind,
           gpointer    user_data)
 {
   OctopusRoute   *route;
+  RouteDataGst   *data;
   OctopusBackend *backend;
   GstPad         *pad;
   gchar          *caps_str;
 
   route = OCTOPUS_ROUTE(user_data);
+
+  data = (RouteDataGst *)g_object_get_data(G_OBJECT(route), "data");
+  if(data->have_type)
+    return;
+  data->have_type=TRUE;
+
   g_object_get(G_OBJECT(route), "backend", &backend, NULL);
   g_assert(OCTOPUS_IS_BACKEND_GST(backend));
 
index c93b19c..0dfec44 100644 (file)
@@ -56,6 +56,7 @@ struct _OctopusRouteDataGst
 {
   GstElement *pipeline;
   GstElement *fakesink;
+  gboolean   have_type;
   gboolean   ready;
   guint      timeout_tag;
   GSList     *modules;