From 66d9dbe49e9123081cef9f283a4e8a1069ff9fff Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Tue, 23 Mar 2010 19:46:43 +0100 Subject: [PATCH] icydemux: Handle upstream Content-Type. Allows us to handle ShoutCast TV (NSV) streams. If the upstream caps have the 'content-type' field set to video/nsv, then we shortcut the typefinding and set video/x-nsv directly. --- gst/icydemux/gsticydemux.c | 67 ++++++++++++++++++++++++++------------ gst/icydemux/gsticydemux.h | 3 ++ 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/gst/icydemux/gsticydemux.c b/gst/icydemux/gsticydemux.c index 2700359544..a2f4ef2c95 100644 --- a/gst/icydemux/gsticydemux.c +++ b/gst/icydemux/gsticydemux.c @@ -180,6 +180,11 @@ gst_icydemux_reset (GstICYDemux * icydemux) gst_buffer_unref (icydemux->typefind_buf); icydemux->typefind_buf = NULL; } + + if (icydemux->content_type) { + g_free (icydemux->content_type); + icydemux->content_type = NULL; + } } static void @@ -206,16 +211,20 @@ gst_icydemux_sink_setcaps (GstPad * pad, GstCaps * caps) { GstICYDemux *icydemux = GST_ICYDEMUX (GST_PAD_PARENT (pad)); GstStructure *structure = gst_caps_get_structure (caps, 0); + const gchar *tmp; if (!gst_structure_get_int (structure, "metadata-interval", &icydemux->meta_interval)) return FALSE; - else { - /* We have a meta interval, so initialise the rest */ - icydemux->remaining = icydemux->meta_interval; - icydemux->meta_remaining = 0; - return TRUE; - } + + /* If incoming caps have the HTTP Content-Type, copy that over */ + if ((tmp = gst_structure_get_string (structure, "content-type"))) + icydemux->content_type = g_strdup (tmp); + + /* We have a meta interval, so initialise the rest */ + icydemux->remaining = icydemux->meta_interval; + icydemux->meta_remaining = 0; + return TRUE; } static void @@ -399,30 +408,46 @@ gst_icydemux_typefind_or_forward (GstICYDemux * icydemux, GstBuffer * buf) { if (icydemux->typefinding) { GstBuffer *tf_buf; - GstCaps *caps; + GstCaps *caps = NULL; GstTypeFindProbability prob; + /* If we have a content-type from upstream, let's see if we can shortcut + * typefinding */ + if (G_UNLIKELY (icydemux->content_type)) { + if (!g_ascii_strcasecmp (icydemux->content_type, "video/nsv")) { + GST_DEBUG ("We have a NSV stream"); + caps = gst_caps_new_simple ("video/x-nsv", NULL); + } else { + GST_DEBUG ("Upstream Content-Type isn't supported"); + g_free (icydemux->content_type); + icydemux->content_type = NULL; + } + } + if (icydemux->typefind_buf) { icydemux->typefind_buf = gst_buffer_join (icydemux->typefind_buf, buf); } else { icydemux->typefind_buf = buf; } - caps = gst_type_find_helper_for_buffer (GST_OBJECT (icydemux), - icydemux->typefind_buf, &prob); - + /* Only typefind if we haven't already got some caps */ if (caps == NULL) { - if (GST_BUFFER_SIZE (icydemux->typefind_buf) < ICY_TYPE_FIND_MAX_SIZE) { - /* Just break for more data */ - return GST_FLOW_OK; - } + caps = gst_type_find_helper_for_buffer (GST_OBJECT (icydemux), + icydemux->typefind_buf, &prob); - /* We failed typefind */ - GST_ELEMENT_ERROR (icydemux, STREAM, TYPE_NOT_FOUND, (NULL), - ("No caps found for contents within an ICY stream")); - gst_buffer_unref (icydemux->typefind_buf); - icydemux->typefind_buf = NULL; - return GST_FLOW_ERROR; + if (caps == NULL) { + if (GST_BUFFER_SIZE (icydemux->typefind_buf) < ICY_TYPE_FIND_MAX_SIZE) { + /* Just break for more data */ + return GST_FLOW_OK; + } + + /* We failed typefind */ + GST_ELEMENT_ERROR (icydemux, STREAM, TYPE_NOT_FOUND, (NULL), + ("No caps found for contents within an ICY stream")); + gst_buffer_unref (icydemux->typefind_buf); + icydemux->typefind_buf = NULL; + return GST_FLOW_ERROR; + } } if (!gst_icydemux_add_srcpad (icydemux, caps)) { @@ -550,7 +575,7 @@ done: return ret; -/* ERRORS */ + /* ERRORS */ not_negotiated: { GST_WARNING_OBJECT (icydemux, "meta_interval not set, buffer probably had " diff --git a/gst/icydemux/gsticydemux.h b/gst/icydemux/gsticydemux.h index 3e676d12d2..d48339af2c 100644 --- a/gst/icydemux/gsticydemux.h +++ b/gst/icydemux/gsticydemux.h @@ -70,6 +70,9 @@ struct _GstICYDemux GstAdapter *meta_adapter; GstBuffer *typefind_buf; + + /* upstream HTTP Content-Type */ + gchar *content_type; }; struct _GstICYDemuxClass