}
static void
+gst_mss_demux_create_streams (GstMssDemux * mssdemux)
+{
+ GSList *streams = gst_mss_manifest_get_streams (mssdemux->manifest);
+ GSList *iter;
+
+ if (streams == NULL) {
+ GST_INFO_OBJECT (mssdemux, "No streams found in the manifest");
+ /* TODO post eos? */
+ }
+
+ for (iter = streams; iter; iter = g_slist_next (iter)) {
+ GstMssManifestStream *manifeststream = iter->data;
+ GstMssManifestStreamType streamtype;
+
+ streamtype = gst_mss_manifest_stream_get_type (manifeststream);
+ GST_DEBUG_OBJECT (mssdemux, "Found stream of type: %s",
+ gst_mss_manifest_stream_type_name (streamtype));
+ }
+}
+
+static void
gst_mss_demux_process_manifest (GstMssDemux * mssdemux)
{
+ GstQuery *query;
+ gchar *uri = NULL;
+ gboolean ret;
+
g_return_if_fail (mssdemux->manifest_buffer != NULL);
g_return_if_fail (mssdemux->manifest == NULL);
+ query = gst_query_new_uri ();
+ ret = gst_pad_peer_query (mssdemux->sinkpad, query);
+ if (ret) {
+ gst_query_parse_uri (query, &uri);
+ /* TODO use this to get the base url for the fragments */
+ g_free (uri);
+ }
+ gst_query_unref (query);
+
mssdemux->manifest = gst_mss_manifest_new (mssdemux->manifest_buffer);
- /* TODO */
+ if (!mssdemux->manifest) {
+ GST_ELEMENT_ERROR (mssdemux, STREAM, FORMAT, ("Bad manifest file"),
+ ("Xml manifest file couldn't be parsed"));
+ return;
+ }
+
+ gst_mss_demux_create_streams (mssdemux);
}
*/
#include <glib.h>
+#include <string.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
#include "gstmssmanifest.h"
+struct _GstMssManifestStream
+{
+ xmlNodePtr xmlnode;
+};
+
struct _GstMssManifest
{
+ xmlDocPtr xml;
+ xmlNodePtr xmlrootnode;
+
+ GSList *streams;
};
GstMssManifest *
-gst_mss_manifest_new (GstBuffer * data)
+gst_mss_manifest_new (const GstBuffer * data)
{
GstMssManifest *manifest;
+ xmlNodePtr root;
+ xmlNodePtr nodeiter;
manifest = g_malloc0 (sizeof (GstMssManifest));
+ manifest->xml = xmlReadMemory ((const gchar *) GST_BUFFER_DATA (data),
+ GST_BUFFER_SIZE (data), "manifest", NULL, 0);
+ root = manifest->xmlrootnode = xmlDocGetRootElement (manifest->xml);
+
+ for (nodeiter = root->children; nodeiter; nodeiter = nodeiter->next) {
+ if (nodeiter->type == XML_ELEMENT_NODE
+ && (strcmp ((const char *) nodeiter->name, "StreamIndex") == 0)) {
+ GstMssManifestStream *stream = g_new0 (GstMssManifestStream, 1);
+
+ manifest->streams = g_slist_append (manifest->streams, stream);
+ stream->xmlnode = nodeiter;
+ }
+ }
+
return manifest;
}
gst_mss_manifest_free (GstMssManifest * manifest)
{
g_return_if_fail (manifest != NULL);
+
+ g_slist_free_full (manifest->streams, g_free);
+
+ xmlFreeDoc (manifest->xml);
g_free (manifest);
}
+
+GSList *
+gst_mss_manifest_get_streams (GstMssManifest * manifest)
+{
+ return manifest->streams;
+}
+
+GstMssManifestStreamType
+gst_mss_manifest_stream_get_type (GstMssManifestStream * stream)
+{
+ gchar *prop = (gchar *) xmlGetProp (stream->xmlnode, (xmlChar *) "Type");
+ GstMssManifestStreamType ret = MSS_STREAM_TYPE_UNKNOWN;
+
+ if (strcmp (prop, "video") == 0) {
+ ret = MSS_STREAM_TYPE_VIDEO;
+ } else if (strcmp (prop, "audio") == 0) {
+ ret = MSS_STREAM_TYPE_AUDIO;
+ }
+ xmlFree (prop);
+ return ret;
+}
+
+const gchar *
+gst_mss_manifest_stream_type_name (GstMssManifestStreamType streamtype)
+{
+ switch (streamtype) {
+ case MSS_STREAM_TYPE_VIDEO:
+ return "video";
+ case MSS_STREAM_TYPE_AUDIO:
+ return "audio";
+ case MSS_STREAM_TYPE_UNKNOWN:
+ default:
+ return "unknown";
+ }
+}
G_BEGIN_DECLS
typedef struct _GstMssManifest GstMssManifest;
+typedef struct _GstMssManifestStream GstMssManifestStream;
-GstMssManifest * gst_mss_manifest_new (GstBuffer * data);
+typedef enum _GstMssManifestStreamType {
+ MSS_STREAM_TYPE_UNKNOWN = 0,
+ MSS_STREAM_TYPE_VIDEO = 1,
+ MSS_STREAM_TYPE_AUDIO = 2
+} GstMssManifestStreamType;
+
+GstMssManifest * gst_mss_manifest_new (const GstBuffer * data);
void gst_mss_manifest_free (GstMssManifest * manifest);
+GSList * gst_mss_manifest_get_streams (GstMssManifest * manifest);
+
+GstMssManifestStreamType gst_mss_manifest_stream_get_type (GstMssManifestStream *stream);
+
+const gchar * gst_mss_manifest_stream_type_name (GstMssManifestStreamType streamtype);
G_END_DECLS
#endif /* __GST_MSS_MANIFEST_H__ */