|
1 /* GStreamer |
|
2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> |
|
3 * Copyright (C) <2004> Thomas Vander Stichele <thomas at apestaart dot org> |
|
4 * |
|
5 * This library is free software; you can redistribute it and/or |
|
6 * modify it under the terms of the GNU Library General Public |
|
7 * License as published by the Free Software Foundation; either |
|
8 * version 2 of the License, or (at your option) any later version. |
|
9 * |
|
10 * This library is distributed in the hope that it will be useful, |
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 * Library General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU Library General Public |
|
16 * License along with this library; if not, write to the |
|
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
|
18 * Boston, MA 02111-1307, USA. |
|
19 */ |
|
20 |
|
21 |
|
22 #ifndef __GST_MULTI_FD_SINK_H__ |
|
23 #define __GST_MULTI_FD_SINK_H__ |
|
24 |
|
25 #include <gst/gst.h> |
|
26 #include <gst/base/gstbasesink.h> |
|
27 |
|
28 G_BEGIN_DECLS |
|
29 |
|
30 #include "gsttcp.h" |
|
31 |
|
32 #define GST_TYPE_MULTI_FD_SINK \ |
|
33 (gst_multi_fd_sink_get_type()) |
|
34 #define GST_MULTI_FD_SINK(obj) \ |
|
35 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MULTI_FD_SINK,GstMultiFdSink)) |
|
36 #define GST_MULTI_FD_SINK_CLASS(klass) \ |
|
37 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MULTI_FD_SINK,GstMultiFdSinkClass)) |
|
38 #define GST_IS_MULTI_FD_SINK(obj) \ |
|
39 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MULTI_FD_SINK)) |
|
40 #define GST_IS_MULTI_FD_SINK_CLASS(klass) \ |
|
41 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MULTI_FD_SINK)) |
|
42 #define GST_MULTI_FD_SINK_GET_CLASS(klass) \ |
|
43 (G_TYPE_INSTANCE_GET_CLASS ((klass), GST_TYPE_MULTI_FD_SINK, GstMultiFdSinkClass)) |
|
44 |
|
45 |
|
46 typedef struct _GstMultiFdSink GstMultiFdSink; |
|
47 typedef struct _GstMultiFdSinkClass GstMultiFdSinkClass; |
|
48 |
|
49 typedef enum { |
|
50 GST_MULTI_FD_SINK_OPEN = (GST_ELEMENT_FLAG_LAST << 0), |
|
51 |
|
52 GST_MULTI_FD_SINK_FLAG_LAST = (GST_ELEMENT_FLAG_LAST << 2) |
|
53 } GstMultiFdSinkFlags; |
|
54 |
|
55 /** |
|
56 * GstRecoverPolicy: |
|
57 * @GST_RECOVER_POLICY_NONE : no recovering is done |
|
58 * @GST_RECOVER_POLICY_RESYNC_LATEST : client is moved to last buffer |
|
59 * @GST_RECOVER_POLICY_RESYNC_SOFT_LIMIT: client is moved to the soft limit |
|
60 * @GST_RECOVER_POLICY_RESYNC_KEYFRAME : client is moved to latest keyframe |
|
61 * |
|
62 * Possible values for the recovery procedure to use when a client consumes |
|
63 * data too slow and has a backlag of more that soft-limit buffers. |
|
64 */ |
|
65 typedef enum |
|
66 { |
|
67 GST_RECOVER_POLICY_NONE, |
|
68 GST_RECOVER_POLICY_RESYNC_LATEST, |
|
69 GST_RECOVER_POLICY_RESYNC_SOFT_LIMIT, |
|
70 GST_RECOVER_POLICY_RESYNC_KEYFRAME |
|
71 } GstRecoverPolicy; |
|
72 |
|
73 /** |
|
74 * GstSyncMethod: |
|
75 * @GST_SYNC_METHOD_LATEST : client receives most recent buffer |
|
76 * @GST_SYNC_METHOD_NEXT_KEYFRAME : client receives next keyframe |
|
77 * @GST_SYNC_METHOD_LATEST_KEYFRAME : client receives latest keyframe (burst) |
|
78 * @GST_SYNC_METHOD_BURST : client receives specific amount of data |
|
79 * @GST_SYNC_METHOD_BURST_KEYFRAME : client receives specific amount of data |
|
80 * starting from latest keyframe |
|
81 * @GST_SYNC_METHOD_BURST_WITH_KEYFRAME : client receives specific amount of data from |
|
82 * a keyframe, or if there is not enough data after |
|
83 * the keyframe, starting before the keyframe |
|
84 * |
|
85 * This enum defines the selection of the first buffer that is sent |
|
86 * to a new client. |
|
87 */ |
|
88 typedef enum |
|
89 { |
|
90 GST_SYNC_METHOD_LATEST, |
|
91 GST_SYNC_METHOD_NEXT_KEYFRAME, |
|
92 GST_SYNC_METHOD_LATEST_KEYFRAME, |
|
93 GST_SYNC_METHOD_BURST, |
|
94 GST_SYNC_METHOD_BURST_KEYFRAME, |
|
95 GST_SYNC_METHOD_BURST_WITH_KEYFRAME |
|
96 } GstSyncMethod; |
|
97 |
|
98 /** |
|
99 * GstUnitType: |
|
100 * @GST_UNIT_TYPE_UNDEFINED: undefined |
|
101 * @GST_UNIT_TYPE_BUFFERS : buffers |
|
102 * @GST_UNIT_TYPE_TIME : timeunits (in nanoseconds) |
|
103 * @GST_UNIT_TYPE_BYTES : bytes |
|
104 * |
|
105 * The units used to specify limits. |
|
106 */ |
|
107 typedef enum |
|
108 { |
|
109 GST_UNIT_TYPE_UNDEFINED, |
|
110 GST_UNIT_TYPE_BUFFERS, |
|
111 GST_UNIT_TYPE_TIME, |
|
112 GST_UNIT_TYPE_BYTES |
|
113 } GstUnitType; |
|
114 |
|
115 /** |
|
116 * GstClientStatus: |
|
117 * @GST_CLIENT_STATUS_OK : client is ok |
|
118 * @GST_CLIENT_STATUS_CLOSED : client closed the socket |
|
119 * @GST_CLIENT_STATUS_REMOVED : client is removed |
|
120 * @GST_CLIENT_STATUS_SLOW : client is too slow |
|
121 * @GST_CLIENT_STATUS_ERROR : client is in error |
|
122 * @GST_CLIENT_STATUS_DUPLICATE: same client added twice |
|
123 * @GST_CLIENT_STATUS_FLUSHING : client is flushing out the remaining buffers. |
|
124 * |
|
125 * This specifies the reason why a client was removed from |
|
126 * multifdsink and is received in the "client-removed" signal. |
|
127 */ |
|
128 typedef enum |
|
129 { |
|
130 GST_CLIENT_STATUS_OK = 0, |
|
131 GST_CLIENT_STATUS_CLOSED = 1, |
|
132 GST_CLIENT_STATUS_REMOVED = 2, |
|
133 GST_CLIENT_STATUS_SLOW = 3, |
|
134 GST_CLIENT_STATUS_ERROR = 4, |
|
135 GST_CLIENT_STATUS_DUPLICATE = 5, |
|
136 GST_CLIENT_STATUS_FLUSHING = 6 |
|
137 } GstClientStatus; |
|
138 |
|
139 /* structure for a client |
|
140 */ |
|
141 typedef struct { |
|
142 GstPollFD fd; |
|
143 |
|
144 gint bufpos; /* position of this client in the global queue */ |
|
145 gint flushcount; /* the remaining number of buffers to flush out or -1 if the |
|
146 client is not flushing. */ |
|
147 |
|
148 GstClientStatus status; |
|
149 gboolean is_socket; |
|
150 |
|
151 GSList *sending; /* the buffers we need to send */ |
|
152 gint bufoffset; /* offset in the first buffer */ |
|
153 |
|
154 gboolean discont; |
|
155 |
|
156 GstTCPProtocol protocol; |
|
157 |
|
158 gboolean caps_sent; |
|
159 gboolean new_connection; |
|
160 |
|
161 gboolean currently_removing; |
|
162 |
|
163 /* method to sync client when connecting */ |
|
164 GstSyncMethod sync_method; |
|
165 GstUnitType burst_min_unit; |
|
166 guint64 burst_min_value; |
|
167 GstUnitType burst_max_unit; |
|
168 guint64 burst_max_value; |
|
169 |
|
170 GstCaps *caps; /* caps of last queued buffer */ |
|
171 |
|
172 /* stats */ |
|
173 guint64 bytes_sent; |
|
174 guint64 connect_time; |
|
175 guint64 disconnect_time; |
|
176 guint64 last_activity_time; |
|
177 guint64 dropped_buffers; |
|
178 guint64 avg_queue_size; |
|
179 } GstTCPClient; |
|
180 |
|
181 #define CLIENTS_LOCK_INIT(fdsink) (g_static_rec_mutex_init(&fdsink->clientslock)) |
|
182 #define CLIENTS_LOCK_FREE(fdsink) (g_static_rec_mutex_free(&fdsink->clientslock)) |
|
183 #define CLIENTS_LOCK(fdsink) (g_static_rec_mutex_lock(&fdsink->clientslock)) |
|
184 #define CLIENTS_UNLOCK(fdsink) (g_static_rec_mutex_unlock(&fdsink->clientslock)) |
|
185 |
|
186 /** |
|
187 * GstMultiFdSink: |
|
188 * |
|
189 * The multifdsink object structure. |
|
190 */ |
|
191 struct _GstMultiFdSink { |
|
192 GstBaseSink element; |
|
193 |
|
194 /*< private >*/ |
|
195 guint64 bytes_to_serve; /* how much bytes we must serve */ |
|
196 guint64 bytes_served; /* how much bytes have we served */ |
|
197 |
|
198 GStaticRecMutex clientslock; /* lock to protect the clients list */ |
|
199 GList *clients; /* list of clients we are serving */ |
|
200 GHashTable *fd_hash; /* index on fd to client */ |
|
201 guint clients_cookie; /* Cookie to detect changes to the clients list */ |
|
202 |
|
203 gint mode; |
|
204 GstPoll *fdset; |
|
205 |
|
206 GSList *streamheader; /* GSList of GstBuffers to use as streamheader */ |
|
207 gboolean previous_buffer_in_caps; |
|
208 |
|
209 GstTCPProtocol protocol; |
|
210 guint mtu; |
|
211 |
|
212 GArray *bufqueue; /* global queue of buffers */ |
|
213 |
|
214 gboolean running; /* the thread state */ |
|
215 GThread *thread; /* the sender thread */ |
|
216 |
|
217 /* these values are used to check if a client is reading fast |
|
218 * enough and to control receovery */ |
|
219 GstUnitType unit_type;/* the type of the units */ |
|
220 gint64 units_max; /* max units to queue for a client */ |
|
221 gint64 units_soft_max; /* max units a client can lag before recovery starts */ |
|
222 GstRecoverPolicy recover_policy; |
|
223 GstClockTime timeout; /* max amount of nanoseconds to remain idle */ |
|
224 |
|
225 GstSyncMethod def_sync_method; /* what method to use for connecting clients */ |
|
226 GstUnitType def_burst_unit; |
|
227 guint64 def_burst_value; |
|
228 |
|
229 /* these values are used to control the amount of data |
|
230 * kept in the queues. It allows clients to perform a burst |
|
231 * on connect. */ |
|
232 gint bytes_min; /* min number of bytes to queue */ |
|
233 gint64 time_min; /* min time to queue */ |
|
234 gint buffers_min; /* min number of buffers to queue */ |
|
235 |
|
236 /* stats */ |
|
237 gint buffers_queued; /* number of queued buffers */ |
|
238 gint bytes_queued; /* number of queued bytes */ |
|
239 gint time_queued; /* number of queued time */ |
|
240 |
|
241 guint8 header_flags; |
|
242 }; |
|
243 |
|
244 struct _GstMultiFdSinkClass { |
|
245 GstBaseSinkClass parent_class; |
|
246 |
|
247 /* element methods */ |
|
248 void (*add) (GstMultiFdSink *sink, int fd); |
|
249 void (*add_full) (GstMultiFdSink *sink, int fd, GstSyncMethod sync, |
|
250 GstUnitType format, guint64 value, |
|
251 GstUnitType max_unit, guint64 max_value); |
|
252 void (*remove) (GstMultiFdSink *sink, int fd); |
|
253 void (*remove_flush) (GstMultiFdSink *sink, int fd); |
|
254 void (*clear) (GstMultiFdSink *sink); |
|
255 GValueArray* (*get_stats) (GstMultiFdSink *sink, int fd); |
|
256 |
|
257 /* vtable */ |
|
258 gboolean (*init) (GstMultiFdSink *sink); |
|
259 gboolean (*wait) (GstMultiFdSink *sink, GstPoll *set); |
|
260 gboolean (*close) (GstMultiFdSink *sink); |
|
261 void (*removed) (GstMultiFdSink *sink, int fd); |
|
262 |
|
263 /* signals */ |
|
264 void (*client_added) (GstElement *element, gint fd); |
|
265 void (*client_removed) (GstElement *element, gint fd, GstClientStatus status); |
|
266 void (*client_fd_removed) (GstElement *element, gint fd); |
|
267 }; |
|
268 #ifdef __SYMBIAN32__ |
|
269 IMPORT_C |
|
270 #endif |
|
271 |
|
272 |
|
273 GType gst_multi_fd_sink_get_type (void); |
|
274 #ifdef __SYMBIAN32__ |
|
275 IMPORT_C |
|
276 #endif |
|
277 |
|
278 |
|
279 void gst_multi_fd_sink_add (GstMultiFdSink *sink, int fd); |
|
280 #ifdef __SYMBIAN32__ |
|
281 IMPORT_C |
|
282 #endif |
|
283 |
|
284 void gst_multi_fd_sink_add_full (GstMultiFdSink *sink, int fd, GstSyncMethod sync, |
|
285 GstUnitType min_unit, guint64 min_value, |
|
286 GstUnitType max_unit, guint64 max_value); |
|
287 #ifdef __SYMBIAN32__ |
|
288 IMPORT_C |
|
289 #endif |
|
290 |
|
291 void gst_multi_fd_sink_remove (GstMultiFdSink *sink, int fd); |
|
292 #ifdef __SYMBIAN32__ |
|
293 IMPORT_C |
|
294 #endif |
|
295 |
|
296 void gst_multi_fd_sink_remove_flush (GstMultiFdSink *sink, int fd); |
|
297 #ifdef __SYMBIAN32__ |
|
298 IMPORT_C |
|
299 #endif |
|
300 |
|
301 void gst_multi_fd_sink_clear (GstMultiFdSink *sink); |
|
302 #ifdef __SYMBIAN32__ |
|
303 IMPORT_C |
|
304 #endif |
|
305 |
|
306 GValueArray* gst_multi_fd_sink_get_stats (GstMultiFdSink *sink, int fd); |
|
307 |
|
308 G_END_DECLS |
|
309 |
|
310 #endif /* __GST_MULTI_FD_SINK_H__ */ |