[telepathy-stream-engine/master] Switch Xv adapter depending on TV-out status
Olivier Crête
olivier.crete at collabora.co.uk
Thu Dec 17 09:19:21 PST 2009
---
src/tp-stream-engine.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 168 insertions(+), 0 deletions(-)
diff --git a/src/tp-stream-engine.c b/src/tp-stream-engine.c
index 0b65393..e4d787b 100644
--- a/src/tp-stream-engine.c
+++ b/src/tp-stream-engine.c
@@ -29,6 +29,7 @@
#include <netinet/ip.h>
#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
#include <libhal.h>
@@ -55,6 +56,9 @@
#define BUS_NAME "org.maemo.Telepathy.StreamEngine"
#define OBJECT_PATH "/org/maemo/Telepathy/StreamEngine"
+#define VIDEO_JACK_UDI "/org/freedesktop/Hal/devices/platform_soc_audio_logicaldev_input"
+#define VIDEO_JACK_PROPERTY "input.jack.type"
+
static void
_create_pipeline (TpStreamEngine *self);
@@ -166,6 +170,11 @@ struct _TpStreamEnginePrivate
GPtrArray *audio_objects;
GHashTable *object_threads;
+
+ DBusGConnection *system_bus_connection;
+ LibHalContext *libhal_ctx;
+
+ gboolean has_tv_out;
};
static void
@@ -354,6 +363,18 @@ tp_stream_engine_dispose (GObject *object)
if (priv->dispose_has_run)
return;
+ if (self->priv->libhal_ctx)
+ {
+ libhal_ctx_shutdown (self->priv->libhal_ctx, NULL);
+ libhal_ctx_free (self->priv->libhal_ctx);
+ self->priv->libhal_ctx = NULL;
+ }
+
+ if (self->priv->system_bus_connection)
+ {
+ dbus_g_connection_unref (self->priv->system_bus_connection);
+ self->priv->system_bus_connection = NULL;
+ }
if (self->priv->reset_failcount_id)
{
@@ -1514,6 +1535,14 @@ preview_size_changed (TpStreamEngineVideoPreview *videopreview,
}
+static void
+set_xv_device (TpStreamEngineVideoPreview *preview, gboolean has_tvout)
+{
+ gchar *device = has_tvout ? "1" : "0";
+
+ g_object_set (preview, "xv-device", device, NULL);
+}
+
/**
* tp_stream_engine_create_preview_window
*
@@ -1540,6 +1569,8 @@ tp_stream_engine_create_preview_window (StreamEngineSvcStreamEngine *iface,
return;
}
+ set_xv_device (preview, self->priv->has_tv_out);
+
g_mutex_lock (self->priv->mutex);
self->priv->preview_sinks = g_list_prepend (self->priv->preview_sinks,
preview);
@@ -1604,6 +1635,7 @@ tp_stream_engine_get_preview_window (StreamEngineSvcStreamEngine *iface,
return;
}
+ set_xv_device (preview, self->priv->has_tv_out);
g_mutex_lock (self->priv->mutex);
self->priv->preview = preview;
@@ -1749,6 +1781,140 @@ tp_stream_engine_attach_to_channel (StreamEngineSvcStreamEngine *iface,
g_signal_emit (self, signals[HANDLING_CHANNEL], 0);
}
+static gboolean
+has_tvout (TpStreamEngine *self)
+{
+ char **values = NULL;
+ int i;
+ DBusError error;
+ gboolean has_video = FALSE;
+
+
+ dbus_error_init (&error);
+
+ values = libhal_device_get_property_strlist (self->priv->libhal_ctx,
+ VIDEO_JACK_UDI, VIDEO_JACK_PROPERTY, NULL);
+
+ if (dbus_error_is_set (&error))
+ {
+ g_warning ("Could not get property list for %s:%s: %s",
+ VIDEO_JACK_UDI, VIDEO_JACK_PROPERTY, error.message);
+ dbus_error_free (&error);
+ return;
+ }
+
+ if (values)
+ {
+ for (i = 0; values[i]; i++)
+ {
+ if (!strcmp ("video-out", values[i]))
+ {
+ has_video = TRUE;
+ break;
+ }
+ }
+ }
+ g_strfreev (values);
+
+ return has_video;
+}
+
+static void
+libhal_property_modified (LibHalContext *ctx,
+ const char *udi,
+ const char *key,
+ dbus_bool_t is_removed,
+ dbus_bool_t is_added)
+{
+ TpStreamEngine *self = libhal_ctx_get_user_data (ctx);
+ gboolean has_tv_out_new;
+
+ if (strcmp (udi, VIDEO_JACK_UDI) || strcmp (key, VIDEO_JACK_PROPERTY))
+ return;
+
+ has_tv_out_new = has_tvout (self);
+
+ if (has_tv_out_new != self->priv->has_tv_out)
+ {
+ GList *item;
+
+ g_debug ("TV out %s, switching preview's Xv adapter",
+ has_tv_out_new ? "enabled" : "disabled");
+
+ self->priv->has_tv_out = has_tv_out_new;
+
+ g_mutex_lock (self->priv->mutex);
+ if (self->priv->preview)
+ set_xv_device (self->priv->preview, has_tv_out_new);
+
+ for (item = self->priv->preview_sinks; item; item = g_list_next (item))
+ set_xv_device (item->data, has_tv_out_new);
+ g_mutex_unlock (self->priv->mutex);
+ }
+}
+
+static void
+setup_hal (TpStreamEngine *self)
+{
+ DBusError error;
+ GError *gerror = NULL;
+
+ dbus_error_init (&error);
+ self->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM,
+ &gerror);
+ if (!self->priv->system_bus_connection)
+ {
+ g_error ("Unable to connect to DBus: %s", gerror->message);
+ g_clear_error (&gerror);
+ return;
+ }
+
+ self->priv->libhal_ctx = libhal_ctx_new ();
+
+ if (!libhal_ctx_set_dbus_connection (self->priv->libhal_ctx,
+ dbus_g_connection_get_connection (
+ self->priv->system_bus_connection)))
+ {
+ g_error ("Error setting dbus connection on hal ctx: %s", error.message);
+ dbus_error_free (&error);
+ return;
+ }
+
+ if (!libhal_ctx_init (self->priv->libhal_ctx, &error))
+ {
+ g_error ("Hal context initializing failure %s", error.message);
+ dbus_error_free (&error);
+ return;
+ }
+
+ libhal_ctx_set_user_data (self->priv->libhal_ctx, self);
+
+ libhal_ctx_set_device_property_modified (self->priv->libhal_ctx,
+ libhal_property_modified);
+
+
+ if (libhal_device_exists (self->priv->libhal_ctx, VIDEO_JACK_UDI, &error))
+ {
+ if (!libhal_device_add_property_watch (self->priv->libhal_ctx,
+ VIDEO_JACK_UDI, &error))
+ {
+ g_warning ("Could not add property watch: %s", error.message);
+ dbus_error_free (&error);
+ return;
+ }
+
+ self->priv->has_tv_out = has_tvout (self);
+ }
+ else
+ {
+ g_warning ("No video jack found: Video out support disabled: %s",
+ error.message);
+ dbus_error_free (&error);
+ return;
+ }
+
+}
+
void
tp_stream_engine_register (TpStreamEngine *self)
{
@@ -1775,6 +1941,8 @@ tp_stream_engine_register (TpStreamEngine *self)
if (request_name_result == DBUS_REQUEST_NAME_REPLY_EXISTS)
g_error ("Failed to acquire bus name, stream engine already running?");
+
+ setup_hal (self);
}
static TfStream *
--
1.5.6.5
More information about the telepathy-commits
mailing list