summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim@centricular.net>2013-05-12 18:28:18 +0100
committerTim-Philipp Müller <tim@centricular.net>2013-05-12 18:52:55 +0100
commitca3a83a60dbe15e3774e4432f4dea013152052c5 (patch)
tree42414046cec8288f1e7af62a41ab91495898d950
parente5288a2464c41f891abe916bffae5a9e61dffd5c (diff)
neonhttpsrc: port to 1.0
-rw-r--r--configure.ac2
-rw-r--r--ext/neon/gstneonhttpsrc.c160
-rw-r--r--ext/neon/gstneonhttpsrc.h2
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;