mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +00:00
neonhttpsrc: port to 1.0
This commit is contained in:
parent
e5288a2464
commit
ca3a83a60d
3 changed files with 67 additions and 97 deletions
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue