gmyth-stream/client/src/gmyth-stream-client.c
author melunko
Wed Apr 11 22:24:39 2007 +0100 (2007-04-11)
branchtrunk
changeset 527 eebe6df8aa11
parent 487 ab3aa66009de
child 534 cb1c3e2988b9
permissions -rw-r--r--
[svn r532] Fixed segmentation fault at program_info_print/debug function
     1 #ifdef HAVE_CONFIG_H
     2 #include "config.h"
     3 #endif
     4 
     5 #include <sys/types.h>
     6 #include <sys/socket.h>
     7 #include <netdb.h>
     8 #include <netinet/in.h>
     9 #include <unistd.h>
    10 #include <glib.h>
    11 #include <glib/gprintf.h>
    12 #include <string.h>
    13 
    14 
    15 #include "gmyth-stream-client.h"
    16 
    17 
    18 #define GMYTH_STREAM_CLIENT_GET_PRIVATE(obj) \
    19     (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_TYPE_STREAM_CLIENT, GMythStreamClientPrivate))
    20 
    21 
    22 typedef struct _GMythStreamClientPrivate GMythStreamClientPrivate;
    23 
    24 struct _GMythStreamClientPrivate
    25 {
    26 	GList *streams;
    27 	struct hostent *host;
    28 	gint sock;
    29 	gboolean connected;
    30    	struct sockaddr_in addr;
    31 };
    32 
    33 typedef struct _StreamData StreamData;
    34 
    35 struct _StreamData
    36 {
    37 	guint id;
    38 	guint port;
    39     gint s;
    40 };
    41 
    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,
    47 														 guint stream_id);
    48 
    49 
    50 G_DEFINE_TYPE(GMythStreamClient, gmyth_stream_client, G_TYPE_OBJECT)
    51 
    52 static void
    53 gmyth_stream_client_class_init (GMythStreamClientClass *klass)
    54 {
    55 	GObjectClass *gobject_class;
    56 	gobject_class = (GObjectClass *) klass;
    57 
    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;
    61 }
    62 
    63 static void
    64 gmyth_stream_client_init (GMythStreamClient *self)
    65 {
    66 }
    67 
    68 static void
    69 gmyth_stream_client_dispose (GObject *object)
    70 {
    71     gmyth_stream_client_disconnect (GMYTH_STREAM_CLIENT (object));
    72 }
    73 
    74 
    75 static void
    76 gmyth_stream_client_finalize (GObject *object)
    77 {
    78 }
    79 
    80 GMythStreamClient*
    81 gmyth_stream_client_new ()
    82 {
    83 	return GMYTH_STREAM_CLIENT (g_object_new (GMYTH_TYPE_STREAM_CLIENT, NULL));
    84 }
    85 
    86 gboolean
    87 gmyth_stream_client_connect (GMythStreamClient *self, const gchar *server, guint port)
    88 {
    89 	GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
    90 	g_return_val_if_fail (priv->connected == FALSE, TRUE);
    91 
    92 	priv->sock = socket (PF_INET, SOCK_STREAM, 0);
    93 	if (priv->sock == -1) {
    94 	    g_debug ("Fail to create sock");
    95 	    return FALSE;
    96 	}
    97 
    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);
   103 
   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);
   107 	    priv->sock = -1;
   108 	    return FALSE;
   109 	}
   110 
   111     priv->connected = TRUE;
   112     return TRUE;
   113 }
   114 
   115 void
   116 gmyth_stream_client_disconnect (GMythStreamClient *self)
   117 {
   118     GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
   119 
   120 	g_return_if_fail (priv->connected == FALSE);
   121 
   122 	GList *lst = priv->streams;
   123 
   124 	for (; lst != NULL; lst = lst->next) {
   125 		StreamData *data = (StreamData *) lst->data;
   126 		gmyth_stream_client_close_stream (self, data->id);
   127 	}
   128 
   129 	close (priv->sock);
   130 	shutdown (priv->sock, SHUT_RDWR);
   131     priv->sock = -1;
   132     priv->connected = FALSE;
   133 }
   134 
   135 guint
   136 gmyth_stream_client_open_stream (GMythStreamClient *self,
   137                 const gchar* file_name,
   138                 const gchar* mux,
   139                 const gchar* vcodec,
   140                 guint vbitrate,
   141                 gdouble fps,
   142                 const gchar* acodec,
   143                 guint abitrate,
   144 				guint width, guint height,
   145 				guint port,
   146 				const gchar* opt)
   147 {
   148 	gchar *cmd;
   149 	StreamData *data = NULL;
   150 	GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
   151 
   152 	g_return_val_if_fail (priv->connected == TRUE, FALSE);
   153 	g_return_val_if_fail (file_name != NULL, FALSE);
   154 
   155 	cmd = g_strdup_printf ("SETUP %s %s %s %d %f %s %d %d %d %d %s\n",
   156 					file_name,
   157 					(mux == NULL? "X" : mux),
   158 					(vcodec == NULL ? "X" : vcodec),
   159 					vbitrate,
   160 					fps,
   161 					(acodec == NULL ? "X" : acodec),
   162 					abitrate,
   163 					width, height, port,
   164 					(opt == NULL ? "X" : opt));
   165 
   166 	if (send (priv->sock, cmd, strlen (cmd), MSG_CONFIRM) == -1) {
   167 		g_free (cmd);
   168 		return -1;
   169 	}
   170 	g_free (cmd);
   171 
   172 
   173 	data = g_new0 (StreamData, 1);
   174 	data->port = port;
   175 	data->id = data->s = socket (PF_INET, SOCK_STREAM, 0);
   176 
   177 
   178 	priv->streams = g_list_append (priv->streams, data);
   179 	return data->id;
   180 }
   181 
   182 static gchar**
   183 _parse_return (int fd)
   184 {
   185 
   186 }
   187 
   188 gboolean
   189 gmyth_stream_client_play_stream (GMythStreamClient *self,
   190 								guint stream_id)
   191 {
   192 	GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
   193 	StreamData *data;
   194 	struct sockaddr_in addr;
   195 	gchar **retval;
   196 
   197 	g_return_val_if_fail (priv->connected == TRUE, FALSE);
   198 
   199 	data = gmtyh_stream_client_get_streamdata (self, stream_id);
   200 	g_return_val_if_fail (data != NULL, FALSE);
   201 
   202 	if (send (priv->sock, "PLAY\n", 5, MSG_MORE) == -1) {
   203 		return FALSE;
   204 	}
   205 
   206 	retval = _read_message (priv->sock);
   207 
   208 	g_usleep (10 * G_USEC_PER_SEC);
   209 
   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");
   217 
   218 	return TRUE;
   219 }
   220 
   221 void
   222 gmyth_stream_client_pause_stream (GMythStreamClient *self,
   223 									guint stream_id)
   224 {
   225 	GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
   226 
   227 	g_return_if_fail (priv->connected == TRUE);
   228 
   229 	if (send (priv->sock, "PAUSE\n", 6, MSG_MORE) == -1) {
   230 		return;
   231 	}
   232 }
   233 
   234 void
   235 gmyth_stream_client_close_stream (GMythStreamClient *self,
   236                     			  guint stream_id)
   237 {
   238 	GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
   239 
   240 	g_return_if_fail (priv->connected == TRUE);
   241 	if (send (priv->sock, "STOP\n", 5, MSG_MORE) == -1) {
   242 		return;
   243 	}
   244 	//TODO: remove from streams list
   245 }
   246 
   247 static StreamData*
   248 gmtyh_stream_client_get_streamdata (GMythStreamClient *self,
   249 									guint stream_id)
   250 {
   251 	GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
   252 	GList *lst;
   253 
   254 	lst = priv->streams;
   255 	for (; lst != NULL; lst = lst->next) {
   256 		StreamData *data = (StreamData *) lst->data;
   257 		if (data->id == stream_id) {
   258 			return data;
   259 		}
   260 	}
   261 	return NULL;
   262 }