6 #include <sys/socket.h>
9 #include <netinet/in.h>
12 #include <glib/gprintf.h>
16 #include "gmyth-stream-client.h"
18 #define BUFFER_SIZE 1024
20 #define GMYTH_STREAM_CLIENT_GET_PRIVATE(obj) \
21 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_TYPE_STREAM_CLIENT,\
22 GMythStreamClientPrivate))
25 typedef struct _sock _socket;
29 struct sockaddr_in addr;
33 typedef struct _GMythStreamClientPrivate GMythStreamClientPrivate;
34 struct _GMythStreamClientPrivate
43 static void gmyth_stream_client_class_init (GMythStreamClientClass *klass);
44 static void gmyth_stream_client_init (GMythStreamClient *object);
45 static void gmyth_stream_client_dispose (GObject *object);
46 static void gmyth_stream_client_finalize (GObject *object);
49 G_DEFINE_TYPE(GMythStreamClient, gmyth_stream_client, G_TYPE_OBJECT)
53 create_socket (const gchar* hostname, gint port)
55 _socket* sock = (_socket*)g_malloc(sizeof(_socket));
57 sock->fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
59 g_debug ("Fail to create sock");
64 sock->addr.sin_family = AF_INET;
65 sock->addr.sin_addr.s_addr = inet_addr(hostname);
66 sock->addr.sin_port = htons(port);
68 if (connect (sock->fd, (struct sockaddr *) &(sock->addr), \
69 sizeof (sock->addr)) == -1) {
70 g_debug ("Fail to connect with server");
79 read_message (int socket)
81 gint64 total_read = 0;
83 gchar buffer[BUFFER_SIZE];
86 total_read = recv(socket, buffer, BUFFER_SIZE, 0);
89 response = g_strsplit_set(buffer, " +\n", 8);
91 if ( g_ascii_strcasecmp(response[0], "OK") == 0 ) {
93 int payload = atoi(response[1]);
98 else if (payload == 1) {
99 total_read = recv(socket, buffer, BUFFER_SIZE, 0);
101 response = g_strsplit_set(buffer, "+\n", 8);
102 result = atoi(response[1]);
107 g_strfreev(response);
115 gmyth_stream_client_class_init (GMythStreamClientClass *klass)
117 GObjectClass *gobject_class;
118 gobject_class = (GObjectClass *) klass;
120 g_type_class_add_private (klass, sizeof (GMythStreamClientPrivate));
121 gobject_class->dispose = gmyth_stream_client_dispose;
122 gobject_class->finalize = gmyth_stream_client_finalize;
126 gmyth_stream_client_init (GMythStreamClient *self)
128 GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
130 priv->sock_stream = NULL;
134 gmyth_stream_client_dispose (GObject *object)
136 gmyth_stream_client_disconnect (GMYTH_STREAM_CLIENT (object));
141 gmyth_stream_client_finalize (GObject *object)
146 gmyth_stream_client_new ()
148 return GMYTH_STREAM_CLIENT (g_object_new (GMYTH_TYPE_STREAM_CLIENT, NULL));
152 gmyth_stream_client_connect (GMythStreamClient *self, const gchar *server, guint port)
154 GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
155 g_return_val_if_fail (priv->connected == FALSE, TRUE);
158 priv->sock = create_socket (server, port);
159 if (priv->sock == NULL) return FALSE;
161 priv->connected = TRUE;
166 gmyth_stream_client_disconnect (GMythStreamClient *self)
168 GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
170 g_return_if_fail (priv->connected == TRUE);
172 close (priv->sock->fd);
173 //shutdown (priv->sock->fd, SHUT_RDWR);
175 priv->connected = FALSE;
179 gmyth_stream_client_open_stream (GMythStreamClient *self,
180 const gchar* file_name,
187 guint width, guint height,
191 GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
193 g_return_val_if_fail (priv->connected == TRUE, FALSE);
194 g_return_val_if_fail (file_name != NULL, FALSE);
196 cmd = g_strdup_printf ("SETUP %s %s %s %d %f %s %d %d %d %s\n",
198 (mux == NULL ? "X" : mux),
199 (vcodec == NULL ? "X" : vcodec),
202 (acodec == NULL ? "X" : acodec),
205 (opt == NULL ? "X" : opt) );
207 if (send (priv->sock->fd, cmd, strlen (cmd), MSG_CONFIRM) == -1) {
213 read_message(priv->sock->fd);
220 gmyth_stream_client_play_stream (GMythStreamClient *self)
222 GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
224 g_return_val_if_fail (priv->connected == TRUE, FALSE);
226 if (send (priv->sock->fd, "PLAY\n", 5, 0) == -1) {
230 gint port = read_message(priv->sock->fd);
231 priv->sock_stream = create_socket(priv->host, port);
233 return priv->sock_stream->fd;
237 gmyth_stream_client_close_stream (GMythStreamClient *self)
239 GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
240 g_return_if_fail (priv->connected == TRUE);
242 if (send (priv->sock->fd, "STOP\n", 5, 0) == -1) {
246 read_message(priv->sock->fd);
248 close(priv->sock_stream->fd);
249 g_free(priv->sock_stream);
250 priv->sock_stream = NULL;