mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 12:10:37 +00:00
mssdemux: add manifest parsing
Continued implementing: 1) parse the manifest with libxml2 2) detect stream types
This commit is contained in:
parent
95e87fbee9
commit
72b05c0051
3 changed files with 122 additions and 3 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Loading…
Reference in a new issue