mssdemux: add manifest parsing

Continued implementing:
1) parse the manifest with libxml2
2) detect stream types
This commit is contained in:
Thiago Santos 2012-11-09 16:47:54 -03:00
parent 95e87fbee9
commit 72b05c0051
3 changed files with 122 additions and 3 deletions

View file

@ -210,12 +210,52 @@ gst_mss_demux_event (GstPad * pad, GstEvent * event)
return ret;
}
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);
}

View file

@ -21,20 +21,48 @@
*/
#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;
}
@ -42,5 +70,44 @@ void
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";
}
}

View file

@ -30,9 +30,21 @@
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__ */