6 #include <sys/socket.h>
8 #include <netinet/in.h>
11 #include <glib/gprintf.h>
15 #include "gmyth-stream-client.h"
18 #define GMYTH_STREAM_CLIENT_GET_PRIVATE(obj) \
19 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_TYPE_STREAM_CLIENT, GMythStreamClientPrivate))
22 typedef struct _GMythStreamClientPrivate GMythStreamClientPrivate;
24 struct _GMythStreamClientPrivate
30 struct sockaddr_in addr;
33 typedef struct _StreamData StreamData;
42 static void gmyth_stream_client_class_init (GMythStreamClientClass *klass);
43 static void gmyth_stream_client_init (GMythStreamClient *object);
44 static void gmyth_stream_client_dispose (GObject *object);
45 static void gmyth_stream_client_finalize (GObject *object);
46 static StreamData* gmtyh_stream_client_get_streamdata (GMythStreamClient *self,
50 G_DEFINE_TYPE(GMythStreamClient, gmyth_stream_client, G_TYPE_OBJECT)
53 gmyth_stream_client_class_init (GMythStreamClientClass *klass)
55 GObjectClass *gobject_class;
56 gobject_class = (GObjectClass *) klass;
58 g_type_class_add_private (klass, sizeof (GMythStreamClientPrivate));
59 gobject_class->dispose = gmyth_stream_client_dispose;
60 gobject_class->finalize = gmyth_stream_client_finalize;
64 gmyth_stream_client_init (GMythStreamClient *self)
69 gmyth_stream_client_dispose (GObject *object)
71 gmyth_stream_client_disconnect (GMYTH_STREAM_CLIENT (object));
76 gmyth_stream_client_finalize (GObject *object)
81 gmyth_stream_client_new ()
83 return GMYTH_STREAM_CLIENT (g_object_new (GMYTH_TYPE_STREAM_CLIENT, NULL));
87 gmyth_stream_client_connect (GMythStreamClient *self, const gchar *server, guint port)
89 GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
90 g_return_val_if_fail (priv->connected == FALSE, TRUE);
92 priv->sock = socket (PF_INET, SOCK_STREAM, 0);
93 if (priv->sock == -1) {
94 g_debug ("Fail to create sock");
98 memset(&(priv->addr), 0, sizeof(priv->addr));
99 priv->host = gethostbyname(server);
100 memcpy(&(priv->addr), *(priv->host->h_addr_list), sizeof(struct in_addr));
101 priv->addr.sin_family = AF_INET;
102 priv->addr.sin_port = htons (port);
104 if (connect (priv->sock, (struct sockaddr *) &(priv->addr), sizeof (priv->addr)) == -1) {
105 g_debug ("Fail to connect with server");
106 shutdown (priv->sock, SHUT_RDWR);
111 priv->connected = TRUE;
116 gmyth_stream_client_disconnect (GMythStreamClient *self)
118 GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
120 g_return_if_fail (priv->connected == FALSE);
122 GList *lst = priv->streams;
124 for (; lst != NULL; lst = lst->next) {
125 StreamData *data = (StreamData *) lst->data;
126 gmyth_stream_client_close_stream (self, data->id);
130 shutdown (priv->sock, SHUT_RDWR);
132 priv->connected = FALSE;
136 gmyth_stream_client_open_stream (GMythStreamClient *self,
137 const gchar* file_name,
144 guint width, guint height,
149 StreamData *data = NULL;
150 GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
152 g_return_val_if_fail (priv->connected == TRUE, FALSE);
153 g_return_val_if_fail (file_name != NULL, FALSE);
155 cmd = g_strdup_printf ("SETUP %s %s %s %d %f %s %d %d %d %d %s\n",
157 (mux == NULL? "X" : mux),
158 (vcodec == NULL ? "X" : vcodec),
161 (acodec == NULL ? "X" : acodec),
164 (opt == NULL ? "X" : opt));
166 if (send (priv->sock, cmd, strlen (cmd), MSG_CONFIRM) == -1) {
173 data = g_new0 (StreamData, 1);
175 data->id = data->s = socket (PF_INET, SOCK_STREAM, 0);
178 priv->streams = g_list_append (priv->streams, data);
183 _parse_return (int fd)
189 gmyth_stream_client_play_stream (GMythStreamClient *self,
192 GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
194 struct sockaddr_in addr;
197 g_return_val_if_fail (priv->connected == TRUE, FALSE);
199 data = gmtyh_stream_client_get_streamdata (self, stream_id);
200 g_return_val_if_fail (data != NULL, FALSE);
202 if (send (priv->sock, "PLAY\n", 5, MSG_MORE) == -1) {
206 retval = _read_message (priv->sock);
208 g_usleep (10 * G_USEC_PER_SEC);
210 memset(&addr, 0, sizeof(addr));
211 memcpy(&addr, *(priv->host->h_addr_list), sizeof(struct in_addr));
212 addr.sin_family = AF_INET;
213 addr.sin_port = htons (data->port);
214 g_debug ("request connection on port %d", data->port);
215 if (connect(data->s,(struct sockaddr*) &addr, sizeof(addr)) == -1)
216 g_warning ("Fail to connect to server");
222 gmyth_stream_client_pause_stream (GMythStreamClient *self,
225 GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
227 g_return_if_fail (priv->connected == TRUE);
229 if (send (priv->sock, "PAUSE\n", 6, MSG_MORE) == -1) {
235 gmyth_stream_client_close_stream (GMythStreamClient *self,
238 GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
240 g_return_if_fail (priv->connected == TRUE);
241 if (send (priv->sock, "STOP\n", 5, MSG_MORE) == -1) {
244 //TODO: remove from streams list
248 gmtyh_stream_client_get_streamdata (GMythStreamClient *self,
251 GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
255 for (; lst != NULL; lst = lst->next) {
256 StreamData *data = (StreamData *) lst->data;
257 if (data->id == stream_id) {