mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-19 16:21:17 +00:00
d058a7f2b2
This fixes conflicts with the HLS plugin, which is also named fragmented. When building its registry, gstreamer was picking one or the other between hls and dashdemux.
108 lines
3.2 KiB
C
108 lines
3.2 KiB
C
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#include <string.h>
|
|
|
|
#include <gst/gst.h>
|
|
|
|
#include "gstfragmented.h"
|
|
#include "gstdashdemux.h"
|
|
|
|
GST_DEBUG_CATEGORY (fragmented_debug);
|
|
|
|
#define XML_BUFFER_SIZE 16
|
|
#define XML_INC_BUFFER { \
|
|
pos++; \
|
|
if (pos == XML_BUFFER_SIZE) { \
|
|
pos = 0; \
|
|
offset += XML_BUFFER_SIZE; \
|
|
data = gst_type_find_peek (tf, offset, XML_BUFFER_SIZE); \
|
|
if (data == NULL) return FALSE; \
|
|
} else { \
|
|
data++; \
|
|
} \
|
|
}
|
|
|
|
static gboolean
|
|
xml_check_first_element (GstTypeFind * tf, const gchar * element, guint elen,
|
|
gboolean strict)
|
|
{
|
|
gboolean got_xmldec;
|
|
const guint8 *data;
|
|
guint offset = 0;
|
|
guint pos = 0;
|
|
|
|
data = gst_type_find_peek (tf, 0, XML_BUFFER_SIZE);
|
|
if (!data)
|
|
return FALSE;
|
|
|
|
/* look for the XMLDec
|
|
* see XML spec 2.8, Prolog and Document Type Declaration
|
|
* http://www.w3.org/TR/2004/REC-xml-20040204/#sec-prolog-dtd */
|
|
got_xmldec = (memcmp (data, "<?xml", 5) == 0);
|
|
|
|
if (strict && !got_xmldec)
|
|
return FALSE;
|
|
|
|
/* skip XMLDec in any case if we've got one */
|
|
if (got_xmldec) {
|
|
pos += 5;
|
|
data += 5;
|
|
}
|
|
|
|
/* look for the first element, it has to be the requested element. Bail
|
|
* out if it is not within the first 4kB. */
|
|
while (data && (offset + pos) < 4096) {
|
|
while (*data != '<' && (offset + pos) < 4096) {
|
|
XML_INC_BUFFER;
|
|
}
|
|
|
|
XML_INC_BUFFER;
|
|
if (!g_ascii_isalpha (*data)) {
|
|
/* if not alphabetic, it's a PI or an element / attribute declaration
|
|
* like <?xxx or <!xxx */
|
|
XML_INC_BUFFER;
|
|
continue;
|
|
}
|
|
|
|
/* the first normal element, check if it's the one asked for */
|
|
data = gst_type_find_peek (tf, offset + pos, elen + 1);
|
|
return (data && element && strncmp ((char *) data, element, elen) == 0);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*** application/dash+xml typefind helper ***/
|
|
|
|
static GstStaticCaps dash_caps = GST_STATIC_CAPS ("application/dash+xml");
|
|
|
|
#define DASH_CAPS gst_static_caps_get (&dash_caps)
|
|
|
|
static void
|
|
dash_type_find (GstTypeFind * tf, gpointer unused)
|
|
{
|
|
if (xml_check_first_element (tf, "MPD", 3, FALSE) ||
|
|
xml_check_first_element (tf, "mpd", 3, FALSE)) {
|
|
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, DASH_CAPS);
|
|
}
|
|
}
|
|
|
|
static gboolean
|
|
fragmented_init (GstPlugin * plugin)
|
|
{
|
|
GST_DEBUG_CATEGORY_INIT (fragmented_debug, "dashdemux", 0, "dashdemux");
|
|
if (!gst_element_register (plugin, "dashdemux", GST_RANK_PRIMARY,
|
|
GST_TYPE_DASH_DEMUX) || FALSE)
|
|
return FALSE;
|
|
gst_type_find_register (plugin, "application/dash+xml",
|
|
GST_RANK_SECONDARY, dash_type_find, NULL, DASH_CAPS, NULL, NULL);
|
|
return TRUE;
|
|
}
|
|
|
|
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
|
GST_VERSION_MINOR,
|
|
"dashdemux",
|
|
"DASH demuxer plugin",
|
|
fragmented_init, VERSION, "LGPL", PACKAGE_NAME, "http://www.gstreamer.org/")
|