Exemplo n.º 1
0
/* takes ownership of tag list */
static gboolean
gst_icydemux_tag_found (GstICYDemux * icydemux, GstTagList * tags)
{
  /* send the tag event if we have finished typefinding and have a src pad */
  if (icydemux->srcpad)
    return gst_icydemux_send_tag_event (icydemux, tags);

  /* if we haven't a source pad yet, cache the tags */
  if (!icydemux->cached_tags) {
    icydemux->cached_tags = tags;
  } else {
    gst_tag_list_insert (icydemux->cached_tags, tags,
        GST_TAG_MERGE_REPLACE_ALL);
    gst_tag_list_free (tags);
  }

  return TRUE;
}
Exemplo n.º 2
0
static GstFlowReturn
gst_icydemux_typefind_or_forward (GstICYDemux * icydemux, GstBuffer * buf)
{
  if (icydemux->typefinding) {
    GstBuffer *tf_buf;
    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;
    }

    /* Only typefind if we haven't already got some caps */
    if (caps == NULL) {
      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;
      }
    }

    if (!gst_icydemux_add_srcpad (icydemux, caps)) {
      GST_DEBUG_OBJECT (icydemux, "Failed to add srcpad");
      gst_caps_unref (caps);
      gst_buffer_unref (icydemux->typefind_buf);
      icydemux->typefind_buf = NULL;
      return GST_FLOW_ERROR;
    }
    gst_caps_unref (caps);

    if (icydemux->cached_events) {
      gst_icydemux_send_cached_events (icydemux);
    }

    if (icydemux->cached_tags) {
      gst_icydemux_send_tag_event (icydemux, icydemux->cached_tags);
      icydemux->cached_tags = NULL;
    }

    /* Move onto streaming: call ourselves recursively with the typefind buffer
     * to get that forwarded. */
    icydemux->typefinding = FALSE;

    tf_buf = icydemux->typefind_buf;
    icydemux->typefind_buf = NULL;
    return gst_icydemux_typefind_or_forward (icydemux, tf_buf);
  } else {
    if (G_UNLIKELY (icydemux->srcpad == NULL)) {
      gst_buffer_unref (buf);
      return GST_FLOW_ERROR;
    }

    buf = gst_buffer_make_metadata_writable (buf);
    gst_buffer_set_caps (buf, icydemux->src_caps);

    /* Most things don't care, and it's a pain to track (we should preserve a
     * 0 offset on the first buffer though if it's there, for id3demux etc.) */
    if (GST_BUFFER_OFFSET (buf) != 0) {
      GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
    }

    return gst_pad_push (icydemux->srcpad, buf);
  }
}
Exemplo n.º 3
0
static void
gst_icydemux_parse_and_send_tags (GstICYDemux * icydemux)
{
  GstTagList *tags = gst_tag_list_new ();
  const guint8 *data;
  int length, i;
  gchar *buffer;
  gchar **strings;
  gboolean found_tag = FALSE;

  length = gst_adapter_available (icydemux->meta_adapter);

  data = gst_adapter_peek (icydemux->meta_adapter, length);

  /* Now, copy this to a buffer where we can NULL-terminate it to make things
   * a bit easier, then do that parsing. */
  buffer = g_malloc (length + 1);
  memcpy (buffer, data, length);
  buffer[length] = 0;

  strings = g_strsplit (buffer, "';", 0);

  for (i = 0; strings[i]; i++) {
    if (!g_ascii_strncasecmp (strings[i], "StreamTitle=", 12)) {
      char *title = gst_icydemux_unicodify (strings[i] + 13);

      if (title && *title) {
        gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_TITLE,
            title, NULL);
        g_free (title);
        found_tag = TRUE;
      }
    } else if (!g_ascii_strncasecmp (strings[i], "StreamUrl=", 10)) {
      char *url = gst_icydemux_unicodify (strings[i] + 11);

      if (url) {
        /* 
           gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_URL, 
           url, NULL); 
           found_tag = TRUE;
         */
        g_free (url);
      }
    }
  }

  g_strfreev (strings);
  g_free (buffer);
  gst_adapter_clear (icydemux->meta_adapter);

  if (found_tag) {
    if (icydemux->srcpad) {
      gst_icydemux_send_tag_event (icydemux, tags);
    } else {
      if (!icydemux->cached_tags) {
        icydemux->cached_tags = gst_tag_list_new ();
      }

      gst_tag_list_insert (icydemux->cached_tags, tags,
          GST_TAG_MERGE_REPLACE_ALL);
    }
  }
}