totem r5095 - in trunk: . src src/backend



Author: hadess
Date: Sun Feb 10 13:27:46 2008
New Revision: 5095
URL: http://svn.gnome.org/viewvc/totem?rev=5095&view=rev

Log:
2008-02-10  Bastien Nocera  <hadess hadess net>

	Patch from Zaheer Abbas Merali <zaheermerali gmail com>

	* src/backend/bacon-video-widget-gst-0.10.c:
	(bacon_video_widget_get_channels_file),
	(bacon_video_widget_can_play),
	(bacon_video_widget_dvb_get_adapter_type),
	(bacon_video_widget_get_mrls):
	Add support for listing DVB channels from the channels.conf
	file, with DVB type-specific filtering

	* src/totem-menu.c: (on_play_dvb_activate),
	(update_drives_menu_items), (update_dvb_menu_items),
	(on_movie_menu_select): Add DVB cards to the Movie menu



Modified:
   trunk/ChangeLog
   trunk/src/backend/bacon-video-widget-gst-0.10.c
   trunk/src/totem-menu.c

Modified: trunk/src/backend/bacon-video-widget-gst-0.10.c
==============================================================================
--- trunk/src/backend/bacon-video-widget-gst-0.10.c	(original)
+++ trunk/src/backend/bacon-video-widget-gst-0.10.c	Sun Feb 10 13:27:46 2008
@@ -3889,6 +3889,25 @@
   return res;
 }
 
+static char *
+bacon_video_widget_get_channels_file (void)
+{
+  gchar *filename;
+
+  filename = g_strdup(g_getenv("GST_DVB_CHANNELS_CONF"));
+  if (filename == NULL) {
+    gchar *directory;
+
+    guint major, minor, micro, nano;
+    gst_version(&major, &minor, &micro, &nano);
+    directory = g_strdup_printf (".gstreamer-%d.%d", major, minor);
+    filename = g_build_filename (g_get_home_dir (), directory, "dvb-channels.conf", NULL);
+    g_free (directory);
+  }
+
+  return filename;
+}
+
 BaconVideoWidgetCanPlayStatus
 bacon_video_widget_can_play (BaconVideoWidget * bvw, TotemDiscMediaType type)
 {
@@ -3914,6 +3933,25 @@
       }
       break;
     }
+    case MEDIA_TYPE_DVB: {
+      GstElement *element;
+      gchar *filename;
+
+      element = gst_element_factory_make ("dvbbasebin", "test_dvb");
+      if (element == NULL)
+        return BVW_CAN_PLAY_MISSING_PLUGINS;
+
+      g_object_unref (element);
+
+      filename = bacon_video_widget_get_channels_file ();
+      if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
+        res = BVW_CAN_PLAY_SUCCESS;
+      } else {
+        res = BVW_CAN_PLAY_MISSING_CHANNELS;
+      }
+      g_free(filename);
+      break;
+    }
     case MEDIA_TYPE_CDDA:
     default:
       res = BVW_CAN_PLAY_UNSUPPORTED;
@@ -3924,6 +3962,62 @@
   return res;
 }
 
+static char
+bacon_video_widget_dvb_get_adapter_type (const char *device)
+{
+  GstElement *dvbelement;
+  GstBus *dvbbus;
+  GstPipeline * pipeline;
+  char adapter_type;
+
+  adapter_type = 'U'; /* unknown */
+  /* let gstreamer know what adapter to use */
+  g_setenv("GST_DVB_ADAPTER", device, TRUE);
+
+  /* HACK: find out type of adapter so it filters out the channels
+   * based on the type of adapter. */
+  dvbelement = gst_element_factory_make ("dvbsrc", "test_dvbsrc");
+  g_object_set (G_OBJECT (dvbelement), "adapter", atoi (device), NULL);
+
+  pipeline = GST_PIPELINE (gst_pipeline_new (""));
+  gst_bin_add (GST_BIN (pipeline), dvbelement);
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY);
+  gst_element_get_state (GST_ELEMENT (pipeline), NULL, NULL, GST_CLOCK_TIME_NONE);
+  dvbbus = gst_pipeline_get_bus (pipeline);
+
+  while (gst_bus_have_pending (dvbbus)) {
+    GstMessage* msg;
+
+    msg = gst_bus_pop (dvbbus);
+    if (msg->type == GST_MESSAGE_ELEMENT && msg->src == GST_OBJECT(dvbelement)) {
+      GstStructure *structure;
+
+      structure = msg->structure;
+
+      if (g_str_equal (gst_structure_get_name (structure), "dvb-adapter") != FALSE) {
+        const GValue* val;
+
+	val = gst_structure_get_value (structure, "type");
+	if (val) {
+	  if (g_str_equal (g_value_get_string (val), "DVB-T") != FALSE) {
+	    adapter_type = 'T';
+	  } else if (g_str_equal (g_value_get_string (val), "DVB-S") != FALSE) {
+	    adapter_type = 'S';
+	  }
+	}
+	gst_message_unref (msg);
+	break;
+      }
+    }
+    gst_message_unref (msg);
+  }
+  g_object_unref (dvbbus);
+  gst_element_set_state (GST_ELEMENT(pipeline), GST_STATE_NULL);
+  g_object_unref (G_OBJECT(pipeline));
+
+  return adapter_type;
+}
+
 gchar **
 bacon_video_widget_get_mrls (BaconVideoWidget * bvw, TotemDiscMediaType type,
 			     const char *device)
@@ -4009,11 +4103,44 @@
       mrls = (char **) g_ptr_array_free (array, FALSE);
       break;
     }
-
     case MEDIA_TYPE_DVB: {
-      //FIXME
-    }
+      gchar* filename;
+      gchar* contents;
+      GPtrArray *array;
+      gchar adapter_type;
+
+      adapter_type = bacon_video_widget_dvb_get_adapter_type (device);
+      filename = bacon_video_widget_get_channels_file ();
 
+      if (g_file_get_contents (filename, &contents, NULL, NULL) != FALSE) {
+        gchar **lines, *line;
+        guint i;
+
+	lines = g_strsplit (contents, "\n", 0);
+        array = g_ptr_array_new ();
+
+	for (i = 0; lines[i] != NULL; i++) {
+	  line = lines[i];
+
+          if (line[0] != '#') {
+            gchar** fields = g_strsplit(line, ":", 0);
+            if ((g_strv_length (fields) == 13 && adapter_type == 'T') ||
+                (g_strv_length (fields) == 8 && adapter_type == 'S')) {
+              g_ptr_array_add (array, g_strdup_printf("dvb://%s", fields[0]));
+            }
+            g_strfreev(fields);
+          }
+          line = lines[++i];
+        }
+        g_strfreev(lines);
+      } else {
+        return NULL;
+      }
+      if (array->len >= 1)
+      	g_ptr_array_add (array, NULL);
+      mrls = (char **) g_ptr_array_free (array, FALSE);
+      break;
+    }
     default:
       mrls = NULL;
       break;

Modified: trunk/src/totem-menu.c
==============================================================================
--- trunk/src/totem-menu.c	(original)
+++ trunk/src/totem-menu.c	Sun Feb 10 13:27:46 2008
@@ -743,6 +743,19 @@
 	totem_action_play_media_device (totem, device_path);
 }
 
+/* Play DVB menu items */
+
+static void
+on_play_dvb_activate (GtkAction *action, Totem *totem)
+{
+	int adapter;
+	char *str;
+
+	adapter = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (action), "adapter"));
+	str = g_strdup_printf ("%d", adapter);
+	totem_action_play_media (totem, MEDIA_TYPE_DVB, str);
+	g_free (str);
+}
 /* A GnomeVFSDrive and GnomeVFSVolume share many similar methods, but do not
    share a base class other than GObject. */
 static char *
@@ -841,28 +854,11 @@
 }
 
 static void
-on_movie_menu_select (GtkMenuItem *movie_menuitem, Totem *totem)
+update_drives_menu_items (GtkMenuItem *movie_menuitem, Totem *totem)
 {
 	GList *devices, *volumes, *drives, *i;
 	guint position;
 
-	if (totem->drives_changed == FALSE)
-		return;
-
-	/* Remove old UI */
-	gtk_ui_manager_remove_ui (totem->ui_manager, totem->devices_ui_id);
-	gtk_ui_manager_ensure_update (totem->ui_manager);
-
-	/* Create new ActionGroup */
-	if (totem->devices_action_group) {
-		gtk_ui_manager_remove_action_group (totem->ui_manager,
-				totem->devices_action_group);
-		g_object_unref (totem->devices_action_group);
-	}
-	totem->devices_action_group = gtk_action_group_new ("devices-action-group");
-	gtk_ui_manager_insert_action_group (totem->ui_manager,
-			totem->devices_action_group, -1);
-
 	/* Create a list of suitable devices */
 	devices = NULL;
 
@@ -896,7 +892,6 @@
 		position++;
 		add_device_to_menu (i->data, position, totem);
 	}
-	gtk_ui_manager_ensure_update (totem->ui_manager);
 
 	g_list_foreach (devices, (GFunc) g_object_unref, NULL);
 	g_list_free (devices);
@@ -905,6 +900,72 @@
 }
 
 static void
+update_dvb_menu_items (GtkMenuItem *movie_menuitem, Totem *totem)
+{
+	guint i;
+
+	for (i = 0 ; i < 8 ; i++) {
+		char *devicenode;
+
+		devicenode = g_strdup_printf("/dev/dvb/adapter%d/frontend0", i);
+
+		if (g_file_test (devicenode, G_FILE_TEST_EXISTS) != FALSE) {
+			char* label;
+			char *name;
+			GtkAction* action;
+
+			label = g_strdup_printf (_("Play DVB Adapter %d"), i);
+			name = g_strdup_printf (_("dvbdevice%d"), i);
+			action = gtk_action_new (name, label, NULL, NULL);
+
+			g_object_set (G_OBJECT(action), "icon-name", "camera-video", "sensitive", TRUE, NULL);
+			gtk_action_group_add_action (totem->devices_action_group, action);
+			g_object_unref (action);
+			gtk_ui_manager_add_ui (totem->ui_manager, totem->devices_ui_id,
+					       "/tmw-menubar/movie/devices-placeholder", name, name,
+					       GTK_UI_MANAGER_MENUITEM, FALSE);
+			g_object_set_data_full (G_OBJECT (action),
+						"adapter", GINT_TO_POINTER (i), NULL);
+			g_signal_connect (G_OBJECT (action), "activate",
+					  G_CALLBACK (on_play_dvb_activate), totem);
+		}
+		g_free (devicenode);
+	}
+}
+
+static void
+on_movie_menu_select (GtkMenuItem *movie_menuitem, Totem *totem)
+{
+	//FIXME we should check whether there's new DVB items
+/*	if (totem->drives_changed == FALSE)
+		return;
+*/
+	/* Remove old UI */
+	gtk_ui_manager_remove_ui (totem->ui_manager, totem->devices_ui_id);
+	gtk_ui_manager_ensure_update (totem->ui_manager);
+
+	/* Create new ActionGroup */
+	if (totem->devices_action_group) {
+		gtk_ui_manager_remove_action_group (totem->ui_manager,
+				totem->devices_action_group);
+		g_object_unref (totem->devices_action_group);
+	}
+	totem->devices_action_group = gtk_action_group_new ("devices-action-group");
+	gtk_ui_manager_insert_action_group (totem->ui_manager,
+			totem->devices_action_group, -1);
+
+
+	if (totem->drives_changed == FALSE)
+		update_drives_menu_items (movie_menuitem, totem);
+
+	/* check for DVB */
+	/* FIXME we should only update if we have an updated as per HAL */
+	update_dvb_menu_items (movie_menuitem, totem);
+
+	gtk_ui_manager_ensure_update (totem->ui_manager);
+}
+
+static void
 on_gnome_vfs_monitor_event (GnomeVFSVolumeMonitor *monitor,
 		GnomeVFSDrive *drive,
 		Totem *totem)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]