diff options
author | Tim-Philipp Müller <tim@centricular.net> | 2013-05-12 18:28:18 +0100 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.net> | 2013-05-12 18:52:55 +0100 |
commit | ca3a83a60dbe15e3774e4432f4dea013152052c5 (patch) | |
tree | 42414046cec8288f1e7af62a41ab91495898d950 | |
parent | e5288a2464c41f891abe916bffae5a9e61dffd5c (diff) |
neonhttpsrc: port to 1.0
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | ext/neon/gstneonhttpsrc.c | 160 | ||||
-rw-r--r-- | ext/neon/gstneonhttpsrc.h | 2 |
3 files changed, 67 insertions, 97 deletions
diff --git a/configure.ac b/configure.ac index 5ae6e4e35..136f62bc8 100644 --- a/configure.ac +++ b/configure.ac @@ -346,7 +346,7 @@ GST_PLUGINS_NONPORTED=" cdxaparse \ linsys vcd \ apexsink cdaudio dc1394 dirac directfb \ gsettings \ - musepack musicbrainz nas neon ofa openal sdl sndfile timidity \ + musepack musicbrainz nas ofa openal sdl sndfile timidity \ directdraw direct3d9 acm wininet \ xvid lv2 teletextdec sndio osx_video quicktime" AC_SUBST(GST_PLUGINS_NONPORTED) diff --git a/ext/neon/gstneonhttpsrc.c b/ext/neon/gstneonhttpsrc.c index bf8617be2..8ecf5e222 100644 --- a/ext/neon/gstneonhttpsrc.c +++ b/ext/neon/gstneonhttpsrc.c @@ -49,7 +49,7 @@ static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", #define HTTP_DEFAULT_HOST "localhost" /* default properties */ -#define DEFAULT_LOCATION "http://"HTTP_DEFAULT_HOST":"G_STRINGIFY(HTTP_DEFAULT_PORT) +#define DEFAULT_LOCATION "http://" HTTP_DEFAULT_HOST ":" G_STRINGIFY(HTTP_DEFAULT_PORT) #define DEFAULT_PROXY "" #define DEFAULT_USER_AGENT "GStreamer neonhttpsrc" #define DEFAULT_AUTOMATIC_REDIRECT TRUE @@ -82,8 +82,8 @@ static void gst_neonhttp_src_set_property (GObject * object, guint prop_id, static void gst_neonhttp_src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static GstFlowReturn gst_neonhttp_src_create (GstPushSrc * psrc, - GstBuffer ** outbuf); +static GstFlowReturn gst_neonhttp_src_fill (GstPushSrc * psrc, + GstBuffer * outbuf); static gboolean gst_neonhttp_src_start (GstBaseSrc * bsrc); static gboolean gst_neonhttp_src_stop (GstBaseSrc * bsrc); static gboolean gst_neonhttp_src_get_size (GstBaseSrc * bsrc, guint64 * size); @@ -95,7 +95,7 @@ static gboolean gst_neonhttp_src_query (GstBaseSrc * bsrc, GstQuery * query); static gboolean gst_neonhttp_src_set_proxy (GstNeonhttpSrc * src, const gchar * uri); static gboolean gst_neonhttp_src_set_location (GstNeonhttpSrc * src, - const gchar * uri); + const gchar * uri, GError ** err); static gint gst_neonhttp_src_send_request_and_redirect (GstNeonhttpSrc * src, ne_session ** ses, ne_request ** req, gint64 offset, gboolean do_redir); static gint gst_neonhttp_src_request_dispatch (GstNeonhttpSrc * src, @@ -104,48 +104,21 @@ static void gst_neonhttp_src_close_session (GstNeonhttpSrc * src); static gchar *gst_neonhttp_src_unicodify (const gchar * str); static void oom_callback (void); -static void -_urihandler_init (GType type) -{ - static const GInterfaceInfo urihandler_info = { - gst_neonhttp_src_uri_handler_init, - NULL, - NULL - }; - - g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info); - - GST_DEBUG_CATEGORY_INIT (neonhttpsrc_debug, "neonhttpsrc", 0, - "NEON HTTP src"); -} - -GST_BOILERPLATE_FULL (GstNeonhttpSrc, gst_neonhttp_src, GstPushSrc, - GST_TYPE_PUSH_SRC, _urihandler_init); - -static void -gst_neonhttp_src_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&srctemplate)); - - gst_element_class_set_static_metadata (element_class, "HTTP client source", - "Source/Network", - "Receive data as a client over the network via HTTP using NEON", - "Edgard Lima <edgard.lima@indt.org.br>, " - "Rosfran Borges <rosfran.borges@indt.org.br>, " - "Andre Moreira Magalhaes <andre.magalhaes@indt.org.br>"); -} +#define parent_class gst_neonhttp_src_parent_class +G_DEFINE_TYPE_WITH_CODE (GstNeonhttpSrc, gst_neonhttp_src, GST_TYPE_PUSH_SRC, + G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, + gst_neonhttp_src_uri_handler_init)); static void gst_neonhttp_src_class_init (GstNeonhttpSrcClass * klass) { GObjectClass *gobject_class; + GstElementClass *element_class; GstBaseSrcClass *gstbasesrc_class; GstPushSrcClass *gstpushsrc_class; gobject_class = (GObjectClass *) klass; + element_class = (GstElementClass *) klass; gstbasesrc_class = (GstBaseSrcClass *) klass; gstpushsrc_class = (GstPushSrcClass *) klass; @@ -238,14 +211,24 @@ gst_neonhttp_src_class_init (GstNeonhttpSrcClass * klass) gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_neonhttp_src_do_seek); gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_neonhttp_src_query); - gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_neonhttp_src_create); + gstpushsrc_class->fill = GST_DEBUG_FUNCPTR (gst_neonhttp_src_fill); GST_DEBUG_CATEGORY_INIT (neonhttpsrc_debug, "neonhttpsrc", 0, "NEON HTTP Client Source"); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&srctemplate)); + + gst_element_class_set_static_metadata (element_class, "HTTP client source", + "Source/Network", + "Receive data as a client over the network via HTTP using NEON", + "Edgard Lima <edgard.lima@indt.org.br>, " + "Rosfran Borges <rosfran.borges@indt.org.br>, " + "Andre Moreira Magalhaes <andre.magalhaes@indt.org.br>"); } static void -gst_neonhttp_src_init (GstNeonhttpSrc * src, GstNeonhttpSrcClass * g_class) +gst_neonhttp_src_init (GstNeonhttpSrc * src) { const gchar *str; @@ -265,11 +248,9 @@ gst_neonhttp_src_init (GstNeonhttpSrc * src, GstNeonhttpSrcClass * g_class) memset (&src->uri, 0, sizeof (src->uri)); memset (&src->proxy, 0, sizeof (src->proxy)); src->content_size = -1; - src->icy_caps = NULL; - src->icy_metaint = 0; src->seekable = TRUE; - gst_neonhttp_src_set_location (src, DEFAULT_LOCATION); + gst_neonhttp_src_set_location (src, DEFAULT_LOCATION, NULL); /* configure proxy */ str = g_getenv ("http_proxy"); @@ -297,11 +278,6 @@ gst_neonhttp_src_dispose (GObject * gobject) src->cookies = NULL; } - if (src->icy_caps) { - gst_caps_unref (src->icy_caps); - src->icy_caps = NULL; - } - if (src->request) { ne_request_destroy (src->request); src->request = NULL; @@ -356,7 +332,7 @@ gst_neonhttp_src_set_property (GObject * object, guint prop_id, GST_WARNING ("location property cannot be NULL"); goto done; } - if (!gst_neonhttp_src_set_location (src, location)) { + if (!gst_neonhttp_src_set_location (src, location, NULL)) { GST_WARNING ("badly formated location"); goto done; } @@ -471,51 +447,38 @@ oom_callback (void) } static GstFlowReturn -gst_neonhttp_src_create (GstPushSrc * psrc, GstBuffer ** outbuf) +gst_neonhttp_src_fill (GstPushSrc * psrc, GstBuffer * outbuf) { GstNeonhttpSrc *src; - GstBaseSrc *basesrc; - GstFlowReturn ret; gint read; src = GST_NEONHTTP_SRC (psrc); - basesrc = GST_BASE_SRC_CAST (psrc); /* The caller should know the number of bytes and not read beyond EOS. */ if (G_UNLIKELY (src->eos)) goto eos; - /* Create the buffer. */ - ret = gst_pad_alloc_buffer (GST_BASE_SRC_PAD (basesrc), - basesrc->segment.last_stop, basesrc->blocksize, - src->icy_caps ? src->icy_caps : - GST_PAD_CAPS (GST_BASE_SRC_PAD (basesrc)), outbuf); - - if (G_UNLIKELY (ret != GST_FLOW_OK)) - goto done; - - read = gst_neonhttp_src_request_dispatch (src, *outbuf); + read = gst_neonhttp_src_request_dispatch (src, outbuf); if (G_UNLIKELY (read < 0)) goto read_error; - GST_LOG_OBJECT (src, "returning %u bytes", GST_BUFFER_SIZE (*outbuf)); + GST_LOG_OBJECT (src, "returning %" G_GSIZE_FORMAT " bytes, " + "offset %" G_GUINT64_FORMAT, gst_buffer_get_size (outbuf), + GST_BUFFER_OFFSET (outbuf)); -done: - return ret; + return GST_FLOW_OK; /* ERRORS */ eos: { GST_DEBUG_OBJECT (src, "EOS reached"); - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; } read_error: { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("Could not read any bytes (%i, %s)", read, ne_get_error (src->session))); - gst_buffer_unref (*outbuf); - *outbuf = NULL; return GST_FLOW_ERROR; } } @@ -562,18 +525,16 @@ gst_neonhttp_src_start (GstBaseSrc * bsrc) if (TRUE) { /* Icecast stuff */ const gchar *str_value; - gint gint_value; + gint icy_metaint; str_value = ne_get_response_header (src->request, "icy-metaint"); if (str_value) { - if (sscanf (str_value, "%d", &gint_value) == 1) { - if (src->icy_caps) { - gst_caps_unref (src->icy_caps); - src->icy_caps = NULL; - } - src->icy_metaint = gint_value; - src->icy_caps = gst_caps_new_simple ("application/x-icy", - "metadata-interval", G_TYPE_INT, src->icy_metaint, NULL); + if (sscanf (str_value, "%d", &icy_metaint) == 1) { + GstCaps *icy_caps; + + icy_caps = gst_caps_new_simple ("application/x-icy", + "metadata-interval", G_TYPE_INT, icy_metaint, NULL); + gst_base_src_set_caps (GST_BASE_SRC (src), icy_caps); } } @@ -658,11 +619,6 @@ gst_neonhttp_src_stop (GstBaseSrc * bsrc) src->iradio_url = NULL; } - if (src->icy_caps) { - gst_caps_unref (src->icy_caps); - src->icy_caps = NULL; - } - src->eos = FALSE; src->content_size = -1; src->read_position = 0; @@ -754,7 +710,8 @@ gst_neonhttp_src_query (GstBaseSrc * bsrc, GstQuery * query) } static gboolean -gst_neonhttp_src_set_location (GstNeonhttpSrc * src, const gchar * uri) +gst_neonhttp_src_set_location (GstNeonhttpSrc * src, const gchar * uri, + GError ** err) { ne_uri_free (&src->uri); if (src->location) { @@ -934,7 +891,7 @@ gst_neonhttp_src_send_request_and_redirect (GstNeonhttpSrc * src, redir = ne_get_response_header (request, "Location"); if (redir != NULL) { ne_uri_free (&src->uri); - gst_neonhttp_src_set_location (src, redir); + gst_neonhttp_src_set_location (src, redir, NULL); GST_LOG_OBJECT (src, "Got HTTP Status Code %d", http_status); GST_LOG_OBJECT (src, "Using 'Location' header [%s]", src->uri.host); } @@ -984,18 +941,24 @@ gst_neonhttp_src_send_request_and_redirect (GstNeonhttpSrc * src, static gint gst_neonhttp_src_request_dispatch (GstNeonhttpSrc * src, GstBuffer * outbuf) { + GstMapInfo map = GST_MAP_INFO_INIT; gint ret; gint read = 0; - gint sizetoread = GST_BUFFER_SIZE (outbuf); + gint sizetoread; /* Loop sending the request: * Retry whilst authentication fails and we supply it. */ ssize_t len = 0; + if (!gst_buffer_map (outbuf, &map, GST_MAP_WRITE)) + return -1; + + sizetoread = map.size; + while (sizetoread > 0) { - len = ne_read_response_block (src->request, - (gchar *) GST_BUFFER_DATA (outbuf) + read, sizetoread); + len = ne_read_response_block (src->request, (gchar *) map.data + read, + sizetoread); if (len > 0) { read += len; sizetoread -= len; @@ -1005,7 +968,8 @@ gst_neonhttp_src_request_dispatch (GstNeonhttpSrc * src, GstBuffer * outbuf) } - GST_BUFFER_SIZE (outbuf) = read; + gst_buffer_set_size (outbuf, read); + GST_BUFFER_OFFSET (outbuf) = src->read_position; if (len < 0) { read = -2; @@ -1026,6 +990,9 @@ gst_neonhttp_src_request_dispatch (GstNeonhttpSrc * src, GstBuffer * outbuf) src->read_position += read; done: + + gst_buffer_unmap (outbuf, &map); + return read; } @@ -1081,33 +1048,35 @@ gst_neonhttp_src_unicodify (const gchar * str) /* GstURIHandler Interface */ static guint -gst_neonhttp_src_uri_get_type (void) +gst_neonhttp_src_uri_get_type (GType type) { return GST_URI_SRC; } static const gchar *const * -gst_neonhttp_src_uri_get_protocols (void) +gst_neonhttp_src_uri_get_protocols (GType type) { static const gchar *protocols[] = { "http", "https", NULL }; return protocols; } -static const gchar * +static gchar * gst_neonhttp_src_uri_get_uri (GstURIHandler * handler) { GstNeonhttpSrc *src = GST_NEONHTTP_SRC (handler); - return src->location; + /* FIXME: make thread-safe */ + return g_strdup (src->location); } static gboolean -gst_neonhttp_src_uri_set_uri (GstURIHandler * handler, const gchar * uri) +gst_neonhttp_src_uri_set_uri (GstURIHandler * handler, const gchar * uri, + GError ** error) { GstNeonhttpSrc *src = GST_NEONHTTP_SRC (handler); - return gst_neonhttp_src_set_location (src, uri); + return gst_neonhttp_src_set_location (src, uri, error); } static void @@ -1129,6 +1098,9 @@ gst_neonhttp_src_uri_handler_init (gpointer g_iface, gpointer iface_data) static gboolean plugin_init (GstPlugin * plugin) { + GST_DEBUG_CATEGORY_INIT (neonhttpsrc_debug, "neonhttpsrc", 0, + "NEON HTTP src"); + return gst_element_register (plugin, "neonhttpsrc", GST_RANK_NONE, GST_TYPE_NEONHTTP_SRC); } diff --git a/ext/neon/gstneonhttpsrc.h b/ext/neon/gstneonhttpsrc.h index 4d2b1c075..1bf7ca6e8 100644 --- a/ext/neon/gstneonhttpsrc.h +++ b/ext/neon/gstneonhttpsrc.h @@ -62,8 +62,6 @@ struct _GstNeonhttpSrc { gchar *iradio_name; gchar *iradio_genre; gchar *iradio_url; - GstCaps *icy_caps; - gint icy_metaint; /* enable Neon HTTP redirects (HTTP 302 status code) */ gboolean automatic_redirect; |