mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
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:
parent
9d77bcfb29
commit
66d9dbe49e
2 changed files with 49 additions and 21 deletions
|
@ -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 "
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue