Initialize Tizen 2.3
[framework/multimedia/gst-plugins-ext0.10.git] / wearable / dashdemux / src / gstplugin.c
1 #ifdef HAVE_CONFIG_H
2 #  include <config.h>
3 #endif
4
5 #include <string.h>
6
7 #include <gst/gst.h>
8
9 #include "gstfragmented.h"
10 #include "gstdashdemux.h"
11
12 GST_DEBUG_CATEGORY (fragmented_debug);
13
14 #define XML_BUFFER_SIZE 16
15 #define XML_INC_BUFFER {                                                \
16   pos++;                                                                \
17   if (pos == XML_BUFFER_SIZE) {                                         \
18     pos = 0;                                                            \
19     offset += XML_BUFFER_SIZE;                                          \
20     data = gst_type_find_peek (tf, offset, XML_BUFFER_SIZE);            \
21     if (data == NULL) return FALSE;                                     \
22   } else {                                                              \
23     data++;                                                             \
24   }                                                                     \
25 }
26
27 static gboolean
28 xml_check_first_element (GstTypeFind * tf, const gchar * element, guint elen,
29     gboolean strict)
30 {
31   gboolean got_xmldec;
32   const guint8 *data;
33   guint offset = 0;
34   guint pos = 0;
35
36   data = gst_type_find_peek (tf, 0, XML_BUFFER_SIZE);
37   if (!data)
38     return FALSE;
39
40   /* look for the XMLDec
41    * see XML spec 2.8, Prolog and Document Type Declaration
42    * http://www.w3.org/TR/2004/REC-xml-20040204/#sec-prolog-dtd */
43   got_xmldec = (memcmp (data, "<?xml", 5) == 0);
44
45   if (strict && !got_xmldec)
46     return FALSE;
47
48   /* skip XMLDec in any case if we've got one */
49   if (got_xmldec) {
50     pos += 5;
51     data += 5;
52   }
53
54   /* look for the first element, it has to be the requested element. Bail
55    * out if it is not within the first 4kB. */
56   while (data && (offset + pos) < 4096) {
57     while (*data != '<' && (offset + pos) < 4096) {
58       XML_INC_BUFFER;
59     }
60
61     XML_INC_BUFFER;
62     if (!g_ascii_isalpha (*data)) {
63       /* if not alphabetic, it's a PI or an element / attribute declaration
64        * like <?xxx or <!xxx */
65       XML_INC_BUFFER;
66       continue;
67     }
68
69     /* the first normal element, check if it's the one asked for */
70     data = gst_type_find_peek (tf, offset + pos, elen + 1);
71     return (data && element && strncmp ((char *) data, element, elen) == 0);
72   }
73
74   return FALSE;
75 }
76
77 /*** application/dash+xml typefind helper ***/
78
79 static GstStaticCaps dash_caps = GST_STATIC_CAPS ("application/dash+xml");
80
81 #define DASH_CAPS gst_static_caps_get (&dash_caps)
82
83 static void
84 dash_type_find (GstTypeFind * tf, gpointer unused)
85 {
86   if (xml_check_first_element (tf, "MPD", 3, FALSE) ||
87       xml_check_first_element (tf, "mpd", 3, FALSE)) {
88     gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, DASH_CAPS);
89   }
90 }
91
92 static gboolean
93 fragmented_init (GstPlugin * plugin)
94 {
95   GST_DEBUG_CATEGORY_INIT (fragmented_debug, "dashdemux", 0, "dashdemux");
96   if (!gst_element_register (plugin, "dashdemux", GST_RANK_PRIMARY,
97           GST_TYPE_DASH_DEMUX) || FALSE)
98     return FALSE;
99   if(!gst_type_find_register (plugin, "application/dash+xml",
100       GST_RANK_SECONDARY, dash_type_find, NULL, DASH_CAPS, NULL, NULL))
101     return FALSE;
102   return TRUE;
103 }
104
105 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
106     GST_VERSION_MINOR,
107     "dashdemux",
108     "DASH demuxer plugin",
109     fragmented_init, VERSION, "LGPL", PACKAGE_NAME, "http://www.gstreamer.org/")