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