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.
This commit is contained in:
Edward Hervey 2010-03-23 19:46:43 +01:00
parent 9d77bcfb29
commit 66d9dbe49e
2 changed files with 49 additions and 21 deletions

View file

@ -180,6 +180,11 @@ gst_icydemux_reset (GstICYDemux * icydemux)
gst_buffer_unref (icydemux->typefind_buf); gst_buffer_unref (icydemux->typefind_buf);
icydemux->typefind_buf = NULL; icydemux->typefind_buf = NULL;
} }
if (icydemux->content_type) {
g_free (icydemux->content_type);
icydemux->content_type = NULL;
}
} }
static void static void
@ -206,16 +211,20 @@ gst_icydemux_sink_setcaps (GstPad * pad, GstCaps * caps)
{ {
GstICYDemux *icydemux = GST_ICYDEMUX (GST_PAD_PARENT (pad)); GstICYDemux *icydemux = GST_ICYDEMUX (GST_PAD_PARENT (pad));
GstStructure *structure = gst_caps_get_structure (caps, 0); GstStructure *structure = gst_caps_get_structure (caps, 0);
const gchar *tmp;
if (!gst_structure_get_int (structure, "metadata-interval", if (!gst_structure_get_int (structure, "metadata-interval",
&icydemux->meta_interval)) &icydemux->meta_interval))
return FALSE; return FALSE;
else {
/* We have a meta interval, so initialise the rest */ /* If incoming caps have the HTTP Content-Type, copy that over */
icydemux->remaining = icydemux->meta_interval; if ((tmp = gst_structure_get_string (structure, "content-type")))
icydemux->meta_remaining = 0; icydemux->content_type = g_strdup (tmp);
return TRUE;
} /* We have a meta interval, so initialise the rest */
icydemux->remaining = icydemux->meta_interval;
icydemux->meta_remaining = 0;
return TRUE;
} }
static void static void
@ -399,30 +408,46 @@ gst_icydemux_typefind_or_forward (GstICYDemux * icydemux, GstBuffer * buf)
{ {
if (icydemux->typefinding) { if (icydemux->typefinding) {
GstBuffer *tf_buf; GstBuffer *tf_buf;
GstCaps *caps; GstCaps *caps = NULL;
GstTypeFindProbability prob; 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) { if (icydemux->typefind_buf) {
icydemux->typefind_buf = gst_buffer_join (icydemux->typefind_buf, buf); icydemux->typefind_buf = gst_buffer_join (icydemux->typefind_buf, buf);
} else { } else {
icydemux->typefind_buf = buf; icydemux->typefind_buf = buf;
} }
caps = gst_type_find_helper_for_buffer (GST_OBJECT (icydemux), /* Only typefind if we haven't already got some caps */
icydemux->typefind_buf, &prob);
if (caps == NULL) { if (caps == NULL) {
if (GST_BUFFER_SIZE (icydemux->typefind_buf) < ICY_TYPE_FIND_MAX_SIZE) { caps = gst_type_find_helper_for_buffer (GST_OBJECT (icydemux),
/* Just break for more data */ icydemux->typefind_buf, &prob);
return GST_FLOW_OK;
}
/* We failed typefind */ if (caps == NULL) {
GST_ELEMENT_ERROR (icydemux, STREAM, TYPE_NOT_FOUND, (NULL), if (GST_BUFFER_SIZE (icydemux->typefind_buf) < ICY_TYPE_FIND_MAX_SIZE) {
("No caps found for contents within an ICY stream")); /* Just break for more data */
gst_buffer_unref (icydemux->typefind_buf); return GST_FLOW_OK;
icydemux->typefind_buf = NULL; }
return GST_FLOW_ERROR;
/* 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)) { if (!gst_icydemux_add_srcpad (icydemux, caps)) {
@ -550,7 +575,7 @@ done:
return ret; return ret;
/* ERRORS */ /* ERRORS */
not_negotiated: not_negotiated:
{ {
GST_WARNING_OBJECT (icydemux, "meta_interval not set, buffer probably had " GST_WARNING_OBJECT (icydemux, "meta_interval not set, buffer probably had "

View file

@ -70,6 +70,9 @@ struct _GstICYDemux
GstAdapter *meta_adapter; GstAdapter *meta_adapter;
GstBuffer *typefind_buf; GstBuffer *typefind_buf;
/* upstream HTTP Content-Type */
gchar *content_type;
}; };
struct _GstICYDemuxClass struct _GstICYDemuxClass