20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
21 * Boston, MA 02111-1307, USA. |
21 * Boston, MA 02111-1307, USA. |
22 */ |
22 */ |
23 /** |
23 /** |
24 * SECTION:element-fdsrc |
24 * SECTION:element-fdsrc |
|
25 * @short_description: read from a unix file descriptor |
25 * @see_also: #GstFdSink |
26 * @see_also: #GstFdSink |
26 * |
27 * |
27 * Read data from a unix file descriptor. |
28 * Read data from a unix file descriptor. |
28 * |
|
29 * To generate data, enter some data on the console folowed by enter. |
|
30 * The above mentioned pipeline should dump data packets to the console. |
|
31 * |
|
32 * If the #GstFdSrc:timeout property is set to a value bigger than 0, fdsrc will |
|
33 * generate an element message named |
|
34 * <classname>"GstFdSrcTimeout"</classname> |
|
35 * if no data was recieved in the given timeout. |
|
36 * The message's structure contains one field: |
|
37 * <itemizedlist> |
|
38 * <listitem> |
|
39 * <para> |
|
40 * #guint64 |
|
41 * <classname>"timeout"</classname>: the timeout in microseconds that |
|
42 * expired when waiting for data. |
|
43 * </para> |
|
44 * </listitem> |
|
45 * </itemizedlist> |
|
46 * |
|
47 * <refsect2> |
|
48 * <title>Example launch line</title> |
|
49 * |[ |
|
50 * echo "Hello GStreamer" | gst-launch -v fdsrc ! fakesink dump=true |
|
51 * ]| A simple pipeline to read from the standard input and dump the data |
|
52 * with a fakesink as hex ascii block. |
|
53 * </refsect2> |
|
54 * |
|
55 * Last reviewed on 2008-06-20 (0.10.21) |
|
56 */ |
29 */ |
|
30 |
57 |
31 |
58 #ifdef HAVE_CONFIG_H |
32 #ifdef HAVE_CONFIG_H |
59 # include "config.h" |
33 # include "config.h" |
60 #endif |
34 #endif |
|
35 #ifdef __SYMBIAN32__ |
|
36 #include <gst_global.h> |
|
37 #endif |
61 #include "gst/gst_private.h" |
38 #include "gst/gst_private.h" |
62 |
39 |
63 #include <sys/types.h> |
40 #include <sys/types.h> |
64 |
|
65 #ifdef G_OS_WIN32 |
|
66 #include <io.h> /* lseek, open, close, read */ |
|
67 #undef lseek |
|
68 #define lseek _lseeki64 |
|
69 #undef off_t |
|
70 #define off_t guint64 |
|
71 #endif |
|
72 |
|
73 #include <sys/stat.h> |
41 #include <sys/stat.h> |
74 #include <sys/socket.h> |
42 #include <sys/socket.h> |
75 #include <fcntl.h> |
43 #include <fcntl.h> |
76 #include <stdio.h> |
44 #include <stdio.h> |
77 #ifdef HAVE_UNISTD_H |
45 #ifdef HAVE_UNISTD_H |
137 static gboolean gst_fd_src_unlock (GstBaseSrc * bsrc); |
106 static gboolean gst_fd_src_unlock (GstBaseSrc * bsrc); |
138 static gboolean gst_fd_src_unlock_stop (GstBaseSrc * bsrc); |
107 static gboolean gst_fd_src_unlock_stop (GstBaseSrc * bsrc); |
139 static gboolean gst_fd_src_is_seekable (GstBaseSrc * bsrc); |
108 static gboolean gst_fd_src_is_seekable (GstBaseSrc * bsrc); |
140 static gboolean gst_fd_src_get_size (GstBaseSrc * src, guint64 * size); |
109 static gboolean gst_fd_src_get_size (GstBaseSrc * src, guint64 * size); |
141 static gboolean gst_fd_src_do_seek (GstBaseSrc * src, GstSegment * segment); |
110 static gboolean gst_fd_src_do_seek (GstBaseSrc * src, GstSegment * segment); |
142 static gboolean gst_fd_src_query (GstBaseSrc * src, GstQuery * query); |
|
143 |
111 |
144 static GstFlowReturn gst_fd_src_create (GstPushSrc * psrc, GstBuffer ** outbuf); |
112 static GstFlowReturn gst_fd_src_create (GstPushSrc * psrc, GstBuffer ** outbuf); |
145 |
113 |
146 static void |
114 static void |
147 gst_fd_src_base_init (gpointer g_class) |
115 gst_fd_src_base_init (gpointer g_class) |
159 static void |
127 static void |
160 gst_fd_src_class_init (GstFdSrcClass * klass) |
128 gst_fd_src_class_init (GstFdSrcClass * klass) |
161 { |
129 { |
162 GObjectClass *gobject_class; |
130 GObjectClass *gobject_class; |
163 GstBaseSrcClass *gstbasesrc_class; |
131 GstBaseSrcClass *gstbasesrc_class; |
|
132 GstElementClass *gstelement_class; |
164 GstPushSrcClass *gstpush_src_class; |
133 GstPushSrcClass *gstpush_src_class; |
165 |
134 |
166 gobject_class = G_OBJECT_CLASS (klass); |
135 gobject_class = G_OBJECT_CLASS (klass); |
|
136 gstelement_class = GST_ELEMENT_CLASS (klass); |
167 gstbasesrc_class = GST_BASE_SRC_CLASS (klass); |
137 gstbasesrc_class = GST_BASE_SRC_CLASS (klass); |
168 gstpush_src_class = GST_PUSH_SRC_CLASS (klass); |
138 gstpush_src_class = GST_PUSH_SRC_CLASS (klass); |
169 |
139 |
170 parent_class = g_type_class_peek_parent (klass); |
140 parent_class = g_type_class_peek_parent (klass); |
171 |
141 |
173 gobject_class->get_property = gst_fd_src_get_property; |
143 gobject_class->get_property = gst_fd_src_get_property; |
174 gobject_class->dispose = gst_fd_src_dispose; |
144 gobject_class->dispose = gst_fd_src_dispose; |
175 |
145 |
176 g_object_class_install_property (gobject_class, PROP_FD, |
146 g_object_class_install_property (gobject_class, PROP_FD, |
177 g_param_spec_int ("fd", "fd", "An open file descriptor to read from", |
147 g_param_spec_int ("fd", "fd", "An open file descriptor to read from", |
178 0, G_MAXINT, DEFAULT_FD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
148 0, G_MAXINT, 0, G_PARAM_READWRITE)); |
179 /** |
|
180 * GstFdSrc:timeout |
|
181 * |
|
182 * Post a message after timeout microseconds |
|
183 * |
|
184 * Since: 0.10.21 |
|
185 */ |
|
186 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TIMEOUT, |
|
187 g_param_spec_uint64 ("timeout", "Timeout", |
|
188 "Post a message after timeout microseconds (0 = disabled)", 0, |
|
189 G_MAXUINT64, DEFAULT_TIMEOUT, |
|
190 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
|
191 |
149 |
192 gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_fd_src_start); |
150 gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_fd_src_start); |
193 gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_fd_src_stop); |
151 gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_fd_src_stop); |
194 gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_fd_src_unlock); |
152 gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_fd_src_unlock); |
195 gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_fd_src_unlock_stop); |
153 gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_fd_src_unlock_stop); |
196 gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_fd_src_is_seekable); |
154 gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_fd_src_is_seekable); |
197 gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_fd_src_get_size); |
155 gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_fd_src_get_size); |
198 gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_fd_src_do_seek); |
156 gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_fd_src_do_seek); |
199 gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_fd_src_query); |
|
200 |
157 |
201 gstpush_src_class->create = GST_DEBUG_FUNCPTR (gst_fd_src_create); |
158 gstpush_src_class->create = GST_DEBUG_FUNCPTR (gst_fd_src_create); |
202 } |
159 } |
203 |
160 |
204 static void |
161 static void |
205 gst_fd_src_init (GstFdSrc * fdsrc, GstFdSrcClass * klass) |
162 gst_fd_src_init (GstFdSrc * fdsrc, GstFdSrcClass * klass) |
206 { |
163 { |
|
164 fdsrc->fd = -1; |
207 fdsrc->new_fd = 0; |
165 fdsrc->new_fd = 0; |
208 fdsrc->seekable_fd = FALSE; |
166 fdsrc->seekable_fd = FALSE; |
209 fdsrc->fd = DEFAULT_FD; |
|
210 fdsrc->timeout = DEFAULT_TIMEOUT; |
|
211 fdsrc->uri = g_strdup_printf ("fd://0"); |
167 fdsrc->uri = g_strdup_printf ("fd://0"); |
212 fdsrc->curoffset = 0; |
168 fdsrc->curoffset = 0; |
213 } |
169 } |
214 |
170 |
215 static void |
171 static void |
354 } else { |
310 } else { |
355 GST_DEBUG_OBJECT (src, "state above ready, not updating to new fd yet"); |
311 GST_DEBUG_OBJECT (src, "state above ready, not updating to new fd yet"); |
356 } |
312 } |
357 GST_OBJECT_UNLOCK (object); |
313 GST_OBJECT_UNLOCK (object); |
358 break; |
314 break; |
359 case PROP_TIMEOUT: |
315 default: |
360 src->timeout = g_value_get_uint64 (value); |
316 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
361 GST_DEBUG_OBJECT (src, "poll timeout set to %" GST_TIME_FORMAT, |
317 break; |
362 GST_TIME_ARGS (src->timeout)); |
318 } |
|
319 } |
|
320 |
|
321 static void |
|
322 gst_fd_src_get_property (GObject * object, guint prop_id, GValue * value, |
|
323 GParamSpec * pspec) |
|
324 { |
|
325 GstFdSrc *src = GST_FD_SRC (object); |
|
326 |
|
327 switch (prop_id) { |
|
328 case PROP_FD: |
|
329 g_value_set_int (value, src->fd); |
363 break; |
330 break; |
364 default: |
331 default: |
365 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
332 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
366 break; |
333 break; |
367 } |
334 } |
368 } |
335 } |
369 |
336 |
370 static void |
|
371 gst_fd_src_get_property (GObject * object, guint prop_id, GValue * value, |
|
372 GParamSpec * pspec) |
|
373 { |
|
374 GstFdSrc *src = GST_FD_SRC (object); |
|
375 |
|
376 switch (prop_id) { |
|
377 case PROP_FD: |
|
378 g_value_set_int (value, src->fd); |
|
379 break; |
|
380 case PROP_TIMEOUT: |
|
381 g_value_set_uint64 (value, src->timeout); |
|
382 break; |
|
383 default: |
|
384 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
|
385 break; |
|
386 } |
|
387 } |
|
388 |
|
389 static GstFlowReturn |
337 static GstFlowReturn |
390 gst_fd_src_create (GstPushSrc * psrc, GstBuffer ** outbuf) |
338 gst_fd_src_create (GstPushSrc * psrc, GstBuffer ** outbuf) |
391 { |
339 { |
392 GstFdSrc *src; |
340 GstFdSrc *src; |
393 GstBuffer *buf; |
341 GstBuffer *buf; |
394 gssize readbytes; |
342 gssize readbytes; |
395 guint blocksize; |
343 guint blocksize; |
396 GstClockTime timeout; |
|
397 |
344 |
398 #ifndef HAVE_WIN32 |
345 #ifndef HAVE_WIN32 |
399 gboolean try_again; |
|
400 gint retval; |
346 gint retval; |
401 #endif |
347 #endif |
402 |
348 |
403 src = GST_FD_SRC (psrc); |
349 src = GST_FD_SRC (psrc); |
404 |
|
405 if (src->timeout > 0) { |
|
406 timeout = src->timeout * GST_USECOND; |
|
407 } else { |
|
408 timeout = GST_CLOCK_TIME_NONE; |
|
409 } |
|
410 |
350 |
411 #ifndef HAVE_WIN32 |
351 #ifndef HAVE_WIN32 |
412 do { |
352 do { |
413 try_again = FALSE; |
353 retval = gst_poll_wait (src->fdset, GST_CLOCK_TIME_NONE); |
414 |
354 } while (retval == -1 && (errno == EINTR || errno == EAGAIN)); /* retry if interrupted */ |
415 GST_LOG_OBJECT (src, "doing poll, timeout %" GST_TIME_FORMAT, |
355 |
416 GST_TIME_ARGS (src->timeout)); |
356 if (retval == -1) { |
417 |
357 if (errno == EBUSY) |
418 retval = gst_poll_wait (src->fdset, timeout); |
358 goto stopped; |
419 GST_LOG_OBJECT (src, "poll returned %d", retval); |
359 else |
420 |
360 goto select_error; |
421 if (G_UNLIKELY (retval == -1)) { |
361 } |
422 if (errno == EINTR || errno == EAGAIN) { |
|
423 /* retry if interrupted */ |
|
424 try_again = TRUE; |
|
425 } else if (errno == EBUSY) { |
|
426 goto stopped; |
|
427 } else { |
|
428 goto poll_error; |
|
429 } |
|
430 } else if (G_UNLIKELY (retval == 0)) { |
|
431 try_again = TRUE; |
|
432 /* timeout, post element message */ |
|
433 gst_element_post_message (GST_ELEMENT_CAST (src), |
|
434 gst_message_new_element (GST_OBJECT_CAST (src), |
|
435 gst_structure_new ("GstFdSrcTimeout", |
|
436 "timeout", G_TYPE_UINT64, src->timeout, NULL))); |
|
437 } |
|
438 } while (G_UNLIKELY (try_again)); /* retry if interrupted or timeout */ |
|
439 #endif |
362 #endif |
440 |
363 |
441 blocksize = GST_BASE_SRC (src)->blocksize; |
364 blocksize = GST_BASE_SRC (src)->blocksize; |
442 |
365 |
443 /* create the buffer */ |
366 /* create the buffer */ |
444 buf = gst_buffer_try_new_and_alloc (blocksize); |
367 buf = gst_buffer_new_and_alloc (blocksize); |
445 if (G_UNLIKELY (buf == NULL)) { |
|
446 GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", blocksize); |
|
447 return GST_FLOW_ERROR; |
|
448 } |
|
449 |
368 |
450 do { |
369 do { |
451 readbytes = read (src->fd, GST_BUFFER_DATA (buf), blocksize); |
370 readbytes = read (src->fd, GST_BUFFER_DATA (buf), blocksize); |
452 GST_LOG_OBJECT (src, "read %" G_GSSIZE_FORMAT, readbytes); |
371 GST_LOG_OBJECT (src, "read %" G_GSSIZE_FORMAT, readbytes); |
453 } while (readbytes == -1 && errno == EINTR); /* retry if interrupted */ |
372 } while (readbytes == -1 && errno == EINTR); /* retry if interrupted */ |
470 |
389 |
471 return GST_FLOW_OK; |
390 return GST_FLOW_OK; |
472 |
391 |
473 /* ERRORS */ |
392 /* ERRORS */ |
474 #ifndef HAVE_WIN32 |
393 #ifndef HAVE_WIN32 |
475 poll_error: |
394 select_error: |
476 { |
395 { |
477 GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), |
396 GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), |
478 ("poll on file descriptor: %s.", g_strerror (errno))); |
397 ("select on file descriptor: %s.", g_strerror (errno))); |
479 GST_DEBUG_OBJECT (psrc, "Error during poll"); |
398 GST_DEBUG_OBJECT (psrc, "Error during select"); |
480 return GST_FLOW_ERROR; |
399 return GST_FLOW_ERROR; |
481 } |
400 } |
482 stopped: |
401 stopped: |
483 { |
402 { |
484 GST_DEBUG_OBJECT (psrc, "Poll stopped"); |
403 GST_DEBUG_OBJECT (psrc, "Select stopped"); |
485 return GST_FLOW_WRONG_STATE; |
404 return GST_FLOW_WRONG_STATE; |
486 } |
405 } |
487 #endif |
406 #endif |
488 eos: |
407 eos: |
489 { |
408 { |
583 GST_DEBUG_OBJECT (src, "lseek returned %" G_GINT64_FORMAT, offset); |
480 GST_DEBUG_OBJECT (src, "lseek returned %" G_GINT64_FORMAT, offset); |
584 return FALSE; |
481 return FALSE; |
585 } |
482 } |
586 |
483 |
587 /*** GSTURIHANDLER INTERFACE *************************************************/ |
484 /*** GSTURIHANDLER INTERFACE *************************************************/ |
588 |
485 #ifdef __SYMBIAN32__ |
589 static GstURIType |
486 GstURIType |
|
487 #else |
|
488 static guint |
|
489 #endif |
|
490 |
590 gst_fd_src_uri_get_type (void) |
491 gst_fd_src_uri_get_type (void) |
591 { |
492 { |
592 return GST_URI_SRC; |
493 return GST_URI_SRC; |
593 } |
494 } |
594 |
|
595 static gchar ** |
495 static gchar ** |
596 gst_fd_src_uri_get_protocols (void) |
496 gst_fd_src_uri_get_protocols (void) |
597 { |
497 { |
598 static gchar *protocols[] = { "fd", NULL }; |
498 static gchar *protocols[] = { "fd", NULL }; |
599 |
499 |
600 return protocols; |
500 return protocols; |
601 } |
501 } |
602 |
|
603 static const gchar * |
502 static const gchar * |
604 gst_fd_src_uri_get_uri (GstURIHandler * handler) |
503 gst_fd_src_uri_get_uri (GstURIHandler * handler) |
605 { |
504 { |
606 GstFdSrc *src = GST_FD_SRC (handler); |
505 GstFdSrc *src = GST_FD_SRC (handler); |
607 |
506 |