#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include "gmyth-stream-client.h" #define GMYTH_STREAM_CLIENT_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_TYPE_STREAM_CLIENT, GMythStreamClientPrivate)) typedef struct _GMythStreamClientPrivate GMythStreamClientPrivate; struct _GMythStreamClientPrivate { GList *streams; gint sock; gboolean connected; }; typedef struct _StreamData StreamData; struct _StreamData { guint id; guint port; }; static void gmyth_stream_client_class_init (GMythStreamClientClass *klass); static void gmyth_stream_client_init (GMythStreamClient *object); static void gmyth_stream_client_dispose (GObject *object); static void gmyth_stream_client_finalize (GObject *object); G_DEFINE_TYPE(GMythStreamClient, gmyth_stream_client, G_TYPE_OBJECT) static void gmyth_stream_client_class_init (GMythStreamClientClass *klass) { GObjectClass *gobject_class; gobject_class = (GObjectClass *) klass; g_type_class_add_private (klass, sizeof (GMythStreamClientPrivate)); gobject_class->dispose = gmyth_stream_client_dispose; gobject_class->finalize = gmyth_stream_client_finalize; } static void gmyth_stream_client_init (GMythStreamClient *self) { } static void gmyth_stream_client_dispose (GObject *object) { gmyth_stream_client_disconnect (GMYTH_STREAM_CLIENT (object)); } static void gmyth_stream_client_finalize (GObject *object) { } GMythStreamClient* gmyth_stream_client_new () { return GMYTH_STREAM_CLIENT (g_object_new (GMYTH_TYPE_STREAM_CLIENT, NULL)); } gboolean gmyth_stream_client_connect (GMythStreamClient *self, const gchar *server, guint port) { struct sockaddr_in addr; struct hostent *hp; GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); g_return_val_if_fail (priv->connected == FALSE, TRUE); priv->sock = socket (PF_INET, SOCK_STREAM, 0); if (priv->sock == -1) { g_debug ("Fail to create sock"); return FALSE; } memset(&addr, 0, sizeof(addr)); hp = gethostbyname(server); memcpy(&addr, *(hp->h_addr_list),sizeof(struct in_addr)); addr.sin_family = AF_INET; addr.sin_port = htons (port); if (connect (priv->sock, (struct sockaddr *) &addr, sizeof (addr)) == -1) { g_debug ("Fail to connect with server"); shutdown (priv->sock, SHUT_RDWR); priv->sock = -1; return FALSE; } priv->connected = TRUE; return TRUE; } void gmyth_stream_client_disconnect (GMythStreamClient *self) { GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); g_return_if_fail (priv->connected == FALSE); GList *lst = priv->streams; for (; lst != NULL; lst = lst->next) { StreamData *data = (StreamData *) lst->data; gmyth_stream_client_close_stream (self, data->id); } close (priv->sock); shutdown (priv->sock, SHUT_RDWR); priv->sock = -1; priv->connected = FALSE; } guint gmyth_stream_client_open_stream (GMythStreamClient *self, const gchar* file_name, const gchar* mux, const gchar* vcodec, guint vbitrate, gdouble fps, const gchar* acodec, guint abitrate, guint width, guint height, guint port, const gchar* opt) { gint stream_id = 0; gchar *cmd; StreamData *data = NULL; GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); g_return_val_if_fail (priv->connected == TRUE, FALSE); if (send (priv->sock, "SETUP", 5, MSG_CONFIRM) == -1) return -1; cmd = g_strdup_printf ("%s %s %s %d %f %s %d %d %d %d %s", file_name, mux, vcodec, vbitrate, fps, acodec, abitrate, width, height, port, opt); if (send (priv->sock, cmd, strlen (cmd), MSG_CONFIRM) == -1) { g_free (cmd); return -1; } g_free (cmd); data = g_new0 (StreamData, 1); data->id = stream_id; data->port = port; priv->streams = g_list_append (priv->streams, data); return stream_id; } gboolean gmyth_stream_client_play_stream (GMythStreamClient *self, guint stream_id) { GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); g_return_val_if_fail (priv->connected == TRUE, FALSE); if (send (priv->sock, "PLAY", 4, MSG_MORE) == -1) { return FALSE; } return TRUE; } void gmyth_stream_client_pause_stream (GMythStreamClient *self, guint stream_id) { GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); g_return_if_fail (priv->connected == TRUE); if (send (priv->sock, "PAUSE", 5, MSG_MORE) == -1) { return; } } void gmyth_stream_client_close_stream (GMythStreamClient *self, guint stream_id) { GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); g_return_if_fail (priv->connected == TRUE); if (send (priv->sock, "STOP", 4, MSG_MORE) == -1) { return; } //TODO: remove from streams list }