dash: Generate an XML content from object.

Add mpd node base class to provide
xml generation facilities for child
objects.
This commit is contained in:
Stéphane Cerveau 2019-12-04 17:25:24 +01:00 committed by GStreamer Merge Bot
parent 4e6a1b9634
commit ac74b042ec
61 changed files with 2838 additions and 963 deletions

View file

@ -862,12 +862,13 @@ gst_dash_demux_setup_all_streams (GstDashDemux * demux)
stream->target_time = GST_CLOCK_TIME_NONE;
/* Set a default average keyframe download time of a quarter of a second */
stream->average_download_time = 250 * GST_MSECOND;
if (active_stream->cur_adapt_set &&
active_stream->cur_adapt_set->RepresentationBase &&
active_stream->cur_adapt_set->RepresentationBase->ContentProtection) {
GST_MPD_REPRESENTATION_BASE_NODE (active_stream->
cur_adapt_set)->ContentProtection) {
GST_DEBUG_OBJECT (demux, "Adding ContentProtection events to source pad");
g_list_foreach (active_stream->cur_adapt_set->
RepresentationBase->ContentProtection,
g_list_foreach (GST_MPD_REPRESENTATION_BASE_NODE
(active_stream->cur_adapt_set)->ContentProtection,
gst_dash_demux_send_content_protection_event, stream);
}
@ -880,7 +881,7 @@ gst_dash_demux_setup_all_streams (GstDashDemux * demux)
static void
gst_dash_demux_send_content_protection_event (gpointer data, gpointer userdata)
{
GstMPDDescriptorType *cp = (GstMPDDescriptorType *) data;
GstMPDDescriptorTypeNode *cp = (GstMPDDescriptorTypeNode *) data;
GstDashDemuxStream *stream = (GstDashDemuxStream *) userdata;
GstEvent *event;
GstBuffer *pssi;

View file

@ -22,7 +22,7 @@
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDAdaptationSetNode, gst_mpd_adaptation_set_node,
GST_TYPE_OBJECT);
GST_TYPE_MPD_REPRESENTATION_BASE_NODE);
/* GObject VMethods */
@ -39,15 +39,14 @@ gst_mpd_adaptation_set_node_finalize (GObject * object)
g_slice_free (GstXMLConditionalUintType, self->segmentAlignment);
g_slice_free (GstXMLConditionalUintType, self->subsegmentAlignment);
g_list_free_full (self->Accessibility,
(GDestroyNotify) gst_mpd_helper_descriptor_type_free);
(GDestroyNotify) gst_mpd_descriptor_type_node_free);
g_list_free_full (self->Role,
(GDestroyNotify) gst_mpd_helper_descriptor_type_free);
(GDestroyNotify) gst_mpd_descriptor_type_node_free);
g_list_free_full (self->Rating,
(GDestroyNotify) gst_mpd_helper_descriptor_type_free);
(GDestroyNotify) gst_mpd_descriptor_type_node_free);
g_list_free_full (self->Viewpoint,
(GDestroyNotify) gst_mpd_helper_descriptor_type_free);
gst_mpd_helper_representation_base_type_free (self->RepresentationBase);
gst_mpd_helper_segment_base_type_free (self->SegmentBase);
(GDestroyNotify) gst_mpd_descriptor_type_node_free);
gst_mpd_segment_base_node_free (self->SegmentBase);
gst_mpd_segment_list_node_free (self->SegmentList);
gst_mpd_segment_template_node_free (self->SegmentTemplate);
g_list_free_full (self->BaseURLs, (GDestroyNotify) gst_mpd_baseurl_node_free);
@ -61,11 +60,105 @@ gst_mpd_adaptation_set_node_finalize (GObject * object)
G_OBJECT_CLASS (gst_mpd_adaptation_set_node_parent_class)->finalize (object);
}
/* Base class */
static xmlNodePtr
gst_mpd_adaptation_set_get_xml_node (GstMPDNode * node)
{
xmlNodePtr adaptation_set_xml_node = NULL;
GstMPDAdaptationSetNode *self = GST_MPD_ADAPTATION_SET_NODE (node);
adaptation_set_xml_node = xmlNewNode (NULL, (xmlChar *) "AdaptationSet");
if (self->id)
gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "id", self->id);
if (self->group)
gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "group",
self->group);
if (self->lang)
gst_xml_helper_set_prop_string (adaptation_set_xml_node, "lang",
self->lang);
if (self->contentType)
gst_xml_helper_set_prop_string (adaptation_set_xml_node, "contentType",
self->contentType);
if (self->minBandwidth)
gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "minBandwidth",
self->minBandwidth);
if (self->maxBandwidth)
gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "maxBandwidth",
self->maxBandwidth);
if (self->minWidth)
gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "minWidth",
self->minWidth);
if (self->maxWidth)
gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "maxWidth",
self->maxWidth);
if (self->minHeight)
gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "minHeight",
self->minHeight);
if (self->maxHeight)
gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "maxHeight",
self->maxHeight);
if (self->par)
gst_xml_helper_set_prop_ratio (adaptation_set_xml_node, "par", self->par);
gst_xml_helper_set_prop_cond_uint (adaptation_set_xml_node,
"segmentAlignment", self->segmentAlignment);
gst_xml_helper_set_prop_cond_uint (adaptation_set_xml_node,
"subsegmentAlignment", self->subsegmentAlignment);
gst_xml_helper_set_prop_uint (adaptation_set_xml_node,
"subsegmentStartsWithSAP", self->subsegmentStartsWithSAP);
gst_xml_helper_set_prop_boolean (adaptation_set_xml_node,
"bitstreamSwitching", self->bitstreamSwitching);
g_list_foreach (self->Accessibility, gst_mpd_node_get_list_item,
adaptation_set_xml_node);
g_list_foreach (self->Role, gst_mpd_node_get_list_item,
adaptation_set_xml_node);
g_list_foreach (self->Rating, gst_mpd_node_get_list_item,
adaptation_set_xml_node);
g_list_foreach (self->Viewpoint, gst_mpd_node_get_list_item,
adaptation_set_xml_node);
gst_mpd_node_add_child_node (GST_MPD_NODE (self->SegmentBase),
adaptation_set_xml_node);
gst_mpd_mult_segment_base_node_add_child_node (GST_MPD_NODE
(self->SegmentList), adaptation_set_xml_node);
gst_mpd_mult_segment_base_node_add_child_node (GST_MPD_NODE
(self->SegmentTemplate), adaptation_set_xml_node);
g_list_foreach (self->BaseURLs, gst_mpd_node_get_list_item,
adaptation_set_xml_node);
g_list_foreach (self->Representations,
gst_mpd_representation_base_node_get_list_item, adaptation_set_xml_node);
g_list_foreach (self->ContentComponents, gst_mpd_node_get_list_item,
adaptation_set_xml_node);
if (self->xlink_href)
gst_xml_helper_set_prop_string (adaptation_set_xml_node, "xlink_href",
self->xlink_href);
if (self->actuate == GST_MPD_XLINK_ACTUATE_ON_LOAD)
gst_xml_helper_set_prop_string (adaptation_set_xml_node, "actuate",
(gchar *) GST_MPD_XLINK_ACTUATE_ON_LOAD_STR);
return adaptation_set_xml_node;
}
static void
gst_mpd_adaptation_set_node_class_init (GstMPDAdaptationSetNodeClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_adaptation_set_node_finalize;
m_klass->get_xml_node = gst_mpd_adaptation_set_get_xml_node;
}
static void
@ -94,8 +187,6 @@ gst_mpd_adaptation_set_node_init (GstMPDAdaptationSetNode * self)
self->Rating = NULL;
/* list of Viewpoint DescriptorType nodes */
self->Viewpoint = NULL;
/* RepresentationBase extension */
self->RepresentationBase = NULL;
/* SegmentBase node */
self->SegmentBase = NULL;
/* SegmentList node */

View file

@ -23,30 +23,18 @@
#include <gst/gst.h>
#include "gstmpdhelper.h"
#include "gstmpdrepresentationbasenode.h"
#include "gstmpdsegmentlistnode.h"
#include "gstmpdsegmenttemplatenode.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_ADAPTATION_SET_NODE gst_mpd_adaptation_set_node_get_type ()
#define GST_MPD_ADAPTATION_SET_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_ADAPTATION_SET_NODE, GstMPDAdaptationSetNode))
#define GST_MPD_ADAPTATION_SET_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_ADAPTATION_SET_NODE, GstMPDAdaptationSetNodeClass))
#define GST_IS_MPD_ADAPTATION_SET_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_ADAPTATION_SET_NODE))
#define GST_IS_MPD_ADAPTATION_SET_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_ADAPTATION_SET_NODE))
#define GST_MPD_ADAPTATION_SET_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_ADAPTATION_SET_NODE, GstMPDAdaptationSetNodeClass))
typedef struct _GstMPDAdaptationSetNode GstMPDAdaptationSetNode;
typedef struct _GstMPDAdaptationSetNodeClass GstMPDAdaptationSetNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDAdaptationSetNode, gst_mpd_adaptation_set_node, GST, MPD_ADAPTATION_SET_NODE, GstMPDRepresentationBaseNode)
struct _GstMPDAdaptationSetNode
{
GstObject parent_instance;
GstMPDRepresentationBaseNode parent_instance;
guint id;
guint group;
gchar *lang; /* LangVectorType RFC 5646 */
@ -70,10 +58,8 @@ struct _GstMPDAdaptationSetNode
GList *Rating;
/* list of Viewpoint DescriptorType nodes */
GList *Viewpoint;
/* RepresentationBase extension */
GstMPDRepresentationBaseType *RepresentationBase;
/* SegmentBase node */
GstMPDSegmentBaseType *SegmentBase;
GstMPDSegmentBaseNode *SegmentBase;
/* SegmentList node */
GstMPDSegmentListNode *SegmentList;
/* SegmentTemplate node */
@ -89,13 +75,6 @@ struct _GstMPDAdaptationSetNode
GstMPDXLinkActuate actuate;
};
struct _GstMPDAdaptationSetNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_adaptation_set_node_get_type (void);
GstMPDAdaptationSetNode * gst_mpd_adaptation_set_node_new (void);
void gst_mpd_adaptation_set_node_free (GstMPDAdaptationSetNode* self);

View file

@ -21,7 +21,7 @@
#include "gstmpdbaseurlnode.h"
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDBaseURLNode, gst_mpd_baseurl_node, GST_TYPE_OBJECT);
G_DEFINE_TYPE (GstMPDBaseURLNode, gst_mpd_baseurl_node, GST_TYPE_MPD_NODE);
/* GObject VMethods */
@ -37,11 +37,42 @@ gst_mpd_baseurl_node_finalize (GObject * object)
G_OBJECT_CLASS (gst_mpd_baseurl_node_parent_class)->finalize (object);
}
/* Base class */
static xmlNodePtr
gst_mpd_baseurl_get_xml_node (GstMPDNode * node)
{
xmlNodePtr baseurl_xml_node = NULL;
GstMPDBaseURLNode *self = GST_MPD_BASEURL_NODE (node);
baseurl_xml_node = xmlNewNode (NULL, (xmlChar *) "BaseURL");
if (self->serviceLocation)
gst_xml_helper_set_prop_string (baseurl_xml_node, "serviceLocation",
self->serviceLocation);
if (self->byteRange)
gst_xml_helper_set_prop_string (baseurl_xml_node, "byteRange",
self->byteRange);
if (self->baseURL)
gst_xml_helper_set_content (baseurl_xml_node, self->baseURL);
return baseurl_xml_node;
}
static void
gst_mpd_baseurl_node_class_init (GstMPDBaseURLNodeClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_baseurl_node_finalize;
m_klass->get_xml_node = gst_mpd_baseurl_get_xml_node;
}
static void

View file

@ -27,20 +27,7 @@
G_BEGIN_DECLS
#define GST_TYPE_MPD_BASEURL_NODE gst_mpd_baseurl_node_get_type ()
#define GST_MPD_BASEURL_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_BASEURL_NODE, GstMPDBaseURLNode))
#define GST_MPD_BASEURL_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_BASEURL_NODE, GstMPDBaseURLNodeClass))
#define GST_IS_MPD_BASEURL_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_BASEURL_NODE))
#define GST_IS_MPD_BASEURL_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_BASEURL_NODE))
#define GST_MPD_BASEURL_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_BASEURL_NODE, GstMPDBaseURLNodeClass))
typedef struct _GstMPDBaseURLNode GstMPDBaseURLNode;
typedef struct _GstMPDBaseURLNodeClass GstMPDBaseURLNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDBaseURLNode, gst_mpd_baseurl_node, GST, MPD_BASEURL_NODE, GstMPDNode)
struct _GstMPDBaseURLNode
{
@ -51,13 +38,6 @@ struct _GstMPDBaseURLNode
/* TODO add missing fields such as weight etc.*/
};
struct _GstMPDBaseURLNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_baseurl_node_get_type (void);
GstMPDBaseURLNode * gst_mpd_baseurl_node_new (void);
void gst_mpd_baseurl_node_free (GstMPDBaseURLNode* self);

View file

@ -28,7 +28,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_dash_mpd_client_debug);
G_DEFINE_TYPE (GstMPDClient, gst_mpd_client, GST_TYPE_OBJECT);
static GstMPDSegmentBaseType *gst_mpd_client_get_segment_base (GstMPDPeriodNode
static GstMPDSegmentBaseNode *gst_mpd_client_get_segment_base (GstMPDPeriodNode
* Period, GstMPDAdaptationSetNode * AdaptationSet,
GstMPDRepresentationNode * Representation);
static GstMPDSegmentListNode *gst_mpd_client_get_segment_list (GstMPDClient *
@ -202,12 +202,12 @@ gst_mpd_client_fetch_external_segment_list (GstMPDClient * client,
return new_segment_list;
}
static GstMPDSegmentBaseType *
static GstMPDSegmentBaseNode *
gst_mpd_client_get_segment_base (GstMPDPeriodNode * Period,
GstMPDAdaptationSetNode * AdaptationSet,
GstMPDRepresentationNode * Representation)
{
GstMPDSegmentBaseType *SegmentBase = NULL;
GstMPDSegmentBaseNode *SegmentBase = NULL;
if (Representation && Representation->SegmentBase) {
SegmentBase = Representation->SegmentBase;
@ -219,17 +219,24 @@ gst_mpd_client_get_segment_base (GstMPDPeriodNode * Period,
/* the SegmentBase element could be encoded also inside a SegmentList element */
if (SegmentBase == NULL) {
if (Representation && Representation->SegmentList
&& Representation->SegmentList->MultSegBaseType
&& Representation->SegmentList->MultSegBaseType->SegBaseType) {
SegmentBase = Representation->SegmentList->MultSegBaseType->SegBaseType;
&& GST_MPD_MULT_SEGMENT_BASE_NODE (Representation->SegmentList)
&& GST_MPD_MULT_SEGMENT_BASE_NODE (Representation->
SegmentList)->SegmentBase) {
SegmentBase =
GST_MPD_MULT_SEGMENT_BASE_NODE (Representation->
SegmentList)->SegmentBase;
} else if (AdaptationSet && AdaptationSet->SegmentList
&& AdaptationSet->SegmentList->MultSegBaseType
&& AdaptationSet->SegmentList->MultSegBaseType->SegBaseType) {
SegmentBase = AdaptationSet->SegmentList->MultSegBaseType->SegBaseType;
&& GST_MPD_MULT_SEGMENT_BASE_NODE (AdaptationSet->SegmentList)
&& GST_MPD_MULT_SEGMENT_BASE_NODE (AdaptationSet->
SegmentList)->SegmentBase) {
SegmentBase =
GST_MPD_MULT_SEGMENT_BASE_NODE (AdaptationSet->
SegmentList)->SegmentBase;
} else if (Period && Period->SegmentList
&& Period->SegmentList->MultSegBaseType
&& Period->SegmentList->MultSegBaseType->SegBaseType) {
SegmentBase = Period->SegmentList->MultSegBaseType->SegBaseType;
&& GST_MPD_MULT_SEGMENT_BASE_NODE (Period->SegmentList)
&& GST_MPD_MULT_SEGMENT_BASE_NODE (Period->SegmentList)->SegmentBase) {
SegmentBase =
GST_MPD_MULT_SEGMENT_BASE_NODE (Period->SegmentList)->SegmentBase;
}
}
@ -281,7 +288,7 @@ gst_mpd_client_get_segment_duration (GstMPDClient * client,
GstActiveStream * stream, guint64 * scale_dur)
{
GstStreamPeriod *stream_period;
GstMPDMultSegmentBaseType *base = NULL;
GstMPDMultSegmentBaseNode *base = NULL;
GstClockTime duration = 0;
g_return_val_if_fail (stream != NULL, GST_CLOCK_TIME_NONE);
@ -289,12 +296,12 @@ gst_mpd_client_get_segment_duration (GstMPDClient * client,
g_return_val_if_fail (stream_period != NULL, GST_CLOCK_TIME_NONE);
if (stream->cur_segment_list) {
base = stream->cur_segment_list->MultSegBaseType;
base = GST_MPD_MULT_SEGMENT_BASE_NODE (stream->cur_segment_list);
} else if (stream->cur_seg_template) {
base = stream->cur_seg_template->MultSegBaseType;
base = GST_MPD_MULT_SEGMENT_BASE_NODE (stream->cur_seg_template);
}
if (base == NULL || base->SegBaseType == NULL) {
if (base == NULL || base->SegmentBase == NULL) {
/* this may happen when we have a single segment */
duration = stream_period->duration;
if (scale_dur)
@ -304,7 +311,7 @@ gst_mpd_client_get_segment_duration (GstMPDClient * client,
duration = base->duration * GST_SECOND;
if (scale_dur)
*scale_dur = duration;
duration /= base->SegBaseType->timescale;
duration /= base->SegmentBase->timescale;
}
return duration;
@ -391,6 +398,22 @@ gst_mpd_client_parse (GstMPDClient * client, const gchar * data, gint size)
return ret;
}
gboolean
gst_mpd_client_get_xml_content (GstMPDClient * client, gchar ** data,
gint * size)
{
gboolean ret = FALSE;
g_return_val_if_fail (client != NULL, ret);
g_return_val_if_fail (client->mpd_root_node != NULL, ret);
ret = gst_mpd_node_get_xml_buffer (GST_MPD_NODE (client->mpd_root_node),
data, (int *) size);
return ret;
}
GstDateTime *
gst_mpd_client_get_availability_start_time (GstMPDClient * client)
{
@ -695,13 +718,15 @@ static void
gst_mpd_client_stream_update_presentation_time_offset (GstMPDClient * client,
GstActiveStream * stream)
{
GstMPDSegmentBaseType *segbase = NULL;
GstMPDSegmentBaseNode *segbase = NULL;
/* Find the used segbase */
if (stream->cur_segment_list) {
segbase = stream->cur_segment_list->MultSegBaseType->SegBaseType;
segbase =
GST_MPD_MULT_SEGMENT_BASE_NODE (stream->cur_segment_list)->SegmentBase;
} else if (stream->cur_seg_template) {
segbase = stream->cur_seg_template->MultSegBaseType->SegBaseType;
segbase =
GST_MPD_MULT_SEGMENT_BASE_NODE (stream->cur_seg_template)->SegmentBase;
} else if (stream->cur_segment_base) {
segbase = stream->cur_segment_base;
}
@ -792,26 +817,32 @@ gst_mpd_client_setup_representation (GstMPDClient * client,
}
/* build segment list */
i = stream->cur_segment_list->MultSegBaseType->startNumber;
i = GST_MPD_MULT_SEGMENT_BASE_NODE (stream->
cur_segment_list)->startNumber;
start = 0;
start_time = PeriodStart;
GST_LOG ("Building media segment list using a SegmentList node");
if (stream->cur_segment_list->MultSegBaseType->SegmentTimeline) {
if (GST_MPD_MULT_SEGMENT_BASE_NODE (stream->
cur_segment_list)->SegmentTimeline) {
GstMPDSegmentTimelineNode *timeline;
GstMPDSNode *S;
GList *list;
GstClockTime presentationTimeOffset;
GstMPDSegmentBaseType *segbase;
GstMPDSegmentBaseNode *segbase;
segbase = stream->cur_segment_list->MultSegBaseType->SegBaseType;
segbase =
GST_MPD_MULT_SEGMENT_BASE_NODE (stream->
cur_segment_list)->SegmentBase;
presentationTimeOffset =
gst_util_uint64_scale (segbase->presentationTimeOffset, GST_SECOND,
segbase->timescale);
GST_LOG ("presentationTimeOffset = %" G_GUINT64_FORMAT,
presentationTimeOffset);
timeline = stream->cur_segment_list->MultSegBaseType->SegmentTimeline;
timeline =
GST_MPD_MULT_SEGMENT_BASE_NODE (stream->
cur_segment_list)->SegmentTimeline;
for (list = g_queue_peek_head_link (&timeline->S); list;
list = g_list_next (list)) {
guint timescale;
@ -820,7 +851,8 @@ gst_mpd_client_setup_representation (GstMPDClient * client,
GST_LOG ("Processing S node: d=%" G_GUINT64_FORMAT " r=%d t=%"
G_GUINT64_FORMAT, S->d, S->r, S->t);
timescale =
stream->cur_segment_list->MultSegBaseType->SegBaseType->timescale;
GST_MPD_MULT_SEGMENT_BASE_NODE (stream->
cur_segment_list)->SegmentBase->timescale;
duration = gst_util_uint64_scale (S->d, GST_SECOND, timescale);
if (S->t > 0) {
@ -873,8 +905,7 @@ gst_mpd_client_setup_representation (GstMPDClient * client,
stream->cur_seg_template = stream_period->period->SegmentTemplate;
}
if (stream->cur_seg_template == NULL
|| stream->cur_seg_template->MultSegBaseType == NULL) {
if (stream->cur_seg_template == NULL) {
gst_mpdparser_init_active_stream_segments (stream);
/* here we should have a single segment for each representation, whose URL is encoded in the baseURL element */
@ -884,11 +915,11 @@ gst_mpd_client_setup_representation (GstMPDClient * client,
}
} else {
GstClockTime presentationTimeOffset;
GstMPDMultSegmentBaseType *mult_seg =
stream->cur_seg_template->MultSegBaseType;
GstMPDMultSegmentBaseNode *mult_seg =
GST_MPD_MULT_SEGMENT_BASE_NODE (stream->cur_seg_template);
presentationTimeOffset =
gst_util_uint64_scale (mult_seg->SegBaseType->presentationTimeOffset,
GST_SECOND, mult_seg->SegBaseType->timescale);
gst_util_uint64_scale (mult_seg->SegmentBase->presentationTimeOffset,
GST_SECOND, mult_seg->SegmentBase->timescale);
GST_LOG ("presentationTimeOffset = %" GST_TIME_FORMAT,
GST_TIME_ARGS (presentationTimeOffset));
/* build segment list */
@ -913,7 +944,7 @@ gst_mpd_client_setup_representation (GstMPDClient * client,
S = (GstMPDSNode *) list->data;
GST_LOG ("Processing S node: d=%" G_GUINT64_FORMAT " r=%u t=%"
G_GUINT64_FORMAT, S->d, S->r, S->t);
timescale = mult_seg->SegBaseType->timescale;
timescale = mult_seg->SegmentBase->timescale;
duration = gst_util_uint64_scale (S->d, GST_SECOND, timescale);
if (S->t > 0) {
start = S->t;
@ -1625,8 +1656,8 @@ gst_mpd_client_stream_seek (GstMPDClient * client, GstActiveStream * stream,
guint segments_count = gst_mpd_client_get_segments_counts (client, stream);
GstClockTime index_time;
g_return_val_if_fail (stream->cur_seg_template->MultSegBaseType->
SegmentTimeline == NULL, FALSE);
g_return_val_if_fail (GST_MPD_MULT_SEGMENT_BASE_NODE
(stream->cur_seg_template)->SegmentTimeline == NULL, FALSE);
if (!GST_CLOCK_TIME_IS_VALID (duration)) {
return FALSE;
}
@ -1775,8 +1806,8 @@ gst_mpd_client_get_next_fragment_timestamp (GstMPDClient * client,
gst_mpd_client_get_segment_duration (client, stream, NULL);
guint segments_count = gst_mpd_client_get_segments_counts (client, stream);
g_return_val_if_fail (stream->cur_seg_template->MultSegBaseType->
SegmentTimeline == NULL, FALSE);
g_return_val_if_fail (GST_MPD_MULT_SEGMENT_BASE_NODE
(stream->cur_seg_template)->SegmentTimeline == NULL, FALSE);
if (!GST_CLOCK_TIME_IS_VALID (duration) || (segments_count > 0
&& stream->segment_index >= segments_count)) {
return FALSE;
@ -1878,8 +1909,8 @@ gst_mpd_client_get_next_fragment (GstMPDClient * client,
stream, NULL);
guint segments_count = gst_mpd_client_get_segments_counts (client, stream);
g_return_val_if_fail (stream->cur_seg_template->MultSegBaseType->
SegmentTimeline == NULL, FALSE);
g_return_val_if_fail (GST_MPD_MULT_SEGMENT_BASE_NODE
(stream->cur_seg_template)->SegmentTimeline == NULL, FALSE);
if (!GST_CLOCK_TIME_IS_VALID (duration) || (segments_count > 0
&& stream->segment_index >= segments_count)) {
return FALSE;
@ -1949,7 +1980,8 @@ gst_mpd_client_get_next_fragment (GstMPDClient * client,
gst_mpdparser_build_URL_from_template (stream->cur_seg_template->
media, stream->cur_representation->id,
stream->segment_index +
stream->cur_seg_template->MultSegBaseType->startNumber,
GST_MPD_MULT_SEGMENT_BASE_NODE (stream->
cur_seg_template)->startNumber,
stream->cur_representation->bandwidth,
stream->segment_index * fragment->duration);
if (stream->cur_seg_template->index) {
@ -1957,7 +1989,8 @@ gst_mpd_client_get_next_fragment (GstMPDClient * client,
gst_mpdparser_build_URL_from_template (stream->cur_seg_template->
index, stream->cur_representation->id,
stream->segment_index +
stream->cur_seg_template->MultSegBaseType->startNumber,
GST_MPD_MULT_SEGMENT_BASE_NODE (stream->
cur_seg_template)->startNumber,
stream->cur_representation->bandwidth,
stream->segment_index * fragment->duration);
}
@ -2255,8 +2288,8 @@ gst_mpd_client_get_next_fragment_duration (GstMPDClient * client,
gst_mpd_client_get_segment_duration (client, stream, NULL);
guint segments_count = gst_mpd_client_get_segments_counts (client, stream);
g_return_val_if_fail (stream->cur_seg_template->
MultSegBaseType->SegmentTimeline == NULL, 0);
g_return_val_if_fail (GST_MPD_MULT_SEGMENT_BASE_NODE
(stream->cur_seg_template)->SegmentTimeline == NULL, 0);
if (!GST_CLOCK_TIME_IS_VALID (duration) || (segments_count > 0
&& seg_idx >= segments_count)) {
@ -2440,9 +2473,10 @@ gst_mpd_client_get_rep_idx_with_max_bandwidth (GList * Representations,
if (!representation)
continue;
framerate = representation->RepresentationBase->frameRate;
framerate = GST_MPD_REPRESENTATION_BASE_NODE (representation)->frameRate;
if (!framerate)
framerate = representation->RepresentationBase->maxFrameRate;
framerate =
GST_MPD_REPRESENTATION_BASE_NODE (representation)->maxFrameRate;
if (framerate && max_video_framerate_n > 0) {
if (gst_util_fraction_compare (framerate->num, framerate->den,
@ -2451,10 +2485,12 @@ gst_mpd_client_get_rep_idx_with_max_bandwidth (GList * Representations,
}
if (max_video_width > 0
&& representation->RepresentationBase->width > max_video_width)
&& GST_MPD_REPRESENTATION_BASE_NODE (representation)->width >
max_video_width)
continue;
if (max_video_height > 0
&& representation->RepresentationBase->height > max_video_height)
&& GST_MPD_REPRESENTATION_BASE_NODE (representation)->height >
max_video_height)
continue;
if (representation->bandwidth <= max_bandwidth &&
@ -2495,8 +2531,8 @@ gst_mpd_client_get_segments_counts (GstMPDClient * client,
if (stream->segments)
return stream->segments->len;
g_return_val_if_fail (stream->cur_seg_template->
MultSegBaseType->SegmentTimeline == NULL, 0);
g_return_val_if_fail (GST_MPD_MULT_SEGMENT_BASE_NODE
(stream->cur_seg_template)->SegmentTimeline == NULL, 0);
stream_period = gst_mpd_client_get_stream_period (client);
if (stream_period->duration != -1)
@ -2552,16 +2588,20 @@ gst_mpd_client_active_stream_contains_subtitles (GstActiveStream * stream)
const gchar *adapt_set_codecs;
const gchar *rep_codecs;
mimeType = stream->cur_representation->RepresentationBase->mimeType;
mimeType =
GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_representation)->mimeType;
if (!mimeType)
mimeType = stream->cur_adapt_set->RepresentationBase->mimeType;
mimeType =
GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_adapt_set)->mimeType;
if (g_strcmp0 (mimeType, "application/ttml+xml") == 0 ||
g_strcmp0 (mimeType, "text/vtt") == 0)
return TRUE;
adapt_set_codecs = stream->cur_adapt_set->RepresentationBase->codecs;
rep_codecs = stream->cur_representation->RepresentationBase->codecs;
adapt_set_codecs =
GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_adapt_set)->codecs;
rep_codecs =
GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_representation)->codecs;
return (adapt_set_codecs && g_str_has_prefix (adapt_set_codecs, "stpp"))
|| (rep_codecs && g_str_has_prefix (rep_codecs, "stpp"));
@ -2577,9 +2617,11 @@ gst_mpd_client_get_stream_caps (GstActiveStream * stream)
|| stream->cur_representation == NULL)
return NULL;
mimeType = stream->cur_representation->RepresentationBase->mimeType;
mimeType =
GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_representation)->mimeType;
if (mimeType == NULL) {
mimeType = stream->cur_adapt_set->RepresentationBase->mimeType;
mimeType =
GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_adapt_set)->mimeType;
}
caps_string = gst_mpd_helper_mimetype_to_caps (mimeType);
@ -2612,9 +2654,9 @@ gst_mpd_client_get_video_stream_width (GstActiveStream * stream)
|| stream->cur_representation == NULL)
return 0;
width = stream->cur_representation->RepresentationBase->width;
width = GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_representation)->width;
if (width == 0) {
width = stream->cur_adapt_set->RepresentationBase->width;
width = GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_adapt_set)->width;
}
return width;
@ -2629,9 +2671,10 @@ gst_mpd_client_get_video_stream_height (GstActiveStream * stream)
|| stream->cur_representation == NULL)
return 0;
height = stream->cur_representation->RepresentationBase->height;
height =
GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_representation)->height;
if (height == 0) {
height = stream->cur_adapt_set->RepresentationBase->height;
height = GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_adapt_set)->height;
}
return height;
@ -2645,32 +2688,50 @@ gst_mpd_client_get_video_stream_framerate (GstActiveStream * stream,
return FALSE;
if (stream->cur_adapt_set &&
stream->cur_adapt_set->RepresentationBase->frameRate != NULL) {
*fps_num = stream->cur_adapt_set->RepresentationBase->frameRate->num;
*fps_den = stream->cur_adapt_set->RepresentationBase->frameRate->den;
GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_adapt_set)->frameRate !=
NULL) {
*fps_num =
GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_adapt_set)->
frameRate->num;
*fps_den =
GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_adapt_set)->
frameRate->den;
return TRUE;
}
if (stream->cur_adapt_set &&
stream->cur_adapt_set->RepresentationBase->maxFrameRate != NULL) {
*fps_num = stream->cur_adapt_set->RepresentationBase->maxFrameRate->num;
*fps_den = stream->cur_adapt_set->RepresentationBase->maxFrameRate->den;
return TRUE;
}
if (stream->cur_representation &&
stream->cur_representation->RepresentationBase->frameRate != NULL) {
*fps_num = stream->cur_representation->RepresentationBase->frameRate->num;
*fps_den = stream->cur_representation->RepresentationBase->frameRate->den;
return TRUE;
}
if (stream->cur_representation &&
stream->cur_representation->RepresentationBase->maxFrameRate != NULL) {
GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_adapt_set)->maxFrameRate !=
NULL) {
*fps_num =
stream->cur_representation->RepresentationBase->maxFrameRate->num;
GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_adapt_set)->
maxFrameRate->num;
*fps_den =
stream->cur_representation->RepresentationBase->maxFrameRate->den;
GST_MPD_REPRESENTATION_BASE_NODE (stream->cur_adapt_set)->
maxFrameRate->den;
return TRUE;
}
if (stream->cur_representation &&
GST_MPD_REPRESENTATION_BASE_NODE (stream->
cur_representation)->frameRate != NULL) {
*fps_num =
GST_MPD_REPRESENTATION_BASE_NODE (stream->
cur_representation)->frameRate->num;
*fps_den =
GST_MPD_REPRESENTATION_BASE_NODE (stream->
cur_representation)->frameRate->den;
return TRUE;
}
if (stream->cur_representation &&
GST_MPD_REPRESENTATION_BASE_NODE (stream->
cur_representation)->maxFrameRate != NULL) {
*fps_num =
GST_MPD_REPRESENTATION_BASE_NODE (stream->
cur_representation)->maxFrameRate->num;
*fps_den =
GST_MPD_REPRESENTATION_BASE_NODE (stream->
cur_representation)->maxFrameRate->den;
return TRUE;
}
@ -2686,9 +2747,13 @@ gst_mpd_client_get_audio_stream_rate (GstActiveStream * stream)
|| stream->cur_representation == NULL)
return 0;
rate = stream->cur_representation->RepresentationBase->audioSamplingRate;
rate =
GST_MPD_REPRESENTATION_BASE_NODE (stream->
cur_representation)->audioSamplingRate;
if (rate == NULL) {
rate = stream->cur_adapt_set->RepresentationBase->audioSamplingRate;
rate =
GST_MPD_REPRESENTATION_BASE_NODE (stream->
cur_adapt_set)->audioSamplingRate;
}
return rate ? atoi (rate) : 0;
@ -2729,10 +2794,10 @@ gst_mpd_client_get_list_and_nb_of_audio_language (GstMPDClient * client,
rep =
gst_mpd_client_get_lowest_representation (adapt_set->Representations);
mimeType = NULL;
if (rep->RepresentationBase)
mimeType = rep->RepresentationBase->mimeType;
if (!mimeType && adapt_set->RepresentationBase) {
mimeType = adapt_set->RepresentationBase->mimeType;
if (GST_MPD_REPRESENTATION_BASE_NODE (rep))
mimeType = GST_MPD_REPRESENTATION_BASE_NODE (rep)->mimeType;
if (!mimeType && GST_MPD_REPRESENTATION_BASE_NODE (adapt_set)) {
mimeType = GST_MPD_REPRESENTATION_BASE_NODE (adapt_set)->mimeType;
}
if (gst_mpd_helper_strncmp_ext (mimeType, this_mimeType) == 0) {

View file

@ -57,6 +57,9 @@ void gst_mpd_client_free (GstMPDClient * client);
/* main mpd parsing methods from xml data */
gboolean gst_mpd_client_parse (GstMPDClient * client, const gchar * data, gint size);
/* xml generator */
gboolean gst_mpd_client_get_xml_content (GstMPDClient * client, gchar ** data, gint * size);
void gst_mpd_client_set_uri_downloader (GstMPDClient * client, GstUriDownloader * download);
void gst_mpd_client_check_profiles (GstMPDClient * client);
void gst_mpd_client_fetch_on_load_external_resources (GstMPDClient * client);

View file

@ -21,9 +21,8 @@
#include "gstmpdcontentcomponentnode.h"
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDContentComponentNode, gst_mpd_content_component_node,
GST_TYPE_OBJECT);
GST_TYPE_MPD_NODE);
/* GObject VMethods */
@ -38,24 +37,60 @@ gst_mpd_content_component_node_finalize (GObject * object)
xmlFree (self->contentType);
g_slice_free (GstXMLRatio, self->par);
g_list_free_full (self->Accessibility,
(GDestroyNotify) gst_mpd_helper_descriptor_type_free);
(GDestroyNotify) gst_mpd_descriptor_type_node_free);
g_list_free_full (self->Role,
(GDestroyNotify) gst_mpd_helper_descriptor_type_free);
(GDestroyNotify) gst_mpd_descriptor_type_node_free);
g_list_free_full (self->Rating,
(GDestroyNotify) gst_mpd_helper_descriptor_type_free);
(GDestroyNotify) gst_mpd_descriptor_type_node_free);
g_list_free_full (self->Viewpoint,
(GDestroyNotify) gst_mpd_helper_descriptor_type_free);
(GDestroyNotify) gst_mpd_descriptor_type_node_free);
G_OBJECT_CLASS (gst_mpd_content_component_node_parent_class)->finalize
(object);
}
/* Base class */
static xmlNodePtr
gst_mpd_content_component_get_xml_node (GstMPDNode * node)
{
xmlNodePtr content_component_xml_node = NULL;
GstMPDContentComponentNode *self = GST_MPD_CONTENT_COMPONENT_NODE (node);
content_component_xml_node =
xmlNewNode (NULL, (xmlChar *) "ContentComponent");
gst_xml_helper_set_prop_uint (content_component_xml_node, "id", self->id);
gst_xml_helper_set_prop_string (content_component_xml_node, "lang",
self->lang);
gst_xml_helper_set_prop_string (content_component_xml_node, "contentType",
self->contentType);
gst_xml_helper_set_prop_ratio (content_component_xml_node, "par", self->par);
g_list_foreach (self->Accessibility, gst_mpd_node_get_list_item,
content_component_xml_node);
g_list_foreach (self->Role, gst_mpd_node_get_list_item,
content_component_xml_node);
g_list_foreach (self->Rating, gst_mpd_node_get_list_item,
content_component_xml_node);
g_list_foreach (self->Viewpoint, gst_mpd_node_get_list_item,
content_component_xml_node);
return content_component_xml_node;
}
static void
gst_mpd_content_component_node_class_init (GstMPDContentComponentNodeClass *
klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_content_component_node_finalize;
m_klass->get_xml_node = gst_mpd_content_component_get_xml_node;
}
static void

View file

@ -27,20 +27,7 @@
G_BEGIN_DECLS
#define GST_TYPE_MPD_CONTENT_COMPONENT_NODE gst_mpd_content_component_node_get_type ()
#define GST_MPD_CONTENT_COMPONENT_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_CONTENT_COMPONENT_NODE, GstMPDContentComponentNode))
#define GST_MPD_CONTENT_COMPONENT_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_CONTENT_COMPONENT_NODE, GstMPDContentComponentNodeClass))
#define GST_IS_MPD_CONTENT_COMPONENT_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_CONTENT_COMPONENT_NODE))
#define GST_IS_MPD_CONTENT_COMPONENT_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_CONTENT_COMPONENT_NODE))
#define GST_MPD_CONTENT_COMPONENT_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_CONTENT_COMPONENT_NODE, GstMPDContentComponentNodeClass))
typedef struct _GstMPDContentComponentNode GstMPDContentComponentNode;
typedef struct _GstMPDContentComponentNodeClass GstMPDContentComponentNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDContentComponentNode, gst_mpd_content_component_node, GST, MPD_CONTENT_COMPONENT_NODE, GstMPDNode)
struct _GstMPDContentComponentNode
{
@ -59,13 +46,6 @@ struct _GstMPDContentComponentNode
GList *Viewpoint;
};
struct _GstMPDContentComponentNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_content_component_node_get_type (void);
GstMPDContentComponentNode * gst_mpd_content_component_node_new (void);
void gst_mpd_content_component_node_free (GstMPDContentComponentNode* self);

View file

@ -0,0 +1,99 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "gstmpddescriptortypenode.h"
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDDescriptorTypeNode, gst_mpd_descriptor_type_node,
GST_TYPE_MPD_NODE);
/* GObject VMethods */
static void
gst_mpd_descriptor_type_node_finalize (GObject * object)
{
GstMPDDescriptorTypeNode *self = GST_MPD_DESCRIPTOR_TYPE_NODE (object);
if (self->schemeIdUri)
xmlFree (self->schemeIdUri);
if (self->value)
xmlFree (self->value);
g_free (self->node_name);
G_OBJECT_CLASS (gst_mpd_descriptor_type_node_parent_class)->finalize (object);
}
/* Base class */
static xmlNodePtr
gst_mpd_descriptor_type_get_xml_node (GstMPDNode * node)
{
xmlNodePtr descriptor_type_xml_node = NULL;
GstMPDDescriptorTypeNode *self = GST_MPD_DESCRIPTOR_TYPE_NODE (node);
descriptor_type_xml_node = xmlNewNode (NULL, (xmlChar *) self->node_name);
gst_xml_helper_set_prop_string (descriptor_type_xml_node, "schemeIdUri",
self->schemeIdUri);
gst_xml_helper_set_prop_string (descriptor_type_xml_node, "value",
self->value);
return descriptor_type_xml_node;
}
static void
gst_mpd_descriptor_type_node_class_init (GstMPDDescriptorTypeNodeClass * klass)
{
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_descriptor_type_node_finalize;
m_klass->get_xml_node = gst_mpd_descriptor_type_get_xml_node;
}
static void
gst_mpd_descriptor_type_node_init (GstMPDDescriptorTypeNode * self)
{
if (self->schemeIdUri)
xmlFree (self->schemeIdUri);
if (self->value)
xmlFree (self->value);
}
GstMPDDescriptorTypeNode *
gst_mpd_descriptor_type_node_new (const gchar * name)
{
GstMPDDescriptorTypeNode *self =
g_object_new (GST_TYPE_MPD_DESCRIPTOR_TYPE_NODE, NULL);
self->node_name = g_strdup (name);
return self;
}
void
gst_mpd_descriptor_type_node_free (GstMPDDescriptorTypeNode * self)
{
if (self)
gst_object_unref (self);
}

View file

@ -0,0 +1,46 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library (COPYING); if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GSTMPDDESCRIPTORTYPENODE_H__
#define __GSTMPDDESCRIPTORTYPENODE_H__
#include <gst/gst.h>
#include "gstmpdhelper.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_DESCRIPTOR_TYPE_NODE gst_mpd_descriptor_type_node_get_type ()
G_DECLARE_FINAL_TYPE (GstMPDDescriptorTypeNode, gst_mpd_descriptor_type_node, GST, MPD_DESCRIPTOR_TYPE_NODE, GstMPDNode)
struct _GstMPDDescriptorTypeNode
{
GstObject parent_instance;
gchar *node_name;
gchar *schemeIdUri;
gchar *value;
};
GstMPDDescriptorTypeNode * gst_mpd_descriptor_type_node_new (const gchar* name);
void gst_mpd_descriptor_type_node_free (GstMPDDescriptorTypeNode* self);
G_END_DECLS
#endif /* __GSTMPDDESCRIPTORTYPENODE_H__ */

View file

@ -78,102 +78,6 @@ gst_mpd_helper_get_SAP_type (xmlNode * a_node,
return exists;
}
GstMPDURLType *
gst_mpd_helper_URLType_clone (GstMPDURLType * url)
{
GstMPDURLType *clone = NULL;
if (url) {
clone = g_slice_new0 (GstMPDURLType);
if (url->sourceURL) {
clone->sourceURL = xmlMemStrdup (url->sourceURL);
}
clone->range = gst_xml_helper_clone_range (url->range);
}
return clone;
}
void
gst_mpd_helper_url_type_node_free (GstMPDURLType * url_type_node)
{
if (url_type_node) {
if (url_type_node->sourceURL)
xmlFree (url_type_node->sourceURL);
g_slice_free (GstXMLRange, url_type_node->range);
g_slice_free (GstMPDURLType, url_type_node);
}
}
void
gst_mpd_helper_descriptor_type_free (GstMPDDescriptorType * descriptor_type)
{
if (descriptor_type) {
if (descriptor_type->schemeIdUri)
xmlFree (descriptor_type->schemeIdUri);
if (descriptor_type->value)
xmlFree (descriptor_type->value);
g_slice_free (GstMPDDescriptorType, descriptor_type);
}
}
void
gst_mpd_helper_segment_base_type_free (GstMPDSegmentBaseType * seg_base_type)
{
if (seg_base_type) {
if (seg_base_type->indexRange)
g_slice_free (GstXMLRange, seg_base_type->indexRange);
gst_mpd_helper_url_type_node_free (seg_base_type->Initialization);
gst_mpd_helper_url_type_node_free (seg_base_type->RepresentationIndex);
g_slice_free (GstMPDSegmentBaseType, seg_base_type);
}
}
void
gst_mpd_helper_mult_seg_base_type_free (GstMPDMultSegmentBaseType *
mult_seg_base_type)
{
if (mult_seg_base_type) {
/* SegmentBaseType extension */
gst_mpd_helper_segment_base_type_free (mult_seg_base_type->SegBaseType);
gst_mpd_segment_timeline_node_free (mult_seg_base_type->SegmentTimeline);
gst_mpd_helper_url_type_node_free (mult_seg_base_type->BitstreamSwitching);
g_slice_free (GstMPDMultSegmentBaseType, mult_seg_base_type);
}
}
void
gst_mpd_helper_representation_base_type_free (GstMPDRepresentationBaseType *
representation_base)
{
if (representation_base) {
if (representation_base->profiles)
xmlFree (representation_base->profiles);
g_slice_free (GstXMLRatio, representation_base->sar);
g_slice_free (GstXMLFrameRate, representation_base->frameRate);
g_slice_free (GstXMLFrameRate, representation_base->minFrameRate);
g_slice_free (GstXMLFrameRate, representation_base->maxFrameRate);
if (representation_base->audioSamplingRate)
xmlFree (representation_base->audioSamplingRate);
if (representation_base->mimeType)
xmlFree (representation_base->mimeType);
if (representation_base->segmentProfiles)
xmlFree (representation_base->segmentProfiles);
if (representation_base->codecs)
xmlFree (representation_base->codecs);
if (representation_base->scanType)
xmlFree (representation_base->scanType);
g_list_free_full (representation_base->FramePacking,
(GDestroyNotify) gst_mpd_helper_descriptor_type_free);
g_list_free_full (representation_base->AudioChannelConfiguration,
(GDestroyNotify) gst_mpd_helper_descriptor_type_free);
g_list_free_full (representation_base->ContentProtection,
(GDestroyNotify) gst_mpd_helper_descriptor_type_free);
g_slice_free (GstMPDRepresentationBaseType, representation_base);
}
}
const gchar *
gst_mpd_helper_mimetype_to_caps (const gchar * mimeType)
{

View file

@ -22,16 +22,15 @@
#define __GST_MPDHELPER_H__
#include "gstxmlhelper.h"
#include "gstmpdnode.h"
#include "gstmpdurltypenode.h"
#include "gstmpddescriptortypenode.h"
#include "gstmpdsegmenttimelinenode.h"
#include "gstmpdsegmentbasenode.h"
G_BEGIN_DECLS
typedef enum
{
GST_MPD_FILE_TYPE_STATIC,
GST_MPD_FILE_TYPE_DYNAMIC
} GstMPDFileType;
typedef enum
{
GST_SAP_TYPE_0 = 0,
@ -43,88 +42,24 @@ typedef enum
GST_SAP_TYPE_6
} GstMPDSAPType;
typedef enum
{
GST_MPD_FILE_TYPE_STATIC = 0,
GST_MPD_FILE_TYPE_DYNAMIC
} GstMPDFileType;
#define GST_MPD_XLINK_ACTUATE_ON_LOAD_STR "onLoad"
typedef enum
{
GST_MPD_XLINK_ACTUATE_ON_REQUEST,
GST_MPD_XLINK_ACTUATE_ON_LOAD
} GstMPDXLinkActuate;
typedef struct _GstMPDURLType
{
gchar *sourceURL;
GstXMLRange *range;
} GstMPDURLType;
typedef struct _GstMPDDescriptorType
{
gchar *schemeIdUri;
gchar *value;
} GstMPDDescriptorType;
typedef struct _GstMPDSegmentBaseType
{
guint timescale;
guint64 presentationTimeOffset;
GstXMLRange *indexRange;
gboolean indexRangeExact;
/* Initialization node */
GstMPDURLType *Initialization;
/* RepresentationIndex node */
GstMPDURLType *RepresentationIndex;
} GstMPDSegmentBaseType;
typedef struct _GstMPDMultSegmentBaseType
{
guint duration; /* in seconds */
guint startNumber;
/* SegmentBaseType extension */
GstMPDSegmentBaseType *SegBaseType;
/* SegmentTimeline node */
GstMPDSegmentTimelineNode *SegmentTimeline;
/* BitstreamSwitching node */
GstMPDURLType *BitstreamSwitching;
} GstMPDMultSegmentBaseType;
typedef struct _GstMPDRepresentationBaseType
{
gchar *profiles;
guint width;
guint height;
GstXMLRatio *sar;
GstXMLFrameRate *minFrameRate;
GstXMLFrameRate *maxFrameRate;
GstXMLFrameRate *frameRate;
gchar *audioSamplingRate;
gchar *mimeType;
gchar *segmentProfiles;
gchar *codecs;
gdouble maximumSAPPeriod;
GstMPDSAPType startWithSAP;
gdouble maxPlayoutRate;
gboolean codingDependency;
gchar *scanType;
/* list of FramePacking DescriptorType nodes */
GList *FramePacking;
/* list of AudioChannelConfiguration DescriptorType nodes */
GList *AudioChannelConfiguration;
/* list of ContentProtection DescriptorType nodes */
GList *ContentProtection;
} GstMPDRepresentationBaseType;
gboolean gst_mpd_helper_get_mpd_type (xmlNode * a_node, const gchar * property_name, GstMPDFileType * property_value);
gboolean gst_mpd_helper_get_SAP_type (xmlNode * a_node, const gchar * property_name, GstMPDSAPType * property_value);
GstMPDURLType *gst_mpd_helper_URLType_clone (GstMPDURLType * url);
void gst_mpd_helper_url_type_node_free (GstMPDURLType * url_type_node);
void gst_mpd_helper_descriptor_type_free (GstMPDDescriptorType *
descriptor_type);
void gst_mpd_helper_segment_base_type_free (GstMPDSegmentBaseType * seg_base_type);
void gst_mpd_helper_mult_seg_base_type_free (GstMPDMultSegmentBaseType *
mult_seg_base_type);
void
gst_mpd_helper_representation_base_type_free (GstMPDRepresentationBaseType *
representation_base);
const gchar * gst_mpd_helper_mimetype_to_caps (const gchar * mimeType);
GstUri *gst_mpd_helper_combine_urls (GstUri * base, GList * list, gchar ** query, guint idx);
int gst_mpd_helper_strncmp_ext (const char *s1, const char *s2);

View file

@ -0,0 +1,84 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "gstmpdlocationnode.h"
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDLocationNode, gst_mpd_location_node, GST_TYPE_MPD_NODE);
/* GObject VMethods */
static void
gst_mpd_location_node_finalize (GObject * object)
{
GstMPDLocationNode *self = GST_MPD_LOCATION_NODE (object);
g_free (self->location);
G_OBJECT_CLASS (gst_mpd_location_node_parent_class)->finalize (object);
}
/* Base class */
static xmlNodePtr
gst_mpd_location_get_xml_node (GstMPDNode * node)
{
xmlNodePtr location_xml_node = NULL;
GstMPDLocationNode *self = GST_MPD_LOCATION_NODE (node);
location_xml_node = xmlNewNode (NULL, (xmlChar *) "Location");
if (self->location)
gst_xml_helper_set_content (location_xml_node, self->location);
return location_xml_node;
}
static void
gst_mpd_location_node_class_init (GstMPDLocationNodeClass * klass)
{
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gst_mpd_location_node_finalize;
m_klass = GST_MPD_NODE_CLASS (klass);
m_klass->get_xml_node = gst_mpd_location_get_xml_node;
}
static void
gst_mpd_location_node_init (GstMPDLocationNode * self)
{
self->location = NULL;
}
GstMPDLocationNode *
gst_mpd_location_node_new (void)
{
return g_object_new (GST_TYPE_MPD_LOCATION_NODE, NULL);
}
void
gst_mpd_location_node_free (GstMPDLocationNode * self)
{
if (self)
gst_object_unref (self);
}

View file

@ -0,0 +1,44 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library (COPYING); if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GSTMPDLOCATIONNODE_H__
#define __GSTMPDLOCATIONNODE_H__
#include <gst/gst.h>
#include "gstmpdhelper.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_LOCATION_NODE gst_mpd_location_node_get_type ()
G_DECLARE_FINAL_TYPE (GstMPDLocationNode, gst_mpd_location_node, GST, MPD_LOCATION_NODE, GstMPDNode)
struct _GstMPDLocationNode
{
GstObject parent_instance;
gchar *location;
};
GstMPDLocationNode * gst_mpd_location_node_new (void);
void gst_mpd_location_node_free (GstMPDLocationNode* self);
G_END_DECLS
#endif /* __GSTMPDLOCATIONNODE_H__ */

View file

@ -21,7 +21,7 @@
#include "gstmpdmetricsnode.h"
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDMetricsNode, gst_mpd_metrics_node, GST_TYPE_OBJECT);
G_DEFINE_TYPE (GstMPDMetricsNode, gst_mpd_metrics_node, GST_TYPE_MPD_NODE);
/* GObject VMethods */
@ -37,11 +37,39 @@ gst_mpd_metrics_node_finalize (GObject * object)
G_OBJECT_CLASS (gst_mpd_metrics_node_parent_class)->finalize (object);
}
/* Base class */
static xmlNodePtr
gst_mpd_metrics_get_xml_node (GstMPDNode * node)
{
xmlNodePtr metrics_xml_node = NULL;
GstMPDMetricsNode *self = GST_MPD_METRICS_NODE (node);
metrics_xml_node = xmlNewNode (NULL, (xmlChar *) "Metrics");
if (self->metrics)
gst_xml_helper_set_prop_string (metrics_xml_node, "metrics", self->metrics);
g_list_foreach (self->Reportings, gst_mpd_node_get_list_item,
metrics_xml_node);
g_list_foreach (self->MetricsRanges, gst_mpd_node_get_list_item,
metrics_xml_node);
return metrics_xml_node;
}
static void
gst_mpd_metrics_node_class_init (GstMPDMetricsNodeClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_metrics_node_finalize;
m_klass->get_xml_node = gst_mpd_metrics_get_xml_node;
}
static void

View file

@ -1,11 +1,7 @@
/*
* No description.
/* GStreamer
*
* gstmpdmetricsnode.h
*
* Copyright (C) 2019 Collabora inc.
* Authors:
* Stéphane Cerveau <scerveau@collabora.com>
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -31,19 +27,7 @@
G_BEGIN_DECLS
#define GST_TYPE_MPD_METRICS_NODE gst_mpd_metrics_node_get_type ()
#define GST_MPD_METRICS_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_METRICS_NODE, GstMPDMetricsNode))
#define GST_MPD_METRICS_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_METRICS_NODE, GstMPDMetricsNodeClass))
#define GST_IS_MPD_METRICS_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_METRICS_NODE))
#define GST_IS_MPD_METRICS_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_METRICS_NODE))
#define GST_MPD_METRICS_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_METRICS_NODE, GstMPDMetricsNodeClass))
typedef struct _GstMPDMetricsNode GstMPDMetricsNode;
typedef struct _GstMPDMetricsNodeClass GstMPDMetricsNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDMetricsNode, gst_mpd_metrics_node, GST, MPD_METRICS_NODE, GstMPDNode)
struct _GstMPDMetricsNode
@ -56,13 +40,6 @@ struct _GstMPDMetricsNode
GList *Reportings;
};
struct _GstMPDMetricsNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_metrics_node_get_type (void);
GstMPDMetricsNode * gst_mpd_metrics_node_new (void);
void gst_mpd_metrics_node_free (GstMPDMetricsNode* self);

View file

@ -22,13 +22,36 @@
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDMetricsRangeNode, gst_mpd_metrics_range_node,
GST_TYPE_OBJECT);
GST_TYPE_MPD_NODE);
/* GObject VMethods */
/* Base class */
static xmlNodePtr
gst_mpd_metrics_range_get_xml_node (GstMPDNode * node)
{
xmlNodePtr metrics_range_xml_node = NULL;
GstMPDMetricsRangeNode *self = GST_MPD_METRICS_RANGE_NODE (node);
metrics_range_xml_node = xmlNewNode (NULL, (xmlChar *) "Range");
if (self->starttime)
gst_xml_helper_set_prop_duration (metrics_range_xml_node, "starttime",
self->starttime);
if (self->duration)
gst_xml_helper_set_prop_duration (metrics_range_xml_node, "duration",
self->duration);
return metrics_range_xml_node;
}
static void
gst_mpd_metrics_range_node_class_init (GstMPDMetricsRangeNodeClass * klass)
{
GstMPDNodeClass *m_klass;
m_klass = GST_MPD_NODE_CLASS (klass);
m_klass->get_xml_node = gst_mpd_metrics_range_get_xml_node;
}
static void

View file

@ -27,20 +27,7 @@
G_BEGIN_DECLS
#define GST_TYPE_MPD_METRICS_RANGE_NODE gst_mpd_metrics_range_node_get_type ()
#define GST_MPD_METRICS_RANGE_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_METRICS_RANGE_NODE, GstMPDMetricsRangeNode))
#define GST_MPD_METRICS_RANGE_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_METRICS_RANGE_NODE, GstMPDMetricsRangeNodeClass))
#define GST_IS_MPD_METRICS_RANGE_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_METRICS_RANGE_NODE))
#define GST_IS_MPD_METRICS_RANGE_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_METRICS_RANGE_NODE))
#define GST_MPD_METRICS_RANGE_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_METRICS_RANGE_NODE, GstMPDMetricsRangeNodeClass))
typedef struct _GstMPDMetricsRangeNode GstMPDMetricsRangeNode;
typedef struct _GstMPDMetricsRangeNodeClass GstMPDMetricsRangeNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDMetricsRangeNode, gst_mpd_metrics_range_node, GST, MPD_METRICS_RANGE_NODE, GstMPDNode)
struct _GstMPDMetricsRangeNode
{
@ -49,13 +36,6 @@ struct _GstMPDMetricsRangeNode
guint64 duration; /* [ms] */
};
struct _GstMPDMetricsRangeNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_metrics_range_node_get_type (void);
GstMPDMetricsRangeNode * gst_mpd_metrics_range_node_new (void);
void gst_mpd_metrics_range_node_free (GstMPDMetricsRangeNode* self);

View file

@ -0,0 +1,97 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "gstmpdmultsegmentbasenode.h"
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDMultSegmentBaseNode, gst_mpd_mult_segment_base_node,
GST_TYPE_MPD_NODE);
/* GObject VMethods */
static void
gst_mpd_mult_segment_base_node_finalize (GObject * object)
{
GstMPDMultSegmentBaseNode *self = GST_MPD_MULT_SEGMENT_BASE_NODE (object);
gst_mpd_segment_base_node_free (self->SegmentBase);
gst_mpd_segment_timeline_node_free (self->SegmentTimeline);
gst_mpd_url_type_node_free (self->BitstreamSwitching);
G_OBJECT_CLASS (gst_mpd_mult_segment_base_node_parent_class)->finalize
(object);
}
/* Base class */
static void
gst_mpd_mult_segment_base_get_xml_node (GstMPDNode * node,
xmlNodePtr mult_segment_base_node)
{
GstMPDMultSegmentBaseNode *self = GST_MPD_MULT_SEGMENT_BASE_NODE (node);
if (self->duration)
gst_xml_helper_set_prop_uint (mult_segment_base_node, "duration",
self->duration);
if (self->startNumber)
gst_xml_helper_set_prop_uint (mult_segment_base_node, "startNumber",
self->startNumber);
if (self->SegmentBase)
gst_mpd_node_add_child_node (GST_MPD_NODE (self->SegmentBase),
mult_segment_base_node);
if (self->SegmentTimeline)
gst_mpd_node_add_child_node (GST_MPD_NODE (self->SegmentTimeline),
mult_segment_base_node);
if (self->BitstreamSwitching)
gst_mpd_node_add_child_node (GST_MPD_NODE (self->BitstreamSwitching),
mult_segment_base_node);
}
static void
gst_mpd_mult_segment_base_node_class_init (GstMPDMultSegmentBaseNodeClass *
klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gst_mpd_mult_segment_base_node_finalize;
}
static void
gst_mpd_mult_segment_base_node_init (GstMPDMultSegmentBaseNode * self)
{
self->duration = 0;
self->startNumber = 0;
self->SegmentBase = NULL;
self->SegmentTimeline = NULL;
self->BitstreamSwitching = NULL;
}
void
gst_mpd_mult_segment_base_node_add_child_node (GstMPDNode * node,
xmlNodePtr parent_xml_node)
{
if (node) {
xmlNodePtr new_xml_node = gst_mpd_node_get_xml_pointer (node);
gst_mpd_mult_segment_base_get_xml_node (node, new_xml_node);
xmlAddChild (parent_xml_node, new_xml_node);
}
}

View file

@ -0,0 +1,48 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library (COPYING); if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GSTMPDMULTSEGMENTBASENODE_H__
#define __GSTMPDMULTSEGMENTBASENODE_H__
#include <gst/gst.h>
#include "gstmpdhelper.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_MULT_SEGMENT_BASE_NODE gst_mpd_mult_segment_base_node_get_type ()
G_DECLARE_FINAL_TYPE (GstMPDMultSegmentBaseNode, gst_mpd_mult_segment_base_node, GST, MPD_MULT_SEGMENT_BASE_NODE, GstMPDNode)
struct _GstMPDMultSegmentBaseNode
{
GstObject base;
guint duration; /* in seconds */
guint startNumber;
/* SegmentBaseType extension */
GstMPDSegmentBaseNode *SegmentBase;
/* SegmentTimeline node */
GstMPDSegmentTimelineNode *SegmentTimeline;
/* BitstreamSwitching node */
GstMPDURLTypeNode *BitstreamSwitching;
};
void gst_mpd_mult_segment_base_node_add_child_node (GstMPDNode* node, xmlNodePtr parent_xml_node);
G_END_DECLS
#endif /* __GSTMPDMULTSEGMENTBASENODE_H__ */

78
ext/dash/gstmpdnode.c Normal file
View file

@ -0,0 +1,78 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "gstmpdnode.h"
G_DEFINE_TYPE (GstMPDNode, gst_mpd_node, GST_TYPE_OBJECT);
/* GObject VMethods */
static void
gst_mpd_node_class_init (GstMPDNodeClass * klass)
{
}
static void
gst_mpd_node_init (GstMPDNode * self)
{
}
void
gst_mpd_node_get_list_item (gpointer data, gpointer user_data)
{
GstMPDNode *node = (GstMPDNode *) data;
xmlNodePtr parent_xml_node = (xmlNodePtr) user_data;
xmlNodePtr new_xml_node = gst_mpd_node_get_xml_pointer (node);
xmlAddChild (parent_xml_node, new_xml_node);
}
void
gst_mpd_node_add_child_node (GstMPDNode * child, xmlNodePtr parent)
{
xmlNodePtr new_xml_node = gst_mpd_node_get_xml_pointer (child);
xmlAddChild (parent, new_xml_node);
}
gboolean
gst_mpd_node_get_xml_buffer (GstMPDNode * node, gchar ** xml_content,
int *xml_size)
{
GstMPDNodeClass *klass;
klass = GST_MPD_NODE_GET_CLASS (node);
if (klass->get_xml_buffer)
return klass->get_xml_buffer (node, xml_content, xml_size);
else
return FALSE;
}
xmlNodePtr
gst_mpd_node_get_xml_pointer (GstMPDNode * node)
{
GstMPDNodeClass *klass;
if (!node)
return NULL;
klass = GST_MPD_NODE_GET_CLASS (node);
if (klass->get_xml_node)
return klass->get_xml_node (node);
else
return NULL;
}

48
ext/dash/gstmpdnode.h Normal file
View file

@ -0,0 +1,48 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library (COPYING); if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GSTMPDNODE_H__
#define __GSTMPDNODE_H__
#include <gst/gst.h>
#include "gstxmlhelper.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_NODE gst_mpd_node_get_type ()
G_DECLARE_DERIVABLE_TYPE (GstMPDNode, gst_mpd_node,GST, MPD_NODE, GstObject)
typedef gboolean (*GstMPDGetXMLBuffer) (GstMPDNode * n, gchar ** doc_content, int *doc_size);
typedef xmlNodePtr (*GstMPDGetXMLNode) (GstMPDNode * n);
struct _GstMPDNodeClass {
GstObjectClass base;
GstMPDGetXMLBuffer get_xml_buffer;
GstMPDGetXMLNode get_xml_node;
};
gboolean gst_mpd_node_get_xml_buffer (GstMPDNode * node, gchar ** xml_content, int * xml_size);
xmlNodePtr gst_mpd_node_get_xml_pointer (GstMPDNode * node);
void gst_mpd_node_get_list_item (gpointer data, gpointer user_data);
void gst_mpd_node_add_child_node (GstMPDNode* data, xmlNodePtr user_data);
G_END_DECLS
#endif /* __GSTMPDNODE_H__ */

View file

@ -43,20 +43,20 @@ static void gst_mpdparser_parse_subrepresentation_node (GList ** list,
xmlNode * a_node);
static void gst_mpdparser_parse_segment_url_node (GList ** list,
xmlNode * a_node);
static void gst_mpdparser_parse_url_type_node (GstMPDURLType ** pointer,
static void gst_mpdparser_parse_url_type_node (GstMPDURLTypeNode ** pointer,
xmlNode * a_node);
static void gst_mpdparser_parse_seg_base_type_ext (GstMPDSegmentBaseType **
pointer, xmlNode * a_node, GstMPDSegmentBaseType * parent);
static void gst_mpdparser_parse_seg_base_type_ext (GstMPDSegmentBaseNode **
pointer, xmlNode * a_node, GstMPDSegmentBaseNode * parent);
static void gst_mpdparser_parse_s_node (GQueue * queue, xmlNode * a_node);
static void gst_mpdparser_parse_segment_timeline_node (GstMPDSegmentTimelineNode
** pointer, xmlNode * a_node);
static gboolean
gst_mpdparser_parse_mult_seg_base_type_ext (GstMPDMultSegmentBaseType **
pointer, xmlNode * a_node, GstMPDMultSegmentBaseType * parent);
gst_mpdparser_parse_mult_seg_base_node (GstMPDMultSegmentBaseNode *
pointer, xmlNode * a_node, GstMPDMultSegmentBaseNode * parent);
static gboolean gst_mpdparser_parse_segment_list_node (GstMPDSegmentListNode **
pointer, xmlNode * a_node, GstMPDSegmentListNode * parent);
static void
gst_mpdparser_parse_representation_base_type (GstMPDRepresentationBaseType **
gst_mpdparser_parse_representation_base (GstMPDRepresentationBaseNode *
pointer, xmlNode * a_node);
static gboolean gst_mpdparser_parse_representation_node (GList ** list,
xmlNode * a_node, GstMPDAdaptationSetNode * parent,
@ -79,41 +79,6 @@ static gboolean gst_mpdparser_parse_root_node (GstMPDRootNode ** pointer,
static void gst_mpdparser_parse_utctiming_node (GList ** list,
xmlNode * a_node);
/* Memory management */
struct GstMpdParserUtcTimingMethod
{
const gchar *name;
GstMPDUTCTimingType method;
};
static const struct GstMpdParserUtcTimingMethod
gst_mpdparser_utc_timing_methods[] = {
{"urn:mpeg:dash:utc:ntp:2014", GST_MPD_UTCTIMING_TYPE_NTP},
{"urn:mpeg:dash:utc:sntp:2014", GST_MPD_UTCTIMING_TYPE_SNTP},
{"urn:mpeg:dash:utc:http-head:2014", GST_MPD_UTCTIMING_TYPE_HTTP_HEAD},
{"urn:mpeg:dash:utc:http-xsdate:2014", GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE},
{"urn:mpeg:dash:utc:http-iso:2014", GST_MPD_UTCTIMING_TYPE_HTTP_ISO},
{"urn:mpeg:dash:utc:http-ntp:2014", GST_MPD_UTCTIMING_TYPE_HTTP_NTP},
{"urn:mpeg:dash:utc:direct:2014", GST_MPD_UTCTIMING_TYPE_DIRECT},
/*
* Early working drafts used the :2012 namespace and this namespace is
* used by some DASH packagers. To work-around these packagers, we also
* accept the early draft scheme names.
*/
{"urn:mpeg:dash:utc:ntp:2012", GST_MPD_UTCTIMING_TYPE_NTP},
{"urn:mpeg:dash:utc:sntp:2012", GST_MPD_UTCTIMING_TYPE_SNTP},
{"urn:mpeg:dash:utc:http-head:2012", GST_MPD_UTCTIMING_TYPE_HTTP_HEAD},
{"urn:mpeg:dash:utc:http-xsdate:2012", GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE},
{"urn:mpeg:dash:utc:http-iso:2012", GST_MPD_UTCTIMING_TYPE_HTTP_ISO},
{"urn:mpeg:dash:utc:http-ntp:2012", GST_MPD_UTCTIMING_TYPE_HTTP_NTP},
{"urn:mpeg:dash:utc:direct:2012", GST_MPD_UTCTIMING_TYPE_DIRECT},
{NULL, 0}
};
/*
Duration Data Type
@ -156,9 +121,10 @@ gst_mpdparser_parse_baseURL_node (GList ** list, xmlNode * a_node)
static void
gst_mpdparser_parse_descriptor_type (GList ** list, xmlNode * a_node)
{
GstMPDDescriptorType *new_descriptor;
GstMPDDescriptorTypeNode *new_descriptor;
new_descriptor = g_slice_new0 (GstMPDDescriptorType);
new_descriptor =
gst_mpd_descriptor_type_node_new ((const gchar *) a_node->name);
*list = g_list_append (*list, new_descriptor);
GST_LOG ("attributes of %s node:", a_node->name);
@ -211,10 +177,14 @@ static void
gst_mpdparser_parse_location_node (GList ** list, xmlNode * a_node)
{
gchar *location = NULL;
GstMPDLocationNode *locationNode;
GST_LOG ("content of Location node:");
if (gst_xml_helper_get_node_content (a_node, &location))
*list = g_list_append (*list, location);
if (gst_xml_helper_get_node_content (a_node, &location)) {
locationNode = gst_mpd_location_node_new ();
locationNode->location = location;
*list = g_list_append (*list, locationNode);
}
}
static void
@ -229,15 +199,15 @@ gst_mpdparser_parse_subrepresentation_node (GList ** list, xmlNode * a_node)
gst_xml_helper_get_prop_unsigned_integer (a_node, "level", 0,
&new_subrep->level);
gst_xml_helper_get_prop_uint_vector_type (a_node, "dependencyLevel",
&new_subrep->dependencyLevel, &new_subrep->size);
&new_subrep->dependencyLevel, &new_subrep->dependencyLevel_size);
gst_xml_helper_get_prop_unsigned_integer (a_node, "bandwidth", 0,
&new_subrep->bandwidth);
gst_xml_helper_get_prop_string_vector_type (a_node,
"contentComponent", &new_subrep->contentComponent);
/* RepresentationBase extension */
gst_mpdparser_parse_representation_base_type (&new_subrep->RepresentationBase,
a_node);
gst_mpdparser_parse_representation_base (GST_MPD_REPRESENTATION_BASE_NODE
(new_subrep), a_node);
}
@ -260,12 +230,14 @@ gst_mpdparser_parse_segment_url_node (GList ** list, xmlNode * a_node)
}
static void
gst_mpdparser_parse_url_type_node (GstMPDURLType ** pointer, xmlNode * a_node)
gst_mpdparser_parse_url_type_node (GstMPDURLTypeNode ** pointer,
xmlNode * a_node)
{
GstMPDURLType *new_url_type;
GstMPDURLTypeNode *new_url_type;
gst_mpd_helper_url_type_node_free (*pointer);
*pointer = new_url_type = g_slice_new0 (GstMPDURLType);
gst_mpd_url_type_node_free (*pointer);
*pointer = new_url_type =
gst_mpd_url_type_node_new ((const gchar *) a_node->name);
GST_LOG ("attributes of URLType node:");
gst_xml_helper_get_prop_string (a_node, "sourceURL",
@ -274,18 +246,18 @@ gst_mpdparser_parse_url_type_node (GstMPDURLType ** pointer, xmlNode * a_node)
}
static void
gst_mpdparser_parse_seg_base_type_ext (GstMPDSegmentBaseType ** pointer,
xmlNode * a_node, GstMPDSegmentBaseType * parent)
gst_mpdparser_parse_seg_base_type_ext (GstMPDSegmentBaseNode ** pointer,
xmlNode * a_node, GstMPDSegmentBaseNode * parent)
{
xmlNode *cur_node;
GstMPDSegmentBaseType *seg_base_type;
GstMPDSegmentBaseNode *seg_base_type;
guint intval;
guint64 int64val;
gboolean boolval;
GstXMLRange *rangeval;
gst_mpd_helper_segment_base_type_free (*pointer);
*pointer = seg_base_type = g_slice_new0 (GstMPDSegmentBaseType);
gst_mpd_segment_base_node_free (*pointer);
*pointer = seg_base_type = gst_mpd_segment_base_node_new ();
/* Initialize values that have defaults */
seg_base_type->indexRangeExact = FALSE;
@ -298,9 +270,9 @@ gst_mpdparser_parse_seg_base_type_ext (GstMPDSegmentBaseType ** pointer,
seg_base_type->indexRange = gst_xml_helper_clone_range (parent->indexRange);
seg_base_type->indexRangeExact = parent->indexRangeExact;
seg_base_type->Initialization =
gst_mpd_helper_URLType_clone (parent->Initialization);
gst_mpd_url_type_node_clone (parent->Initialization);
seg_base_type->RepresentationIndex =
gst_mpd_helper_URLType_clone (parent->RepresentationIndex);
gst_mpd_url_type_node_clone (parent->RepresentationIndex);
}
/* We must retrieve each value first to see if it exists. If it does not
@ -386,47 +358,43 @@ gst_mpdparser_parse_segment_timeline_node (GstMPDSegmentTimelineNode ** pointer,
}
static gboolean
gst_mpdparser_parse_mult_seg_base_type_ext (GstMPDMultSegmentBaseType **
pointer, xmlNode * a_node, GstMPDMultSegmentBaseType * parent)
gst_mpdparser_parse_mult_seg_base_node (GstMPDMultSegmentBaseNode *
mult_seg_base_node, xmlNode * a_node, GstMPDMultSegmentBaseNode * parent)
{
xmlNode *cur_node;
GstMPDMultSegmentBaseType *mult_seg_base_type;
guint intval;
gboolean has_timeline = FALSE, has_duration = FALSE;
gst_mpd_helper_mult_seg_base_type_free (*pointer);
mult_seg_base_type = g_slice_new0 (GstMPDMultSegmentBaseType);
mult_seg_base_type->duration = 0;
mult_seg_base_type->startNumber = 1;
mult_seg_base_node->duration = 0;
mult_seg_base_node->startNumber = 1;
/* Inherit attribute values from parent */
if (parent) {
mult_seg_base_type->duration = parent->duration;
mult_seg_base_type->startNumber = parent->startNumber;
mult_seg_base_type->SegmentTimeline =
mult_seg_base_node->duration = parent->duration;
mult_seg_base_node->startNumber = parent->startNumber;
mult_seg_base_node->SegmentTimeline =
gst_mpd_segment_timeline_node_clone (parent->SegmentTimeline);
mult_seg_base_type->BitstreamSwitching =
gst_mpd_helper_URLType_clone (parent->BitstreamSwitching);
mult_seg_base_node->BitstreamSwitching =
gst_mpd_url_type_node_clone (parent->BitstreamSwitching);
}
GST_LOG ("attributes of MultipleSegmentBaseType extension:");
if (gst_xml_helper_get_prop_unsigned_integer (a_node, "duration", 0, &intval)) {
mult_seg_base_type->duration = intval;
mult_seg_base_node->duration = intval;
}
/* duration might be specified from parent */
if (mult_seg_base_type->duration)
if (mult_seg_base_node->duration)
has_duration = TRUE;
if (gst_xml_helper_get_prop_unsigned_integer (a_node, "startNumber", 1,
&intval)) {
mult_seg_base_type->startNumber = intval;
mult_seg_base_node->startNumber = intval;
}
GST_LOG ("extension of MultipleSegmentBaseType extension:");
gst_mpdparser_parse_seg_base_type_ext (&mult_seg_base_type->SegBaseType,
a_node, (parent ? parent->SegBaseType : NULL));
gst_mpdparser_parse_seg_base_type_ext (&mult_seg_base_node->SegmentBase,
a_node, (parent ? parent->SegmentBase : NULL));
/* explore children nodes */
for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
@ -434,31 +402,25 @@ gst_mpdparser_parse_mult_seg_base_type_ext (GstMPDMultSegmentBaseType **
if (xmlStrcmp (cur_node->name, (xmlChar *) "SegmentTimeline") == 0) {
/* parse frees the segmenttimeline if any */
gst_mpdparser_parse_segment_timeline_node
(&mult_seg_base_type->SegmentTimeline, cur_node);
(&mult_seg_base_node->SegmentTimeline, cur_node);
} else if (xmlStrcmp (cur_node->name,
(xmlChar *) "BitstreamSwitching") == 0) {
/* parse frees the old url before setting the new one */
gst_mpdparser_parse_url_type_node
(&mult_seg_base_type->BitstreamSwitching, cur_node);
(&mult_seg_base_node->BitstreamSwitching, cur_node);
}
}
}
has_timeline = mult_seg_base_type->SegmentTimeline != NULL;
has_timeline = mult_seg_base_node->SegmentTimeline != NULL;
/* Checking duration and timeline only at Representation's child level */
if (xmlStrcmp (a_node->parent->name, (xmlChar *) "Representation") == 0
&& !has_duration && !has_timeline) {
GST_ERROR ("segment has neither duration nor timeline");
goto error;
}
*pointer = mult_seg_base_type;
return TRUE;
error:
gst_mpd_helper_mult_seg_base_type_free (mult_seg_base_type);
return FALSE;
}
static gboolean
@ -492,15 +454,15 @@ gst_mpdparser_parse_segment_list_node (GstMPDSegmentListNode ** pointer,
"http://www.w3.org/1999/xlink", "href", &new_segment_list->xlink_href)
&& gst_xml_helper_get_ns_prop_string (a_node,
"http://www.w3.org/1999/xlink", "actuate", &actuate)) {
if (strcmp (actuate, "onLoad") == 0)
if (strcmp (actuate, GST_MPD_XLINK_ACTUATE_ON_LOAD_STR) == 0)
new_segment_list->actuate = GST_MPD_XLINK_ACTUATE_ON_LOAD;
xmlFree (actuate);
}
GST_LOG ("extension of SegmentList node:");
if (!gst_mpdparser_parse_mult_seg_base_type_ext
(&new_segment_list->MultSegBaseType, a_node,
(parent ? parent->MultSegBaseType : NULL)))
if (!gst_mpdparser_parse_mult_seg_base_node
(GST_MPD_MULT_SEGMENT_BASE_NODE (new_segment_list), a_node,
(parent ? GST_MPD_MULT_SEGMENT_BASE_NODE (parent) : NULL)))
goto error;
/* explore children nodes */
@ -548,8 +510,9 @@ gst_mpdparser_parse_content_protection_node (GList ** list, xmlNode * a_node)
for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
if (cur_node->type == XML_ELEMENT_NODE) {
if (xmlStrcmp (cur_node->name, (xmlChar *) "pro") == 0) {
GstMPDDescriptorType *new_descriptor;
new_descriptor = g_slice_new0 (GstMPDDescriptorType);
GstMPDDescriptorTypeNode *new_descriptor;
new_descriptor = gst_mpd_descriptor_type_node_new ((const gchar *)
cur_node->name);
*list = g_list_append (*list, new_descriptor);
gst_xml_helper_get_prop_string_stripped (a_node, "schemeIdUri",
@ -572,14 +535,10 @@ beach:
}
static void
gst_mpdparser_parse_representation_base_type (GstMPDRepresentationBaseType **
pointer, xmlNode * a_node)
gst_mpdparser_parse_representation_base (GstMPDRepresentationBaseNode *
representation_base, xmlNode * a_node)
{
xmlNode *cur_node;
GstMPDRepresentationBaseType *representation_base;
gst_mpd_helper_representation_base_type_free (*pointer);
*pointer = representation_base = g_slice_new0 (GstMPDRepresentationBaseType);
GST_LOG ("attributes of RepresentationBaseType extension:");
gst_xml_helper_get_prop_string (a_node, "profiles",
@ -659,10 +618,9 @@ gst_mpdparser_parse_representation_node (GList ** list, xmlNode * a_node,
&new_representation->dependencyId);
gst_xml_helper_get_prop_string_vector_type (a_node,
"mediaStreamStructureId", &new_representation->mediaStreamStructureId);
/* RepresentationBase extension */
gst_mpdparser_parse_representation_base_type
(&new_representation->RepresentationBase, a_node);
gst_mpdparser_parse_representation_base
(GST_MPD_REPRESENTATION_BASE_NODE (new_representation), a_node);
/* explore children nodes */
for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
@ -764,8 +722,8 @@ gst_mpdparser_parse_adaptation_set_node (GList ** list, xmlNode * a_node,
&new_adap_set->subsegmentStartsWithSAP);
/* RepresentationBase extension */
gst_mpdparser_parse_representation_base_type
(&new_adap_set->RepresentationBase, a_node);
gst_mpdparser_parse_representation_base
(GST_MPD_REPRESENTATION_BASE_NODE (new_adap_set), a_node);
/* explore children nodes */
for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) {
@ -833,7 +791,7 @@ gst_mpdparser_parse_subset_node (GList ** list, xmlNode * a_node)
GST_LOG ("attributes of Subset node:");
gst_xml_helper_get_prop_uint_vector_type (a_node, "contains",
&new_subset->contains, &new_subset->size);
&new_subset->contains, &new_subset->contains_size);
}
static gboolean
@ -847,9 +805,9 @@ gst_mpdparser_parse_segment_template_node (GstMPDSegmentTemplateNode ** pointer,
new_segment_template = gst_mpd_segment_template_node_new ();
GST_LOG ("extension of SegmentTemplate node:");
if (!gst_mpdparser_parse_mult_seg_base_type_ext
(&new_segment_template->MultSegBaseType, a_node,
(parent ? parent->MultSegBaseType : NULL)))
if (!gst_mpdparser_parse_mult_seg_base_node
(GST_MPD_MULT_SEGMENT_BASE_NODE (new_segment_template), a_node,
(parent ? GST_MPD_MULT_SEGMENT_BASE_NODE (parent) : NULL)))
goto error;
/* Inherit attribute values from parent when the value isn't found */
@ -1048,15 +1006,7 @@ gst_mpdparser_parse_utctiming_node (GList ** list, xmlNode * a_node)
GST_LOG ("attributes of UTCTiming node:");
if (gst_xml_helper_get_prop_string (a_node, "schemeIdUri", &method)) {
int i;
for (i = 0; gst_mpdparser_utc_timing_methods[i].name; ++i) {
if (g_ascii_strncasecmp (gst_mpdparser_utc_timing_methods[i].name,
method, strlen (gst_mpdparser_utc_timing_methods[i].name)) == 0) {
new_timing->method = gst_mpdparser_utc_timing_methods[i].method;
break;
}
}
new_timing->method = gst_mpd_utctiming_get_method (method);
xmlFree (method);
}
@ -1439,7 +1389,7 @@ gst_mpdparser_free_active_stream (GstActiveStream * active_stream)
const gchar *
gst_mpdparser_get_initializationURL (GstActiveStream * stream,
GstMPDURLType * InitializationURL)
GstMPDURLTypeNode * InitializationURL)
{
const gchar *url_prefix;
@ -1473,10 +1423,10 @@ gst_mpdparser_representation_get_mimetype (GstMPDAdaptationSetNode * adapt_set,
GstMPDRepresentationNode * rep)
{
gchar *mime = NULL;
if (rep->RepresentationBase)
mime = rep->RepresentationBase->mimeType;
if (mime == NULL && adapt_set->RepresentationBase) {
mime = adapt_set->RepresentationBase->mimeType;
if (rep)
mime = GST_MPD_REPRESENTATION_BASE_NODE (rep)->mimeType;
if (mime == NULL) {
mime = GST_MPD_REPRESENTATION_BASE_NODE (adapt_set)->mimeType;
}
if (gst_mpd_helper_strncmp_ext (mime, "audio") == 0)

View file

@ -42,6 +42,7 @@
#include "gstmpdsegmenttemplatenode.h"
#include "gstmpdsegmenturlnode.h"
#include "gstmpdsegmentlistnode.h"
#include "gstmpdsegmentbasenode.h"
#include "gstmpdperiodnode.h"
#include "gstmpdrepresentationnode.h"
#include "gstmpdsubrepresentationnode.h"
@ -49,6 +50,12 @@
#include "gstmpdadaptationsetnode.h"
#include "gstmpdsubsetnode.h"
#include "gstmpdprograminformationnode.h"
#include "gstmpdlocationnode.h"
#include "gstmpdreportingnode.h"
#include "gstmpdurltypenode.h"
#include "gstmpddescriptortypenode.h"
#include "gstmpdrepresentationbasenode.h"
#include "gstmpdmultsegmentbasenode.h"
G_BEGIN_DECLS
@ -129,7 +136,7 @@ struct _GstActiveStream
GstMPDAdaptationSetNode *cur_adapt_set; /* active adaptation set */
gint representation_idx; /* index of current representation */
GstMPDRepresentationNode *cur_representation; /* active representation */
GstMPDSegmentBaseType *cur_segment_base; /* active segment base */
GstMPDSegmentBaseNode *cur_segment_base; /* active segment base */
GstMPDSegmentListNode *cur_segment_list; /* active segment list */
GstMPDSegmentTemplateNode *cur_seg_template; /* active segment template */
gint segment_index; /* index of next sequence chunk */
@ -155,7 +162,7 @@ void gst_mpdparser_media_fragment_info_clear (GstMediaFragmentInfo * fragment);
/* Active stream methods*/
void gst_mpdparser_init_active_stream_segments (GstActiveStream * stream);
gchar *gst_mpdparser_get_mediaURL (GstActiveStream * stream, GstMPDSegmentURLNode * segmentURL);
const gchar *gst_mpdparser_get_initializationURL (GstActiveStream * stream, GstMPDURLType * InitializationURL);
const gchar *gst_mpdparser_get_initializationURL (GstActiveStream * stream, GstMPDURLTypeNode * InitializationURL);
gchar *gst_mpdparser_build_URL_from_template (const gchar * url_template, const gchar * id, guint number, guint bandwidth, guint64 time);
G_END_DECLS

View file

@ -21,8 +21,7 @@
#include "gstmpdperiodnode.h"
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDPeriodNode, gst_mpd_period_node, GST_TYPE_OBJECT);
G_DEFINE_TYPE (GstMPDPeriodNode, gst_mpd_period_node, GST_TYPE_MPD_NODE);
/* GObject VMethods */
static void
@ -32,7 +31,7 @@ gst_mpd_period_node_finalize (GObject * object)
if (self->id)
xmlFree (self->id);
gst_mpd_helper_segment_base_type_free (self->SegmentBase);
gst_mpd_segment_base_node_free (self->SegmentBase);
gst_mpd_segment_list_node_free (self->SegmentList);
gst_mpd_segment_template_node_free (self->SegmentTemplate);
g_list_free_full (self->AdaptationSets,
@ -45,11 +44,58 @@ gst_mpd_period_node_finalize (GObject * object)
G_OBJECT_CLASS (gst_mpd_period_node_parent_class)->finalize (object);
}
/* Base class */
static xmlNodePtr
gst_mpd_period_get_xml_node (GstMPDNode * node)
{
xmlNodePtr period_xml_node = NULL;
GstMPDPeriodNode *self = GST_MPD_PERIOD_NODE (node);
period_xml_node = xmlNewNode (NULL, (xmlChar *) "Period");
if (self->id)
gst_xml_helper_set_prop_string (period_xml_node, "id", self->id);
gst_xml_helper_set_prop_duration (period_xml_node, "start", self->start);
gst_xml_helper_set_prop_duration (period_xml_node, "duration",
self->duration);
gst_xml_helper_set_prop_boolean (period_xml_node, "bitstreamSwitching",
self->bitstreamSwitching);
if (self->SegmentBase)
gst_mpd_node_add_child_node (GST_MPD_NODE (self->SegmentBase),
period_xml_node);
if (self->SegmentList)
gst_mpd_mult_segment_base_node_add_child_node (GST_MPD_NODE
(self->SegmentList), period_xml_node);
if (self->SegmentTemplate)
gst_mpd_mult_segment_base_node_add_child_node (GST_MPD_NODE
(self->SegmentTemplate), period_xml_node);
g_list_foreach (self->AdaptationSets,
gst_mpd_representation_base_node_get_list_item, period_xml_node);
g_list_foreach (self->Subsets, gst_mpd_node_get_list_item, period_xml_node);
g_list_foreach (self->BaseURLs, gst_mpd_node_get_list_item, period_xml_node);
return period_xml_node;
}
static void
gst_mpd_period_node_class_init (GstMPDPeriodNodeClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_period_node_finalize;
m_klass->get_xml_node = gst_mpd_period_get_xml_node;
}
static void

View file

@ -31,19 +31,7 @@ G_BEGIN_DECLS
struct _GstSegmentTemplateNode;
#define GST_TYPE_MPD_PERIOD_NODE gst_mpd_period_node_get_type ()
#define GST_MPD_PERIOD_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_PERIOD_NODE, GstMPDPeriodNode))
#define GST_MPD_PERIOD_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_PERIOD_NODE, GstMPDPeriodNodeClass))
#define GST_IS_MPD_PERIOD_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_PERIOD_NODE))
#define GST_IS_MPD_PERIOD_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_PERIOD_NODE))
#define GST_MPD_PERIOD_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_PERIOD_NODE, GstMPDPeriodNodeClass))
typedef struct _GstMPDPeriodNode GstMPDPeriodNode;
typedef struct _GstMPDPeriodNodeClass GstMPDPeriodNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDPeriodNode, gst_mpd_period_node, GST, MPD_PERIOD_NODE, GstMPDNode)
struct _GstMPDPeriodNode
{
@ -53,7 +41,7 @@ struct _GstMPDPeriodNode
guint64 duration; /* [ms] */
gboolean bitstreamSwitching;
/* SegmentBase node */
GstMPDSegmentBaseType *SegmentBase;
GstMPDSegmentBaseNode *SegmentBase;
/* SegmentList node */
GstMPDSegmentListNode *SegmentList;
/* SegmentTemplate node */
@ -69,13 +57,6 @@ struct _GstMPDPeriodNode
int actuate;
};
struct _GstMPDPeriodNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_period_node_get_type (void);
GstMPDPeriodNode * gst_mpd_period_node_new (void);
void gst_mpd_period_node_free (GstMPDPeriodNode* self);

View file

@ -22,7 +22,7 @@
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDProgramInformationNode, gst_mpd_program_information_node,
GST_TYPE_OBJECT);
GST_TYPE_MPD_NODE);
/* GObject VMethods */
@ -47,12 +47,58 @@ gst_mpd_program_information_node_finalize (GObject * object)
(object);
}
/* Base class */
static xmlNodePtr
gst_mpd_program_information_get_xml_node (GstMPDNode * node)
{
xmlNodePtr program_info_xml_node = NULL;
xmlNodePtr child_node = NULL;
GstMPDProgramInformationNode *self = GST_MPD_PROGRAM_INFORMATION_NODE (node);
program_info_xml_node = xmlNewNode (NULL, (xmlChar *) "ProgramInformation");
if (self->lang)
gst_xml_helper_set_prop_string (program_info_xml_node, "lang", self->lang);
if (self->moreInformationURL)
gst_xml_helper_set_prop_string (program_info_xml_node, "moreInformationURL",
self->moreInformationURL);
if (self->Title) {
child_node = xmlNewNode (NULL, (xmlChar *) "Title");
gst_xml_helper_set_content (child_node, self->Title);
xmlAddChild (program_info_xml_node, child_node);
}
if (self->Source) {
child_node = xmlNewNode (NULL, (xmlChar *) "Source");
gst_xml_helper_set_content (child_node, self->Source);
xmlAddChild (program_info_xml_node, child_node);
}
if (self->Copyright) {
child_node = xmlNewNode (NULL, (xmlChar *) "Copyright");
gst_xml_helper_set_content (child_node, self->Copyright);
xmlAddChild (program_info_xml_node, child_node);
}
return program_info_xml_node;
}
static void
gst_mpd_program_information_node_class_init (GstMPDProgramInformationNodeClass *
klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_program_information_node_finalize;
m_klass->get_xml_node = gst_mpd_program_information_get_xml_node;
}
static void

View file

@ -27,20 +27,7 @@
G_BEGIN_DECLS
#define GST_TYPE_MPD_PROGRAM_INFORMATION_NODE gst_mpd_program_information_node_get_type ()
#define GST_MPD_PROGRAM_INFORMATION_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_PROGRAM_INFORMATION_NODE, GstMPDProgramInformationNode))
#define GST_MPD_PROGRAM_INFORMATION_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_PROGRAM_INFORMATION_NODE, GstMPDProgramInformationNodeClass))
#define GST_IS_MPD_PROGRAM_INFORMATION_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_PROGRAM_INFORMATION_NODE))
#define GST_IS_MPD_PROGRAM_INFORMATION_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_PROGRAM_INFORMATION_NODE))
#define GST_MPD_PROGRAM_INFORMATION_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_PROGRAM_INFORMATION_NODE, GstMPDProgramInformationNodeClass))
typedef struct _GstMPDProgramInformationNode GstMPDProgramInformationNode;
typedef struct _GstMPDProgramInformationNodeClass GstMPDProgramInformationNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDProgramInformationNode, gst_mpd_program_information_node, GST, MPD_PROGRAM_INFORMATION_NODE, GstMPDNode)
struct _GstMPDProgramInformationNode
{
@ -53,13 +40,6 @@ struct _GstMPDProgramInformationNode
gchar *Copyright;
};
struct _GstMPDProgramInformationNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_program_information_node_get_type (void);
GstMPDProgramInformationNode * gst_mpd_program_information_node_new (void);
void gst_mpd_program_information_node_free (GstMPDProgramInformationNode* self);

View file

@ -0,0 +1,64 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "gstmpdreportingnode.h"
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDReportingNode, gst_mpd_reporting_node, GST_TYPE_MPD_NODE);
/* Base class */
static xmlNodePtr
gst_mpd_reporting_get_xml_node (GstMPDNode * node)
{
xmlNodePtr reporting_xml_node = NULL;
reporting_xml_node = xmlNewNode (NULL, (xmlChar *) "Reporting");
return reporting_xml_node;
}
static void
gst_mpd_reporting_node_class_init (GstMPDReportingNodeClass * klass)
{
GstMPDNodeClass *m_klass;
m_klass = GST_MPD_NODE_CLASS (klass);
m_klass->get_xml_node = gst_mpd_reporting_get_xml_node;
}
static void
gst_mpd_reporting_node_init (GstMPDReportingNode * self)
{
}
GstMPDReportingNode *
gst_mpd_reporting_node_new (void)
{
return g_object_new (GST_TYPE_MPD_REPORTING_NODE, NULL);
}
void
gst_mpd_reporting_node_free (GstMPDReportingNode * self)
{
if (self)
gst_object_unref (self);
}

View file

@ -0,0 +1,42 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library (COPYING); if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GSTMPDREPORTINGNODE_H__
#define __GSTMPDREPORTINGNODE_H__
#include <gst/gst.h>
#include "gstmpdhelper.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_REPORTING_NODE gst_mpd_reporting_node_get_type ()
G_DECLARE_FINAL_TYPE (GstMPDReportingNode, gst_mpd_reporting_node, GST, MPD_REPORTING_NODE, GstMPDNode)
struct _GstMPDReportingNode
{
GstObject parent_instance;
};
GstMPDReportingNode * gst_mpd_reporting_node_new (void);
void gst_mpd_reporting_node_free (GstMPDReportingNode* self);
G_END_DECLS
#endif /* __GSTMPDREPORTINGNODE_H__ */

View file

@ -0,0 +1,165 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "gstmpdrepresentationbasenode.h"
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDRepresentationBaseNode, gst_mpd_representation_base_node,
GST_TYPE_MPD_NODE);
/* GObject VMethods */
static void
gst_mpd_representation_base_node_finalize (GObject * object)
{
GstMPDRepresentationBaseNode *self =
GST_MPD_REPRESENTATION_BASE_NODE (object);
if (self->profiles)
xmlFree (self->profiles);
g_slice_free (GstXMLRatio, self->sar);
g_slice_free (GstXMLFrameRate, self->frameRate);
g_slice_free (GstXMLFrameRate, self->minFrameRate);
g_slice_free (GstXMLFrameRate, self->maxFrameRate);
if (self->audioSamplingRate)
xmlFree (self->audioSamplingRate);
if (self->mimeType)
xmlFree (self->mimeType);
if (self->segmentProfiles)
xmlFree (self->segmentProfiles);
if (self->codecs)
xmlFree (self->codecs);
if (self->scanType)
xmlFree (self->scanType);
g_list_free_full (self->FramePacking,
(GDestroyNotify) gst_mpd_descriptor_type_node_free);
g_list_free_full (self->AudioChannelConfiguration,
(GDestroyNotify) gst_mpd_descriptor_type_node_free);
g_list_free_full (self->ContentProtection,
(GDestroyNotify) gst_mpd_descriptor_type_node_free);
G_OBJECT_CLASS (gst_mpd_representation_base_node_parent_class)->finalize
(object);
}
/* Base class */
static void
gst_mpd_representation_base_get_xml_node (GstMPDNode * node,
xmlNodePtr representation_base_node)
{
GstMPDRepresentationBaseNode *self = GST_MPD_REPRESENTATION_BASE_NODE (node);
if (self->profiles)
gst_xml_helper_set_prop_string (representation_base_node, "profiles",
self->profiles);
if (self->width)
gst_xml_helper_set_prop_uint (representation_base_node, "width",
self->width);
if (self->height)
gst_xml_helper_set_prop_uint (representation_base_node, "height",
self->height);
gst_xml_helper_set_prop_ratio (representation_base_node, "sar", self->sar);
gst_xml_helper_set_prop_framerate (representation_base_node, "minFrameRate",
self->minFrameRate);
gst_xml_helper_set_prop_framerate (representation_base_node, "maxFrameRate",
self->maxFrameRate);
gst_xml_helper_set_prop_framerate (representation_base_node, "frameRate",
self->frameRate);
gst_xml_helper_set_prop_string (representation_base_node,
"audioSamplingRate", self->audioSamplingRate);
gst_xml_helper_set_prop_string (representation_base_node, "mimeType",
self->mimeType);
gst_xml_helper_set_prop_string (representation_base_node, "segmentProfiles",
self->segmentProfiles);
gst_xml_helper_set_prop_string (representation_base_node, "codecs",
self->codecs);
if (self->maximumSAPPeriod)
gst_xml_helper_set_prop_double (representation_base_node,
"maximumSAPPeriod", self->maximumSAPPeriod);
if (self->startWithSAP)
gst_xml_helper_set_prop_int (representation_base_node, "startWithSAP",
self->startWithSAP);
if (self->maxPlayoutRate)
gst_xml_helper_set_prop_double (representation_base_node, "maxPlayoutRate",
self->maxPlayoutRate);
if (self->codingDependency)
gst_xml_helper_set_prop_boolean (representation_base_node,
"codingDependency", self->codingDependency);
gst_xml_helper_set_prop_string (representation_base_node, "scanType",
self->scanType);
g_list_foreach (self->FramePacking,
gst_mpd_node_get_list_item, representation_base_node);
g_list_foreach (self->AudioChannelConfiguration,
gst_mpd_node_get_list_item, representation_base_node);
g_list_foreach (self->ContentProtection,
gst_mpd_node_get_list_item, representation_base_node);
}
static void
gst_mpd_representation_base_node_class_init (GstMPDRepresentationBaseNodeClass *
klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gst_mpd_representation_base_node_finalize;
}
static void
gst_mpd_representation_base_node_init (GstMPDRepresentationBaseNode * self)
{
self->profiles = NULL;
self->width = 0;
self->height = 0;
self->sar = NULL;
self->minFrameRate = NULL;
self->maxFrameRate = NULL;
self->frameRate = NULL;
self->audioSamplingRate = NULL;
self->mimeType = NULL;
self->segmentProfiles = NULL;
self->codecs = NULL;
self->maximumSAPPeriod = 0;
self->startWithSAP = GST_SAP_TYPE_0;
self->maxPlayoutRate = 0.0;
self->codingDependency = FALSE;
self->scanType = NULL;
self->FramePacking = NULL;
self->AudioChannelConfiguration = NULL;
self->ContentProtection = NULL;
}
void
gst_mpd_representation_base_node_get_list_item (gpointer data,
gpointer user_data)
{
GstMPDNode *node = (GstMPDNode *) data;
xmlNodePtr parent_xml_node = (xmlNodePtr) user_data;
xmlNodePtr new_xml_node = gst_mpd_node_get_xml_pointer (node);
gst_mpd_representation_base_get_xml_node (node, new_xml_node);
xmlAddChild (parent_xml_node, new_xml_node);
}

View file

@ -0,0 +1,63 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library (COPYING); if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GSTMPDREPRESENTATIONBASENODE_H__
#define __GSTMPDREPRESENTATIONBASENODE_H__
#include <gst/gst.h>
#include "gstmpdhelper.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_REPRESENTATION_BASE_NODE gst_mpd_representation_base_node_get_type ()
G_DECLARE_FINAL_TYPE (GstMPDRepresentationBaseNode, gst_mpd_representation_base_node, GST, MPD_REPRESENTATION_BASE_NODE, GstMPDNode)
struct _GstMPDRepresentationBaseNode
{
GstObject base;
gchar *profiles;
guint width;
guint height;
GstXMLRatio *sar;
GstXMLFrameRate *minFrameRate;
GstXMLFrameRate *maxFrameRate;
GstXMLFrameRate *frameRate;
gchar *audioSamplingRate;
gchar *mimeType;
gchar *segmentProfiles;
gchar *codecs;
gdouble maximumSAPPeriod;
GstMPDSAPType startWithSAP;
gdouble maxPlayoutRate;
gboolean codingDependency;
gchar *scanType;
/* list of FramePacking DescriptorType nodes */
GList *FramePacking;
/* list of AudioChannelConfiguration DescriptorType nodes */
GList *AudioChannelConfiguration;
/* list of ContentProtection DescriptorType nodes */
GList *ContentProtection;
};
void gst_mpd_representation_base_node_get_list_item (gpointer data, gpointer user_data);
G_END_DECLS
#endif /* __GSTMPDREPRESENTATIONBASENODE_H__ */

View file

@ -22,7 +22,7 @@
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDRepresentationNode, gst_mpd_representation_node,
GST_TYPE_OBJECT);
GST_TYPE_MPD_REPRESENTATION_BASE_NODE);
/* GObject VMethods */
@ -35,10 +35,9 @@ gst_mpd_representation_node_finalize (GObject * object)
xmlFree (self->id);
g_strfreev (self->dependencyId);
g_strfreev (self->mediaStreamStructureId);
gst_mpd_helper_representation_base_type_free (self->RepresentationBase);
g_list_free_full (self->SubRepresentations,
(GDestroyNotify) gst_mpd_sub_representation_node_free);
gst_mpd_helper_segment_base_type_free (self->SegmentBase);
gst_mpd_segment_base_node_free (self->SegmentBase);
gst_mpd_segment_template_node_free (self->SegmentTemplate);
gst_mpd_segment_list_node_free (self->SegmentList);
g_list_free_full (self->BaseURLs, (GDestroyNotify) gst_mpd_baseurl_node_free);
@ -46,11 +45,65 @@ gst_mpd_representation_node_finalize (GObject * object)
G_OBJECT_CLASS (gst_mpd_representation_node_parent_class)->finalize (object);
}
/* Base class */
static xmlNodePtr
gst_mpd_representation_get_xml_node (GstMPDNode * node)
{
gchar *value;
xmlNodePtr representation_xml_node = NULL;
GstMPDRepresentationNode *self = GST_MPD_REPRESENTATION_NODE (node);
representation_xml_node = xmlNewNode (NULL, (xmlChar *) "Representation");
gst_xml_helper_set_prop_string (representation_xml_node, "id", self->id);
gst_xml_helper_set_prop_uint (representation_xml_node, "bandwidth",
self->bandwidth);
if (self->qualityRanking)
gst_xml_helper_set_prop_uint (representation_xml_node, "qualityRanking",
self->qualityRanking);
if (self->dependencyId) {
value = g_strjoinv (" ", self->dependencyId);
gst_xml_helper_set_prop_string (representation_xml_node, "dependencyId",
value);
g_free (value);
}
if (self->mediaStreamStructureId) {
value = g_strjoinv (" ", self->mediaStreamStructureId);
gst_xml_helper_set_prop_string (representation_xml_node,
"mediaStreamStructureId", value);
g_free (value);
}
g_list_foreach (self->BaseURLs, gst_mpd_node_get_list_item,
representation_xml_node);
g_list_foreach (self->SubRepresentations,
gst_mpd_representation_base_node_get_list_item, representation_xml_node);
gst_mpd_node_add_child_node (GST_MPD_NODE (self->SegmentBase),
representation_xml_node);
gst_mpd_mult_segment_base_node_add_child_node (GST_MPD_NODE
(self->SegmentTemplate), representation_xml_node);
gst_mpd_mult_segment_base_node_add_child_node (GST_MPD_NODE
(self->SegmentList), representation_xml_node);
return representation_xml_node;
}
static void
gst_mpd_representation_node_class_init (GstMPDRepresentationNodeClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_representation_node_finalize;
m_klass->get_xml_node = gst_mpd_representation_get_xml_node;
}
static void
@ -61,7 +114,6 @@ gst_mpd_representation_node_init (GstMPDRepresentationNode * self)
self->qualityRanking = 0;
self->dependencyId = NULL;
self->mediaStreamStructureId = NULL;
self->RepresentationBase = NULL;
self->BaseURLs = NULL;
self->SubRepresentations = NULL;
self->SegmentBase = NULL;

View file

@ -23,55 +23,35 @@
#include <gst/gst.h>
#include "gstmpdhelper.h"
#include "gstmpdrepresentationbasenode.h"
#include "gstmpdsegmentlistnode.h"
#include "gstmpdsegmenttemplatenode.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_REPRESENTATION_NODE gst_mpd_representation_node_get_type ()
#define GST_MPD_REPRESENTATION_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_REPRESENTATION_NODE, GstMPDRepresentationNode))
#define GST_MPD_REPRESENTATION_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_REPRESENTATION_NODE, GstMPDRepresentationNodeClass))
#define GST_IS_MPD_REPRESENTATION_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_REPRESENTATION_NODE))
#define GST_IS_MPD_REPRESENTATION_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_REPRESENTATION_NODE))
#define GST_MPD_REPRESENTATION_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_REPRESENTATION_NODE, GstMPDRepresentationNodeClass))
typedef struct _GstMPDRepresentationNode GstMPDRepresentationNode;
typedef struct _GstMPDRepresentationNodeClass GstMPDRepresentationNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDRepresentationNode, gst_mpd_representation_node, GST, MPD_REPRESENTATION_NODE, GstMPDRepresentationBaseNode)
struct _GstMPDRepresentationNode
{
GstObject parent_instance;
GstMPDRepresentationBaseNode parent_instance;
gchar *id;
guint bandwidth;
guint qualityRanking;
gchar **dependencyId; /* StringVectorType */
gchar **mediaStreamStructureId; /* StringVectorType */
/* RepresentationBase extension */
GstMPDRepresentationBaseType *RepresentationBase;
/* list of BaseURL nodes */
GList *BaseURLs;
/* list of SubRepresentation nodes */
GList *SubRepresentations;
/* SegmentBase node */
GstMPDSegmentBaseType *SegmentBase;
GstMPDSegmentBaseNode *SegmentBase;
/* SegmentTemplate node */
GstMPDSegmentTemplateNode *SegmentTemplate;
/* SegmentList node */
GstMPDSegmentListNode *SegmentList;
};
struct _GstMPDRepresentationNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_representation_node_get_type (void);
GstMPDRepresentationNode * gst_mpd_representation_node_new (void);
void gst_mpd_representation_node_free (GstMPDRepresentationNode* self);

View file

@ -21,7 +21,8 @@
#include "gstmpdrootnode.h"
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDRootNode, gst_mpd_root_node, GST_TYPE_OBJECT);
G_DEFINE_TYPE (GstMPDRootNode, gst_mpd_root_node, GST_TYPE_MPD_NODE);
/* GObject VMethods */
static void
@ -44,7 +45,8 @@ gst_mpd_root_node_finalize (GObject * object)
g_list_free_full (self->ProgramInfos,
(GDestroyNotify) gst_mpd_program_information_node_free);
g_list_free_full (self->BaseURLs, (GDestroyNotify) gst_mpd_baseurl_node_free);
g_list_free_full (self->Locations, (GDestroyNotify) g_free);
g_list_free_full (self->Locations,
(GDestroyNotify) gst_mpd_location_node_free);
g_list_free_full (self->Periods, (GDestroyNotify) gst_mpd_period_node_free);
g_list_free_full (self->Metrics, (GDestroyNotify) gst_mpd_metrics_node_free);
g_list_free_full (self->UTCTimings,
@ -54,11 +56,105 @@ gst_mpd_root_node_finalize (GObject * object)
G_OBJECT_CLASS (gst_mpd_root_node_parent_class)->finalize (object);
}
/* Base class */
static xmlNodePtr
gst_mpd_root_get_xml_node (GstMPDNode * node)
{
xmlNodePtr root_xml_node;
GstMPDRootNode *self = GST_MPD_ROOT_NODE (node);
root_xml_node = xmlNewNode (NULL, (xmlChar *) "MPD");
gst_xml_helper_set_prop_string (root_xml_node, "xmlns",
self->default_namespace);
gst_xml_helper_set_prop_string (root_xml_node, "profiles", self->profiles);
gst_xml_helper_set_prop_string (root_xml_node, "schemaLocation",
self->schemaLocation);
gst_xml_helper_set_prop_string (root_xml_node, "xmlns:xsi",
self->namespace_xsi);
gst_xml_helper_set_prop_string (root_xml_node, "xmlns:ext",
self->namespace_ext);
gst_xml_helper_set_prop_string (root_xml_node, "id", self->id);
if (self->type == GST_MPD_FILE_TYPE_STATIC)
gst_xml_helper_set_prop_string (root_xml_node, "type", (gchar *) "static");
else
gst_xml_helper_set_prop_string (root_xml_node, "type", (gchar *) "dynamic");
gst_xml_helper_set_prop_date_time (root_xml_node, "availabilityStartTime",
self->availabilityStartTime);
gst_xml_helper_set_prop_date_time (root_xml_node, "availabilityEndTime",
self->availabilityEndTime);
if (self->mediaPresentationDuration)
gst_xml_helper_set_prop_duration (root_xml_node,
"mediaPresentationDuration", self->mediaPresentationDuration);
if (self->minimumUpdatePeriod)
gst_xml_helper_set_prop_duration (root_xml_node, "minimumUpdatePeriod",
self->minimumUpdatePeriod);
if (self->minimumUpdatePeriod)
gst_xml_helper_set_prop_duration (root_xml_node, "minBufferTime",
self->minBufferTime);
if (self->timeShiftBufferDepth)
gst_xml_helper_set_prop_duration (root_xml_node, "timeShiftBufferDepth",
self->timeShiftBufferDepth);
if (self->suggestedPresentationDelay)
gst_xml_helper_set_prop_duration (root_xml_node,
"suggestedPresentationDelay", self->suggestedPresentationDelay);
if (self->maxSegmentDuration)
gst_xml_helper_set_prop_duration (root_xml_node, "maxSegmentDuration",
self->maxSegmentDuration);
if (self->maxSubsegmentDuration)
gst_xml_helper_set_prop_duration (root_xml_node, "maxSubsegmentDuration",
self->maxSubsegmentDuration);
g_list_foreach (self->BaseURLs, gst_mpd_node_get_list_item, root_xml_node);
g_list_foreach (self->Locations, gst_mpd_node_get_list_item, root_xml_node);
g_list_foreach (self->ProgramInfos, gst_mpd_node_get_list_item,
root_xml_node);
g_list_foreach (self->Periods, gst_mpd_node_get_list_item, root_xml_node);
g_list_foreach (self->Metrics, gst_mpd_node_get_list_item, root_xml_node);
g_list_foreach (self->UTCTimings, gst_mpd_node_get_list_item, root_xml_node);
return root_xml_node;
}
static gboolean
gst_mpd_root_get_xml_buffer (GstMPDNode * node, gchar ** doc_content,
gint * doc_size)
{
xmlDocPtr doc;
xmlNodePtr root_xml_node;
xmlChar *xmlbody;
doc = xmlNewDoc ((xmlChar *) "1.0");
root_xml_node = gst_mpd_root_get_xml_node (node);
xmlDocSetRootElement (doc, root_xml_node);
xmlDocDumpMemory (doc, &xmlbody, doc_size);
*doc_content = g_strndup ((gchar *) xmlbody, *doc_size);
xmlFree (xmlbody);
xmlFreeDoc (doc);
return TRUE;
}
static void
gst_mpd_root_node_class_init (GstMPDRootNodeClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_root_node_finalize;
m_klass->get_xml_buffer = gst_mpd_root_get_xml_buffer;
m_klass->get_xml_node = gst_mpd_root_get_xml_node;
}
static void

View file

@ -27,20 +27,7 @@
G_BEGIN_DECLS
#define GST_TYPE_MPD_ROOT_NODE gst_mpd_root_node_get_type ()
#define GST_MPD_ROOT_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_ROOT_NODE, GstMPDRootNode))
#define GST_MPD_ROOT_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_ROOT_NODE, GstMPDRootNodeClass))
#define GST_IS_MPD_ROOT_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_ROOT_NODE))
#define GST_IS_MPD_ROOT_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_ROOT_NODE))
#define GST_MPD_ROOT_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_ROOT_NODE, GstMPDRootNodeClass))
typedef struct _GstMPDRootNode GstMPDRootNode;
typedef struct _GstMPDRootNodeClass GstMPDRootNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDRootNode, gst_mpd_root_node, GST, MPD_ROOT_NODE, GstMPDNode)
struct _GstMPDRootNode
{
@ -75,13 +62,6 @@ struct _GstMPDRootNode
GList *UTCTimings;
};
struct _GstMPDRootNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_root_node_get_type (void);
GstMPDRootNode * gst_mpd_root_node_new (void);
void gst_mpd_root_node_free (GstMPDRootNode* self);

View file

@ -0,0 +1,112 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "gstmpdsegmentbasenode.h"
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDSegmentBaseNode, gst_mpd_segment_base_node,
GST_TYPE_MPD_NODE);
/* GObject VMethods */
static void
gst_mpd_segment_base_node_finalize (GObject * object)
{
GstMPDSegmentBaseNode *self = GST_MPD_SEGMENT_BASE_NODE (object);
if (self->indexRange)
g_slice_free (GstXMLRange, self->indexRange);
gst_mpd_url_type_node_free (self->Initialization);
gst_mpd_url_type_node_free (self->RepresentationIndex);
G_OBJECT_CLASS (gst_mpd_segment_base_node_parent_class)->finalize (object);
}
/* Base class */
static xmlNodePtr
gst_mpd_segment_base_get_xml_node (GstMPDNode * node)
{
xmlNodePtr segment_base_xml_node = NULL;
GstMPDSegmentBaseNode *self = GST_MPD_SEGMENT_BASE_NODE (node);
segment_base_xml_node = xmlNewNode (NULL, (xmlChar *) "SegmentBase");
if (self->timescale)
gst_xml_helper_set_prop_uint (segment_base_xml_node, "timescale",
self->timescale);
if (self->presentationTimeOffset)
gst_xml_helper_set_prop_uint64 (segment_base_xml_node,
"presentationTimeOffset", self->presentationTimeOffset);
if (self->indexRange) {
gst_xml_helper_set_prop_range (segment_base_xml_node, "indexRange",
self->indexRange);
gst_xml_helper_set_prop_boolean (segment_base_xml_node, "indexRangeExact",
self->indexRangeExact);
}
if (self->Initialization)
gst_mpd_node_add_child_node (GST_MPD_NODE (self->Initialization),
segment_base_xml_node);
if (self->RepresentationIndex)
gst_mpd_node_add_child_node (GST_MPD_NODE (self->RepresentationIndex),
segment_base_xml_node);
return segment_base_xml_node;
}
static void
gst_mpd_segment_base_node_class_init (GstMPDSegmentBaseNodeClass * klass)
{
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_segment_base_node_finalize;
m_klass->get_xml_node = gst_mpd_segment_base_get_xml_node;
}
static void
gst_mpd_segment_base_node_init (GstMPDSegmentBaseNode * self)
{
self->timescale = 0;
self->presentationTimeOffset = 0;
self->indexRange = NULL;
self->indexRangeExact = FALSE;
/* Initialization node */
self->Initialization = NULL;
/* RepresentationIndex node */
self->RepresentationIndex = NULL;
}
GstMPDSegmentBaseNode *
gst_mpd_segment_base_node_new (void)
{
return g_object_new (GST_TYPE_MPD_SEGMENT_BASE_NODE, NULL);
}
void
gst_mpd_segment_base_node_free (GstMPDSegmentBaseNode * self)
{
if (self)
gst_object_unref (self);
}

View file

@ -0,0 +1,51 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library (COPYING); if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GSTMPDSEGMENTBASENODE_H__
#define __GSTMPDSEGMENTBASENODE_H__
#include <gst/gst.h>
#include "gstmpdnode.h"
#include "gstmpdurltypenode.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_SEGMENT_BASE_NODE gst_mpd_segment_base_node_get_type ()
G_DECLARE_FINAL_TYPE (GstMPDSegmentBaseNode, gst_mpd_segment_base_node, GST, MPD_SEGMENT_BASE_NODE, GstMPDNode)
struct _GstMPDSegmentBaseNode
{
GstObject parent_instance;
guint timescale;
guint64 presentationTimeOffset;
GstXMLRange *indexRange;
gboolean indexRangeExact;
/* Initialization node */
GstMPDURLTypeNode *Initialization;
/* RepresentationIndex node */
GstMPDURLTypeNode *RepresentationIndex;
};
GstMPDSegmentBaseNode * gst_mpd_segment_base_node_new (void);
void gst_mpd_segment_base_node_free (GstMPDSegmentBaseNode* self);
G_END_DECLS
#endif /* __GSTMPDSEGMENTBASENODE_H__ */

View file

@ -20,10 +20,9 @@
*/
#include "gstmpdsegmentlistnode.h"
#include "gstmpdparser.h"
#include "gstmpdhelper.h"
G_DEFINE_TYPE (GstMPDSegmentListNode, gst_mpd_segment_list_node,
GST_TYPE_OBJECT);
GST_TYPE_MPD_MULT_SEGMENT_BASE_NODE);
/* GObject VMethods */
@ -34,25 +33,49 @@ gst_mpd_segment_list_node_finalize (GObject * object)
g_list_free_full (self->SegmentURL,
(GDestroyNotify) gst_mpd_segment_url_node_free);
/* MultipleSegmentBaseType extension */
gst_mpd_helper_mult_seg_base_type_free (self->MultSegBaseType);
if (self->xlink_href)
xmlFree (self->xlink_href);
G_OBJECT_CLASS (gst_mpd_segment_list_node_parent_class)->finalize (object);
}
/* Base class */
static xmlNodePtr
gst_mpd_segment_list_get_xml_node (GstMPDNode * node)
{
xmlNodePtr segment_list_xml_node = NULL;
GstMPDSegmentListNode *self = GST_MPD_SEGMENT_LIST_NODE (node);
segment_list_xml_node = xmlNewNode (NULL, (xmlChar *) "SegmentList");
g_list_foreach (self->SegmentURL, gst_mpd_node_get_list_item,
segment_list_xml_node);
if (self->xlink_href)
gst_xml_helper_set_prop_string (segment_list_xml_node, "xlink_href",
self->xlink_href);
return segment_list_xml_node;
}
static void
gst_mpd_segment_list_node_class_init (GstMPDSegmentListNodeClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_segment_list_node_finalize;
m_klass->get_xml_node = gst_mpd_segment_list_get_xml_node;
}
static void
gst_mpd_segment_list_node_init (GstMPDSegmentListNode * self)
{
self->MultSegBaseType = NULL;
self->SegmentURL = NULL;
self->xlink_href = NULL;
self->actuate = GST_MPD_XLINK_ACTUATE_ON_REQUEST;

View file

@ -23,31 +23,19 @@
#include <gst/gst.h>
#include "gstmpdhelper.h"
#include "gstmpdmultsegmentbasenode.h"
#include "gstmpdsegmenturlnode.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_SEGMENT_LIST_NODE gst_mpd_segment_list_node_get_type ()
#define GST_MPD_SEGMENT_LIST_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_SEGMENT_LIST_NODE, GstMPDSegmentListNode))
#define GST_MPD_SEGMENT_LIST_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_SEGMENT_LIST_NODE, GstMPDSegmentListNodeClass))
#define GST_IS_MPD_SEGMENT_LIST_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_SEGMENT_LIST_NODE))
#define GST_IS_MPD_SEGMENT_LIST_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_SEGMENT_LIST_NODE))
#define GST_MPD_SEGMENT_LIST_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_SEGMENT_LIST_NODE, GstMPDSegmentListNodeClass))
typedef struct _GstMPDSegmentListNode GstMPDSegmentListNode;
typedef struct _GstMPDSegmentListNodeClass GstMPDSegmentListNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDSegmentListNode, gst_mpd_segment_list_node, GST, MPD_SEGMENT_LIST_NODE, GstMPDMultSegmentBaseNode)
struct _GstMPDSegmentListNode
{
GstObject parent_instance;
GstMPDMultSegmentBaseNode parent_instance;
/* extension */
GstMPDMultSegmentBaseType *MultSegBaseType;
/* list of SegmentURL nodes */
GList *SegmentURL;
@ -55,13 +43,6 @@ struct _GstMPDSegmentListNode
GstMPDXLinkActuate actuate;
};
struct _GstMPDSegmentListNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_segment_list_node_get_type (void);
GstMPDSegmentListNode * gst_mpd_segment_list_node_new (void);
void gst_mpd_segment_list_node_free (GstMPDSegmentListNode* self);

View file

@ -22,7 +22,7 @@
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDSegmentTemplateNode, gst_mpd_segment_template_node,
GST_TYPE_OBJECT);
GST_TYPE_MPD_MULT_SEGMENT_BASE_NODE);
/* GObject VMethods */
@ -39,25 +39,58 @@ gst_mpd_segment_template_node_finalize (GObject * object)
xmlFree (self->initialization);
if (self->bitstreamSwitching)
xmlFree (self->bitstreamSwitching);
/* MultipleSegmentBaseType extension */
gst_mpd_helper_mult_seg_base_type_free (self->MultSegBaseType);
G_OBJECT_CLASS (gst_mpd_segment_template_node_parent_class)->finalize
(object);
}
/* Base class */
static xmlNodePtr
gst_mpd_segment_template_get_xml_node (GstMPDNode * node)
{
xmlNodePtr segment_template_xml_node = NULL;
GstMPDSegmentTemplateNode *self = GST_MPD_SEGMENT_TEMPLATE_NODE (node);
segment_template_xml_node = xmlNewNode (NULL, (xmlChar *) "SegmentTemplate");
if (self->media)
gst_xml_helper_set_prop_string (segment_template_xml_node, "media",
self->media);
if (self->index)
gst_xml_helper_set_prop_string (segment_template_xml_node, "index",
self->index);
if (self->initialization)
gst_xml_helper_set_prop_string (segment_template_xml_node, "initialization",
self->initialization);
if (self->bitstreamSwitching)
gst_xml_helper_set_prop_string (segment_template_xml_node,
"bitstreamSwitching", self->bitstreamSwitching);
return segment_template_xml_node;
}
static void
gst_mpd_segment_template_node_class_init (GstMPDSegmentTemplateNodeClass *
klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_segment_template_node_finalize;
m_klass->get_xml_node = gst_mpd_segment_template_get_xml_node;
}
static void
gst_mpd_segment_template_node_init (GstMPDSegmentTemplateNode * self)
{
self->MultSegBaseType = NULL;
self->media = NULL;
self->index = NULL;
self->initialization = NULL;

View file

@ -23,43 +23,23 @@
#include <gst/gst.h>
#include "gstmpdhelper.h"
#include "gstmpdmultsegmentbasenode.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_SEGMENT_TEMPLATE_NODE gst_mpd_segment_template_node_get_type ()
#define GST_MPD_SEGMENT_TEMPLATE_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_SEGMENT_TEMPLATE_NODE, GstMPDSegmentTemplateNode))
#define GST_MPD_SEGMENT_TEMPLATE_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_SEGMENT_TEMPLATE_NODE, GstMPDSegmentTemplateNodeClass))
#define GST_IS_MPD_SEGMENT_TEMPLATE_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_SEGMENT_TEMPLATE_NODE))
#define GST_IS_MPD_SEGMENT_TEMPLATE_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_SEGMENT_TEMPLATE_NODE))
#define GST_MPD_SEGMENT_TEMPLATE_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_SEGMENT_TEMPLATE_NODE, GstMPDSegmentTemplateNodeClass))
typedef struct _GstMPDSegmentTemplateNode GstMPDSegmentTemplateNode;
typedef struct _GstMPDSegmentTemplateNodeClass GstMPDSegmentTemplateNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDSegmentTemplateNode, gst_mpd_segment_template_node, GST, MPD_SEGMENT_TEMPLATE_NODE, GstMPDMultSegmentBaseNode)
struct _GstMPDSegmentTemplateNode
{
GstObject parent_instance;
/* extension */
GstMPDMultSegmentBaseType *MultSegBaseType;
GstMPDMultSegmentBaseNode parent_instance;
gchar *media;
gchar *index;
gchar *initialization;
gchar *bitstreamSwitching;
};
struct _GstMPDSegmentTemplateNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_segment_template_node_get_type (void);
GstMPDSegmentTemplateNode * gst_mpd_segment_template_node_new (void);
void gst_mpd_segment_template_node_free (GstMPDSegmentTemplateNode* self);

View file

@ -22,7 +22,7 @@
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDSegmentTimelineNode, gst_mpd_segment_timeline_node,
GST_TYPE_OBJECT);
GST_TYPE_MPD_NODE);
/* GObject VMethods */
@ -38,12 +38,35 @@ gst_mpd_segment_timeline_node_finalize (GObject * object)
(object);
}
/* Base class */
static xmlNodePtr
gst_mpd_segment_timeline_get_xml_node (GstMPDNode * node)
{
xmlNodePtr segment_timeline_xml_node = NULL;
GstMPDSegmentTimelineNode *self = GST_MPD_SEGMENT_TIMELINE_NODE (node);
segment_timeline_xml_node = xmlNewNode (NULL, (xmlChar *) "SegmentTimeline");
g_queue_foreach (&self->S, (GFunc) gst_mpd_node_get_list_item,
segment_timeline_xml_node);
return segment_timeline_xml_node;
}
static void
gst_mpd_segment_timeline_node_class_init (GstMPDSegmentTimelineNodeClass *
klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_segment_timeline_node_finalize;
m_klass->get_xml_node = gst_mpd_segment_timeline_get_xml_node;
}
static void

View file

@ -22,25 +22,12 @@
#define __GSTMPDSEGMENTTIMELINENODE_H__
#include <gst/gst.h>
#include "gstxmlhelper.h"
#include "gstmpdnode.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_SEGMENT_TIMELINE_NODE gst_mpd_segment_timeline_node_get_type ()
#define GST_MPD_SEGMENT_TIMELINE_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_SEGMENT_TIMELINE_NODE, GstMPDSegmentTimelineNode))
#define GST_MPD_SEGMENT_TIMELINE_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_SEGMENT_TIMELINE_NODE, GstMPDSegmentTimelineNodeClass))
#define GST_IS_MPD_SEGMENT_TIMELINE_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_SEGMENT_TIMELINE_NODE))
#define GST_IS_MPD_SEGMENT_TIMELINE_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_SEGMENT_TIMELINE_NODE))
#define GST_MPD_SEGMENT_TIMELINE_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_SEGMENT_TIMELINE_NODE, GstMPDSegmentTimelineNodeClass))
typedef struct _GstMPDSegmentTimelineNode GstMPDSegmentTimelineNode;
typedef struct _GstMPDSegmentTimelineNodeClass GstMPDSegmentTimelineNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDSegmentTimelineNode, gst_mpd_segment_timeline_node, GST, MPD_SEGMENT_TIMELINE_NODE, GstMPDNode)
struct _GstMPDSegmentTimelineNode
{
@ -49,13 +36,6 @@ struct _GstMPDSegmentTimelineNode
GQueue S;
};
struct _GstMPDSegmentTimelineNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_segment_timeline_node_get_type (void);
GstMPDSegmentTimelineNode * gst_mpd_segment_timeline_node_new (void);
void gst_mpd_segment_timeline_node_free (GstMPDSegmentTimelineNode* self);

View file

@ -22,7 +22,8 @@
#include "gstmpdparser.h"
#include "gstmpdhelper.h"
G_DEFINE_TYPE (GstMPDSegmentURLNode, gst_mpd_segment_url_node, GST_TYPE_OBJECT);
G_DEFINE_TYPE (GstMPDSegmentURLNode, gst_mpd_segment_url_node,
GST_TYPE_MPD_NODE);
/* GObject VMethods */
@ -41,11 +42,45 @@ gst_mpd_segment_url_node_finalize (GObject * object)
G_OBJECT_CLASS (gst_mpd_segment_url_node_parent_class)->finalize (object);
}
/* Base class */
static xmlNodePtr
gst_mpd_segment_url_get_xml_node (GstMPDNode * node)
{
xmlNodePtr segment_url_xml_node = NULL;
GstMPDSegmentURLNode *self = GST_MPD_SEGMENT_URL_NODE (node);
segment_url_xml_node = xmlNewNode (NULL, (xmlChar *) "SegmentURL");
if (self->media)
gst_xml_helper_set_prop_string (segment_url_xml_node, "media", self->media);
if (self->mediaRange)
gst_xml_helper_set_prop_range (segment_url_xml_node, "mediaRange",
self->mediaRange);
if (self->index)
gst_xml_helper_set_prop_string (segment_url_xml_node, "index", self->index);
if (self->indexRange)
gst_xml_helper_set_prop_range (segment_url_xml_node, "indexRange",
self->indexRange);
return segment_url_xml_node;
}
static void
gst_mpd_segment_url_node_class_init (GstMPDSegmentURLNodeClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_segment_url_node_finalize;
m_klass->get_xml_node = gst_mpd_segment_url_get_xml_node;
}
static void

View file

@ -22,25 +22,12 @@
#define __GSTMPDSEGMENTURLNODE_H__
#include <gst/gst.h>
#include "gstmpdhelper.h"
#include "gstmpdnode.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_SEGMENT_URL_NODE gst_mpd_segment_url_node_get_type ()
#define GST_MPD_SEGMENT_URL_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_SEGMENT_URL_NODE, GstMPDSegmentURLNode))
#define GST_MPD_SEGMENT_URL_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_SEGMENT_URL_NODE, GstMPDSegmentURLNodeClass))
#define GST_IS_MPD_SEGMENT_URL_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_SEGMENT_URL_NODE))
#define GST_IS_MPD_SEGMENT_URL_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_SEGMENT_URL_NODE))
#define GST_MPD_SEGMENT_URL_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_SEGMENT_URL_NODE, GstMPDSegmentURLNodeClass))
typedef struct _GstMPDSegmentURLNode GstMPDSegmentURLNode;
typedef struct _GstMPDSegmentURLNodeClass GstMPDSegmentURLNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDSegmentURLNode, gst_mpd_segment_url_node, GST, MPD_SEGMENT_URL_NODE, GstMPDNode)
struct _GstMPDSegmentURLNode
{
@ -51,13 +38,6 @@ struct _GstMPDSegmentURLNode
GstXMLRange *indexRange;
};
struct _GstMPDSegmentURLNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_segment_url_node_get_type (void);
GstMPDSegmentURLNode * gst_mpd_segment_url_node_new (void);
void gst_mpd_segment_url_node_free (GstMPDSegmentURLNode* self);

View file

@ -21,13 +21,38 @@
#include "gstmpdsnode.h"
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDSNode, gst_mpd_s_node, GST_TYPE_OBJECT);
G_DEFINE_TYPE (GstMPDSNode, gst_mpd_s_node, GST_TYPE_MPD_NODE);
/* GObject VMethods */
/* Base class */
static xmlNodePtr
gst_mpd_s_get_xml_node (GstMPDNode * node)
{
xmlNodePtr s_xml_node = NULL;
GstMPDSNode *self = GST_MPD_S_NODE (node);
s_xml_node = xmlNewNode (NULL, (xmlChar *) "S");
if (self->t)
gst_xml_helper_set_prop_uint64 (s_xml_node, "t", self->t);
if (self->d)
gst_xml_helper_set_prop_uint64 (s_xml_node, "d", self->d);
if (self->r)
gst_xml_helper_set_prop_int (s_xml_node, "r", self->r);
return s_xml_node;
}
static void
gst_mpd_s_node_class_init (GstMPDSNodeClass * klass)
{
GstMPDNodeClass *m_klass;
m_klass = GST_MPD_NODE_CLASS (klass);
m_klass->get_xml_node = gst_mpd_s_get_xml_node;
}
static void

View file

@ -22,25 +22,12 @@
#define __GSTMPDSNODE_H__
#include <gst/gst.h>
#include "gstmpdhelper.h"
#include "gstmpdnode.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_S_NODE gst_mpd_s_node_get_type ()
#define GST_MPD_S_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_S_NODE, GstMPDSNode))
#define GST_MPD_S_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_S_NODE, GstMPDSNodeClass))
#define GST_IS_MPD_S_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_S_NODE))
#define GST_IS_MPD_S_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_S_NODE))
#define GST_MPD_S_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_S_NODE, GstMPDSNodeClass))
typedef struct _GstMPDSNode GstMPDSNode;
typedef struct _GstMPDSNodeClass GstMPDSNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDSNode, gst_mpd_s_node, GST, MPD_S_NODE, GstMPDNode)
struct _GstMPDSNode
{
@ -50,13 +37,6 @@ struct _GstMPDSNode
gint r;
};
struct _GstMPDSNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_s_node_get_type (void);
GstMPDSNode * gst_mpd_s_node_new (void);
void gst_mpd_s_node_free (GstMPDSNode* self);

View file

@ -22,7 +22,7 @@
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDSubRepresentationNode, gst_mpd_sub_representation_node,
GST_TYPE_OBJECT);
GST_TYPE_MPD_REPRESENTATION_BASE_NODE);
/* GObject VMethods */
@ -31,7 +31,6 @@ gst_mpd_sub_representation_node_finalize (GObject * object)
{
GstMPDSubRepresentationNode *self = GST_MPD_SUB_REPRESENTATION_NODE (object);
gst_mpd_helper_representation_base_type_free (self->RepresentationBase);
if (self->dependencyLevel)
xmlFree (self->dependencyLevel);
g_strfreev (self->contentComponent);
@ -40,21 +39,58 @@ gst_mpd_sub_representation_node_finalize (GObject * object)
(object);
}
/* Base class */
static xmlNodePtr
gst_mpd_sub_representation_get_xml_node (GstMPDNode * node)
{
gchar *value = NULL;
xmlNodePtr sub_representation_xml_node = NULL;
GstMPDSubRepresentationNode *self = GST_MPD_SUB_REPRESENTATION_NODE (node);
sub_representation_xml_node =
xmlNewNode (NULL, (xmlChar *) "SubRepresentation");
gst_xml_helper_set_prop_uint (sub_representation_xml_node, "level",
self->level);
gst_xml_helper_set_prop_uint_vector_type (sub_representation_xml_node,
"dependencyLevel", self->dependencyLevel, self->dependencyLevel_size);
gst_xml_helper_set_prop_uint (sub_representation_xml_node, "bandwidth",
self->level);
if (self->contentComponent) {
value = g_strjoinv (" ", self->contentComponent);
gst_xml_helper_set_prop_string (sub_representation_xml_node,
"contentComponent", value);
g_free (value);
}
return sub_representation_xml_node;
}
static void
gst_mpd_sub_representation_node_class_init (GstMPDSubRepresentationNodeClass *
klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_sub_representation_node_finalize;
m_klass->get_xml_node = gst_mpd_sub_representation_get_xml_node;
}
static void
gst_mpd_sub_representation_node_init (GstMPDSubRepresentationNode * self)
{
self->RepresentationBase = NULL;
self->level = 0;
self->dependencyLevel = NULL;
self->size = 0;
self->dependencyLevel_size = 0;
self->bandwidth = 0;
self->contentComponent = NULL;
}

View file

@ -23,44 +23,24 @@
#include <gst/gst.h>
#include "gstmpdhelper.h"
#include "gstmpdrepresentationbasenode.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_SUB_REPRESENTATION_NODE gst_mpd_sub_representation_node_get_type ()
#define GST_MPD_SUB_REPRESENTATION_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_SUB_REPRESENTATION_NODE, GstMPDSubRepresentationNode))
#define GST_MPD_SUB_REPRESENTATION_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_SUB_REPRESENTATION_NODE, GstMPDSubRepresentationNodeClass))
#define GST_IS_MPD_SUB_REPRESENTATION_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_SUB_REPRESENTATION_NODE))
#define GST_IS_MPD_SUB_REPRESENTATION_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_SUB_REPRESENTATION_NODE))
#define GST_MPD_SUB_REPRESENTATION_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_SUB_REPRESENTATION_NODE, GstMPDSubRepresentationNodeClass))
typedef struct _GstMPDSubRepresentationNode GstMPDSubRepresentationNode;
typedef struct _GstMPDSubRepresentationNodeClass GstMPDSubRepresentationNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDSubRepresentationNode, gst_mpd_sub_representation_node, GST, MPD_SUB_REPRESENTATION_NODE, GstMPDRepresentationBaseNode)
struct _GstMPDSubRepresentationNode
{
GstObject parent_instance;
GstMPDRepresentationBaseNode parent_instance;
/* RepresentationBase extension */
GstMPDRepresentationBaseType *RepresentationBase;
guint level;
guint *dependencyLevel; /* UIntVectorType */
guint size; /* size of "dependencyLevel" array */
guint dependencyLevel_size; /* size of "dependencyLevel" array */
guint bandwidth;
gchar **contentComponent; /* StringVectorType */
};
struct _GstMPDSubRepresentationNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_sub_representation_node_get_type (void);
GstMPDSubRepresentationNode * gst_mpd_sub_representation_node_new (void);
void gst_mpd_sub_representation_node_free (GstMPDSubRepresentationNode* self);

View file

@ -21,7 +21,7 @@
#include "gstmpdsubsetnode.h"
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDSubsetNode, gst_mpd_subset_node, GST_TYPE_OBJECT);
G_DEFINE_TYPE (GstMPDSubsetNode, gst_mpd_subset_node, GST_TYPE_MPD_NODE);
/* GObject VMethods */
@ -36,17 +36,41 @@ gst_mpd_subset_node_finalize (GObject * object)
G_OBJECT_CLASS (gst_mpd_subset_node_parent_class)->finalize (object);
}
/* Base class */
static xmlNodePtr
gst_mpd_subset_get_xml_node (GstMPDNode * node)
{
xmlNodePtr subset_xml_node = NULL;
GstMPDSubsetNode *self = GST_MPD_SUBSET_NODE (node);
subset_xml_node = xmlNewNode (NULL, (xmlChar *) "Subset");
if (self->contains)
gst_xml_helper_set_prop_uint_vector_type (subset_xml_node, "contains",
self->contains, self->contains_size);
return subset_xml_node;
}
static void
gst_mpd_subset_node_class_init (GstMPDSubsetNodeClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_subset_node_finalize;
m_klass->get_xml_node = gst_mpd_subset_get_xml_node;
}
static void
gst_mpd_subset_node_init (GstMPDSubsetNode * self)
{
self->size = 0;
self->contains_size = 0;
self->contains = NULL;
}

View file

@ -22,40 +22,25 @@
#define __GSTMPDSUBSETNODE_H__
#include <gst/gst.h>
#include "gstmpdhelper.h"
#include "gstmpdnode.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_SUBSET_NODE gst_mpd_subset_node_get_type ()
#define GST_MPD_SUBSET_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_SUBSET_NODE, GstMPDSubsetNode))
#define GST_MPD_SUBSET_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_SUBSET_NODE, GstMPDSubsetNodeClass))
#define GST_IS_MPD_SUBSET_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_SUBSET_NODE))
#define GST_IS_MPD_SUBSET_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_SUBSET_NODE))
#define GST_MPD_SUBSET_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_SUBSET_NODE, GstMPDSubsetNodeClass))
typedef struct _GstMPDSubsetNode GstMPDSubsetNode;
typedef struct _GstMPDSubsetNodeClass GstMPDSubsetNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDSubsetNode, gst_mpd_subset_node, GST, MPD_SUBSET_NODE, GstMPDNode)
struct _GstMPDSubsetNode
{
GstObject parent_instance;
guint *contains; /* UIntVectorType */
guint size; /* size of the "contains" array */
guint contains_size; /* size of the "contains" array */
};
struct _GstMPDSubsetNodeClass {
GstObjectClass parent_class;
GstMPDNodeClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_subset_node_get_type (void);
GstMPDSubsetNode * gst_mpd_subset_node_new (void);
void gst_mpd_subset_node_free (GstMPDSubsetNode* self);

View file

@ -0,0 +1,110 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "gstmpdurltypenode.h"
#include "gstmpdparser.h"
G_DEFINE_TYPE (GstMPDURLTypeNode, gst_mpd_url_type_node, GST_TYPE_MPD_NODE);
/* GObject VMethods */
static void
gst_mpd_url_type_node_finalize (GObject * object)
{
GstMPDURLTypeNode *self = GST_MPD_URL_TYPE_NODE (object);
if (self->sourceURL)
xmlFree (self->sourceURL);
g_slice_free (GstXMLRange, self->range);
g_free (self->node_name);
G_OBJECT_CLASS (gst_mpd_url_type_node_parent_class)->finalize (object);
}
/* Base class */
static xmlNodePtr
gst_mpd_url_type_get_xml_node (GstMPDNode * node)
{
xmlNodePtr url_type_xml_node = NULL;
GstMPDURLTypeNode *self = GST_MPD_URL_TYPE_NODE (node);
url_type_xml_node = xmlNewNode (NULL, (xmlChar *) self->node_name);
gst_xml_helper_set_prop_string (url_type_xml_node, "sourceURL",
self->sourceURL);
gst_xml_helper_set_prop_range (url_type_xml_node, "range", self->range);
return url_type_xml_node;
}
static void
gst_mpd_url_type_node_class_init (GstMPDURLTypeNodeClass * klass)
{
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_url_type_node_finalize;
m_klass->get_xml_node = gst_mpd_url_type_get_xml_node;
}
static void
gst_mpd_url_type_node_init (GstMPDURLTypeNode * self)
{
self->node_name = NULL;
self->sourceURL = NULL;
self->range = NULL;
}
GstMPDURLTypeNode *
gst_mpd_url_type_node_new (const gchar * name)
{
GstMPDURLTypeNode *self = g_object_new (GST_TYPE_MPD_URL_TYPE_NODE, NULL);
self->node_name = g_strdup (name);
return self;
}
void
gst_mpd_url_type_node_free (GstMPDURLTypeNode * self)
{
if (self)
gst_object_unref (self);
}
GstMPDURLTypeNode *
gst_mpd_url_type_node_clone (GstMPDURLTypeNode * url)
{
GstMPDURLTypeNode *clone = NULL;
if (url) {
clone = gst_mpd_url_type_node_new (url->node_name);
if (url->sourceURL) {
clone->sourceURL = xmlMemStrdup (url->sourceURL);
}
clone->range = gst_xml_helper_clone_range (url->range);
}
return clone;
}

View file

@ -0,0 +1,47 @@
/* GStreamer
*
* Copyright (C) 2019 Collabora Ltd.
* Author: Stéphane Cerveau <scerveau@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library (COPYING); if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GSTMPDURLTYPENODE_H__
#define __GSTMPDURLTYPENODE_H__
#include <gst/gst.h>
#include "gstmpdnode.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_URL_TYPE_NODE gst_mpd_url_type_node_get_type ()
G_DECLARE_FINAL_TYPE (GstMPDURLTypeNode, gst_mpd_url_type_node, GST, MPD_URL_TYPE_NODE, GstMPDNode)
struct _GstMPDURLTypeNode
{
GstObject parent_instance;
gchar* node_name;
gchar *sourceURL;
GstXMLRange *range;
};
GstMPDURLTypeNode * gst_mpd_url_type_node_new (const gchar* name);
void gst_mpd_url_type_node_free (GstMPDURLTypeNode* self);
GstMPDURLTypeNode *gst_mpd_url_type_node_clone (GstMPDURLTypeNode * url);
G_END_DECLS
#endif /* __GSTMPDURLTYPENODE_H__ */

View file

@ -26,10 +26,33 @@ enum
PROP_MPD_UTCTIMING_0,
};
G_DEFINE_TYPE (GstMPDUTCTimingNode, gst_mpd_utctiming_node, GST_TYPE_OBJECT);
G_DEFINE_TYPE (GstMPDUTCTimingNode, gst_mpd_utctiming_node, GST_TYPE_MPD_NODE);
/* GObject VMethods */
static const struct GstMPDUTCTimingMethod gst_mpd_utctiming_methods[] = {
{"urn:mpeg:dash:utc:ntp:2014", GST_MPD_UTCTIMING_TYPE_NTP},
{"urn:mpeg:dash:utc:sntp:2014", GST_MPD_UTCTIMING_TYPE_SNTP},
{"urn:mpeg:dash:utc:http-head:2014", GST_MPD_UTCTIMING_TYPE_HTTP_HEAD},
{"urn:mpeg:dash:utc:http-xsdate:2014", GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE},
{"urn:mpeg:dash:utc:http-iso:2014", GST_MPD_UTCTIMING_TYPE_HTTP_ISO},
{"urn:mpeg:dash:utc:http-ntp:2014", GST_MPD_UTCTIMING_TYPE_HTTP_NTP},
{"urn:mpeg:dash:utc:direct:2014", GST_MPD_UTCTIMING_TYPE_DIRECT},
/*
* Early working drafts used the :2012 namespace and this namespace is
* used by some DASH packagers. To work-around these packagers, we also
* accept the early draft scheme names.
*/
{"urn:mpeg:dash:utc:ntp:2012", GST_MPD_UTCTIMING_TYPE_NTP},
{"urn:mpeg:dash:utc:sntp:2012", GST_MPD_UTCTIMING_TYPE_SNTP},
{"urn:mpeg:dash:utc:http-head:2012", GST_MPD_UTCTIMING_TYPE_HTTP_HEAD},
{"urn:mpeg:dash:utc:http-xsdate:2012", GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE},
{"urn:mpeg:dash:utc:http-iso:2012", GST_MPD_UTCTIMING_TYPE_HTTP_ISO},
{"urn:mpeg:dash:utc:http-ntp:2012", GST_MPD_UTCTIMING_TYPE_HTTP_NTP},
{"urn:mpeg:dash:utc:direct:2012", GST_MPD_UTCTIMING_TYPE_DIRECT},
{NULL, 0}
};
static void
gst_mpd_utctiming_node_finalize (GObject * object)
{
@ -40,11 +63,42 @@ gst_mpd_utctiming_node_finalize (GObject * object)
G_OBJECT_CLASS (gst_mpd_utctiming_node_parent_class)->finalize (object);
}
/* Base class */
static xmlNodePtr
gst_mpd_utc_timing_get_xml_node (GstMPDNode * node)
{
xmlNodePtr utc_timing_xml_node = NULL;
gchar *value = NULL;
GstMPDUTCTimingNode *self = GST_MPD_UTCTIMING_NODE (node);
utc_timing_xml_node = xmlNewNode (NULL, (xmlChar *) "UTCTiming");
if (self->method) {
gst_xml_helper_set_prop_string (utc_timing_xml_node, "schemeiduri",
(gchar *) gst_mpd_utctiming_get_scheme_id_uri (self->method));
}
if (self->urls) {
value = g_strjoinv (" ", self->urls);
gst_xml_helper_set_prop_string (utc_timing_xml_node, "value", value);
g_free (value);
}
return utc_timing_xml_node;
}
static void
gst_mpd_utctiming_node_class_init (GstMPDUTCTimingNodeClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass *object_class;
GstMPDNodeClass *m_klass;
object_class = G_OBJECT_CLASS (klass);
m_klass = GST_MPD_NODE_CLASS (klass);
object_class->finalize = gst_mpd_utctiming_node_finalize;
m_klass->get_xml_node = gst_mpd_utc_timing_get_xml_node;
}
static void
@ -66,3 +120,26 @@ gst_mpd_utctiming_node_free (GstMPDUTCTimingNode * self)
if (self)
gst_object_unref (self);
}
const gchar *
gst_mpd_utctiming_get_scheme_id_uri (GstMPDUTCTimingType type)
{
int i;
for (i = 0; gst_mpd_utctiming_methods[i].name; ++i) {
if (type == gst_mpd_utctiming_methods[i].method)
return gst_mpd_utctiming_methods[i].name;
}
return NULL;
}
GstMPDUTCTimingType
gst_mpd_utctiming_get_method (gchar * schemeIDURI)
{
int i;
for (i = 0; gst_mpd_utctiming_methods[i].name; ++i) {
if (g_ascii_strncasecmp (gst_mpd_utctiming_methods[i].name,
schemeIDURI, strlen (gst_mpd_utctiming_methods[i].name)) == 0)
return gst_mpd_utctiming_methods[i].method;
}
return GST_MPD_UTCTIMING_TYPE_UNKNOWN;
}

View file

@ -22,25 +22,12 @@
#define __GSTMPDUTCTIMINGNODE_H__
#include <gst/gst.h>
#include "gstxmlhelper.h"
#include "gstmpdnode.h"
G_BEGIN_DECLS
#define GST_TYPE_MPD_UTCTIMING_NODE gst_mpd_utctiming_node_get_type ()
#define GST_MPD_UTCTIMING_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPD_UTCTIMING_NODE, GstMPDUTCTimingNode))
#define GST_MPD_UTCTIMING_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MPD_UTCTIMING_NODE, GstMPDUTCTimingNodeClass))
#define GST_IS_MPD_UTCTIMING_NODE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPD_UTCTIMING_NODE))
#define GST_IS_MPD_UTCTIMING_NODE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MPD_UTCTIMING_NODE))
#define GST_MPD_UTCTIMING_NODE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MPD_UTCTIMING_NODE, GstMPDUTCTimingNodeClass))
typedef struct _GstMPDUTCTimingNode GstMPDUTCTimingNode;
typedef struct _GstMPDUTCTimingNodeClass GstMPDUTCTimingNodeClass;
G_DECLARE_FINAL_TYPE (GstMPDUTCTimingNode, gst_mpd_utctiming_node, GST, MPD_UTCTIMING_NODE, GstMPDNode)
typedef enum
{
@ -54,6 +41,12 @@ typedef enum
GST_MPD_UTCTIMING_TYPE_DIRECT = 0x40
} GstMPDUTCTimingType;
struct GstMPDUTCTimingMethod
{
const gchar *name;
GstMPDUTCTimingType method;
};
struct _GstMPDUTCTimingNode
{
GstObject parent_instance;
@ -63,16 +56,13 @@ struct _GstMPDUTCTimingNode
/* TODO add missing fields such as weight etc.*/
};
struct _GstMPDUTCTimingNodeClass {
GstObjectClass parent_class;
};
G_GNUC_INTERNAL GType gst_mpd_utctiming_node_get_type (void);
GstMPDUTCTimingNode * gst_mpd_utctiming_node_new (void);
void gst_mpd_utctiming_node_free (GstMPDUTCTimingNode* self);
const gchar* gst_mpd_utctiming_get_scheme_id_uri (GstMPDUTCTimingType type);
GstMPDUTCTimingType gst_mpd_utctiming_get_method (gchar* schemeIDURI);
G_END_DECLS
#endif /* __GSTMPDUTCTIMINGNODE_H__ */

View file

@ -21,6 +21,12 @@
#include "gstxmlhelper.h"
#define XML_HELPER_MINUTE_TO_SEC 60
#define XML_HELPER_HOUR_TO_SEC (60 * XML_HELPER_MINUTE_TO_SEC)
#define XML_HELPER_DAY_TO_SEC (24 * XML_HELPER_HOUR_TO_SEC)
#define XML_HELPER_MONTH_TO_SEC (30 * XML_HELPER_DAY_TO_SEC)
#define XML_HELPER_YEAR_TO_SEC (365 * XML_HELPER_DAY_TO_SEC)
#define XML_HELPER_MS_TO_SEC(time) ((time) / 1000)
/* static methods */
/* this function computes decimals * 10 ^ (3 - pos) */
static guint
@ -295,6 +301,34 @@ gst_xml_helper_clone_range (GstXMLRange * range)
return clone;
}
GstXMLRatio *
gst_xml_helper_clone_ratio (GstXMLRatio * ratio)
{
GstXMLRatio *clone = NULL;
if (ratio) {
clone = g_slice_new0 (GstXMLRatio);
clone->num = ratio->num;
clone->den = ratio->den;
}
return clone;
}
GstXMLFrameRate *
gst_xml_helper_clone_frame_rate (GstXMLFrameRate * frameRate)
{
GstXMLFrameRate *clone = NULL;
if (frameRate) {
clone = g_slice_new0 (GstXMLFrameRate);
clone->num = frameRate->num;
clone->den = frameRate->den;
}
return clone;
}
/* XML property get method */
gboolean
gst_xml_helper_get_prop_validated_string (xmlNode * a_node,
@ -1022,3 +1056,204 @@ gst_xml_helper_get_prop_string_no_whitespace (xmlNode * a_node,
return gst_xml_helper_get_prop_validated_string (a_node, property_name,
property_value, _mpd_helper_validate_no_whitespace);
}
/* XML property set method */
void
gst_xml_helper_set_prop_string (xmlNodePtr node, const gchar * name,
gchar * value)
{
if (value)
xmlSetProp (node, (xmlChar *) name, (xmlChar *) value);
}
void
gst_xml_helper_set_prop_boolean (xmlNodePtr node, const gchar * name,
gboolean value)
{
if (value)
xmlSetProp (node, (xmlChar *) name, (xmlChar *) "true");
else
xmlSetProp (node, (xmlChar *) name, (xmlChar *) "false");
}
void
gst_xml_helper_set_prop_int (xmlNodePtr node, const gchar * name, gint value)
{
gchar *text;
text = g_strdup_printf ("%d", value);
xmlSetProp (node, (xmlChar *) name, (xmlChar *) text);
g_free (text);
}
void
gst_xml_helper_set_prop_uint (xmlNodePtr node, const gchar * name, guint value)
{
gchar *text;
text = g_strdup_printf ("%d", value);
xmlSetProp (node, (xmlChar *) name, (xmlChar *) text);
g_free (text);
}
void
gst_xml_helper_set_prop_int64 (xmlNodePtr node, const gchar * name,
gint64 value)
{
gchar *text;
text = g_strdup_printf ("%" G_GINT64_FORMAT, value);
xmlSetProp (node, (xmlChar *) name, (xmlChar *) text);
g_free (text);
}
void
gst_xml_helper_set_prop_uint64 (xmlNodePtr node, const gchar * name,
guint64 value)
{
gchar *text;
text = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
xmlSetProp (node, (xmlChar *) name, (xmlChar *) text);
g_free (text);
}
void
gst_xml_helper_set_prop_double (xmlNodePtr node, const gchar * name,
gdouble value)
{
gchar *text;
text = g_strdup_printf ("%lf", value);
xmlSetProp (node, (xmlChar *) name, (xmlChar *) text);
g_free (text);
}
void
gst_xml_helper_set_prop_uint_vector_type (xmlNode * node, const gchar * name,
guint * value, guint value_size)
{
int i;
gchar *text = NULL;
gchar *prev;
gchar *temp;
for (i = 0; i < value_size; i++) {
temp = g_strdup_printf ("%d", value[i]);
prev = text;
text = g_strjoin (" ", text, prev, NULL);
g_free (prev);
g_free (temp);
}
if (text) {
xmlSetProp (node, (xmlChar *) name, (xmlChar *) text);
g_free (text);
}
}
void
gst_xml_helper_set_prop_date_time (xmlNodePtr node, const gchar * name,
GstDateTime * value)
{
gchar *text;
if (value) {
text = gst_date_time_to_iso8601_string (value);
xmlSetProp (node, (xmlChar *) name, (xmlChar *) text);
g_free (text);
}
}
void
gst_xml_helper_set_prop_duration (xmlNode * node, const gchar * name,
guint64 value)
{
gchar *text;
gint years, months, days, hours, minutes, seconds, milliseconds;
if (value) {
years = (gint) (XML_HELPER_MS_TO_SEC (value) / (XML_HELPER_YEAR_TO_SEC));
months =
(gint) ((XML_HELPER_MS_TO_SEC (value) % XML_HELPER_YEAR_TO_SEC) /
XML_HELPER_MONTH_TO_SEC);
days =
(gint) ((XML_HELPER_MS_TO_SEC (value) % XML_HELPER_MONTH_TO_SEC) /
XML_HELPER_DAY_TO_SEC);
hours =
(gint) ((XML_HELPER_MS_TO_SEC (value) % XML_HELPER_DAY_TO_SEC) /
XML_HELPER_HOUR_TO_SEC);
minutes =
(gint) ((XML_HELPER_MS_TO_SEC (value) % XML_HELPER_HOUR_TO_SEC) /
XML_HELPER_MINUTE_TO_SEC);
seconds = (gint) (XML_HELPER_MS_TO_SEC (value) % XML_HELPER_MINUTE_TO_SEC);
milliseconds = value % 1000;
text =
g_strdup_printf ("P%dY%dM%dDT%dH%dM%d.%dS", years, months, days, hours,
minutes, seconds, milliseconds);
GST_LOG ("duration %" G_GUINT64_FORMAT " -> %s", value, text);
xmlSetProp (node, (xmlChar *) name, (xmlChar *) text);
g_free (text);
}
}
void
gst_xml_helper_set_prop_ratio (xmlNodePtr node, const gchar * name,
GstXMLRatio * value)
{
gchar *text;
if (value) {
text = g_strdup_printf ("%d:%d", value->num, value->den);
xmlSetProp (node, (xmlChar *) name, (xmlChar *) text);
g_free (text);
}
}
void
gst_xml_helper_set_prop_framerate (xmlNodePtr node, const gchar * name,
GstXMLFrameRate * value)
{
gchar *text;
if (value) {
text = g_strdup_printf ("%d/%d", value->num, value->den);
xmlSetProp (node, (xmlChar *) name, (xmlChar *) text);
g_free (text);
}
}
void
gst_xml_helper_set_prop_range (xmlNodePtr node, const gchar * name,
GstXMLRange * value)
{
gchar *text;
if (value) {
text =
g_strdup_printf ("%" G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT,
value->first_byte_pos, value->last_byte_pos);
xmlSetProp (node, (xmlChar *) name, (xmlChar *) text);
g_free (text);
}
}
void
gst_xml_helper_set_prop_cond_uint (xmlNodePtr node, const gchar * name,
GstXMLConditionalUintType * cond)
{
gchar *text;
if (cond) {
if (cond->flag)
if (cond->value)
text = g_strdup_printf ("%d", cond->value);
else
text = g_strdup_printf ("%s", "true");
else
text = g_strdup_printf ("%s", "false");
xmlSetProp (node, (xmlChar *) name, (xmlChar *) text);
g_free (text);
}
}
void
gst_xml_helper_set_content (xmlNodePtr node, gchar * content)
{
if (content)
xmlNodeSetContent (node, (xmlChar *) content);
}

View file

@ -57,6 +57,8 @@ struct _GstXMLConditionalUintType
};
GstXMLRange *gst_xml_helper_clone_range (GstXMLRange * range);
GstXMLRatio *gst_xml_helper_clone_ratio (GstXMLRatio * ratio);
GstXMLFrameRate *gst_xml_helper_clone_frame_rate (GstXMLFrameRate * frameRate);
/* XML property get method */
gboolean gst_xml_helper_get_prop_validated_string (xmlNode * a_node,
@ -109,5 +111,22 @@ gchar *gst_xml_helper_get_node_namespace (xmlNode * a_node,
gboolean gst_xml_helper_get_node_as_string (xmlNode * a_node,
gchar ** content);
/* XML property set method */
void gst_xml_helper_set_prop_string (xmlNodePtr node, const gchar * name, gchar* value);
void gst_xml_helper_set_prop_boolean (xmlNodePtr node, const gchar * name, gboolean value);
void gst_xml_helper_set_prop_int (xmlNodePtr root, const gchar * name, gint value);
void gst_xml_helper_set_prop_uint (xmlNodePtr root, const gchar * name, guint value);
void gst_xml_helper_set_prop_int64 (xmlNodePtr node, const gchar * name, gint64 value);
void gst_xml_helper_set_prop_uint64 (xmlNodePtr node, const gchar * name, guint64 value);
void gst_xml_helper_set_prop_uint_vector_type (xmlNode * a_node, const gchar * name, guint * value, guint value_size);
void gst_xml_helper_set_prop_double (xmlNodePtr node, const gchar * name, gdouble value);
void gst_xml_helper_set_prop_date_time (xmlNodePtr node, const gchar * name, GstDateTime* value);
void gst_xml_helper_set_prop_duration (xmlNode * node, const gchar * name, guint64 value);
void gst_xml_helper_set_prop_ratio (xmlNodePtr node, const gchar * name, GstXMLRatio* value);
void gst_xml_helper_set_prop_framerate (xmlNodePtr node, const gchar * name, GstXMLFrameRate* value);
void gst_xml_helper_set_prop_range (xmlNodePtr node, const gchar * name, GstXMLRange* value);
void gst_xml_helper_set_prop_cond_uint (xmlNode * a_node, const gchar * property_name, GstXMLConditionalUintType * cond);
void gst_xml_helper_set_content (xmlNodePtr node, gchar * content);
G_END_DECLS
#endif /* __GST_XMLHELPER_H__ */

View file

@ -1,5 +1,6 @@
dash_sources = [
'gstdashdemux.c',
'gstmpdnode.c',
'gstmpdrootnode.c',
'gstmpdbaseurlnode.c',
'gstmpdutctimingnode.c',
@ -10,13 +11,20 @@ dash_sources = [
'gstmpdsegmenttemplatenode.c',
'gstmpdsegmenturlnode.c',
'gstmpdsegmentlistnode.c',
'gstmpdsegmentbasenode.c',
'gstmpdperiodnode.c',
'gstmpdrepresentationbasenode.c',
'gstmpdmultsegmentbasenode.c',
'gstmpdrepresentationnode.c',
'gstmpdsubrepresentationnode.c',
'gstmpdcontentcomponentnode.c',
'gstmpdadaptationsetnode.c',
'gstmpdsubsetnode.c',
'gstmpdprograminformationnode.c',
'gstmpdlocationnode.c',
'gstmpdreportingnode.c',
'gstmpdurltypenode.c',
'gstmpddescriptortypenode.c',
'gstxmlhelper.c',
'gstmpdhelper.c',
'gstmpdparser.c',

View file

@ -21,6 +21,9 @@
#include "../../ext/dash/gstmpdparser.c"
#include "../../ext/dash/gstxmlhelper.c"
#include "../../ext/dash/gstmpdhelper.c"
#include "../../ext/dash/gstmpdnode.c"
#include "../../ext/dash/gstmpdrepresentationbasenode.c"
#include "../../ext/dash/gstmpdmultsegmentbasenode.c"
#include "../../ext/dash/gstmpdrootnode.c"
#include "../../ext/dash/gstmpdbaseurlnode.c"
#include "../../ext/dash/gstmpdutctimingnode.c"
@ -31,6 +34,7 @@
#include "../../ext/dash/gstmpdsegmenttemplatenode.c"
#include "../../ext/dash/gstmpdsegmenturlnode.c"
#include "../../ext/dash/gstmpdsegmentlistnode.c"
#include "../../ext/dash/gstmpdsegmentbasenode.c"
#include "../../ext/dash/gstmpdperiodnode.c"
#include "../../ext/dash/gstmpdsubrepresentationnode.c"
#include "../../ext/dash/gstmpdrepresentationnode.c"
@ -38,6 +42,10 @@
#include "../../ext/dash/gstmpdadaptationsetnode.c"
#include "../../ext/dash/gstmpdsubsetnode.c"
#include "../../ext/dash/gstmpdprograminformationnode.c"
#include "../../ext/dash/gstmpdlocationnode.c"
#include "../../ext/dash/gstmpdreportingnode.c"
#include "../../ext/dash/gstmpdurltypenode.c"
#include "../../ext/dash/gstmpddescriptortypenode.c"
#include "../../ext/dash/gstmpdclient.c"
#undef GST_CAT_DEFAULT
@ -212,8 +220,8 @@ GST_START_TEST (dash_mpdparser_programInformation)
assert_equals_int (ret, TRUE);
program =
(GstMPDProgramInformationNode *) mpdclient->mpd_root_node->
ProgramInfos->data;
(GstMPDProgramInformationNode *) mpdclient->mpd_root_node->ProgramInfos->
data;
assert_equals_string (program->lang, "en");
assert_equals_string (program->moreInformationURL, "TestMoreInformationUrl");
assert_equals_string (program->Title, "TestTitle");
@ -261,7 +269,7 @@ GST_END_TEST;
*/
GST_START_TEST (dash_mpdparser_location)
{
const gchar *location;
GstMPDLocationNode *location;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -274,8 +282,8 @@ GST_START_TEST (dash_mpdparser_location)
ret = gst_mpd_client_parse (mpdclient, xml, (gint) strlen (xml));
assert_equals_int (ret, TRUE);
location = (gchar *) mpdclient->mpd_root_node->Locations->data;
assert_equals_string (location, "TestLocation");
location = (GstMPDLocationNode *) mpdclient->mpd_root_node->Locations->data;
assert_equals_string (location->location, "TestLocation");
gst_mpd_client_free (mpdclient);
}
@ -449,7 +457,7 @@ GST_END_TEST;
GST_START_TEST (dash_mpdparser_period_segmentBase)
{
GstMPDPeriodNode *periodNode;
GstMPDSegmentBaseType *segmentBase;
GstMPDSegmentBaseNode *segmentBase;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -487,8 +495,8 @@ GST_END_TEST;
GST_START_TEST (dash_mpdparser_period_segmentBase_initialization)
{
GstMPDPeriodNode *periodNode;
GstMPDSegmentBaseType *segmentBase;
GstMPDURLType *initialization;
GstMPDSegmentBaseNode *segmentBase;
GstMPDURLTypeNode *initialization;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -524,8 +532,8 @@ GST_END_TEST;
GST_START_TEST (dash_mpdparser_period_segmentBase_representationIndex)
{
GstMPDPeriodNode *periodNode;
GstMPDSegmentBaseType *segmentBase;
GstMPDURLType *representationIndex;
GstMPDSegmentBaseNode *segmentBase;
GstMPDURLTypeNode *representationIndex;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -591,7 +599,7 @@ GST_START_TEST (dash_mpdparser_period_segmentList_multipleSegmentBaseType)
{
GstMPDPeriodNode *periodNode;
GstMPDSegmentListNode *segmentList;
GstMPDMultSegmentBaseType *multSegBaseType;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -609,9 +617,11 @@ GST_START_TEST (dash_mpdparser_period_segmentList_multipleSegmentBaseType)
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
segmentList = periodNode->SegmentList;
multSegBaseType = segmentList->MultSegBaseType;
assert_equals_uint64 (multSegBaseType->duration, 10);
assert_equals_uint64 (multSegBaseType->startNumber, 11);
assert_equals_uint64 (GST_MPD_MULT_SEGMENT_BASE_NODE (segmentList)->duration,
10);
assert_equals_uint64 (GST_MPD_MULT_SEGMENT_BASE_NODE
(segmentList)->startNumber, 11);
gst_mpd_client_free (mpdclient);
}
@ -627,8 +637,7 @@ GST_START_TEST
{
GstMPDPeriodNode *periodNode;
GstMPDSegmentListNode *segmentList;
GstMPDMultSegmentBaseType *multSegBaseType;
GstMPDSegmentBaseType *segBaseType;
GstMPDSegmentBaseNode *segmentBase;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -649,13 +658,12 @@ GST_START_TEST
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
segmentList = periodNode->SegmentList;
multSegBaseType = segmentList->MultSegBaseType;
segBaseType = multSegBaseType->SegBaseType;
assert_equals_uint64 (segBaseType->timescale, 10);
assert_equals_uint64 (segBaseType->presentationTimeOffset, 11);
assert_equals_uint64 (segBaseType->indexRange->first_byte_pos, 20);
assert_equals_uint64 (segBaseType->indexRange->last_byte_pos, 21);
assert_equals_int (segBaseType->indexRangeExact, FALSE);
segmentBase = GST_MPD_MULT_SEGMENT_BASE_NODE (segmentList)->SegmentBase;
assert_equals_uint64 (segmentBase->timescale, 10);
assert_equals_uint64 (segmentBase->presentationTimeOffset, 11);
assert_equals_uint64 (segmentBase->indexRange->first_byte_pos, 20);
assert_equals_uint64 (segmentBase->indexRange->last_byte_pos, 21);
assert_equals_int (segmentBase->indexRangeExact, FALSE);
gst_mpd_client_free (mpdclient);
}
@ -671,7 +679,6 @@ GST_START_TEST
{
GstMPDPeriodNode *periodNode;
GstMPDSegmentListNode *segmentList;
GstMPDMultSegmentBaseType *multSegBaseType;
GstMPDSegmentTimelineNode *segmentTimeline;
const gchar *xml =
"<?xml version=\"1.0\"?>"
@ -690,8 +697,8 @@ GST_START_TEST
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
segmentList = periodNode->SegmentList;
multSegBaseType = segmentList->MultSegBaseType;
segmentTimeline = multSegBaseType->SegmentTimeline;
segmentTimeline =
GST_MPD_MULT_SEGMENT_BASE_NODE (segmentList)->SegmentTimeline;
fail_if (segmentTimeline == NULL);
gst_mpd_client_free (mpdclient);
@ -708,7 +715,6 @@ GST_START_TEST
{
GstMPDPeriodNode *periodNode;
GstMPDSegmentListNode *segmentList;
GstMPDMultSegmentBaseType *multSegBaseType;
GstMPDSegmentTimelineNode *segmentTimeline;
GstMPDSNode *sNode;
const gchar *xml =
@ -729,8 +735,8 @@ GST_START_TEST
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
segmentList = periodNode->SegmentList;
multSegBaseType = segmentList->MultSegBaseType;
segmentTimeline = multSegBaseType->SegmentTimeline;
segmentTimeline =
GST_MPD_MULT_SEGMENT_BASE_NODE (segmentList)->SegmentTimeline;
sNode = (GstMPDSNode *) g_queue_peek_head (&segmentTimeline->S);
assert_equals_uint64 (sNode->t, 1);
assert_equals_uint64 (sNode->d, 2);
@ -750,8 +756,7 @@ GST_START_TEST
{
GstMPDPeriodNode *periodNode;
GstMPDSegmentListNode *segmentList;
GstMPDMultSegmentBaseType *multSegBaseType;
GstMPDURLType *bitstreamSwitching;
GstMPDURLTypeNode *bitstreamSwitching;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -770,8 +775,9 @@ GST_START_TEST
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
segmentList = periodNode->SegmentList;
multSegBaseType = segmentList->MultSegBaseType;
bitstreamSwitching = multSegBaseType->BitstreamSwitching;
bitstreamSwitching =
GST_MPD_MULT_SEGMENT_BASE_NODE (segmentList)->BitstreamSwitching;
assert_equals_string (bitstreamSwitching->sourceURL, "TestSourceURL");
assert_equals_uint64 (bitstreamSwitching->range->first_byte_pos, 100);
assert_equals_uint64 (bitstreamSwitching->range->last_byte_pos, 200);
@ -962,7 +968,6 @@ GST_START_TEST (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType)
{
GstMPDPeriodNode *periodNode;
GstMPDSegmentTemplateNode *segmentTemplate;
GstMPDMultSegmentBaseType *multSegBaseType;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -980,9 +985,11 @@ GST_START_TEST (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType)
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
segmentTemplate = periodNode->SegmentTemplate;
multSegBaseType = segmentTemplate->MultSegBaseType;
assert_equals_uint64 (multSegBaseType->duration, 10);
assert_equals_uint64 (multSegBaseType->startNumber, 11);
assert_equals_uint64 (GST_MPD_MULT_SEGMENT_BASE_NODE
(segmentTemplate)->duration, 10);
assert_equals_uint64 (GST_MPD_MULT_SEGMENT_BASE_NODE
(segmentTemplate)->startNumber, 11);
gst_mpd_client_free (mpdclient);
}
@ -998,8 +1005,7 @@ GST_START_TEST
{
GstMPDPeriodNode *periodNode;
GstMPDSegmentTemplateNode *segmentTemplate;
GstMPDMultSegmentBaseType *multSegBaseType;
GstMPDSegmentBaseType *segBaseType;
GstMPDSegmentBaseNode *segmentBase;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1020,13 +1026,12 @@ GST_START_TEST
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
segmentTemplate = periodNode->SegmentTemplate;
multSegBaseType = segmentTemplate->MultSegBaseType;
segBaseType = multSegBaseType->SegBaseType;
assert_equals_uint64 (segBaseType->timescale, 123456);
assert_equals_uint64 (segBaseType->presentationTimeOffset, 123456789);
assert_equals_uint64 (segBaseType->indexRange->first_byte_pos, 100);
assert_equals_uint64 (segBaseType->indexRange->last_byte_pos, 200);
assert_equals_int (segBaseType->indexRangeExact, TRUE);
segmentBase = GST_MPD_MULT_SEGMENT_BASE_NODE (segmentTemplate)->SegmentBase;
assert_equals_uint64 (segmentBase->timescale, 123456);
assert_equals_uint64 (segmentBase->presentationTimeOffset, 123456789);
assert_equals_uint64 (segmentBase->indexRange->first_byte_pos, 100);
assert_equals_uint64 (segmentBase->indexRange->last_byte_pos, 200);
assert_equals_int (segmentBase->indexRangeExact, TRUE);
gst_mpd_client_free (mpdclient);
}
@ -1042,7 +1047,6 @@ GST_START_TEST
{
GstMPDPeriodNode *periodNode;
GstMPDSegmentTemplateNode *segmentTemplate;
GstMPDMultSegmentBaseType *multSegBaseType;
GstMPDSegmentTimelineNode *segmentTimeline;
const gchar *xml =
"<?xml version=\"1.0\"?>"
@ -1061,9 +1065,9 @@ GST_START_TEST
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
segmentTemplate = periodNode->SegmentTemplate;
multSegBaseType = segmentTemplate->MultSegBaseType;
segmentTimeline =
(GstMPDSegmentTimelineNode *) multSegBaseType->SegmentTimeline;
segmentTimeline = (GstMPDSegmentTimelineNode *)
GST_MPD_MULT_SEGMENT_BASE_NODE (segmentTemplate)->SegmentTimeline;
fail_if (segmentTimeline == NULL);
gst_mpd_client_free (mpdclient);
@ -1080,7 +1084,6 @@ GST_START_TEST
{
GstMPDPeriodNode *periodNode;
GstMPDSegmentTemplateNode *segmentTemplate;
GstMPDMultSegmentBaseType *multSegBaseType;
GstMPDSegmentTimelineNode *segmentTimeline;
GstMPDSNode *sNode;
const gchar *xml =
@ -1101,9 +1104,8 @@ GST_START_TEST
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
segmentTemplate = periodNode->SegmentTemplate;
multSegBaseType = segmentTemplate->MultSegBaseType;
segmentTimeline =
(GstMPDSegmentTimelineNode *) multSegBaseType->SegmentTimeline;
segmentTimeline = (GstMPDSegmentTimelineNode *)
GST_MPD_MULT_SEGMENT_BASE_NODE (segmentTemplate)->SegmentTimeline;
sNode = (GstMPDSNode *) g_queue_peek_head (&segmentTimeline->S);
assert_equals_uint64 (sNode->t, 1);
assert_equals_uint64 (sNode->d, 2);
@ -1123,8 +1125,7 @@ GST_START_TEST
{
GstMPDPeriodNode *periodNode;
GstMPDSegmentTemplateNode *segmentTemplate;
GstMPDMultSegmentBaseType *multSegBaseType;
GstMPDURLType *bitstreamSwitching;
GstMPDURLTypeNode *bitstreamSwitching;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1143,8 +1144,8 @@ GST_START_TEST
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
segmentTemplate = periodNode->SegmentTemplate;
multSegBaseType = segmentTemplate->MultSegBaseType;
bitstreamSwitching = multSegBaseType->BitstreamSwitching;
bitstreamSwitching =
GST_MPD_MULT_SEGMENT_BASE_NODE (segmentTemplate)->BitstreamSwitching;
assert_equals_string (bitstreamSwitching->sourceURL, "TestSourceURL");
assert_equals_uint64 (bitstreamSwitching->range->first_byte_pos, 100);
assert_equals_uint64 (bitstreamSwitching->range->last_byte_pos, 200);
@ -1206,14 +1207,14 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet)
assert_equals_uint64 (adaptationSet->maxWidth, 2000);
assert_equals_uint64 (adaptationSet->minHeight, 1100);
assert_equals_uint64 (adaptationSet->maxHeight, 2100);
assert_equals_uint64 (adaptationSet->RepresentationBase->minFrameRate->num,
25);
assert_equals_uint64 (adaptationSet->RepresentationBase->minFrameRate->den,
123);
assert_equals_uint64 (adaptationSet->RepresentationBase->maxFrameRate->num,
26);
assert_equals_uint64 (adaptationSet->RepresentationBase->maxFrameRate->den,
1);
assert_equals_uint64 (GST_MPD_REPRESENTATION_BASE_NODE
(adaptationSet)->minFrameRate->num, 25);
assert_equals_uint64 (GST_MPD_REPRESENTATION_BASE_NODE
(adaptationSet)->minFrameRate->den, 123);
assert_equals_uint64 (GST_MPD_REPRESENTATION_BASE_NODE
(adaptationSet)->maxFrameRate->num, 26);
assert_equals_uint64 (GST_MPD_REPRESENTATION_BASE_NODE
(adaptationSet)->maxFrameRate->den, 1);
assert_equals_int (adaptationSet->segmentAlignment->flag, 1);
assert_equals_uint64 (adaptationSet->segmentAlignment->value, 2);
assert_equals_int (adaptationSet->subsegmentAlignment->flag, 0);
@ -1234,7 +1235,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_representationBase)
{
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDRepresentationBaseType *representationBase;
GstMPDRepresentationBaseNode *representationBase;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1264,7 +1265,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_representationBase)
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
representationBase = adaptationSet->RepresentationBase;
representationBase = GST_MPD_REPRESENTATION_BASE_NODE (adaptationSet);
assert_equals_string (representationBase->profiles, "TestProfiles");
assert_equals_uint64 (representationBase->width, 100);
assert_equals_uint64 (representationBase->height, 200);
@ -1297,8 +1298,8 @@ GST_START_TEST
(dash_mpdparser_period_adaptationSet_representationBase_framePacking) {
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDRepresentationBaseType *representationBase;
GstMPDDescriptorType *framePacking;
GstMPDRepresentationBaseNode *representationBase;
GstMPDDescriptorTypeNode *framePacking;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1317,9 +1318,9 @@ GST_START_TEST
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
representationBase = adaptationSet->RepresentationBase;
representationBase = GST_MPD_REPRESENTATION_BASE_NODE (adaptationSet);
framePacking =
(GstMPDDescriptorType *) representationBase->FramePacking->data;
(GstMPDDescriptorTypeNode *) representationBase->FramePacking->data;
assert_equals_string (framePacking->schemeIdUri, "TestSchemeIdUri");
assert_equals_string (framePacking->value, "TestValue");
@ -1337,8 +1338,8 @@ GST_START_TEST
{
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDRepresentationBaseType *representationBase;
GstMPDDescriptorType *audioChannelConfiguration;
GstMPDRepresentationBaseNode *representationBase;
GstMPDDescriptorTypeNode *audioChannelConfiguration;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1357,10 +1358,9 @@ GST_START_TEST
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
representationBase = adaptationSet->RepresentationBase;
audioChannelConfiguration =
(GstMPDDescriptorType *) representationBase->
AudioChannelConfiguration->data;
representationBase = GST_MPD_REPRESENTATION_BASE_NODE (adaptationSet);
audioChannelConfiguration = (GstMPDDescriptorTypeNode *)
representationBase->AudioChannelConfiguration->data;
assert_equals_string (audioChannelConfiguration->schemeIdUri,
"TestSchemeIdUri");
assert_equals_string (audioChannelConfiguration->value, "TestValue");
@ -1378,8 +1378,8 @@ GST_START_TEST
(dash_mpdparser_period_adaptationSet_representationBase_contentProtection) {
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDRepresentationBaseType *representationBase;
GstMPDDescriptorType *contentProtection;
GstMPDRepresentationBaseNode *representationBase;
GstMPDDescriptorTypeNode *contentProtection;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1398,9 +1398,9 @@ GST_START_TEST
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
representationBase = adaptationSet->RepresentationBase;
representationBase = GST_MPD_REPRESENTATION_BASE_NODE (adaptationSet);
contentProtection =
(GstMPDDescriptorType *) representationBase->ContentProtection->data;
(GstMPDDescriptorTypeNode *) representationBase->ContentProtection->data;
assert_equals_string (contentProtection->schemeIdUri, "TestSchemeIdUri");
assert_equals_string (contentProtection->value, "TestValue");
@ -1416,8 +1416,8 @@ GST_START_TEST (dash_mpdparser_contentProtection_no_value)
{
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDRepresentationBaseType *representationBase;
GstMPDDescriptorType *contentProtection;
GstMPDRepresentationBaseNode *representationBase;
GstMPDDescriptorTypeNode *contentProtection;
const gchar *xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1444,9 +1444,9 @@ GST_START_TEST (dash_mpdparser_contentProtection_no_value)
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
representationBase = adaptationSet->RepresentationBase;
representationBase = GST_MPD_REPRESENTATION_BASE_NODE (adaptationSet);
assert_equals_int (g_list_length (representationBase->ContentProtection), 3);
contentProtection = (GstMPDDescriptorType *)
contentProtection = (GstMPDDescriptorTypeNode *)
g_list_nth (representationBase->ContentProtection, 1)->data;
assert_equals_string (contentProtection->schemeIdUri,
"urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4");
@ -1479,8 +1479,8 @@ GST_START_TEST (dash_mpdparser_contentProtection_no_value_no_encoding)
{
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDRepresentationBaseType *representationBase;
GstMPDDescriptorType *contentProtection;
GstMPDRepresentationBaseNode *representationBase;
GstMPDDescriptorTypeNode *contentProtection;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1502,9 +1502,9 @@ GST_START_TEST (dash_mpdparser_contentProtection_no_value_no_encoding)
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
representationBase = adaptationSet->RepresentationBase;
representationBase = GST_MPD_REPRESENTATION_BASE_NODE (adaptationSet);
assert_equals_int (g_list_length (representationBase->ContentProtection), 2);
contentProtection = (GstMPDDescriptorType *)
contentProtection = (GstMPDDescriptorTypeNode *)
g_list_nth (representationBase->ContentProtection, 1)->data;
assert_equals_string (contentProtection->schemeIdUri,
"urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4");
@ -1522,7 +1522,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_accessibility)
{
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDDescriptorType *accessibility;
GstMPDDescriptorTypeNode *accessibility;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1541,7 +1541,8 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_accessibility)
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
accessibility = (GstMPDDescriptorType *) adaptationSet->Accessibility->data;
accessibility =
(GstMPDDescriptorTypeNode *) adaptationSet->Accessibility->data;
assert_equals_string (accessibility->schemeIdUri, "TestSchemeIdUri");
assert_equals_string (accessibility->value, "TestValue");
@ -1558,7 +1559,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_role)
{
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDDescriptorType *role;
GstMPDDescriptorTypeNode *role;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1577,7 +1578,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_role)
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
role = (GstMPDDescriptorType *) adaptationSet->Role->data;
role = (GstMPDDescriptorTypeNode *) adaptationSet->Role->data;
assert_equals_string (role->schemeIdUri, "TestSchemeIdUri");
assert_equals_string (role->value, "TestValue");
@ -1594,7 +1595,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_rating)
{
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDDescriptorType *rating;
GstMPDDescriptorTypeNode *rating;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1613,7 +1614,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_rating)
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
rating = (GstMPDDescriptorType *) adaptationSet->Rating->data;
rating = (GstMPDDescriptorTypeNode *) adaptationSet->Rating->data;
assert_equals_string (rating->schemeIdUri, "TestSchemeIdUri");
assert_equals_string (rating->value, "TestValue");
@ -1630,7 +1631,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_viewpoint)
{
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDDescriptorType *viewpoint;
GstMPDDescriptorTypeNode *viewpoint;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1649,7 +1650,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_viewpoint)
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
viewpoint = (GstMPDDescriptorType *) adaptationSet->Viewpoint->data;
viewpoint = (GstMPDDescriptorTypeNode *) adaptationSet->Viewpoint->data;
assert_equals_string (viewpoint->schemeIdUri, "TestSchemeIdUri");
assert_equals_string (viewpoint->value, "TestValue");
@ -1709,7 +1710,7 @@ GST_START_TEST
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDContentComponentNode *contentComponent;
GstMPDDescriptorType *accessibility;
GstMPDDescriptorTypeNode *accessibility;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1733,7 +1734,7 @@ GST_START_TEST
contentComponent = (GstMPDContentComponentNode *)
adaptationSet->ContentComponents->data;
accessibility =
(GstMPDDescriptorType *) contentComponent->Accessibility->data;
(GstMPDDescriptorTypeNode *) contentComponent->Accessibility->data;
assert_equals_string (accessibility->schemeIdUri, "TestSchemeIdUri");
assert_equals_string (accessibility->value, "TestValue");
@ -1751,7 +1752,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent_role)
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDContentComponentNode *contentComponent;
GstMPDDescriptorType *role;
GstMPDDescriptorTypeNode *role;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1773,7 +1774,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent_role)
adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
contentComponent = (GstMPDContentComponentNode *)
adaptationSet->ContentComponents->data;
role = (GstMPDDescriptorType *) contentComponent->Role->data;
role = (GstMPDDescriptorTypeNode *) contentComponent->Role->data;
assert_equals_string (role->schemeIdUri, "TestSchemeIdUri");
assert_equals_string (role->value, "TestValue");
@ -1791,7 +1792,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent_rating)
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDContentComponentNode *contentComponent;
GstMPDDescriptorType *rating;
GstMPDDescriptorTypeNode *rating;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1814,7 +1815,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent_rating)
adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
contentComponent = (GstMPDContentComponentNode *)
adaptationSet->ContentComponents->data;
rating = (GstMPDDescriptorType *) contentComponent->Rating->data;
rating = (GstMPDDescriptorTypeNode *) contentComponent->Rating->data;
assert_equals_string (rating->schemeIdUri, "TestSchemeIdUri");
assert_equals_string (rating->value, "TestValue");
@ -1832,7 +1833,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent_viewpoint)
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDContentComponentNode *contentComponent;
GstMPDDescriptorType *viewpoint;
GstMPDDescriptorTypeNode *viewpoint;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1855,7 +1856,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent_viewpoint)
adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
contentComponent = (GstMPDContentComponentNode *)
adaptationSet->ContentComponents->data;
viewpoint = (GstMPDDescriptorType *) contentComponent->Viewpoint->data;
viewpoint = (GstMPDDescriptorTypeNode *) contentComponent->Viewpoint->data;
assert_equals_string (viewpoint->schemeIdUri, "TestSchemeIdUri");
assert_equals_string (viewpoint->value, "TestValue");
@ -1909,7 +1910,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentBase)
{
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDSegmentBaseType *segmentBase;
GstMPDSegmentBaseNode *segmentBase;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1950,8 +1951,8 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentBase_initialization)
{
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDSegmentBaseType *segmentBase;
GstMPDURLType *initialization;
GstMPDSegmentBaseNode *segmentBase;
GstMPDURLTypeNode *initialization;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -1990,8 +1991,8 @@ GST_START_TEST
(dash_mpdparser_period_adaptationSet_segmentBase_representationIndex) {
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDSegmentBaseType *segmentBase;
GstMPDURLType *representationIndex;
GstMPDSegmentBaseNode *segmentBase;
GstMPDURLTypeNode *representationIndex;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -2149,7 +2150,7 @@ GST_START_TEST
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDRepresentationNode *representation;
GstMPDSegmentBaseType *segmentBase;
GstMPDSegmentBaseNode *segmentBase;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -2195,8 +2196,7 @@ GST_START_TEST (dash_mpdparser_adapt_repr_segmentTemplate_inherit)
GstMPDAdaptationSetNode *adaptationSet;
GstMPDSegmentTemplateNode *segmentTemplate;
GstMPDRepresentationNode *representation;
GstMPDMultSegmentBaseType *multSegBaseType;
GstMPDSegmentBaseType *segBaseType;
GstMPDSegmentBaseNode *segmentBase;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -2221,12 +2221,13 @@ GST_START_TEST (dash_mpdparser_adapt_repr_segmentTemplate_inherit)
adaptationSet->Representations->data;
segmentTemplate = representation->SegmentTemplate;
fail_if (segmentTemplate == NULL);
multSegBaseType = segmentTemplate->MultSegBaseType;
segBaseType = multSegBaseType->SegBaseType;
segmentBase = GST_MPD_MULT_SEGMENT_BASE_NODE (segmentTemplate)->SegmentBase;
assert_equals_uint64 (segBaseType->timescale, 12800);
assert_equals_uint64 (multSegBaseType->duration, 25600);
assert_equals_uint64 (multSegBaseType->startNumber, 1);
assert_equals_uint64 (segmentBase->timescale, 12800);
assert_equals_uint64 (GST_MPD_MULT_SEGMENT_BASE_NODE
(segmentTemplate)->duration, 25600);
assert_equals_uint64 (GST_MPD_MULT_SEGMENT_BASE_NODE
(segmentTemplate)->startNumber, 1);
assert_equals_string (segmentTemplate->media, "track1_$Number$.m4s");
assert_equals_string (segmentTemplate->initialization, "set1_init.mp4");
@ -2334,7 +2335,7 @@ GST_START_TEST
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDRepresentationNode *representation;
GstMPDRepresentationBaseType *representationBase;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -2354,9 +2355,8 @@ GST_START_TEST
adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
representation = (GstMPDRepresentationNode *)
adaptationSet->Representations->data;
representationBase = (GstMPDRepresentationBaseType *)
representation->RepresentationBase;
fail_if (representationBase == NULL);
fail_if (representation == NULL);
gst_mpd_client_free (mpdclient);
}
@ -2441,7 +2441,7 @@ GST_START_TEST
subRepresentation = (GstMPDSubRepresentationNode *)
representation->SubRepresentations->data;
assert_equals_uint64 (subRepresentation->level, 100);
assert_equals_uint64 (subRepresentation->size, 3);
assert_equals_uint64 (subRepresentation->dependencyLevel_size, 3);
assert_equals_uint64 (subRepresentation->dependencyLevel[0], 1);
assert_equals_uint64 (subRepresentation->dependencyLevel[1], 2);
assert_equals_uint64 (subRepresentation->dependencyLevel[2], 3);
@ -2466,7 +2466,7 @@ GST_START_TEST
GstMPDAdaptationSetNode *adaptationSet;
GstMPDRepresentationNode *representation;
GstMPDSubRepresentationNode *subRepresentation;
GstMPDRepresentationBaseType *representationBase;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -2490,9 +2490,8 @@ GST_START_TEST
adaptationSet->Representations->data;
subRepresentation = (GstMPDSubRepresentationNode *)
representation->SubRepresentations->data;
representationBase = (GstMPDRepresentationBaseType *)
subRepresentation->RepresentationBase;
fail_if (representationBase == NULL);
fail_if (subRepresentation == NULL);
gst_mpd_client_free (mpdclient);
}
@ -2508,7 +2507,7 @@ GST_START_TEST (dash_mpdparser_period_adaptationSet_representation_segmentBase)
GstMPDPeriodNode *periodNode;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDRepresentationNode *representation;
GstMPDSegmentBaseType *segmentBase;
GstMPDSegmentBaseNode *segmentBase;
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
@ -2638,7 +2637,7 @@ GST_START_TEST (dash_mpdparser_period_subset)
periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
subset = (GstMPDSubsetNode *) periodNode->Subsets->data;
assert_equals_uint64 (subset->size, 3);
assert_equals_uint64 (subset->contains_size, 3);
assert_equals_uint64 (subset->contains[0], 1);
assert_equals_uint64 (subset->contains[1], 2);
assert_equals_uint64 (subset->contains[2], 3);
@ -4479,7 +4478,7 @@ GST_END_TEST;
GST_START_TEST (dash_mpdparser_inherited_segmentBase)
{
GstMPDPeriodNode *periodNode;
GstMPDSegmentBaseType *segmentBase;
GstMPDSegmentBaseNode *segmentBase;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDRepresentationNode *representation;
const gchar *xml =
@ -5446,7 +5445,7 @@ GST_END_TEST;
GST_START_TEST (dash_mpdparser_read_unsigned_from_negative_values)
{
GstMPDPeriodNode *periodNode;
GstMPDSegmentBaseType *segmentBase;
GstMPDSegmentBaseNode *segmentBase;
GstMPDAdaptationSetNode *adaptationSet;
GstMPDRepresentationNode *representation;
GstMPDSubRepresentationNode *subRepresentation;
@ -5501,7 +5500,8 @@ GST_START_TEST (dash_mpdparser_read_unsigned_from_negative_values)
fail_if (adaptationSet->par != NULL);
/* minFrameRate parsing should fail */
fail_if (adaptationSet->RepresentationBase->minFrameRate != NULL);
fail_if (GST_MPD_REPRESENTATION_BASE_NODE (adaptationSet)->minFrameRate !=
NULL);
/* segmentAlignment parsing should fail */
fail_if (adaptationSet->segmentAlignment != NULL);
@ -5960,7 +5960,157 @@ GST_START_TEST (dash_mpdparser_datetime_with_tz_offset)
GST_END_TEST;
/*
* Test generate xml content.
*
*/
GST_START_TEST (dash_mpdparser_check_mpd_xml_generator)
{
const gchar *xml =
"<?xml version=\"1.0\"?>"
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
" profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
" schemaLocation=\"TestSchemaLocation\""
" xmlns:xsi=\"TestNamespaceXSI\""
" xmlns:ext=\"TestNamespaceEXT\""
" id=\"testId\""
" type=\"static\""
" availabilityStartTime=\"2015-03-24T1:10:50+08:00\""
" availabilityEndTime=\"2015-03-24T1:10:50.123456-04:30\""
" mediaPresentationDuration=\"P0Y1M2DT12H10M20.5S\""
" minimumUpdatePeriod=\"P0Y1M2DT12H10M20.5S\""
" minBufferTime=\"P0Y1M2DT12H10M20.5S\""
" timeShiftBufferDepth=\"P0Y1M2DT12H10M20.5S\""
" suggestedPresentationDelay=\"P0Y1M2DT12H10M20.5S\""
" maxSegmentDuration=\"P0Y1M2DT12H10M20.5S\""
" maxSubsegmentDuration=\"P0Y1M2DT12H10M20.5S\">"
" <BaseURL serviceLocation=\"TestServiceLocation\""
" byteRange=\"TestByteRange\">TestBaseURL</BaseURL>"
" <Location>TestLocation</Location>"
" <ProgramInformation lang=\"en\""
" moreInformationURL=\"TestMoreInformationUrl\">"
" <Title>TestTitle</Title>"
" <Source>TestSource</Source>"
" <Copyright>TestCopyright</Copyright>"
" </ProgramInformation>"
" <Metrics metrics=\"TestMetric\"><Range starttime=\"P0Y1M2DT12H10M20.5S\""
" duration=\"P0Y1M2DT12H10M20.1234567S\">"
" </Range></Metrics>"
" <Period>"
" <AdaptationSet>"
" <Representation id=\"1\" bandwidth=\"250000\">"
" <SegmentTemplate duration=\"1\">"
" </SegmentTemplate>"
" </Representation></AdaptationSet></Period>" " </MPD>";
gboolean ret;
gchar *new_xml;
gint new_xml_size;
GstMPDClient *first_mpdclient = NULL;
GstMPDClient *second_mpdclient = NULL;
GstMPDBaseURLNode *first_baseURL, *second_baseURL;
GstMPDLocationNode *first_location, *second_location;
GstMPDProgramInformationNode *first_prog_info, *second_prog_info;
GstMPDMetricsNode *first_metrics, *second_metrics;
GstMPDMetricsRangeNode *first_metrics_range, *second_metrics_range;
first_mpdclient = gst_mpd_client_new ();
ret = gst_mpd_client_parse (first_mpdclient, xml, (gint) strlen (xml));
assert_equals_int (ret, TRUE);
gst_mpd_client_get_xml_content (first_mpdclient, &new_xml, &new_xml_size);
second_mpdclient = gst_mpd_client_new ();
ret = gst_mpd_client_parse (second_mpdclient, new_xml, new_xml_size);
assert_equals_int (ret, TRUE);
g_free (new_xml);
/* assert that parameters are equal */
assert_equals_string (first_mpdclient->mpd_root_node->default_namespace,
second_mpdclient->mpd_root_node->default_namespace);
assert_equals_string (first_mpdclient->mpd_root_node->namespace_xsi,
second_mpdclient->mpd_root_node->namespace_xsi);
assert_equals_string (first_mpdclient->mpd_root_node->namespace_ext,
second_mpdclient->mpd_root_node->namespace_ext);
assert_equals_string (first_mpdclient->mpd_root_node->schemaLocation,
second_mpdclient->mpd_root_node->schemaLocation);
assert_equals_string (first_mpdclient->mpd_root_node->id,
second_mpdclient->mpd_root_node->id);
assert_equals_string (first_mpdclient->mpd_root_node->profiles,
second_mpdclient->mpd_root_node->profiles);
assert_equals_uint64 (first_mpdclient->
mpd_root_node->mediaPresentationDuration,
second_mpdclient->mpd_root_node->mediaPresentationDuration);
assert_equals_uint64 (first_mpdclient->mpd_root_node->minimumUpdatePeriod,
second_mpdclient->mpd_root_node->minimumUpdatePeriod);
assert_equals_uint64 (first_mpdclient->mpd_root_node->minBufferTime,
second_mpdclient->mpd_root_node->minBufferTime);
assert_equals_uint64 (first_mpdclient->mpd_root_node->timeShiftBufferDepth,
second_mpdclient->mpd_root_node->timeShiftBufferDepth);
assert_equals_uint64 (first_mpdclient->
mpd_root_node->suggestedPresentationDelay,
second_mpdclient->mpd_root_node->suggestedPresentationDelay);
assert_equals_uint64 (first_mpdclient->mpd_root_node->maxSegmentDuration,
second_mpdclient->mpd_root_node->maxSegmentDuration);
assert_equals_uint64 (first_mpdclient->mpd_root_node->maxSubsegmentDuration,
second_mpdclient->mpd_root_node->maxSubsegmentDuration);
/* baseURLs */
first_baseURL =
(GstMPDBaseURLNode *) first_mpdclient->mpd_root_node->BaseURLs->data;
second_baseURL =
(GstMPDBaseURLNode *) second_mpdclient->mpd_root_node->BaseURLs->data;
assert_equals_string (first_baseURL->baseURL, second_baseURL->baseURL);
assert_equals_string (first_baseURL->serviceLocation,
second_baseURL->serviceLocation);
assert_equals_string (first_baseURL->byteRange, second_baseURL->byteRange);
/* locations */
first_location =
(GstMPDLocationNode *) first_mpdclient->mpd_root_node->Locations->data;
second_location =
(GstMPDLocationNode *) second_mpdclient->mpd_root_node->Locations->data;
assert_equals_string (first_location->location, second_location->location);
/* ProgramInformation */
first_prog_info =
(GstMPDProgramInformationNode *) first_mpdclient->mpd_root_node->
ProgramInfos->data;
second_prog_info =
(GstMPDProgramInformationNode *) second_mpdclient->mpd_root_node->
ProgramInfos->data;
assert_equals_string (first_prog_info->lang, second_prog_info->lang);
assert_equals_string (first_prog_info->moreInformationURL,
second_prog_info->moreInformationURL);
assert_equals_string (first_prog_info->Title, second_prog_info->Title);
assert_equals_string (first_prog_info->Source, second_prog_info->Source);
assert_equals_string (first_prog_info->Copyright,
second_prog_info->Copyright);
/* Metrics */
first_metrics =
(GstMPDMetricsNode *) first_mpdclient->mpd_root_node->Metrics->data;
second_metrics =
(GstMPDMetricsNode *) second_mpdclient->mpd_root_node->Metrics->data;
assert_equals_string (first_metrics->metrics, second_metrics->metrics);
/* Metrics Range */
first_metrics_range =
(GstMPDMetricsRangeNode *) first_metrics->MetricsRanges->data;
second_metrics_range =
(GstMPDMetricsRangeNode *) second_metrics->MetricsRanges->data;
assert_equals_uint64 (first_metrics_range->starttime,
second_metrics_range->starttime);
assert_equals_uint64 (first_metrics_range->duration,
second_metrics_range->duration);
gst_mpd_client_free (first_mpdclient);
gst_mpd_client_free (second_mpdclient);
}
GST_END_TEST;
/*
* create a test suite containing all dash testcases
@ -5981,6 +6131,9 @@ dash_suite (void)
/* test parsing the simplest possible mpd */
tcase_add_test (tc_simpleMPD, dash_mpdparser_validsimplempd);
/* test parsing the simplest possible mpd */
tcase_add_test (tc_simpleMPD, dash_mpdparser_check_mpd_xml_generator);
/* tests parsing attributes from each element type */
tcase_add_test (tc_simpleMPD, dash_mpdparser_mpd);
tcase_add_test (tc_simpleMPD, dash_mpdparser_datetime_with_tz_offset);