icydemux: Handle upstream Content-Type.
authorEdward Hervey <bilboed@bilboed.com>
Tue, 23 Mar 2010 18:46:43 +0000 (19:46 +0100)
committerEdward Hervey <bilboed@bilboed.com>
Tue, 23 Mar 2010 18:48:24 +0000 (19:48 +0100)
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
gst/icydemux/gsticydemux.h

index 2700359..a2f4ef2 100644 (file)
@@ -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);
+
+      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;
       }
-
-      /* 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 "
index 3e676d1..d48339a 100644 (file)
@@ -70,6 +70,9 @@ struct _GstICYDemux
   GstAdapter *meta_adapter;
 
   GstBuffer *typefind_buf;
+
+  /* upstream HTTP Content-Type */
+  gchar *content_type;
 };
 
 struct _GstICYDemuxClass