gstreamer_core/plugins/elements/gstfdsrc.c
branchRCL_3
changeset 29 567bb019e3e3
parent 0 0e761a78d257
child 30 7e817e7e631c
equal deleted inserted replaced
6:9b2c3c7a1a9c 29:567bb019e3e3
    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
       
    26  * @see_also: #GstFdSink
    25  * @see_also: #GstFdSink
    27  *
    26  *
    28  * Read data from a unix file descriptor.
    27  * 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>&quot;GstFdSrcTimeout&quot;</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>&quot;timeout&quot;</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)
    29  */
    56  */
    30 
       
    31 
    57 
    32 #ifdef HAVE_CONFIG_H
    58 #ifdef HAVE_CONFIG_H
    33 #  include "config.h"
    59 #  include "config.h"
    34 #endif
    60 #endif
    35 #ifdef __SYMBIAN32__
    61 #include "gst/gst_private.h"
    36 #include <gst_global.h>
    62 
       
    63 #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
    37 #endif
    71 #endif
    38 #include "gst/gst_private.h"
    72 
    39 
       
    40 #include <sys/types.h>
       
    41 #include <sys/stat.h>
    73 #include <sys/stat.h>
    42 #include <sys/socket.h>
    74 #include <sys/socket.h>
    43 #include <fcntl.h>
    75 #include <fcntl.h>
    44 #include <stdio.h>
    76 #include <stdio.h>
    45 #ifdef HAVE_UNISTD_H
    77 #ifdef HAVE_UNISTD_H
    50 #endif
    82 #endif
    51 #include <stdlib.h>
    83 #include <stdlib.h>
    52 #include <errno.h>
    84 #include <errno.h>
    53 
    85 
    54 #include "gstfdsrc.h"
    86 #include "gstfdsrc.h"
    55 #ifdef __SYMBIAN32__
       
    56 #include <glib_global.h>
       
    57 #include <gobject_global.h>
       
    58 #include <gstpoll.h>
       
    59 #include <gstelement.h>
       
    60 #endif
       
    61 
       
    62 #define DEFAULT_BLOCKSIZE       4096
       
    63 
    87 
    64 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
    88 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
    65     GST_PAD_SRC,
    89     GST_PAD_SRC,
    66     GST_PAD_ALWAYS,
    90     GST_PAD_ALWAYS,
    67     GST_STATIC_CAPS_ANY);
    91     GST_STATIC_CAPS_ANY);
    68 
    92 
    69 GST_DEBUG_CATEGORY_STATIC (gst_fd_src_debug);
    93 GST_DEBUG_CATEGORY_STATIC (gst_fd_src_debug);
    70 #define GST_CAT_DEFAULT gst_fd_src_debug
    94 #define GST_CAT_DEFAULT gst_fd_src_debug
    71 
    95 
       
    96 #define DEFAULT_FD              0
       
    97 #define DEFAULT_TIMEOUT         0
       
    98 
    72 enum
    99 enum
    73 {
   100 {
    74   PROP_0,
   101   PROP_0,
       
   102 
    75   PROP_FD,
   103   PROP_FD,
       
   104   PROP_TIMEOUT,
       
   105 
       
   106   PROP_LAST
    76 };
   107 };
    77 
   108 
    78 static void gst_fd_src_uri_handler_init (gpointer g_iface, gpointer iface_data);
   109 static void gst_fd_src_uri_handler_init (gpointer g_iface, gpointer iface_data);
    79 
   110 
    80 static void
   111 static void
   106 static gboolean gst_fd_src_unlock (GstBaseSrc * bsrc);
   137 static gboolean gst_fd_src_unlock (GstBaseSrc * bsrc);
   107 static gboolean gst_fd_src_unlock_stop (GstBaseSrc * bsrc);
   138 static gboolean gst_fd_src_unlock_stop (GstBaseSrc * bsrc);
   108 static gboolean gst_fd_src_is_seekable (GstBaseSrc * bsrc);
   139 static gboolean gst_fd_src_is_seekable (GstBaseSrc * bsrc);
   109 static gboolean gst_fd_src_get_size (GstBaseSrc * src, guint64 * size);
   140 static gboolean gst_fd_src_get_size (GstBaseSrc * src, guint64 * size);
   110 static gboolean gst_fd_src_do_seek (GstBaseSrc * src, GstSegment * segment);
   141 static gboolean gst_fd_src_do_seek (GstBaseSrc * src, GstSegment * segment);
       
   142 static gboolean gst_fd_src_query (GstBaseSrc * src, GstQuery * query);
   111 
   143 
   112 static GstFlowReturn gst_fd_src_create (GstPushSrc * psrc, GstBuffer ** outbuf);
   144 static GstFlowReturn gst_fd_src_create (GstPushSrc * psrc, GstBuffer ** outbuf);
   113 
   145 
   114 static void
   146 static void
   115 gst_fd_src_base_init (gpointer g_class)
   147 gst_fd_src_base_init (gpointer g_class)
   127 static void
   159 static void
   128 gst_fd_src_class_init (GstFdSrcClass * klass)
   160 gst_fd_src_class_init (GstFdSrcClass * klass)
   129 {
   161 {
   130   GObjectClass *gobject_class;
   162   GObjectClass *gobject_class;
   131   GstBaseSrcClass *gstbasesrc_class;
   163   GstBaseSrcClass *gstbasesrc_class;
   132   GstElementClass *gstelement_class;
       
   133   GstPushSrcClass *gstpush_src_class;
   164   GstPushSrcClass *gstpush_src_class;
   134 
   165 
   135   gobject_class = G_OBJECT_CLASS (klass);
   166   gobject_class = G_OBJECT_CLASS (klass);
   136   gstelement_class = GST_ELEMENT_CLASS (klass);
       
   137   gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
   167   gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
   138   gstpush_src_class = GST_PUSH_SRC_CLASS (klass);
   168   gstpush_src_class = GST_PUSH_SRC_CLASS (klass);
   139 
   169 
   140   parent_class = g_type_class_peek_parent (klass);
   170   parent_class = g_type_class_peek_parent (klass);
   141 
   171 
   143   gobject_class->get_property = gst_fd_src_get_property;
   173   gobject_class->get_property = gst_fd_src_get_property;
   144   gobject_class->dispose = gst_fd_src_dispose;
   174   gobject_class->dispose = gst_fd_src_dispose;
   145 
   175 
   146   g_object_class_install_property (gobject_class, PROP_FD,
   176   g_object_class_install_property (gobject_class, PROP_FD,
   147       g_param_spec_int ("fd", "fd", "An open file descriptor to read from",
   177       g_param_spec_int ("fd", "fd", "An open file descriptor to read from",
   148           0, G_MAXINT, 0, G_PARAM_READWRITE));
   178           0, G_MAXINT, DEFAULT_FD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   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));
   149 
   191 
   150   gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_fd_src_start);
   192   gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_fd_src_start);
   151   gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_fd_src_stop);
   193   gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_fd_src_stop);
   152   gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_fd_src_unlock);
   194   gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_fd_src_unlock);
   153   gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_fd_src_unlock_stop);
   195   gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_fd_src_unlock_stop);
   154   gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_fd_src_is_seekable);
   196   gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_fd_src_is_seekable);
   155   gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_fd_src_get_size);
   197   gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_fd_src_get_size);
   156   gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_fd_src_do_seek);
   198   gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_fd_src_do_seek);
       
   199   gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_fd_src_query);
   157 
   200 
   158   gstpush_src_class->create = GST_DEBUG_FUNCPTR (gst_fd_src_create);
   201   gstpush_src_class->create = GST_DEBUG_FUNCPTR (gst_fd_src_create);
   159 }
   202 }
   160 
   203 
   161 static void
   204 static void
   162 gst_fd_src_init (GstFdSrc * fdsrc, GstFdSrcClass * klass)
   205 gst_fd_src_init (GstFdSrc * fdsrc, GstFdSrcClass * klass)
   163 {
   206 {
   164   fdsrc->fd = -1;
       
   165   fdsrc->new_fd = 0;
   207   fdsrc->new_fd = 0;
   166   fdsrc->seekable_fd = FALSE;
   208   fdsrc->seekable_fd = FALSE;
       
   209   fdsrc->fd = DEFAULT_FD;
       
   210   fdsrc->timeout = DEFAULT_TIMEOUT;
   167   fdsrc->uri = g_strdup_printf ("fd://0");
   211   fdsrc->uri = g_strdup_printf ("fd://0");
   168   fdsrc->curoffset = 0;
   212   fdsrc->curoffset = 0;
   169 }
   213 }
   170 
   214 
   171 static void
   215 static void
   183 gst_fd_src_update_fd (GstFdSrc * src)
   227 gst_fd_src_update_fd (GstFdSrc * src)
   184 {
   228 {
   185   struct stat stat_results;
   229   struct stat stat_results;
   186 
   230 
   187   /* we need to always update the fdset since it may not have existed when
   231   /* we need to always update the fdset since it may not have existed when
   188    * gst_fd_src_update_fd() was called earlier */
   232    * gst_fd_src_update_fd () was called earlier */
   189   if (src->fdset != NULL) {
   233   if (src->fdset != NULL) {
   190     GstPollFD fd = GST_POLL_FD_INIT;
   234     GstPollFD fd = GST_POLL_FD_INIT;
   191 
   235 
   192     if (src->fd >= 0) {
   236     if (src->fd >= 0) {
   193       fd.fd = src->fd;
   237       fd.fd = src->fd;
   310       } else {
   354       } else {
   311         GST_DEBUG_OBJECT (src, "state above ready, not updating to new fd yet");
   355         GST_DEBUG_OBJECT (src, "state above ready, not updating to new fd yet");
   312       }
   356       }
   313       GST_OBJECT_UNLOCK (object);
   357       GST_OBJECT_UNLOCK (object);
   314       break;
   358       break;
       
   359     case PROP_TIMEOUT:
       
   360       src->timeout = g_value_get_uint64 (value);
       
   361       GST_DEBUG_OBJECT (src, "poll timeout set to %" GST_TIME_FORMAT,
       
   362           GST_TIME_ARGS (src->timeout));
       
   363       break;
   315     default:
   364     default:
   316       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   365       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   317       break;
   366       break;
   318   }
   367   }
   319 }
   368 }
   325   GstFdSrc *src = GST_FD_SRC (object);
   374   GstFdSrc *src = GST_FD_SRC (object);
   326 
   375 
   327   switch (prop_id) {
   376   switch (prop_id) {
   328     case PROP_FD:
   377     case PROP_FD:
   329       g_value_set_int (value, src->fd);
   378       g_value_set_int (value, src->fd);
       
   379       break;
       
   380     case PROP_TIMEOUT:
       
   381       g_value_set_uint64 (value, src->timeout);
   330       break;
   382       break;
   331     default:
   383     default:
   332       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   384       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   333       break;
   385       break;
   334   }
   386   }
   339 {
   391 {
   340   GstFdSrc *src;
   392   GstFdSrc *src;
   341   GstBuffer *buf;
   393   GstBuffer *buf;
   342   gssize readbytes;
   394   gssize readbytes;
   343   guint blocksize;
   395   guint blocksize;
       
   396   GstClockTime timeout;
   344 
   397 
   345 #ifndef HAVE_WIN32
   398 #ifndef HAVE_WIN32
       
   399   gboolean try_again;
   346   gint retval;
   400   gint retval;
   347 #endif
   401 #endif
   348 
   402 
   349   src = GST_FD_SRC (psrc);
   403   src = GST_FD_SRC (psrc);
   350 
   404 
       
   405   if (src->timeout > 0) {
       
   406     timeout = src->timeout * GST_USECOND;
       
   407   } else {
       
   408     timeout = GST_CLOCK_TIME_NONE;
       
   409   }
       
   410 
   351 #ifndef HAVE_WIN32
   411 #ifndef HAVE_WIN32
   352   do {
   412   do {
   353     retval = gst_poll_wait (src->fdset, GST_CLOCK_TIME_NONE);
   413     try_again = FALSE;
   354   } while (retval == -1 && (errno == EINTR || errno == EAGAIN));        /* retry if interrupted */
   414 
   355 
   415     GST_LOG_OBJECT (src, "doing poll, timeout %" GST_TIME_FORMAT,
   356   if (retval == -1) {
   416         GST_TIME_ARGS (src->timeout));
   357     if (errno == EBUSY)
   417 
   358       goto stopped;
   418     retval = gst_poll_wait (src->fdset, timeout);
   359     else
   419     GST_LOG_OBJECT (src, "poll returned %d", retval);
   360       goto select_error;
   420 
   361   }
   421     if (G_UNLIKELY (retval == -1)) {
       
   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 */
   362 #endif
   439 #endif
   363 
   440 
   364   blocksize = GST_BASE_SRC (src)->blocksize;
   441   blocksize = GST_BASE_SRC (src)->blocksize;
   365 
   442 
   366   /* create the buffer */
   443   /* create the buffer */
   367   buf = gst_buffer_new_and_alloc (blocksize);
   444   buf = gst_buffer_try_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   }
   368 
   449 
   369   do {
   450   do {
   370     readbytes = read (src->fd, GST_BUFFER_DATA (buf), blocksize);
   451     readbytes = read (src->fd, GST_BUFFER_DATA (buf), blocksize);
   371     GST_LOG_OBJECT (src, "read %" G_GSSIZE_FORMAT, readbytes);
   452     GST_LOG_OBJECT (src, "read %" G_GSSIZE_FORMAT, readbytes);
   372   } while (readbytes == -1 && errno == EINTR);  /* retry if interrupted */
   453   } while (readbytes == -1 && errno == EINTR);  /* retry if interrupted */
   389 
   470 
   390   return GST_FLOW_OK;
   471   return GST_FLOW_OK;
   391 
   472 
   392   /* ERRORS */
   473   /* ERRORS */
   393 #ifndef HAVE_WIN32
   474 #ifndef HAVE_WIN32
   394 select_error:
   475 poll_error:
   395   {
   476   {
   396     GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
   477     GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
   397         ("select on file descriptor: %s.", g_strerror (errno)));
   478         ("poll on file descriptor: %s.", g_strerror (errno)));
   398     GST_DEBUG_OBJECT (psrc, "Error during select");
   479     GST_DEBUG_OBJECT (psrc, "Error during poll");
   399     return GST_FLOW_ERROR;
   480     return GST_FLOW_ERROR;
   400   }
   481   }
   401 stopped:
   482 stopped:
   402   {
   483   {
   403     GST_DEBUG_OBJECT (psrc, "Select stopped");
   484     GST_DEBUG_OBJECT (psrc, "Poll stopped");
   404     return GST_FLOW_WRONG_STATE;
   485     return GST_FLOW_WRONG_STATE;
   405   }
   486   }
   406 #endif
   487 #endif
   407 eos:
   488 eos:
   408   {
   489   {
   419     return GST_FLOW_ERROR;
   500     return GST_FLOW_ERROR;
   420   }
   501   }
   421 }
   502 }
   422 
   503 
   423 static gboolean
   504 static gboolean
       
   505 gst_fd_src_query (GstBaseSrc * basesrc, GstQuery * query)
       
   506 {
       
   507   gboolean ret = FALSE;
       
   508   GstFdSrc *src = GST_FD_SRC (basesrc);
       
   509 
       
   510   switch (GST_QUERY_TYPE (query)) {
       
   511     case GST_QUERY_URI:
       
   512       gst_query_set_uri (query, src->uri);
       
   513       ret = TRUE;
       
   514       break;
       
   515     default:
       
   516       ret = FALSE;
       
   517       break;
       
   518   }
       
   519 
       
   520   if (!ret)
       
   521     ret = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query);
       
   522 
       
   523   return ret;
       
   524 }
       
   525 
       
   526 static gboolean
   424 gst_fd_src_is_seekable (GstBaseSrc * bsrc)
   527 gst_fd_src_is_seekable (GstBaseSrc * bsrc)
   425 {
   528 {
   426   GstFdSrc *src = GST_FD_SRC (bsrc);
   529   GstFdSrc *src = GST_FD_SRC (bsrc);
   427 
   530 
   428   return src->seekable_fd;
   531   return src->seekable_fd;
   480   GST_DEBUG_OBJECT (src, "lseek returned %" G_GINT64_FORMAT, offset);
   583   GST_DEBUG_OBJECT (src, "lseek returned %" G_GINT64_FORMAT, offset);
   481   return FALSE;
   584   return FALSE;
   482 }
   585 }
   483 
   586 
   484 /*** GSTURIHANDLER INTERFACE *************************************************/
   587 /*** GSTURIHANDLER INTERFACE *************************************************/
   485 #ifdef __SYMBIAN32__
   588 
   486 GstURIType
   589 static GstURIType
   487 #else
       
   488 static guint
       
   489 #endif
       
   490 
       
   491 gst_fd_src_uri_get_type (void)
   590 gst_fd_src_uri_get_type (void)
   492 {
   591 {
   493   return GST_URI_SRC;
   592   return GST_URI_SRC;
   494 }
   593 }
       
   594 
   495 static gchar **
   595 static gchar **
   496 gst_fd_src_uri_get_protocols (void)
   596 gst_fd_src_uri_get_protocols (void)
   497 {
   597 {
   498   static gchar *protocols[] = { "fd", NULL };
   598   static gchar *protocols[] = { "fd", NULL };
   499 
   599 
   500   return protocols;
   600   return protocols;
   501 }
   601 }
       
   602 
   502 static const gchar *
   603 static const gchar *
   503 gst_fd_src_uri_get_uri (GstURIHandler * handler)
   604 gst_fd_src_uri_get_uri (GstURIHandler * handler)
   504 {
   605 {
   505   GstFdSrc *src = GST_FD_SRC (handler);
   606   GstFdSrc *src = GST_FD_SRC (handler);
   506 
   607