1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/gmyth-stream/client/src/gmyth-stream-client.c Wed Apr 04 00:10:15 2007 +0100
1.3 @@ -0,0 +1,218 @@
1.4 +#ifdef HAVE_CONFIG_H
1.5 +#include "config.h"
1.6 +#endif
1.7 +
1.8 +#include <sys/types.h>
1.9 +#include <sys/socket.h>
1.10 +#include <netdb.h>
1.11 +#include <netinet/in.h>
1.12 +#include <unistd.h>
1.13 +#include <glib.h>
1.14 +#include <glib/gprintf.h>
1.15 +#include <string.h>
1.16 +
1.17 +#include "gmyth-stream-client.h"
1.18 +
1.19 +
1.20 +#define GMYTH_STREAM_CLIENT_GET_PRIVATE(obj) \
1.21 + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_TYPE_STREAM_CLIENT, GMythStreamClientPrivate))
1.22 +
1.23 +
1.24 +typedef struct _GMythStreamClientPrivate GMythStreamClientPrivate;
1.25 +
1.26 +struct _GMythStreamClientPrivate
1.27 +{
1.28 + GList *streams;
1.29 + gint sock;
1.30 + gboolean connected;
1.31 +};
1.32 +
1.33 +typedef struct _StreamData StreamData;
1.34 +
1.35 +struct _StreamData
1.36 +{
1.37 + guint id;
1.38 + guint port;
1.39 +};
1.40 +
1.41 +static void gmyth_stream_client_class_init (GMythStreamClientClass *klass);
1.42 +static void gmyth_stream_client_init (GMythStreamClient *object);
1.43 +static void gmyth_stream_client_dispose (GObject *object);
1.44 +static void gmyth_stream_client_finalize (GObject *object);
1.45 +
1.46 +G_DEFINE_TYPE(GMythStreamClient, gmyth_stream_client, G_TYPE_OBJECT)
1.47 +
1.48 +static void
1.49 +gmyth_stream_client_class_init (GMythStreamClientClass *klass)
1.50 +{
1.51 + GObjectClass *gobject_class;
1.52 +
1.53 + gobject_class = (GObjectClass *) klass;
1.54 +
1.55 + g_type_class_add_private (klass, sizeof (GMythStreamClientPrivate));
1.56 +
1.57 + gobject_class->dispose = gmyth_stream_client_dispose;
1.58 + gobject_class->finalize = gmyth_stream_client_finalize;
1.59 +}
1.60 +
1.61 +static void
1.62 +gmyth_stream_client_init (GMythStreamClient *self)
1.63 +{
1.64 +}
1.65 +
1.66 +static void
1.67 +gmyth_stream_client_dispose (GObject *object)
1.68 +{
1.69 + gmyth_stream_client_disconnect (GMYTH_STREAM_CLIENT (object));
1.70 +}
1.71 +
1.72 +
1.73 +static void
1.74 +gmyth_stream_client_finalize (GObject *object)
1.75 +{
1.76 +}
1.77 +
1.78 +GMythStreamClient*
1.79 +gmyth_stream_client_new ()
1.80 +{
1.81 + return GMYTH_STREAM_CLIENT (g_object_new (GMYTH_TYPE_STREAM_CLIENT, NULL));
1.82 +}
1.83 +
1.84 +gboolean
1.85 +gmyth_stream_client_connect (GMythStreamClient *self, const gchar *server, guint port)
1.86 +{
1.87 + struct sockaddr_in addr;
1.88 + struct hostent *hp;
1.89 +
1.90 + GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
1.91 +
1.92 + g_return_val_if_fail (priv->connected == FALSE, TRUE);
1.93 +
1.94 + priv->sock = socket (PF_INET, SOCK_STREAM, 0);
1.95 + if (priv->sock == -1) {
1.96 + g_debug ("Fail to create sock");
1.97 + return FALSE;
1.98 + }
1.99 +
1.100 + memset(&addr, 0, sizeof(addr));
1.101 + hp = gethostbyname(server);
1.102 + memcpy(&addr, *(hp->h_addr_list),sizeof(struct in_addr));
1.103 + addr.sin_family = AF_INET;
1.104 + addr.sin_port = htons (port);
1.105 +
1.106 + if (connect (priv->sock, (struct sockaddr *) &addr, sizeof (addr)) == -1) {
1.107 + g_debug ("Fail to connect with server");
1.108 + shutdown (priv->sock, SHUT_RDWR);
1.109 + priv->sock = -1;
1.110 + return FALSE;
1.111 + }
1.112 +
1.113 + priv->connected = TRUE;
1.114 + return TRUE;
1.115 +}
1.116 +
1.117 +void
1.118 +gmyth_stream_client_disconnect (GMythStreamClient *self)
1.119 +{
1.120 + GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
1.121 +
1.122 + g_return_if_fail (priv->connected == FALSE);
1.123 +
1.124 + GList *lst = priv->streams;
1.125 +
1.126 + for (; lst != NULL; lst = lst->next) {
1.127 + StreamData *data = (StreamData *) lst->data;
1.128 + gmyth_stream_client_close_stream (self, data->id);
1.129 + }
1.130 +
1.131 + close (priv->sock);
1.132 + shutdown (priv->sock, SHUT_RDWR);
1.133 + priv->sock = -1;
1.134 + priv->connected = FALSE;
1.135 +}
1.136 +
1.137 +guint
1.138 +gmyth_stream_client_open_stream (GMythStreamClient *self,
1.139 + const gchar* file_name,
1.140 + const gchar* mux,
1.141 + const gchar* vcodec,
1.142 + guint vbitrate,
1.143 + gdouble fps,
1.144 + const gchar* acodec,
1.145 + guint abitrate,
1.146 + guint width, guint height,
1.147 + guint port,
1.148 + const gchar* opt)
1.149 +{
1.150 + gint stream_id = 0;
1.151 + gchar *cmd;
1.152 + StreamData *data = NULL;
1.153 + GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
1.154 +
1.155 + g_return_val_if_fail (priv->connected == TRUE, FALSE);
1.156 +
1.157 + if (send (priv->sock, "SETUP", 5, MSG_CONFIRM) == -1)
1.158 + return -1;
1.159 +
1.160 + cmd = g_strdup_printf ("%s %s %s %d %f %s %d %d %d %d %s",
1.161 + file_name, mux, vcodec, vbitrate, fps,
1.162 + acodec, abitrate, width, height, port, opt);
1.163 +
1.164 +
1.165 + if (send (priv->sock, cmd, strlen (cmd), MSG_CONFIRM) == -1) {
1.166 + g_free (cmd);
1.167 + return -1;
1.168 + }
1.169 + g_free (cmd);
1.170 +
1.171 +
1.172 + data = g_new0 (StreamData, 1);
1.173 + data->id = stream_id;
1.174 + data->port = port;
1.175 +
1.176 + priv->streams = g_list_append (priv->streams, data);
1.177 + return stream_id;
1.178 +}
1.179 +
1.180 +gboolean
1.181 +gmyth_stream_client_play_stream (GMythStreamClient *self,
1.182 + guint stream_id)
1.183 +{
1.184 + GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
1.185 +
1.186 + g_return_val_if_fail (priv->connected == TRUE, FALSE);
1.187 +
1.188 + if (send (priv->sock, "PLAY", 4, MSG_MORE) == -1) {
1.189 + return FALSE;
1.190 + }
1.191 + return TRUE;
1.192 +}
1.193 +
1.194 +void
1.195 +gmyth_stream_client_pause_stream (GMythStreamClient *self,
1.196 + guint stream_id)
1.197 +{
1.198 + GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
1.199 +
1.200 + g_return_if_fail (priv->connected == TRUE);
1.201 +
1.202 + if (send (priv->sock, "PAUSE", 5, MSG_MORE) == -1) {
1.203 + return;
1.204 + }
1.205 +}
1.206 +
1.207 +void
1.208 +gmyth_stream_client_close_stream (GMythStreamClient *self,
1.209 + guint stream_id)
1.210 +{
1.211 + GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
1.212 +
1.213 + g_return_if_fail (priv->connected == TRUE);
1.214 +
1.215 + if (send (priv->sock, "STOP", 4, MSG_MORE) == -1) {
1.216 + return;
1.217 + }
1.218 +
1.219 + //TODO: remove from streams list
1.220 +
1.221 +}