diff -r 92acf23b87f0 -r cb1c3e2988b9 gmyth-stream/client/src/gmyth-stream-client.c --- a/gmyth-stream/client/src/gmyth-stream-client.c Wed Apr 11 18:39:39 2007 +0100 +++ b/gmyth-stream/client/src/gmyth-stream-client.c Thu Apr 12 20:35:08 2007 +0100 @@ -4,65 +4,130 @@ #include #include +#include #include #include #include #include #include #include - +#include #include "gmyth-stream-client.h" +#define BUFFER_SIZE 1024 #define GMYTH_STREAM_CLIENT_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_TYPE_STREAM_CLIENT, GMythStreamClientPrivate)) + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_TYPE_STREAM_CLIENT,\ + GMythStreamClientPrivate)) + + +typedef struct _sock _socket; +struct _sock +{ + gint fd; + struct sockaddr_in addr; +}; typedef struct _GMythStreamClientPrivate GMythStreamClientPrivate; - struct _GMythStreamClientPrivate { - GList *streams; - struct hostent *host; - gint sock; - gboolean connected; - struct sockaddr_in addr; + const gchar *host; + _socket* sock; + _socket* sock_stream; + gboolean connected; }; -typedef struct _StreamData StreamData; -struct _StreamData -{ - guint id; - guint port; - gint s; -}; - -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); -static StreamData* gmtyh_stream_client_get_streamdata (GMythStreamClient *self, - guint stream_id); +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 _socket* +create_socket (const gchar* hostname, gint port) +{ + _socket* sock = (_socket*)g_malloc(sizeof(_socket)); + + sock->fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock->fd == -1) { + g_debug ("Fail to create sock"); + g_free(sock); + return NULL; + } + + sock->addr.sin_family = AF_INET; + sock->addr.sin_addr.s_addr = inet_addr(hostname); + sock->addr.sin_port = htons(port); + + if (connect (sock->fd, (struct sockaddr *) &(sock->addr), \ + sizeof (sock->addr)) == -1) { + g_debug ("Fail to connect with server"); + g_free(sock); + return NULL; + } + + return sock; +} + +static gint +read_message (int socket) +{ + gint64 total_read = 0; + gint result = -1; + gchar buffer[BUFFER_SIZE]; + gchar** response; + + total_read = recv(socket, buffer, BUFFER_SIZE, 0); + + if (total_read > 0) { + response = g_strsplit_set(buffer, " +\n", 8); + + if ( g_ascii_strcasecmp(response[0], "OK") == 0 ) { + + int payload = atoi(response[1]); + + if (payload == 0) + result = 0; + + else if (payload == 1) { + total_read = recv(socket, buffer, BUFFER_SIZE, 0); + + response = g_strsplit_set(buffer, "+\n", 8); + result = atoi(response[1]); + } + + } + + g_strfreev(response); + } + + return result; +} + + static void gmyth_stream_client_class_init (GMythStreamClientClass *klass) { - GObjectClass *gobject_class; - gobject_class = (GObjectClass *) 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; + 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) { + GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); + priv->sock = NULL; + priv->sock_stream = NULL; } static void @@ -80,33 +145,18 @@ GMythStreamClient* gmyth_stream_client_new () { - return GMYTH_STREAM_CLIENT (g_object_new (GMYTH_TYPE_STREAM_CLIENT, NULL)); + return GMYTH_STREAM_CLIENT (g_object_new (GMYTH_TYPE_STREAM_CLIENT, NULL)); } gboolean gmyth_stream_client_connect (GMythStreamClient *self, const gchar *server, guint port) { - GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); - g_return_val_if_fail (priv->connected == FALSE, TRUE); + 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(&(priv->addr), 0, sizeof(priv->addr)); - priv->host = gethostbyname(server); - memcpy(&(priv->addr), *(priv->host->h_addr_list), sizeof(struct in_addr)); - priv->addr.sin_family = AF_INET; - priv->addr.sin_port = htons (port); - - if (connect (priv->sock, (struct sockaddr *) &(priv->addr), sizeof (priv->addr)) == -1) { - g_debug ("Fail to connect with server"); - shutdown (priv->sock, SHUT_RDWR); - priv->sock = -1; - return FALSE; - } + priv->host = server; + priv->sock = create_socket (server, port); + if (priv->sock == NULL) return FALSE; priv->connected = TRUE; return TRUE; @@ -117,146 +167,85 @@ { GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); - g_return_if_fail (priv->connected == FALSE); + g_return_if_fail (priv->connected == TRUE); - 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; + close (priv->sock->fd); + //shutdown (priv->sock->fd, SHUT_RDWR); + priv->sock->fd = -1; priv->connected = FALSE; } -guint +gint 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) + const gchar* file_name, + const gchar* mux, + const gchar* vcodec, + guint vbitrate, + gdouble fps, + const gchar* acodec, + guint abitrate, + guint width, guint height, + const gchar* opt) { - gchar *cmd; - StreamData *data = NULL; - GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); + gchar *cmd; + GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); - g_return_val_if_fail (priv->connected == TRUE, FALSE); - g_return_val_if_fail (file_name != NULL, FALSE); + g_return_val_if_fail (priv->connected == TRUE, FALSE); + g_return_val_if_fail (file_name != NULL, FALSE); - cmd = g_strdup_printf ("SETUP %s %s %s %d %f %s %d %d %d %d %s\n", - file_name, - (mux == NULL? "X" : mux), - (vcodec == NULL ? "X" : vcodec), - vbitrate, - fps, - (acodec == NULL ? "X" : acodec), - abitrate, - width, height, port, - (opt == NULL ? "X" : opt)); + cmd = g_strdup_printf ("SETUP %s %s %s %d %f %s %d %d %d %s\n", + file_name, + (mux == NULL ? "X" : mux), + (vcodec == NULL ? "X" : vcodec), + vbitrate, + fps, + (acodec == NULL ? "X" : acodec), + abitrate, + width, height, + (opt == NULL ? "X" : opt) ); - if (send (priv->sock, cmd, strlen (cmd), MSG_CONFIRM) == -1) { - g_free (cmd); - return -1; - } - g_free (cmd); + if (send (priv->sock->fd, cmd, strlen (cmd), MSG_CONFIRM) == -1) { + g_free (cmd); + return -1; + } + g_free (cmd); + read_message(priv->sock->fd); - data = g_new0 (StreamData, 1); - data->port = port; - data->id = data->s = socket (PF_INET, SOCK_STREAM, 0); - - - priv->streams = g_list_append (priv->streams, data); - return data->id; + return 0; } -static gchar** -_parse_return (int fd) + +gint +gmyth_stream_client_play_stream (GMythStreamClient *self) { + GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); -} + g_return_val_if_fail (priv->connected == TRUE, FALSE); -gboolean -gmyth_stream_client_play_stream (GMythStreamClient *self, - guint stream_id) -{ - GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); - StreamData *data; - struct sockaddr_in addr; - gchar **retval; + if (send (priv->sock->fd, "PLAY\n", 5, 0) == -1) { + return -1; + } - g_return_val_if_fail (priv->connected == TRUE, FALSE); + gint port = read_message(priv->sock->fd); + priv->sock_stream = create_socket(priv->host, port); - data = gmtyh_stream_client_get_streamdata (self, stream_id); - g_return_val_if_fail (data != NULL, FALSE); - - if (send (priv->sock, "PLAY\n", 5, MSG_MORE) == -1) { - return FALSE; - } - - retval = _read_message (priv->sock); - - g_usleep (10 * G_USEC_PER_SEC); - - memset(&addr, 0, sizeof(addr)); - memcpy(&addr, *(priv->host->h_addr_list), sizeof(struct in_addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons (data->port); - g_debug ("request connection on port %d", data->port); - if (connect(data->s,(struct sockaddr*) &addr, sizeof(addr)) == -1) - g_warning ("Fail to connect to server"); - - return TRUE; + return priv->sock_stream->fd; } void -gmyth_stream_client_pause_stream (GMythStreamClient *self, - guint stream_id) +gmyth_stream_client_close_stream (GMythStreamClient *self) { - GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); + GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); + g_return_if_fail (priv->connected == TRUE); - g_return_if_fail (priv->connected == TRUE); + if (send (priv->sock->fd, "STOP\n", 5, 0) == -1) { + return; + } - if (send (priv->sock, "PAUSE\n", 6, MSG_MORE) == -1) { - return; - } + read_message(priv->sock->fd); + + close(priv->sock_stream->fd); + g_free(priv->sock_stream); + priv->sock_stream = NULL; } - -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\n", 5, MSG_MORE) == -1) { - return; - } - //TODO: remove from streams list -} - -static StreamData* -gmtyh_stream_client_get_streamdata (GMythStreamClient *self, - guint stream_id) -{ - GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self); - GList *lst; - - lst = priv->streams; - for (; lst != NULL; lst = lst->next) { - StreamData *data = (StreamData *) lst->data; - if (data->id == stream_id) { - return data; - } - } - return NULL; -}