summaryrefslogtreecommitdiff
path: root/ext/neon
diff options
context:
space:
mode:
authorSébastien Moutte <sebastien@moutte.net>2006-04-29 15:36:16 +0000
committerSébastien Moutte <sebastien@moutte.net>2006-04-29 15:36:16 +0000
commitb840a153aff1d4bad63dadd9c4824a231643abe8 (patch)
treedb508b9c54a359597871e81cf5ed3b68607c830f /ext/neon
parentb203f4cee76075d43055e3b1d7dc31c444c28837 (diff)
downloadgstreamer-plugins-bad-b840a153aff1d4bad63dadd9c4824a231643abe8.tar.gz
ext/neon/gstneonhttpsrc.*: added iradio-mode support as in gnomevfssrc to enable connections with icydemux that will ...
Original commit message from CVS: * ext/neon/gstneonhttpsrc.c: * ext/neon/gstneonhttpsrc.h: added iradio-mode support as in gnomevfssrc to enable connections with icydemux that will send title tag messages on shoutcast/icecast streams. I've also added iradio properties iradio-name, iradio-genre, iradio-url. added user-agent property because some shoutcast streams don't return data if the GET requests don't have a User-Agent. * win32/common/libgstneon.dsp: use debug version of libneon in debug mode
Diffstat (limited to 'ext/neon')
-rw-r--r--ext/neon/gstneonhttpsrc.c226
-rw-r--r--ext/neon/gstneonhttpsrc.h8
2 files changed, 226 insertions, 8 deletions
diff --git a/ext/neon/gstneonhttpsrc.c b/ext/neon/gstneonhttpsrc.c
index b8932e4a1..356da9a01 100644
--- a/ext/neon/gstneonhttpsrc.c
+++ b/ext/neon/gstneonhttpsrc.c
@@ -22,7 +22,7 @@
#define HTTP_DEFAULT_HOST "localhost"
#define HTTP_DEFAULT_PORT 80
-#define HTTPS_DEFAULT_PORT 443
+#define HTTPS_DEFAULT_PORT 443
GST_DEBUG_CATEGORY (neonhttpsrc_debug);
#define GST_CAT_DEFAULT neonhttpsrc_debug
@@ -41,13 +41,17 @@ static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY);
-
enum
{
PROP_0,
PROP_LOCATION,
PROP_URI,
- PROP_PROXY
+ PROP_PROXY,
+ PROP_USER_AGENT,
+ PROP_IRADIO_MODE,
+ PROP_IRADIO_NAME,
+ PROP_IRADIO_GENRE,
+ PROP_IRADIO_URL
};
static void oom_callback ();
@@ -119,7 +123,7 @@ gst_neonhttp_src_class_init (GstNeonhttpSrcClass * klass)
gobject_class->finalize = gst_neonhttp_src_finalize;
g_object_class_install_property
- (G_OBJECT_CLASS (klass), PROP_LOCATION,
+ (gobject_class, PROP_LOCATION,
g_param_spec_string ("location", "Location",
"The location. In the form:"
"\n\t\t\thttp://a.com/file.txt - default port '80' "
@@ -130,19 +134,47 @@ gst_neonhttp_src_class_init (GstNeonhttpSrcClass * klass)
"", G_PARAM_READWRITE));
g_object_class_install_property
- (G_OBJECT_CLASS (klass), PROP_URI,
+ (gobject_class, PROP_URI,
g_param_spec_string ("uri", "Uri",
"The location in form of a URI (deprecated; use location)",
"", G_PARAM_READWRITE));
g_object_class_install_property
- (G_OBJECT_CLASS (klass), PROP_PROXY,
+ (gobject_class, PROP_PROXY,
g_param_spec_string ("proxy", "Proxy",
"The proxy. In the form myproxy.mycompany.com:8080. "
"\n\t\t\tIf nothing is passed g_getenv(\"http_proxy\") will be used "
"\n\t\t\tIf that http_proxy enviroment var isn't define no proxy is used",
"", G_PARAM_READWRITE));
+ g_object_class_install_property
+ (gobject_class, PROP_USER_AGENT,
+ g_param_spec_string ("user-agent", "User-Agent",
+ "The User-Agent used for connection.",
+ "neonhttpsrc", G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (gobject_class, PROP_IRADIO_MODE,
+ g_param_spec_boolean ("iradio-mode", "iradio-mode",
+ "Enable internet radio mode (extraction of shoutcast/icecast metadata)",
+ FALSE, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_IRADIO_NAME,
+ g_param_spec_string ("iradio-name",
+ "iradio-name", "Name of the stream", NULL, G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_IRADIO_GENRE,
+ g_param_spec_string ("iradio-genre",
+ "iradio-genre", "Genre of the stream", NULL, G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_IRADIO_URL,
+ g_param_spec_string ("iradio-url",
+ "iradio-url",
+ "Homepage URL for radio stream", NULL, G_PARAM_READABLE));
+
gstbasesrc_class->start = gst_neonhttp_src_start;
gstbasesrc_class->stop = gst_neonhttp_src_stop;
gstbasesrc_class->unlock = gst_neonhttp_src_unlock;
@@ -171,6 +203,15 @@ gst_neonhttp_src_init (GstNeonhttpSrc * this, GstNeonhttpSrcClass * g_class)
this->adapter = gst_adapter_new ();
+ this->user_agent = g_strdup ("neonhttpsrc");
+
+ this->iradio_mode = FALSE;
+ this->iradio_name = NULL;
+ this->iradio_genre = NULL;
+ this->iradio_url = NULL;
+ this->icy_caps = NULL;
+ this->icy_metaint = 0;
+
GST_OBJECT_FLAG_UNSET (this, GST_NEONHTTP_SRC_OPEN);
}
@@ -182,6 +223,30 @@ gst_neonhttp_src_finalize (GObject * gobject)
ne_uri_free (&this->uri);
ne_uri_free (&this->proxy);
+ if (this->user_agent) {
+ g_free (this->user_agent);
+ this->user_agent = NULL;
+ }
+
+ if (this->iradio_name) {
+ g_free (this->iradio_name);
+ this->iradio_name = NULL;
+ }
+
+ if (this->iradio_genre) {
+ g_free (this->iradio_genre);
+ this->iradio_genre = NULL;
+ }
+
+ if (this->iradio_url) {
+ g_free (this->iradio_url);
+ this->iradio_url = NULL;
+ }
+
+ if (this->icy_caps) {
+ gst_caps_unref (this->icy_caps);
+ this->icy_caps = NULL;
+ }
if (this->request) {
ne_request_destroy (this->request);
@@ -288,7 +353,11 @@ gst_neonhttp_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
if (read > 0) {
if (*outbuf) {
- gst_buffer_set_caps (*outbuf, GST_PAD_CAPS (GST_BASE_SRC_PAD (src)));
+ if (src->icy_caps) {
+ gst_buffer_set_caps (*outbuf, src->icy_caps);
+ } else {
+ gst_buffer_set_caps (*outbuf, GST_PAD_CAPS (GST_BASE_SRC_PAD (src)));
+ }
}
} else if (read < 0) {
@@ -316,6 +385,42 @@ wrong_state:
}
+/* The following two charset mangling functions were copied from gnomevfssrc.
+ * Preserve them under the unverified assumption that they do something vaguely
+ * worthwhile.
+ */
+static char *
+unicodify (const char *str, int len, ...)
+{
+ char *ret = NULL, *cset;
+ va_list args;
+ gsize bytes_read, bytes_written;
+
+ if (g_utf8_validate (str, len, NULL))
+ return g_strndup (str, len >= 0 ? len : strlen (str));
+
+ va_start (args, len);
+ while ((cset = va_arg (args, char *)) != NULL)
+ {
+ if (!strcmp (cset, "locale"))
+ ret = g_locale_to_utf8 (str, len, &bytes_read, &bytes_written, NULL);
+ else
+ ret = g_convert (str, len, "UTF-8", cset,
+ &bytes_read, &bytes_written, NULL);
+ if (ret)
+ break;
+ }
+ va_end (args);
+
+ return ret;
+}
+
+static char *
+gst_neonhttp_src_unicodify (const char *str)
+{
+ return unicodify (str, -1, "locale", "ISO-8859-1", NULL);
+}
+
/* create a socket for connecting to remote server */
static gboolean
gst_neonhttp_src_start (GstBaseSrc * bsrc)
@@ -344,6 +449,14 @@ gst_neonhttp_src_start (GstBaseSrc * bsrc)
src->request = ne_request_create (src->session, "GET", src->uri.path);
+ if (src->user_agent) {
+ ne_add_request_header (src->request, "User-Agent", src->user_agent);
+ }
+
+ if (src->iradio_mode) {
+ ne_add_request_header (src->request, "icy-metadata", "1");
+ }
+
if (NE_OK != ne_begin_request (src->request)) {
ret = FALSE;
goto done;
@@ -357,6 +470,50 @@ gst_neonhttp_src_start (GstBaseSrc * bsrc)
src->content_size = -1;
}
+ if (src->iradio_mode) {
+ /* Icecast stuff */
+ const char *str_value;
+ gint gint_value;
+
+ 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);
+ }
+ }
+
+ str_value = ne_get_response_header (src->request, "icy-name");
+ if (str_value) {
+ if (src->iradio_name) {
+ g_free (src->iradio_name);
+ src->iradio_name = NULL;
+ }
+ src->iradio_name = gst_neonhttp_src_unicodify (str_value);
+ }
+ str_value = ne_get_response_header (src->request, "icy-genre");
+ if (str_value) {
+ if (src->iradio_genre) {
+ g_free (src->iradio_genre);
+ src->iradio_genre = NULL;
+ }
+ src->iradio_genre = gst_neonhttp_src_unicodify (str_value);
+ }
+ str_value = ne_get_response_header (src->request, "icy-url");
+ if (str_value) {
+ if (src->iradio_url) {
+ g_free (src->iradio_url);
+ src->iradio_url = NULL;
+ }
+ src->iradio_url = gst_neonhttp_src_unicodify (str_value);
+ }
+ }
+
GST_OBJECT_FLAG_SET (src, GST_NEONHTTP_SRC_OPEN);
done:
@@ -405,6 +562,26 @@ gst_neonhttp_src_stop (GstBaseSrc * bsrc)
src = GST_NEONHTTP_SRC (bsrc);
+ if (src->iradio_name) {
+ g_free (src->iradio_name);
+ src->iradio_name = NULL;
+ }
+
+ if (src->iradio_genre) {
+ g_free (src->iradio_genre);
+ src->iradio_genre = NULL;
+ }
+
+ if (src->iradio_url) {
+ g_free (src->iradio_url);
+ src->iradio_url = 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;
@@ -575,7 +752,24 @@ gst_neonhttp_src_set_property (GObject * object, guint prop_id,
}
}
break;
+ case PROP_USER_AGENT:
+ {
+ if (this->user_agent) {
+ g_free (this->user_agent);
+ this->user_agent = NULL;
+ }
+
+ if (g_value_get_string (value)) {
+ this->user_agent = g_strdup (g_value_get_string (value));
+ }
+ break;
+ }
+ case PROP_IRADIO_MODE:
+ {
+ this->iradio_mode = g_value_get_boolean (value);
+ break;
+ }
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -626,7 +820,23 @@ gst_neonhttp_src_get_property (GObject * object, guint prop_id,
}
}
break;
-
+ case PROP_USER_AGENT:
+ {
+ g_value_set_string (value, neonhttpsrc->user_agent);
+ break;
+ }
+ case PROP_IRADIO_MODE:
+ g_value_set_boolean (value, neonhttpsrc->iradio_mode);
+ break;
+ case PROP_IRADIO_NAME:
+ g_value_set_string (value, neonhttpsrc->iradio_name);
+ break;
+ case PROP_IRADIO_GENRE:
+ g_value_set_string (value, neonhttpsrc->iradio_genre);
+ break;
+ case PROP_IRADIO_URL:
+ g_value_set_string (value, neonhttpsrc->iradio_url);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
diff --git a/ext/neon/gstneonhttpsrc.h b/ext/neon/gstneonhttpsrc.h
index ce749cc98..4f20e0ef9 100644
--- a/ext/neon/gstneonhttpsrc.h
+++ b/ext/neon/gstneonhttpsrc.h
@@ -55,6 +55,7 @@ struct _GstNeonhttpSrc {
ne_uri uri;
gchar *uristr;
ne_uri proxy;
+ gchar *user_agent;
gboolean ishttps;
@@ -64,6 +65,13 @@ struct _GstNeonhttpSrc {
gboolean eos;
+ /* icecast/audiocast metadata extraction handling */
+ gboolean iradio_mode;
+ gchar *iradio_name;
+ gchar *iradio_genre;
+ gchar *iradio_url;
+ GstCaps *icy_caps;
+ gint icy_metaint;
};
struct _GstNeonhttpSrcClass {