gstreamer_core/plugins/elements/gstfdsrc.c
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
equal deleted inserted replaced
29:567bb019e3e3 30:7e817e7e631c
    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>&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)
       
    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
    82 #endif
    50 #endif
    83 #include <stdlib.h>
    51 #include <stdlib.h>
    84 #include <errno.h>
    52 #include <errno.h>
    85 
    53 
    86 #include "gstfdsrc.h"
    54 #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
    87 
    63 
    88 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
    64 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
    89     GST_PAD_SRC,
    65     GST_PAD_SRC,
    90     GST_PAD_ALWAYS,
    66     GST_PAD_ALWAYS,
    91     GST_STATIC_CAPS_ANY);
    67     GST_STATIC_CAPS_ANY);
    92 
    68 
    93 GST_DEBUG_CATEGORY_STATIC (gst_fd_src_debug);
    69 GST_DEBUG_CATEGORY_STATIC (gst_fd_src_debug);
    94 #define GST_CAT_DEFAULT gst_fd_src_debug
    70 #define GST_CAT_DEFAULT gst_fd_src_debug
    95 
    71 
    96 #define DEFAULT_FD              0
       
    97 #define DEFAULT_TIMEOUT         0
       
    98 
       
    99 enum
    72 enum
   100 {
    73 {
   101   PROP_0,
    74   PROP_0,
   102 
       
   103   PROP_FD,
    75   PROP_FD,
   104   PROP_TIMEOUT,
       
   105 
       
   106   PROP_LAST
       
   107 };
    76 };
   108 
    77 
   109 static void gst_fd_src_uri_handler_init (gpointer g_iface, gpointer iface_data);
    78 static void gst_fd_src_uri_handler_init (gpointer g_iface, gpointer iface_data);
   110 
    79 
   111 static void
    80 static void
   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
   227 gst_fd_src_update_fd (GstFdSrc * src)
   183 gst_fd_src_update_fd (GstFdSrc * src)
   228 {
   184 {
   229   struct stat stat_results;
   185   struct stat stat_results;
   230 
   186 
   231   /* we need to always update the fdset since it may not have existed when
   187   /* we need to always update the fdset since it may not have existed when
   232    * gst_fd_src_update_fd () was called earlier */
   188    * gst_fd_src_update_fd() was called earlier */
   233   if (src->fdset != NULL) {
   189   if (src->fdset != NULL) {
   234     GstPollFD fd = GST_POLL_FD_INIT;
   190     GstPollFD fd = GST_POLL_FD_INIT;
   235 
   191 
   236     if (src->fd >= 0) {
   192     if (src->fd >= 0) {
   237       fd.fd = src->fd;
   193       fd.fd = src->fd;
   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   {
   500     return GST_FLOW_ERROR;
   419     return GST_FLOW_ERROR;
   501   }
   420   }
   502 }
   421 }
   503 
   422 
   504 static gboolean
   423 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
       
   527 gst_fd_src_is_seekable (GstBaseSrc * bsrc)
   424 gst_fd_src_is_seekable (GstBaseSrc * bsrc)
   528 {
   425 {
   529   GstFdSrc *src = GST_FD_SRC (bsrc);
   426   GstFdSrc *src = GST_FD_SRC (bsrc);
   530 
   427 
   531   return src->seekable_fd;
   428   return src->seekable_fd;
   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