diff --git a/plugins/elements/gstdataurisrc.c b/plugins/elements/gstdataurisrc.c index 446ca84078..ef9e328c14 100644 --- a/plugins/elements/gstdataurisrc.c +++ b/plugins/elements/gstdataurisrc.c @@ -61,56 +61,32 @@ static void gst_data_uri_src_set_property (GObject * object, static void gst_data_uri_src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static GstCaps *gst_data_uri_src_get_caps (GstBaseSrc * src); +static GstCaps *gst_data_uri_src_get_caps (GstBaseSrc * src, GstCaps * filter); static gboolean gst_data_uri_src_get_size (GstBaseSrc * src, guint64 * size); static gboolean gst_data_uri_src_is_seekable (GstBaseSrc * src); static GstFlowReturn gst_data_uri_src_create (GstBaseSrc * src, guint64 offset, guint size, GstBuffer ** buf); -static gboolean gst_data_uri_src_check_get_range (GstBaseSrc * src); static gboolean gst_data_uri_src_start (GstBaseSrc * src); static void gst_data_uri_src_handler_init (gpointer g_iface, gpointer iface_data); -static GstURIType gst_data_uri_src_get_uri_type (void); -static gchar **gst_data_uri_src_get_protocols (void); +static GstURIType gst_data_uri_src_get_uri_type (GType type); +static gchar **gst_data_uri_src_get_protocols (GType type); static const gchar *gst_data_uri_src_get_uri (GstURIHandler * handler); static gboolean gst_data_uri_src_set_uri (GstURIHandler * handler, const gchar * uri); -static void -_do_init (GType gtype) -{ - static const GInterfaceInfo urihandler_info = { - gst_data_uri_src_handler_init, - 0, 0 - }; - GST_DEBUG_CATEGORY_INIT (data_uri_src_debug, "dataurisrc", 0, - "data: URI source"); - g_type_add_interface_static (gtype, GST_TYPE_URI_HANDLER, &urihandler_info); -} - -GST_BOILERPLATE_FULL (GstDataURISrc, gst_data_uri_src, GstBaseSrc, - GST_TYPE_BASE_SRC, _do_init); - -static void -gst_data_uri_src_base_init (gpointer klass) -{ - GstElementClass *element_class = (GstElementClass *) (klass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_template)); - gst_element_class_set_details_simple (element_class, - "data: URI source element", "Source", "Handles data: uris", - "Philippe Normand , " - "Sebastian Dröge "); - -} +#define gst_data_uri_src_parent_class parent_class +G_DEFINE_TYPE_WITH_CODE (GstDataURISrc, gst_data_uri_src, GST_TYPE_BASE_SRC, + G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, + gst_data_uri_src_handler_init)); static void gst_data_uri_src_class_init (GstDataURISrcClass * klass) { GObjectClass *gobject_class = (GObjectClass *) klass; + GstElementClass *element_class = (GstElementClass *) klass; GstBaseSrcClass *basesrc_class = (GstBaseSrcClass *) klass; gobject_class->finalize = gst_data_uri_src_finalize; @@ -123,19 +99,26 @@ gst_data_uri_src_class_init (GstDataURISrcClass * klass) "URI that should be used", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_template)); + gst_element_class_set_details_simple (element_class, + "data: URI source element", "Source", "Handles data: uris", + "Philippe Normand , " + "Sebastian Dröge "); + + GST_DEBUG_CATEGORY_INIT (data_uri_src_debug, "dataurisrc", 0, + "data: URI source"); + basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_data_uri_src_get_caps); basesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_data_uri_src_get_size); basesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_data_uri_src_is_seekable); basesrc_class->create = GST_DEBUG_FUNCPTR (gst_data_uri_src_create); - basesrc_class->check_get_range = - GST_DEBUG_FUNCPTR (gst_data_uri_src_check_get_range); basesrc_class->start = GST_DEBUG_FUNCPTR (gst_data_uri_src_start); } static void -gst_data_uri_src_init (GstDataURISrc * src, GstDataURISrcClass * g_class) +gst_data_uri_src_init (GstDataURISrc * src) { - gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_BYTES); } static void @@ -188,16 +171,16 @@ gst_data_uri_src_get_property (GObject * object, } static GstCaps * -gst_data_uri_src_get_caps (GstBaseSrc * basesrc) +gst_data_uri_src_get_caps (GstBaseSrc * basesrc, GstCaps * filter) { GstDataURISrc *src = GST_DATA_URI_SRC (basesrc); GstCaps *caps; GST_OBJECT_LOCK (src); - if (!src->buffer || !GST_BUFFER_CAPS (src->buffer)) - caps = gst_caps_new_empty (); + if (gst_pad_has_current_caps (GST_BASE_SRC_PAD (basesrc))) + caps = gst_pad_get_current_caps (GST_BASE_SRC_PAD (basesrc)); else - caps = gst_buffer_get_caps (src->buffer); + caps = gst_caps_new_any (); GST_OBJECT_UNLOCK (src); return caps; @@ -215,7 +198,7 @@ gst_data_uri_src_get_size (GstBaseSrc * basesrc, guint64 * size) *size = -1; } else { ret = TRUE; - *size = GST_BUFFER_SIZE (src->buffer); + *size = gst_buffer_get_size (src->buffer); } GST_OBJECT_UNLOCK (src); @@ -242,14 +225,13 @@ gst_data_uri_src_create (GstBaseSrc * basesrc, guint64 offset, guint size, /* This is only correct because GstBaseSrc already clips size for us to be no * larger than the max. available size if a segment at the end is requested */ - if (offset + size > GST_BUFFER_SIZE (src->buffer)) { + if (offset + size > gst_buffer_get_size (src->buffer)) { ret = GST_FLOW_UNEXPECTED; } else { ret = GST_FLOW_OK; - *buf = gst_buffer_create_sub (src->buffer, offset, size); - gst_buffer_set_caps (*buf, GST_BUFFER_CAPS (src->buffer)); + *buf = + gst_buffer_copy_region (src->buffer, GST_BUFFER_COPY_ALL, offset, size); } - GST_OBJECT_UNLOCK (src); return ret; @@ -263,12 +245,6 @@ no_buffer: } } -static gboolean -gst_data_uri_src_check_get_range (GstBaseSrc * basesrc) -{ - return TRUE; -} - static gboolean gst_data_uri_src_start (GstBaseSrc * basesrc) { @@ -294,25 +270,14 @@ no_uri: } } -static void -gst_data_uri_src_handler_init (gpointer g_iface, gpointer iface_data) -{ - GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; - - iface->get_type = gst_data_uri_src_get_uri_type; - iface->get_protocols = gst_data_uri_src_get_protocols; - iface->get_uri = gst_data_uri_src_get_uri; - iface->set_uri = gst_data_uri_src_set_uri; -} - static GstURIType -gst_data_uri_src_get_uri_type (void) +gst_data_uri_src_get_uri_type (GType type) { return GST_URI_SRC; } static gchar ** -gst_data_uri_src_get_protocols (void) +gst_data_uri_src_get_protocols (GType type) { static gchar *protocols[] = { (char *) "data", 0 }; @@ -337,12 +302,16 @@ gst_data_uri_src_set_uri (GstURIHandler * handler, const gchar * uri) const gchar *data_start; const gchar *orig_uri = uri; GstCaps *caps; + GstBuffer *buffer; gboolean base64 = FALSE; gchar *charset = NULL; + gpointer bdata; + gsize bsize; GST_OBJECT_LOCK (src); if (GST_STATE (src) >= GST_STATE_PAUSED) goto wrong_state; + GST_OBJECT_UNLOCK (src); /* uri must be an URI as defined in RFC 2397 * data:[][;base64], @@ -392,74 +361,63 @@ gst_data_uri_src_set_uri (GstURIHandler * handler, const gchar * uri) /* Skip comma */ data_start += 1; if (base64) { - gsize bsize; - - src->buffer = gst_buffer_new (); - GST_BUFFER_DATA (src->buffer) = - (guint8 *) g_base64_decode (data_start, &bsize); - GST_BUFFER_MALLOCDATA (src->buffer) = GST_BUFFER_DATA (src->buffer); - GST_BUFFER_SIZE (src->buffer) = bsize; + bdata = g_base64_decode (data_start, &bsize); } else { - gchar *data; - /* URI encoded, i.e. "percent" encoding */ - data = g_uri_unescape_string (data_start, NULL); - if (data == NULL) + bdata = g_uri_unescape_string (data_start, NULL); + if (bdata == NULL) goto invalid_uri_encoded_data; - - src->buffer = gst_buffer_new (); - GST_BUFFER_DATA (src->buffer) = (guint8 *) data; - GST_BUFFER_MALLOCDATA (src->buffer) = GST_BUFFER_DATA (src->buffer); - GST_BUFFER_SIZE (src->buffer) = strlen (data) + 1; + bsize = strlen (bdata) + 1; } - /* Convert to UTF8 */ if (strcmp ("text/plain", mimetype) == 0 && charset && g_ascii_strcasecmp ("US-ASCII", charset) != 0 && g_ascii_strcasecmp ("UTF-8", charset) != 0) { gsize read; gsize written; - gchar *old_data = (gchar *) GST_BUFFER_DATA (src->buffer); - gchar *data; + gpointer data; data = - g_convert_with_fallback (old_data, -1, "UTF-8", charset, (char *) "*", + g_convert_with_fallback (bdata, -1, "UTF-8", charset, (char *) "*", &read, &written, NULL); - g_free (old_data); - GST_BUFFER_DATA (src->buffer) = GST_BUFFER_MALLOCDATA (src->buffer) = - (guint8 *) data; - GST_BUFFER_SIZE (src->buffer) = written; - } + g_free (bdata); - caps = gst_type_find_helper_for_buffer (GST_OBJECT (src), src->buffer, NULL); + bdata = data; + bsize = written; + } + buffer = gst_buffer_new_wrapped (bdata, bsize); + + caps = gst_type_find_helper_for_buffer (GST_OBJECT (src), buffer, NULL); if (!caps) caps = gst_caps_new_simple (mimetype, NULL); - gst_buffer_set_caps (src->buffer, caps); + gst_base_src_set_caps (GST_BASE_SRC_CAST (src), caps); gst_caps_unref (caps); + GST_OBJECT_LOCK (src); + gst_buffer_replace (&src->buffer, buffer); g_free (src->uri); src->uri = g_strdup (orig_uri); + GST_OBJECT_UNLOCK (src); ret = TRUE; out: - GST_OBJECT_UNLOCK (src); - g_free (mimetype); g_free (charset); return ret; -invalid_uri: - { - GST_WARNING_OBJECT (src, "invalid URI '%s'", uri); - goto out; - } wrong_state: { GST_WARNING_OBJECT (src, "Can't set URI in %s state", gst_element_state_get_name (GST_STATE (src))); + GST_OBJECT_UNLOCK (src); + goto out; + } +invalid_uri: + { + GST_WARNING_OBJECT (src, "invalid URI '%s'", uri); goto out; } invalid_uri_encoded_data: @@ -469,6 +427,17 @@ invalid_uri_encoded_data: } } +static void +gst_data_uri_src_handler_init (gpointer g_iface, gpointer iface_data) +{ + GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; + + iface->get_type = gst_data_uri_src_get_uri_type; + iface->get_protocols = gst_data_uri_src_get_protocols; + iface->get_uri = gst_data_uri_src_get_uri; + iface->set_uri = gst_data_uri_src_set_uri; +} + static gboolean plugin_init (GstPlugin * plugin) {