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@487
|
14 |
#include "gmyth-stream-client.h"
|
renatofilho@487
|
15 |
|
renatofilho@487
|
16 |
|
renatofilho@487
|
17 |
#define GMYTH_STREAM_CLIENT_GET_PRIVATE(obj) \
|
renatofilho@487
|
18 |
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_TYPE_STREAM_CLIENT, GMythStreamClientPrivate))
|
renatofilho@487
|
19 |
|
renatofilho@487
|
20 |
|
renatofilho@487
|
21 |
typedef struct _GMythStreamClientPrivate GMythStreamClientPrivate;
|
renatofilho@487
|
22 |
|
renatofilho@487
|
23 |
struct _GMythStreamClientPrivate
|
renatofilho@487
|
24 |
{
|
renatofilho@487
|
25 |
GList *streams;
|
renatofilho@487
|
26 |
gint sock;
|
renatofilho@487
|
27 |
gboolean connected;
|
renatofilho@487
|
28 |
};
|
renatofilho@487
|
29 |
|
renatofilho@487
|
30 |
typedef struct _StreamData StreamData;
|
renatofilho@487
|
31 |
|
renatofilho@487
|
32 |
struct _StreamData
|
renatofilho@487
|
33 |
{
|
renatofilho@487
|
34 |
guint id;
|
renatofilho@487
|
35 |
guint port;
|
renatofilho@487
|
36 |
};
|
renatofilho@487
|
37 |
|
renatofilho@487
|
38 |
static void gmyth_stream_client_class_init (GMythStreamClientClass *klass);
|
renatofilho@487
|
39 |
static void gmyth_stream_client_init (GMythStreamClient *object);
|
renatofilho@487
|
40 |
static void gmyth_stream_client_dispose (GObject *object);
|
renatofilho@487
|
41 |
static void gmyth_stream_client_finalize (GObject *object);
|
renatofilho@487
|
42 |
|
renatofilho@487
|
43 |
G_DEFINE_TYPE(GMythStreamClient, gmyth_stream_client, G_TYPE_OBJECT)
|
renatofilho@487
|
44 |
|
renatofilho@487
|
45 |
static void
|
renatofilho@487
|
46 |
gmyth_stream_client_class_init (GMythStreamClientClass *klass)
|
renatofilho@487
|
47 |
{
|
renatofilho@487
|
48 |
GObjectClass *gobject_class;
|
renatofilho@487
|
49 |
|
renatofilho@487
|
50 |
gobject_class = (GObjectClass *) klass;
|
renatofilho@487
|
51 |
|
renatofilho@487
|
52 |
g_type_class_add_private (klass, sizeof (GMythStreamClientPrivate));
|
renatofilho@487
|
53 |
|
renatofilho@487
|
54 |
gobject_class->dispose = gmyth_stream_client_dispose;
|
renatofilho@487
|
55 |
gobject_class->finalize = gmyth_stream_client_finalize;
|
renatofilho@487
|
56 |
}
|
renatofilho@487
|
57 |
|
renatofilho@487
|
58 |
static void
|
renatofilho@487
|
59 |
gmyth_stream_client_init (GMythStreamClient *self)
|
renatofilho@487
|
60 |
{
|
renatofilho@487
|
61 |
}
|
renatofilho@487
|
62 |
|
renatofilho@487
|
63 |
static void
|
renatofilho@487
|
64 |
gmyth_stream_client_dispose (GObject *object)
|
renatofilho@487
|
65 |
{
|
renatofilho@487
|
66 |
gmyth_stream_client_disconnect (GMYTH_STREAM_CLIENT (object));
|
renatofilho@487
|
67 |
}
|
renatofilho@487
|
68 |
|
renatofilho@487
|
69 |
|
renatofilho@487
|
70 |
static void
|
renatofilho@487
|
71 |
gmyth_stream_client_finalize (GObject *object)
|
renatofilho@487
|
72 |
{
|
renatofilho@487
|
73 |
}
|
renatofilho@487
|
74 |
|
renatofilho@487
|
75 |
GMythStreamClient*
|
renatofilho@487
|
76 |
gmyth_stream_client_new ()
|
renatofilho@487
|
77 |
{
|
renatofilho@487
|
78 |
return GMYTH_STREAM_CLIENT (g_object_new (GMYTH_TYPE_STREAM_CLIENT, NULL));
|
renatofilho@487
|
79 |
}
|
renatofilho@487
|
80 |
|
renatofilho@487
|
81 |
gboolean
|
renatofilho@487
|
82 |
gmyth_stream_client_connect (GMythStreamClient *self, const gchar *server, guint port)
|
renatofilho@487
|
83 |
{
|
renatofilho@487
|
84 |
struct sockaddr_in addr;
|
renatofilho@487
|
85 |
struct hostent *hp;
|
renatofilho@487
|
86 |
|
renatofilho@487
|
87 |
GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
|
renatofilho@487
|
88 |
|
renatofilho@487
|
89 |
g_return_val_if_fail (priv->connected == FALSE, TRUE);
|
renatofilho@487
|
90 |
|
renatofilho@487
|
91 |
priv->sock = socket (PF_INET, SOCK_STREAM, 0);
|
renatofilho@487
|
92 |
if (priv->sock == -1) {
|
renatofilho@487
|
93 |
g_debug ("Fail to create sock");
|
renatofilho@487
|
94 |
return FALSE;
|
renatofilho@487
|
95 |
}
|
renatofilho@487
|
96 |
|
renatofilho@487
|
97 |
memset(&addr, 0, sizeof(addr));
|
renatofilho@487
|
98 |
hp = gethostbyname(server);
|
renatofilho@487
|
99 |
memcpy(&addr, *(hp->h_addr_list),sizeof(struct in_addr));
|
renatofilho@487
|
100 |
addr.sin_family = AF_INET;
|
renatofilho@487
|
101 |
addr.sin_port = htons (port);
|
renatofilho@487
|
102 |
|
renatofilho@487
|
103 |
if (connect (priv->sock, (struct sockaddr *) &addr, sizeof (addr)) == -1) {
|
renatofilho@487
|
104 |
g_debug ("Fail to connect with server");
|
renatofilho@487
|
105 |
shutdown (priv->sock, SHUT_RDWR);
|
renatofilho@487
|
106 |
priv->sock = -1;
|
renatofilho@487
|
107 |
return FALSE;
|
renatofilho@487
|
108 |
}
|
renatofilho@487
|
109 |
|
renatofilho@487
|
110 |
priv->connected = TRUE;
|
renatofilho@487
|
111 |
return TRUE;
|
renatofilho@487
|
112 |
}
|
renatofilho@487
|
113 |
|
renatofilho@487
|
114 |
void
|
renatofilho@487
|
115 |
gmyth_stream_client_disconnect (GMythStreamClient *self)
|
renatofilho@487
|
116 |
{
|
renatofilho@487
|
117 |
GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
|
renatofilho@487
|
118 |
|
renatofilho@487
|
119 |
g_return_if_fail (priv->connected == FALSE);
|
renatofilho@487
|
120 |
|
renatofilho@487
|
121 |
GList *lst = priv->streams;
|
renatofilho@487
|
122 |
|
renatofilho@487
|
123 |
for (; lst != NULL; lst = lst->next) {
|
renatofilho@487
|
124 |
StreamData *data = (StreamData *) lst->data;
|
renatofilho@487
|
125 |
gmyth_stream_client_close_stream (self, data->id);
|
renatofilho@487
|
126 |
}
|
renatofilho@487
|
127 |
|
renatofilho@487
|
128 |
close (priv->sock);
|
renatofilho@487
|
129 |
shutdown (priv->sock, SHUT_RDWR);
|
renatofilho@487
|
130 |
priv->sock = -1;
|
renatofilho@487
|
131 |
priv->connected = FALSE;
|
renatofilho@487
|
132 |
}
|
renatofilho@487
|
133 |
|
renatofilho@487
|
134 |
guint
|
renatofilho@487
|
135 |
gmyth_stream_client_open_stream (GMythStreamClient *self,
|
renatofilho@487
|
136 |
const gchar* file_name,
|
renatofilho@487
|
137 |
const gchar* mux,
|
renatofilho@487
|
138 |
const gchar* vcodec,
|
renatofilho@487
|
139 |
guint vbitrate,
|
renatofilho@487
|
140 |
gdouble fps,
|
renatofilho@487
|
141 |
const gchar* acodec,
|
renatofilho@487
|
142 |
guint abitrate,
|
renatofilho@487
|
143 |
guint width, guint height,
|
renatofilho@487
|
144 |
guint port,
|
renatofilho@487
|
145 |
const gchar* opt)
|
renatofilho@487
|
146 |
{
|
renatofilho@487
|
147 |
gint stream_id = 0;
|
renatofilho@487
|
148 |
gchar *cmd;
|
renatofilho@487
|
149 |
StreamData *data = NULL;
|
renatofilho@487
|
150 |
GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
|
renatofilho@487
|
151 |
|
renatofilho@487
|
152 |
g_return_val_if_fail (priv->connected == TRUE, FALSE);
|
renatofilho@487
|
153 |
|
renatofilho@487
|
154 |
if (send (priv->sock, "SETUP", 5, MSG_CONFIRM) == -1)
|
renatofilho@487
|
155 |
return -1;
|
renatofilho@487
|
156 |
|
renatofilho@487
|
157 |
cmd = g_strdup_printf ("%s %s %s %d %f %s %d %d %d %d %s",
|
renatofilho@487
|
158 |
file_name, mux, vcodec, vbitrate, fps,
|
renatofilho@487
|
159 |
acodec, abitrate, width, height, port, opt);
|
renatofilho@487
|
160 |
|
renatofilho@487
|
161 |
|
renatofilho@487
|
162 |
if (send (priv->sock, cmd, strlen (cmd), MSG_CONFIRM) == -1) {
|
renatofilho@487
|
163 |
g_free (cmd);
|
renatofilho@487
|
164 |
return -1;
|
renatofilho@487
|
165 |
}
|
renatofilho@487
|
166 |
g_free (cmd);
|
renatofilho@487
|
167 |
|
renatofilho@487
|
168 |
|
renatofilho@487
|
169 |
data = g_new0 (StreamData, 1);
|
renatofilho@487
|
170 |
data->id = stream_id;
|
renatofilho@487
|
171 |
data->port = port;
|
renatofilho@487
|
172 |
|
renatofilho@487
|
173 |
priv->streams = g_list_append (priv->streams, data);
|
renatofilho@487
|
174 |
return stream_id;
|
renatofilho@487
|
175 |
}
|
renatofilho@487
|
176 |
|
renatofilho@487
|
177 |
gboolean
|
renatofilho@487
|
178 |
gmyth_stream_client_play_stream (GMythStreamClient *self,
|
renatofilho@487
|
179 |
guint stream_id)
|
renatofilho@487
|
180 |
{
|
renatofilho@487
|
181 |
GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
|
renatofilho@487
|
182 |
|
renatofilho@487
|
183 |
g_return_val_if_fail (priv->connected == TRUE, FALSE);
|
renatofilho@487
|
184 |
|
renatofilho@487
|
185 |
if (send (priv->sock, "PLAY", 4, MSG_MORE) == -1) {
|
renatofilho@487
|
186 |
return FALSE;
|
renatofilho@487
|
187 |
}
|
renatofilho@487
|
188 |
return TRUE;
|
renatofilho@487
|
189 |
}
|
renatofilho@487
|
190 |
|
renatofilho@487
|
191 |
void
|
renatofilho@487
|
192 |
gmyth_stream_client_pause_stream (GMythStreamClient *self,
|
renatofilho@487
|
193 |
guint stream_id)
|
renatofilho@487
|
194 |
{
|
renatofilho@487
|
195 |
GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
|
renatofilho@487
|
196 |
|
renatofilho@487
|
197 |
g_return_if_fail (priv->connected == TRUE);
|
renatofilho@487
|
198 |
|
renatofilho@487
|
199 |
if (send (priv->sock, "PAUSE", 5, MSG_MORE) == -1) {
|
renatofilho@487
|
200 |
return;
|
renatofilho@487
|
201 |
}
|
renatofilho@487
|
202 |
}
|
renatofilho@487
|
203 |
|
renatofilho@487
|
204 |
void
|
renatofilho@487
|
205 |
gmyth_stream_client_close_stream (GMythStreamClient *self,
|
renatofilho@487
|
206 |
guint stream_id)
|
renatofilho@487
|
207 |
{
|
renatofilho@487
|
208 |
GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
|
renatofilho@487
|
209 |
|
renatofilho@487
|
210 |
g_return_if_fail (priv->connected == TRUE);
|
renatofilho@487
|
211 |
|
renatofilho@487
|
212 |
if (send (priv->sock, "STOP", 4, MSG_MORE) == -1) {
|
renatofilho@487
|
213 |
return;
|
renatofilho@487
|
214 |
}
|
renatofilho@487
|
215 |
|
renatofilho@487
|
216 |
//TODO: remove from streams list
|
renatofilho@487
|
217 |
|
renatofilho@487
|
218 |
}
|