gst_plugins_base/ext/gio/gstgiosrc.c
changeset 0 0e761a78d257
equal deleted inserted replaced
-1:000000000000 0:0e761a78d257
       
     1 /* GStreamer
       
     2  *
       
     3  * Copyright (C) 2007 Rene Stadler <mail@renestadler.de>
       
     4  * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
       
     5  * 
       
     6  * This library is free software; you can redistribute it and/or
       
     7  * modify it under the terms of the GNU Library General Public
       
     8  * License as published by the Free Software Foundation; either
       
     9  * version 2 of the License, or (at your option) any later version.
       
    10  *
       
    11  * This library is distributed in the hope that it will be useful,
       
    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    14  * Library General Public License for more details.
       
    15  *
       
    16  * You should have received a copy of the GNU Library General Public
       
    17  * License along with this library; if not, write to the
       
    18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       
    19  * Boston, MA 02111-1307, USA.
       
    20  */
       
    21 
       
    22 /**
       
    23  * SECTION:element-giosrc
       
    24  * @short_description: Read from any GIO-supported location
       
    25  * @see_also: #GstFileSrc, #GstGnomeVFSSrc, #GstGioSink
       
    26  *
       
    27  * <refsect2>
       
    28  * <para>
       
    29  * This plugin reads data from a local or remote location specified
       
    30  * by an URI. This location can be specified using any protocol supported by
       
    31  * the GIO library or it's VFS backends. Common protocols are 'file', 'http',
       
    32  * 'ftp', or 'smb'.
       
    33  * </para>
       
    34  * <para>
       
    35  * Example pipeline:
       
    36  * <programlisting>
       
    37  * gst-launch -v giosrc location=file:///home/joe/foo.xyz ! fakesink
       
    38  * </programlisting>
       
    39  * The above pipeline will simply read a local file and do nothing with the
       
    40  * data read. Instead of giosrc, we could just as well have used the
       
    41  * filesrc element here.
       
    42  * </para>
       
    43  * <para>
       
    44  * Another example pipeline:
       
    45  * <programlisting>
       
    46  * gst-launch -v giosrc location=smb://othercomputer/foo.xyz ! filesink location=/home/joe/foo.xyz
       
    47  * </programlisting>
       
    48  * The above pipeline will copy a file from a remote host to the local file
       
    49  * system using the Samba protocol.
       
    50  * </para>
       
    51  * <para>
       
    52  * Yet another example pipeline:
       
    53  * <programlisting>
       
    54  * gst-launch -v giosrc location=http://music.foobar.com/demo.mp3 ! mad ! audioconvert ! audioresample ! alsasink
       
    55  * </programlisting>
       
    56  * The above pipeline will read and decode and play an mp3 file from a
       
    57  * web server using the http protocol.
       
    58  * </para>
       
    59  * </refsect2>
       
    60  */
       
    61 
       
    62 /* FIXME: We would like to mount the enclosing volume of an URL
       
    63  *        if it isn't mounted yet but this is possible async-only.
       
    64  *        Unfortunately this requires a running main loop from the
       
    65  *        default context and we can't guarantuee this!
       
    66  *
       
    67  *        We would also like to do authentication while mounting.
       
    68  */
       
    69 
       
    70 #ifdef HAVE_CONFIG_H
       
    71 #include <config.h>
       
    72 #endif
       
    73 
       
    74 #include "gstgiosrc.h"
       
    75 
       
    76 GST_DEBUG_CATEGORY_STATIC (gst_gio_src_debug);
       
    77 #define GST_CAT_DEFAULT gst_gio_src_debug
       
    78 
       
    79 enum
       
    80 {
       
    81   ARG_0,
       
    82   ARG_LOCATION
       
    83 };
       
    84 
       
    85 GST_BOILERPLATE_FULL (GstGioSrc, gst_gio_src, GstGioBaseSrc,
       
    86     GST_TYPE_GIO_BASE_SRC, gst_gio_uri_handler_do_init);
       
    87 
       
    88 static void gst_gio_src_finalize (GObject * object);
       
    89 static void gst_gio_src_set_property (GObject * object, guint prop_id,
       
    90     const GValue * value, GParamSpec * pspec);
       
    91 static void gst_gio_src_get_property (GObject * object, guint prop_id,
       
    92     GValue * value, GParamSpec * pspec);
       
    93 static gboolean gst_gio_src_start (GstBaseSrc * base_src);
       
    94 
       
    95 static void
       
    96 gst_gio_src_base_init (gpointer gclass)
       
    97 {
       
    98   static GstElementDetails element_details = {
       
    99     "GIO source",
       
   100     "Source/File",
       
   101     "Read from any GIO-supported location",
       
   102     "Ren\xc3\xa9 Stadler <mail@renestadler.de>, "
       
   103         "Sebastian Dröge <slomo@circular-chaos.org>"
       
   104   };
       
   105   GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
       
   106 
       
   107   GST_DEBUG_CATEGORY_INIT (gst_gio_src_debug, "gio_src", 0, "GIO source");
       
   108 
       
   109   gst_element_class_set_details (element_class, &element_details);
       
   110 }
       
   111 
       
   112 static void
       
   113 gst_gio_src_class_init (GstGioSrcClass * klass)
       
   114 {
       
   115   GObjectClass *gobject_class;
       
   116   GstElementClass *gstelement_class;
       
   117   GstBaseSrcClass *gstbasesrc_class;
       
   118 
       
   119   gobject_class = (GObjectClass *) klass;
       
   120   gstelement_class = (GstElementClass *) klass;
       
   121   gstbasesrc_class = (GstBaseSrcClass *) klass;
       
   122 
       
   123   gobject_class->finalize = gst_gio_src_finalize;
       
   124   gobject_class->set_property = gst_gio_src_set_property;
       
   125   gobject_class->get_property = gst_gio_src_get_property;
       
   126 
       
   127   g_object_class_install_property (gobject_class, ARG_LOCATION,
       
   128       g_param_spec_string ("location", "Location", "URI location to read from",
       
   129           NULL, G_PARAM_READWRITE));
       
   130 
       
   131   gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_gio_src_start);
       
   132 }
       
   133 
       
   134 static void
       
   135 gst_gio_src_init (GstGioSrc * src, GstGioSrcClass * gclass)
       
   136 {
       
   137 }
       
   138 
       
   139 static void
       
   140 gst_gio_src_finalize (GObject * object)
       
   141 {
       
   142   GstGioSrc *src = GST_GIO_SRC (object);
       
   143 
       
   144   if (src->location) {
       
   145     g_free (src->location);
       
   146     src->location = NULL;
       
   147   }
       
   148 
       
   149   GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
       
   150 }
       
   151 
       
   152 static void
       
   153 gst_gio_src_set_property (GObject * object, guint prop_id,
       
   154     const GValue * value, GParamSpec * pspec)
       
   155 {
       
   156   GstGioSrc *src = GST_GIO_SRC (object);
       
   157 
       
   158   switch (prop_id) {
       
   159     case ARG_LOCATION:
       
   160       if (GST_STATE (src) == GST_STATE_PLAYING ||
       
   161           GST_STATE (src) == GST_STATE_PAUSED)
       
   162         break;
       
   163 
       
   164       g_free (src->location);
       
   165       src->location = g_strdup (g_value_get_string (value));
       
   166       break;
       
   167     default:
       
   168       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       
   169       break;
       
   170   }
       
   171 }
       
   172 
       
   173 static void
       
   174 gst_gio_src_get_property (GObject * object, guint prop_id,
       
   175     GValue * value, GParamSpec * pspec)
       
   176 {
       
   177   GstGioSrc *src = GST_GIO_SRC (object);
       
   178 
       
   179   switch (prop_id) {
       
   180     case ARG_LOCATION:
       
   181       g_value_set_string (value, src->location);
       
   182       break;
       
   183     default:
       
   184       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       
   185       break;
       
   186   }
       
   187 }
       
   188 
       
   189 static gboolean
       
   190 gst_gio_src_start (GstBaseSrc * base_src)
       
   191 {
       
   192   GstGioSrc *src = GST_GIO_SRC (base_src);
       
   193   GFile *file;
       
   194   GError *err = NULL;
       
   195   GInputStream *stream;
       
   196   GCancellable *cancel = GST_GIO_BASE_SRC (src)->cancel;
       
   197 
       
   198   if (src->location == NULL) {
       
   199     GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("No location given"));
       
   200     return FALSE;
       
   201   }
       
   202 
       
   203   file = g_file_new_for_uri (src->location);
       
   204 
       
   205   if (file == NULL) {
       
   206     GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
       
   207         ("Malformed URI or protocol not supported (%s)", src->location));
       
   208     return FALSE;
       
   209   }
       
   210 
       
   211   stream = G_INPUT_STREAM (g_file_read (file, cancel, &err));
       
   212 
       
   213   g_object_unref (file);
       
   214 
       
   215   if (stream == NULL && !gst_gio_error (src, "g_file_read", &err, NULL)) {
       
   216 
       
   217     if (GST_GIO_ERROR_MATCHES (err, NOT_FOUND)) {
       
   218       GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
       
   219           ("Could not open location %s for reading: %s",
       
   220               src->location, err->message));
       
   221     } else {
       
   222       GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
       
   223           ("Could not open location %s for reading: %s",
       
   224               src->location, err->message));
       
   225     }
       
   226 
       
   227     g_clear_error (&err);
       
   228     return FALSE;
       
   229   } else if (stream == NULL) {
       
   230     return FALSE;
       
   231   }
       
   232 
       
   233   gst_gio_base_src_set_stream (GST_GIO_BASE_SRC (src), stream);
       
   234 
       
   235   GST_DEBUG_OBJECT (src, "opened location %s", src->location);
       
   236 
       
   237   return GST_BASE_SRC_CLASS (parent_class)->start (base_src);
       
   238 }