summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2010-12-27 19:06:03 +0100
committerWim Taymans <wim.taymans@collabora.co.uk>2010-12-27 19:06:03 +0100
commitaea1b57df9af4348dfd34c3c201dd64a80ffc234 (patch)
tree847da30e77569a94bf73ac133fc411c3429b56af
parent45d589e0432cf3c2248400efb44cdc8e9cd6f92a (diff)
texture: add avahi support
-rw-r--r--clutter-shared/Makefile.am2
-rw-r--r--clutter-shared/clutter-shared-video-texture.c170
-rw-r--r--configure.ac8
-rw-r--r--examples/Makefile.am1
4 files changed, 180 insertions, 1 deletions
diff --git a/clutter-shared/Makefile.am b/clutter-shared/Makefile.am
index 215f59c..6b8a6a6 100644
--- a/clutter-shared/Makefile.am
+++ b/clutter-shared/Makefile.am
@@ -59,7 +59,7 @@ AM_CFLAGS = \
lib_LTLIBRARIES = libclutter-shared-@CLUTTER_SHARED_MAJORMINOR@.la
-libclutter_shared_@CLUTTER_SHARED_MAJORMINOR@_la_LIBADD = $(CLUTTER_GST_LIBS) $(GST_RTSP_SERVER_LIBS)
+libclutter_shared_@CLUTTER_SHARED_MAJORMINOR@_la_LIBADD = $(CLUTTER_GST_LIBS) $(GST_RTSP_SERVER_LIBS) $(AVAHI_LIBS)
libclutter_shared_@CLUTTER_SHARED_MAJORMINOR@_la_LDFLAGS = @CLUTTER_SHARED_LT_LDFLAGS@
cluttersharedheadersdir = $(includedir)/clutter-@CLUTTER_API_VERSION@/clutter-shared
diff --git a/clutter-shared/clutter-shared-video-texture.c b/clutter-shared/clutter-shared-video-texture.c
index 048266c..924ffbf 100644
--- a/clutter-shared/clutter-shared-video-texture.c
+++ b/clutter-shared/clutter-shared-video-texture.c
@@ -46,6 +46,14 @@
#include <gst/rtsp-server/rtsp-server.h>
#include <clutter-gst/clutter-gst.h>
+#include <avahi-client/client.h>
+#include <avahi-client/publish.h>
+#include <avahi-common/alternative.h>
+#include <avahi-common/error.h>
+#include <avahi-common/timeval.h>
+#include <avahi-glib/glib-watch.h>
+#include <avahi-glib/glib-malloc.h>
+
#include "clutter-shared-enum-types.h"
#include "clutter-shared-video-texture.h"
@@ -53,8 +61,14 @@ struct _ClutterSharedVideoTexturePrivate
{
GstRTSPServer *server;
GstRTSPMediaFactoryURI *factory;
+
+ gchar *name;
+ AvahiClient *client;
+ AvahiEntryGroup *group;
};
+static void create_services (AvahiClient *c, ClutterSharedVideoTexture *video_texture);
+
enum {
PROP_0,
@@ -206,11 +220,154 @@ clutter_shared_video_texture_class_init (ClutterSharedVideoTextureClass *klass)
}
static void
+entry_group_callback (AvahiEntryGroup *g, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void *userdata)
+{
+ ClutterSharedVideoTexture *video_texture = userdata;
+ ClutterSharedVideoTexturePrivate *priv = video_texture->priv;
+
+ /* Called whenever the entry group state changes */
+ switch (state)
+ {
+ case AVAHI_ENTRY_GROUP_ESTABLISHED :
+ /* The entry group has been established successfully */
+ fprintf(stderr, "Service '%s' successfully established.\n", priv->name);
+ break;
+
+ case AVAHI_ENTRY_GROUP_COLLISION : {
+ char *n;
+
+ /* A service name collision with a remote service
+ * happened. Let's pick a new name */
+ n = avahi_alternative_service_name (priv->name);
+ avahi_free (priv->name);
+ priv->name = n;
+
+ fprintf(stderr, "Service name collision, renaming service to '%s'\n", priv->name);
+
+ /* And recreate the services */
+ create_services (avahi_entry_group_get_client (g), video_texture);
+ break;
+ }
+
+ case AVAHI_ENTRY_GROUP_FAILURE :
+
+ fprintf(stderr, "Entry group failure: %s\n", avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))));
+ /* Some kind of failure happened while we were registering our services */
+ break;
+
+ case AVAHI_ENTRY_GROUP_UNCOMMITED:
+ case AVAHI_ENTRY_GROUP_REGISTERING:
+ break;
+ }
+}
+
+static void
+create_services (AvahiClient *c, ClutterSharedVideoTexture *video_texture)
+{
+ ClutterSharedVideoTexturePrivate *priv = video_texture->priv;
+ int ret;
+ gchar *n;
+
+ /* If this is the first time we're called, let's create a new
+ * entry group if necessary */
+ if (!priv->group) {
+ if (!(priv->group = avahi_entry_group_new (c, entry_group_callback, video_texture))) {
+ fprintf(stderr, "avahi_entry_group_new() failed: %s\n", avahi_strerror (avahi_client_errno (c)));
+ goto fail;
+ }
+ }
+
+ /* If the group is empty (either because it was just created, or
+ * because it was reset previously, add our entries. */
+ if (avahi_entry_group_is_empty (priv->group)) {
+
+ /* Add the service for IPP */
+ if ((ret = avahi_entry_group_add_service (priv->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
+ 0, priv->name, "_rtsp._tcp", NULL, NULL, 8554, NULL)) < 0) {
+
+ if (ret == AVAHI_ERR_COLLISION) {
+ goto collision;
+ }
+
+ fprintf(stderr, "Failed to add _rtsp._tcp service: %s\n", avahi_strerror (ret));
+ goto fail;
+ }
+
+ /* Tell the server to register the service */
+ if ((ret = avahi_entry_group_commit (priv->group)) < 0) {
+ fprintf(stderr, "Failed to commit entry group: %s\n", avahi_strerror(ret));
+ goto fail;
+ }
+ }
+ return;
+
+collision:
+ /* A service name collision with a local service happened. Let's
+ * pick a new name */
+ n = avahi_alternative_service_name (priv->name);
+ avahi_free (priv->name);
+ priv->name = n;
+
+ fprintf(stderr, "Service name collision, renaming service to '%s'\n", priv->name);
+
+ avahi_entry_group_reset (priv->group);
+ create_services (c, video_texture);
+ return;
+
+fail:
+ return;
+}
+
+
+static void
+client_callback (AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata)
+{
+ ClutterSharedVideoTexture *video_texture = userdata;
+ ClutterSharedVideoTexturePrivate *priv = video_texture->priv;
+
+ video_texture = CLUTTER_SHARED_VIDEO_TEXTURE (userdata);
+
+ /* Called whenever the client or server state changes */
+ switch (state)
+ {
+ case AVAHI_CLIENT_S_RUNNING:
+ /* The server has startup successfully and registered its host
+ * name on the network, so it's time to create our services */
+ create_services (c, video_texture);
+ break;
+
+ case AVAHI_CLIENT_FAILURE:
+ g_warning ("Client failure: %s\n", avahi_strerror (avahi_client_errno (c)));
+ break;
+
+ case AVAHI_CLIENT_S_COLLISION:
+ /* Let's drop our registered services. When the server is back
+ * in AVAHI_SERVER_RUNNING state we will register them
+ * again with the new host name. */
+ case AVAHI_CLIENT_S_REGISTERING:
+ /* The server records are now being established. This
+ * might be caused by a host name change. We need to wait
+ * for our own records to register until the host name is
+ * properly esatblished. */
+ if (priv->group)
+ avahi_entry_group_reset (priv->group);
+ break;
+
+ case AVAHI_CLIENT_CONNECTING:
+ break;
+ }
+}
+
+
+static void
clutter_shared_video_texture_init (ClutterSharedVideoTexture *video_texture)
{
ClutterSharedVideoTexturePrivate *priv;
ClutterSharedVideoTextureClass *klass;
GstRTSPMediaMapping *mapping;
+ const AvahiPoll *poll_api;
+ AvahiGLibPoll *glib_poll;
+ int error;
video_texture->priv = priv =
G_TYPE_INSTANCE_GET_PRIVATE (video_texture,
@@ -237,6 +394,19 @@ clutter_shared_video_texture_init (ClutterSharedVideoTexture *video_texture)
/* attach the server to the custom maincontext */
if (gst_rtsp_server_attach (priv->server, klass->context) == 0)
g_warning ("could not attach server to mainloop");
+
+ /* Create the GLIB Adaptor */
+ glib_poll = avahi_glib_poll_new (NULL, G_PRIORITY_DEFAULT);
+ poll_api = avahi_glib_poll_get (glib_poll);
+
+ priv->name = avahi_strdup ("ClutterShared");
+
+ /* Allocate a new client */
+ priv->client = avahi_client_new (poll_api, 0, client_callback, video_texture, &error);
+ /* Check wether creating the client object succeeded */
+ if (!priv->client) {
+ g_warning ("Failed to create client: %s\n", avahi_strerror(error));
+ }
}
/**
diff --git a/configure.ac b/configure.ac
index 06669bd..e1ac42f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -125,6 +125,11 @@ PKG_CHECK_MODULES(GST_RTSP_SERVER, [$pkg_modules])
dnl ========================================================================
+pkg_modules="avahi-client >= 0.6.0 avahi-glib"
+PKG_CHECK_MODULES(AVAHI, [$pkg_modules])
+
+dnl ========================================================================
+
m4_define([maintainer_flags_default], [yes])
AC_ARG_ENABLE([maintainer-flags],
[AC_HELP_STRING([--enable-maintainer-flags=@<:@no/yes@:>@],
@@ -191,6 +196,9 @@ AC_SUBST(GST_LIBS)
AC_SUBST(CLUTTER_GST_CFLAGS)
AC_SUBST(CLUTTER_GST_LIBS)
+AC_SUBST(AVAHI_CFLAGS)
+AC_SUBST(AVAHI_LIBS)
+
AC_OUTPUT([
Makefile
build/Makefile
diff --git a/examples/Makefile.am b/examples/Makefile.am
index b85ce0b..af08de2 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -11,6 +11,7 @@ shared_video_player_CFLAGS = $(CLUTTER_SHARED_CFLAGS) $(CLUTTER_GST_CFLAGS) $(GS
shared_video_player_LDFLAGS = \
$(CLUTTER_SHARED_LIBS) \
$(CLUTTER_GST_LIBS) \
+ $(AVAHI_LIBS) \
$(GST_LIBS) \
$(top_builddir)/clutter-shared/libclutter-shared-@CLUTTER_SHARED_MAJORMINOR@.la