• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  *
3  * Copyright (C) 2019 Collabora Ltd.
4  *   Author: Stéphane Cerveau <scerveau@collabora.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
19  *
20  */
21 #include "gstmpdadaptationsetnode.h"
22 #include "gstmpdparser.h"
23 
24 G_DEFINE_TYPE (GstMPDAdaptationSetNode, gst_mpd_adaptation_set_node,
25     GST_TYPE_MPD_REPRESENTATION_BASE_NODE);
26 
27 enum
28 {
29   PROP_MPD_ADAPTATION_SET_0,
30   PROP_MPD_ADAPTATION_SET_ID,
31   PROP_MPD_ADAPTATION_SET_CONTENT_TYPE,
32 };
33 
34 /* GObject VMethods */
35 
36 static void
gst_mpd_adaptation_set_node_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)37 gst_mpd_adaptation_set_node_set_property (GObject * object, guint prop_id,
38     const GValue * value, GParamSpec * pspec)
39 {
40   GstMPDAdaptationSetNode *self = GST_MPD_ADAPTATION_SET_NODE (object);
41   switch (prop_id) {
42     case PROP_MPD_ADAPTATION_SET_ID:
43       self->id = g_value_get_int (value);
44       break;
45     case PROP_MPD_ADAPTATION_SET_CONTENT_TYPE:
46       g_free (self->contentType);
47       self->contentType = g_value_dup_string (value);
48       break;
49     default:
50       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
51       break;
52   }
53 }
54 
55 static void
gst_mpd_adaptation_set_node_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)56 gst_mpd_adaptation_set_node_get_property (GObject * object, guint prop_id,
57     GValue * value, GParamSpec * pspec)
58 {
59   GstMPDAdaptationSetNode *self = GST_MPD_ADAPTATION_SET_NODE (object);
60   switch (prop_id) {
61     case PROP_MPD_ADAPTATION_SET_ID:
62       g_value_set_int (value, self->id);
63       break;
64     case PROP_MPD_ADAPTATION_SET_CONTENT_TYPE:
65       g_value_set_string (value, self->contentType);
66       break;
67     default:
68       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
69       break;
70   }
71 }
72 
73 static void
gst_mpd_adaptation_set_node_finalize(GObject * object)74 gst_mpd_adaptation_set_node_finalize (GObject * object)
75 {
76   GstMPDAdaptationSetNode *self = GST_MPD_ADAPTATION_SET_NODE (object);
77 
78   if (self->lang)
79     xmlFree (self->lang);
80   if (self->contentType)
81     xmlFree (self->contentType);
82   g_slice_free (GstXMLRatio, self->par);
83   g_slice_free (GstXMLConditionalUintType, self->segmentAlignment);
84   g_slice_free (GstXMLConditionalUintType, self->subsegmentAlignment);
85   g_list_free_full (self->Accessibility,
86       (GDestroyNotify) gst_mpd_descriptor_type_node_free);
87   g_list_free_full (self->Role,
88       (GDestroyNotify) gst_mpd_descriptor_type_node_free);
89   g_list_free_full (self->Rating,
90       (GDestroyNotify) gst_mpd_descriptor_type_node_free);
91   g_list_free_full (self->Viewpoint,
92       (GDestroyNotify) gst_mpd_descriptor_type_node_free);
93   gst_mpd_segment_base_node_free (self->SegmentBase);
94   gst_mpd_segment_list_node_free (self->SegmentList);
95   gst_mpd_segment_template_node_free (self->SegmentTemplate);
96   g_list_free_full (self->BaseURLs, (GDestroyNotify) gst_mpd_baseurl_node_free);
97   g_list_free_full (self->Representations,
98       (GDestroyNotify) gst_mpd_representation_node_free);
99   g_list_free_full (self->ContentComponents,
100       (GDestroyNotify) gst_mpd_content_component_node_free);
101   if (self->xlink_href)
102     xmlFree (self->xlink_href);
103 
104   G_OBJECT_CLASS (gst_mpd_adaptation_set_node_parent_class)->finalize (object);
105 }
106 
107 /* Base class */
108 
109 static xmlNodePtr
gst_mpd_adaptation_set_get_xml_node(GstMPDNode * node)110 gst_mpd_adaptation_set_get_xml_node (GstMPDNode * node)
111 {
112   xmlNodePtr adaptation_set_xml_node = NULL;
113   GstMPDAdaptationSetNode *self = GST_MPD_ADAPTATION_SET_NODE (node);
114 
115   adaptation_set_xml_node = xmlNewNode (NULL, (xmlChar *) "AdaptationSet");
116 
117   if (self->id)
118     gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "id", self->id);
119   if (self->group)
120     gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "group",
121         self->group);
122 
123   if (self->lang)
124     gst_xml_helper_set_prop_string (adaptation_set_xml_node, "lang",
125         self->lang);
126 
127   if (self->contentType)
128     gst_xml_helper_set_prop_string (adaptation_set_xml_node, "contentType",
129         self->contentType);
130 
131   if (self->minBandwidth)
132     gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "minBandwidth",
133         self->minBandwidth);
134   if (self->maxBandwidth)
135     gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "maxBandwidth",
136         self->maxBandwidth);
137   if (self->minWidth)
138     gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "minWidth",
139         self->minWidth);
140   if (self->maxWidth)
141     gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "maxWidth",
142         self->maxWidth);
143   if (self->minHeight)
144     gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "minHeight",
145         self->minHeight);
146   if (self->maxHeight)
147     gst_xml_helper_set_prop_uint (adaptation_set_xml_node, "maxHeight",
148         self->maxHeight);
149 
150   if (self->par)
151     gst_xml_helper_set_prop_ratio (adaptation_set_xml_node, "par", self->par);
152 
153   gst_xml_helper_set_prop_cond_uint (adaptation_set_xml_node,
154       "segmentAlignment", self->segmentAlignment);
155   gst_xml_helper_set_prop_cond_uint (adaptation_set_xml_node,
156       "subsegmentAlignment", self->subsegmentAlignment);
157   gst_xml_helper_set_prop_uint (adaptation_set_xml_node,
158       "subsegmentStartsWithSAP", self->subsegmentStartsWithSAP);
159   gst_xml_helper_set_prop_boolean (adaptation_set_xml_node,
160       "bitstreamSwitching", self->bitstreamSwitching);
161 
162   g_list_foreach (self->Accessibility, gst_mpd_node_get_list_item,
163       adaptation_set_xml_node);
164   g_list_foreach (self->Role, gst_mpd_node_get_list_item,
165       adaptation_set_xml_node);
166   g_list_foreach (self->Rating, gst_mpd_node_get_list_item,
167       adaptation_set_xml_node);
168   g_list_foreach (self->Viewpoint, gst_mpd_node_get_list_item,
169       adaptation_set_xml_node);
170 
171   gst_mpd_node_add_child_node (GST_MPD_NODE (self->SegmentBase),
172       adaptation_set_xml_node);
173   gst_mpd_mult_segment_base_node_add_child_node (GST_MPD_NODE
174       (self->SegmentList), adaptation_set_xml_node);
175   gst_mpd_mult_segment_base_node_add_child_node (GST_MPD_NODE
176       (self->SegmentTemplate), adaptation_set_xml_node);
177 
178   g_list_foreach (self->BaseURLs, gst_mpd_node_get_list_item,
179       adaptation_set_xml_node);
180   g_list_foreach (self->Representations,
181       gst_mpd_representation_base_node_get_list_item, adaptation_set_xml_node);
182   g_list_foreach (self->ContentComponents, gst_mpd_node_get_list_item,
183       adaptation_set_xml_node);
184 
185   if (self->xlink_href)
186     gst_xml_helper_set_prop_string (adaptation_set_xml_node, "xlink_href",
187         self->xlink_href);
188   if (self->actuate == GST_MPD_XLINK_ACTUATE_ON_LOAD)
189     gst_xml_helper_set_prop_string (adaptation_set_xml_node, "actuate",
190         (gchar *) GST_MPD_XLINK_ACTUATE_ON_LOAD_STR);
191   return adaptation_set_xml_node;
192 }
193 
194 static void
gst_mpd_adaptation_set_node_class_init(GstMPDAdaptationSetNodeClass * klass)195 gst_mpd_adaptation_set_node_class_init (GstMPDAdaptationSetNodeClass * klass)
196 {
197   GObjectClass *object_class;
198   GstMPDNodeClass *m_klass;
199 
200   object_class = G_OBJECT_CLASS (klass);
201   m_klass = GST_MPD_NODE_CLASS (klass);
202 
203   object_class->finalize = gst_mpd_adaptation_set_node_finalize;
204   object_class->set_property = gst_mpd_adaptation_set_node_set_property;
205   object_class->get_property = gst_mpd_adaptation_set_node_get_property;
206 
207   m_klass->get_xml_node = gst_mpd_adaptation_set_get_xml_node;
208 
209   g_object_class_install_property (object_class, PROP_MPD_ADAPTATION_SET_ID,
210       g_param_spec_int ("id", "id",
211           "adaptation set id", 0, G_MAXINT, 0,
212           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
213   g_object_class_install_property (object_class,
214       PROP_MPD_ADAPTATION_SET_CONTENT_TYPE, g_param_spec_string ("content-type",
215           "content type", "content type of the adaptation set", NULL,
216           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
217 }
218 
219 static void
gst_mpd_adaptation_set_node_init(GstMPDAdaptationSetNode * self)220 gst_mpd_adaptation_set_node_init (GstMPDAdaptationSetNode * self)
221 {
222   self->id = 0;
223   self->group = 0;
224   self->lang = NULL;            /* LangVectorType RFC 5646 */
225   self->contentType = NULL;
226   self->par = 0;
227   self->minBandwidth = 0;
228   self->maxBandwidth = 0;
229   self->minWidth = 0;
230   self->maxWidth = 0;
231   self->minHeight = 0;
232   self->maxHeight = 0;
233   self->segmentAlignment = NULL;
234   self->subsegmentAlignment = NULL;
235   self->subsegmentStartsWithSAP = GST_SAP_TYPE_0;
236   self->bitstreamSwitching = FALSE;
237   /* list of Accessibility DescriptorType nodes */
238   self->Accessibility = NULL;
239   /* list of Role DescriptorType nodes */
240   self->Role = NULL;
241   /* list of Rating DescriptorType nodes */
242   self->Rating = NULL;
243   /* list of Viewpoint DescriptorType nodes */
244   self->Viewpoint = NULL;
245   /* SegmentBase node */
246   self->SegmentBase = NULL;
247   /* SegmentList node */
248   self->SegmentList = NULL;
249   /* SegmentTemplate node */
250   self->SegmentTemplate = NULL;
251   /* list of BaseURL nodes */
252   self->BaseURLs = NULL;
253   /* list of Representation nodes */
254   self->Representations = NULL;
255   /* list of ContentComponent nodes */
256   self->ContentComponents = NULL;
257 
258   self->xlink_href = NULL;
259   self->actuate = GST_MPD_XLINK_ACTUATE_ON_REQUEST;
260 }
261 
262 GstMPDAdaptationSetNode *
gst_mpd_adaptation_set_node_new(void)263 gst_mpd_adaptation_set_node_new (void)
264 {
265   return g_object_new (GST_TYPE_MPD_ADAPTATION_SET_NODE, NULL);
266 }
267 
268 void
gst_mpd_adaptation_set_node_free(GstMPDAdaptationSetNode * self)269 gst_mpd_adaptation_set_node_free (GstMPDAdaptationSetNode * self)
270 {
271   if (self)
272     gst_object_unref (self);
273 }
274