gst_plugins_base/ext/gio/gstgio.c
branchRCL_3
changeset 29 567bb019e3e3
parent 6 9b2c3c7a1a9c
child 30 7e817e7e631c
equal deleted inserted replaced
6:9b2c3c7a1a9c 29:567bb019e3e3
     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 #ifdef HAVE_CONFIG_H
       
    23 #include "config.h"
       
    24 #endif
       
    25 
       
    26 #include "gstgio.h"
       
    27 #include "gstgiosink.h"
       
    28 #include "gstgiosrc.h"
       
    29 #include "gstgiostreamsink.h"
       
    30 #include "gstgiostreamsrc.h"
       
    31 
       
    32 GST_DEBUG_CATEGORY_STATIC (gst_gio_debug);
       
    33 #define GST_CAT_DEFAULT gst_gio_debug
       
    34 
       
    35 /* @func_name: Name of the GIO function, for debugging messages.
       
    36  * @err: Error location.  *err may be NULL, but err must be non-NULL.
       
    37  * @ret: Flow return location.  May be NULL.  Is set to either #GST_FLOW_ERROR
       
    38  * or #GST_FLOW_WRONG_STATE.
       
    39  *
       
    40  * Returns: TRUE to indicate a handled error.  Error at given location err will
       
    41  * be freed and *err will be set to NULL.  A FALSE return indicates an unhandled
       
    42  * error: The err location is unchanged and guaranteed to be != NULL.  ret, if
       
    43  * given, is set to GST_FLOW_ERROR.
       
    44  */
       
    45 gboolean
       
    46 gst_gio_error (gpointer element, const gchar * func_name, GError ** err,
       
    47     GstFlowReturn * ret)
       
    48 {
       
    49   gboolean handled = TRUE;
       
    50 
       
    51   if (ret)
       
    52     *ret = GST_FLOW_ERROR;
       
    53 
       
    54   if (GST_GIO_ERROR_MATCHES (*err, CANCELLED)) {
       
    55     GST_DEBUG_OBJECT (element, "blocking I/O call cancelled (%s)", func_name);
       
    56     if (ret)
       
    57       *ret = GST_FLOW_WRONG_STATE;
       
    58   } else if (*err != NULL) {
       
    59     handled = FALSE;
       
    60   } else {
       
    61     GST_ELEMENT_ERROR (element, LIBRARY, FAILED, (NULL),
       
    62         ("%s call failed without error set", func_name));
       
    63   }
       
    64 
       
    65   if (handled)
       
    66     g_clear_error (err);
       
    67 
       
    68   return handled;
       
    69 }
       
    70 
       
    71 GstFlowReturn
       
    72 gst_gio_seek (gpointer element, GSeekable * stream, guint64 offset,
       
    73     GCancellable * cancel)
       
    74 {
       
    75   gboolean success;
       
    76   GstFlowReturn ret;
       
    77   GError *err = NULL;
       
    78 
       
    79   GST_LOG_OBJECT (element, "seeking to offset %" G_GINT64_FORMAT, offset);
       
    80 
       
    81   success = g_seekable_seek (stream, offset, G_SEEK_SET, cancel, &err);
       
    82 
       
    83   if (success)
       
    84     ret = GST_FLOW_OK;
       
    85   else if (!gst_gio_error (element, "g_seekable_seek", &err, &ret)) {
       
    86     GST_ELEMENT_ERROR (element, RESOURCE, SEEK, (NULL),
       
    87         ("Could not seek: %s", err->message));
       
    88     g_clear_error (&err);
       
    89   }
       
    90 
       
    91   return ret;
       
    92 }
       
    93 
       
    94 static gchar **
       
    95 gst_gio_get_supported_protocols (void)
       
    96 {
       
    97   return g_strdupv ((gchar **)
       
    98       g_vfs_get_supported_uri_schemes (g_vfs_get_default ()));
       
    99 }
       
   100 
       
   101 static GstURIType
       
   102 gst_gio_uri_handler_get_type_sink (void)
       
   103 {
       
   104   return GST_URI_SINK;
       
   105 }
       
   106 
       
   107 static GstURIType
       
   108 gst_gio_uri_handler_get_type_src (void)
       
   109 {
       
   110   return GST_URI_SRC;
       
   111 }
       
   112 
       
   113 static gchar **
       
   114 gst_gio_uri_handler_get_protocols (void)
       
   115 {
       
   116   static gchar **protocols = NULL;
       
   117 
       
   118   if (!protocols)
       
   119     protocols = gst_gio_get_supported_protocols ();
       
   120 
       
   121   return protocols;
       
   122 }
       
   123 
       
   124 static const gchar *
       
   125 gst_gio_uri_handler_get_uri (GstURIHandler * handler)
       
   126 {
       
   127   GstElement *element = GST_ELEMENT (handler);
       
   128   const gchar *uri;
       
   129 
       
   130   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
       
   131 
       
   132   g_object_get (G_OBJECT (element), "location", &uri, NULL);
       
   133 
       
   134   return uri;
       
   135 }
       
   136 
       
   137 static gboolean
       
   138 gst_gio_uri_handler_set_uri (GstURIHandler * handler, const gchar * uri)
       
   139 {
       
   140   GstElement *element = GST_ELEMENT (handler);
       
   141 
       
   142   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
       
   143 
       
   144   if (GST_STATE (element) == GST_STATE_PLAYING ||
       
   145       GST_STATE (element) == GST_STATE_PAUSED)
       
   146     return FALSE;
       
   147 
       
   148   g_object_set (G_OBJECT (element), "location", uri, NULL);
       
   149 
       
   150   return TRUE;
       
   151 }
       
   152 
       
   153 static void
       
   154 gst_gio_uri_handler_init (gpointer g_iface, gpointer iface_data)
       
   155 {
       
   156   GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
       
   157   gboolean sink = GPOINTER_TO_INT (iface_data); /* See in do_init below. */
       
   158 
       
   159   if (sink)
       
   160     iface->get_type = gst_gio_uri_handler_get_type_sink;
       
   161   else
       
   162     iface->get_type = gst_gio_uri_handler_get_type_src;
       
   163   iface->get_protocols = gst_gio_uri_handler_get_protocols;
       
   164   iface->get_uri = gst_gio_uri_handler_get_uri;
       
   165   iface->set_uri = gst_gio_uri_handler_set_uri;
       
   166 }
       
   167 
       
   168 void
       
   169 gst_gio_uri_handler_do_init (GType type)
       
   170 {
       
   171   GInterfaceInfo uri_handler_info = {
       
   172     gst_gio_uri_handler_init,
       
   173     NULL,
       
   174     NULL
       
   175   };
       
   176 
       
   177   /* Store information for uri_handler_init to use for distinguishing the
       
   178    * element types.  This lets us use a single interface implementation for both
       
   179    * classes. */
       
   180   uri_handler_info.interface_data = GINT_TO_POINTER (g_type_is_a (type,
       
   181           GST_TYPE_BASE_SINK));
       
   182 
       
   183   g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &uri_handler_info);
       
   184 }
       
   185 
       
   186 static gboolean
       
   187 plugin_init (GstPlugin * plugin)
       
   188 {
       
   189   gboolean ret = TRUE;
       
   190 
       
   191   GST_DEBUG_CATEGORY_INIT (gst_gio_debug, "gio", 0, "GIO elements");
       
   192 
       
   193   /* FIXME: Rank is MARGINAL for now, should be at least SECONDARY+1 in the future
       
   194    * to replace gnomevfssink/src. For testing purposes PRIMARY+1 one makes sense
       
   195    * so it gets autoplugged and preferred over filesrc/sink. */
       
   196 
       
   197   ret &= gst_element_register (plugin, "giosink", GST_RANK_MARGINAL,
       
   198       GST_TYPE_GIO_SINK);
       
   199 
       
   200   ret &= gst_element_register (plugin, "giosrc", GST_RANK_MARGINAL,
       
   201       GST_TYPE_GIO_SRC);
       
   202 
       
   203   ret &= gst_element_register (plugin, "giostreamsink", GST_RANK_NONE,
       
   204       GST_TYPE_GIO_STREAM_SINK);
       
   205 
       
   206   ret &= gst_element_register (plugin, "giostreamsrc", GST_RANK_NONE,
       
   207       GST_TYPE_GIO_STREAM_SRC);
       
   208 
       
   209   return ret;
       
   210 }
       
   211 
       
   212 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "gio",
       
   213     "GIO elements", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME,
       
   214     GST_PACKAGE_ORIGIN)