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
This commit is contained in:
parent
b203f4cee7
commit
b840a153af
12
ChangeLog
12
ChangeLog
@ -1,3 +1,15 @@
|
|||||||
|
2006-04-29 Sebastien Moutte <sebastien@moutte.net>
|
||||||
|
|
||||||
|
* 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
|
||||||
2006-04-28 Thomas Vander Stichele <thomas at apestaart dot org>
|
2006-04-28 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||||
|
|
||||||
* configure.ac:
|
* configure.ac:
|
||||||
|
2
common
2
common
@ -1 +1 @@
|
|||||||
Subproject commit a6710e67fd82147e32a18f1b63177583faffd498
|
Subproject commit 6b67aa6dd111fb139e1be0f6a386e3ff84cce091
|
@ -41,13 +41,17 @@ static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
|
|||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS_ANY);
|
GST_STATIC_CAPS_ANY);
|
||||||
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_LOCATION,
|
PROP_LOCATION,
|
||||||
PROP_URI,
|
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 ();
|
static void oom_callback ();
|
||||||
@ -119,7 +123,7 @@ gst_neonhttp_src_class_init (GstNeonhttpSrcClass * klass)
|
|||||||
gobject_class->finalize = gst_neonhttp_src_finalize;
|
gobject_class->finalize = gst_neonhttp_src_finalize;
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(G_OBJECT_CLASS (klass), PROP_LOCATION,
|
(gobject_class, PROP_LOCATION,
|
||||||
g_param_spec_string ("location", "Location",
|
g_param_spec_string ("location", "Location",
|
||||||
"The location. In the form:"
|
"The location. In the form:"
|
||||||
"\n\t\t\thttp://a.com/file.txt - default port '80' "
|
"\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_PARAM_READWRITE));
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(G_OBJECT_CLASS (klass), PROP_URI,
|
(gobject_class, PROP_URI,
|
||||||
g_param_spec_string ("uri", "Uri",
|
g_param_spec_string ("uri", "Uri",
|
||||||
"The location in form of a URI (deprecated; use location)",
|
"The location in form of a URI (deprecated; use location)",
|
||||||
"", G_PARAM_READWRITE));
|
"", G_PARAM_READWRITE));
|
||||||
|
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
(G_OBJECT_CLASS (klass), PROP_PROXY,
|
(gobject_class, PROP_PROXY,
|
||||||
g_param_spec_string ("proxy", "Proxy",
|
g_param_spec_string ("proxy", "Proxy",
|
||||||
"The proxy. In the form myproxy.mycompany.com:8080. "
|
"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 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",
|
"\n\t\t\tIf that http_proxy enviroment var isn't define no proxy is used",
|
||||||
"", G_PARAM_READWRITE));
|
"", 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->start = gst_neonhttp_src_start;
|
||||||
gstbasesrc_class->stop = gst_neonhttp_src_stop;
|
gstbasesrc_class->stop = gst_neonhttp_src_stop;
|
||||||
gstbasesrc_class->unlock = gst_neonhttp_src_unlock;
|
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->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);
|
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->uri);
|
||||||
ne_uri_free (&this->proxy);
|
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) {
|
if (this->request) {
|
||||||
ne_request_destroy (this->request);
|
ne_request_destroy (this->request);
|
||||||
@ -288,8 +353,12 @@ gst_neonhttp_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
|
|||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
|
|
||||||
if (*outbuf) {
|
if (*outbuf) {
|
||||||
|
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)));
|
gst_buffer_set_caps (*outbuf, GST_PAD_CAPS (GST_BASE_SRC_PAD (src)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (read < 0) {
|
} else if (read < 0) {
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
@ -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 */
|
/* create a socket for connecting to remote server */
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_neonhttp_src_start (GstBaseSrc * bsrc)
|
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);
|
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)) {
|
if (NE_OK != ne_begin_request (src->request)) {
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
goto done;
|
goto done;
|
||||||
@ -357,6 +470,50 @@ gst_neonhttp_src_start (GstBaseSrc * bsrc)
|
|||||||
src->content_size = -1;
|
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);
|
GST_OBJECT_FLAG_SET (src, GST_NEONHTTP_SRC_OPEN);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
@ -405,6 +562,26 @@ gst_neonhttp_src_stop (GstBaseSrc * bsrc)
|
|||||||
|
|
||||||
src = GST_NEONHTTP_SRC (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) {
|
if (src->request) {
|
||||||
ne_request_destroy (src->request);
|
ne_request_destroy (src->request);
|
||||||
src->request = NULL;
|
src->request = NULL;
|
||||||
@ -575,7 +752,24 @@ gst_neonhttp_src_set_property (GObject * object, guint prop_id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -626,7 +820,23 @@ gst_neonhttp_src_get_property (GObject * object, guint prop_id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -55,6 +55,7 @@ struct _GstNeonhttpSrc {
|
|||||||
ne_uri uri;
|
ne_uri uri;
|
||||||
gchar *uristr;
|
gchar *uristr;
|
||||||
ne_uri proxy;
|
ne_uri proxy;
|
||||||
|
gchar *user_agent;
|
||||||
|
|
||||||
gboolean ishttps;
|
gboolean ishttps;
|
||||||
|
|
||||||
@ -64,6 +65,13 @@ struct _GstNeonhttpSrc {
|
|||||||
|
|
||||||
gboolean eos;
|
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 {
|
struct _GstNeonhttpSrcClass {
|
||||||
|
@ -84,7 +84,7 @@ BSC32=bscmake.exe
|
|||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||||
# ADD LINK32 ws2_32.lib libneon.lib libgstreamer-0.10.lib libgstbase-0.10.lib glib-2.0D.lib gobject-2.0D.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../gstreamer/win32/vs6/debug" /libpath:"../../../gst-plugins-base/win32/vs6/debug" /libpath:"./debug"
|
# ADD LINK32 ws2_32.lib libneonD.lib libgstreamer-0.10.lib libgstbase-0.10.lib glib-2.0D.lib gobject-2.0D.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"../../../gstreamer/win32/vs6/debug" /libpath:"../../../gst-plugins-base/win32/vs6/debug" /libpath:"./debug"
|
||||||
# Begin Special Build Tool
|
# Begin Special Build Tool
|
||||||
TargetPath=.\Debug\libgstneon.dll
|
TargetPath=.\Debug\libgstneon.dll
|
||||||
SOURCE="$(InputPath)"
|
SOURCE="$(InputPath)"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user