• 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 "gstmpdrepresentationbasenode.h"
22 #include "gstmpdparser.h"
23 
24 G_DEFINE_TYPE (GstMPDRepresentationBaseNode, gst_mpd_representation_base_node,
25     GST_TYPE_MPD_NODE);
26 
27 enum
28 {
29   PROP_MPD_REPRESENTATION_BASE_0 = 100,
30   PROP_MPD_REPRESENTATION_BASE_PROFILES,
31   PROP_MPD_REPRESENTATION_BASE_WIDTH,
32   PROP_MPD_REPRESENTATION_BASE_HEIGHT,
33   PROP_MPD_REPRESENTATION_BASE_SAR,
34   PROP_MPD_REPRESENTATION_BASE_MIN_FRAME_RATE,
35   PROP_MPD_REPRESENTATION_BASE_MAX_FRAME_RATE,
36   PROP_MPD_REPRESENTATION_BASE_FRAME_RATE,
37   PROP_MPD_REPRESENTATION_BASE_AUDIO_SAMPLING_RATE,
38   PROP_MPD_REPRESENTATION_BASE_MIMETYPE,
39   PROP_MPD_REPRESENTATION_BASE_SEGMENT_PROFILES,
40   PROP_MPD_REPRESENTATION_BASE_CODECS,
41   PROP_MPD_REPRESENTATION_BASE_MAX_SAP_PERIOD,
42   PROP_MPD_REPRESENTATION_BASE_START_WITH_SAP,
43   PROP_MPD_REPRESENTATION_BASE_MAX_PLAYOUT_RATE,
44   PROP_MPD_REPRESENTATION_BASE_CODING_DEPENDENCY,
45   PROP_MPD_REPRESENTATION_BASE_SCAN_TYPE,
46 };
47 
48 /* GObject VMethods */
49 
50 static void
gst_mpd_representation_base_node_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)51 gst_mpd_representation_base_node_set_property (GObject * object, guint prop_id,
52     const GValue * value, GParamSpec * pspec)
53 {
54   GstMPDRepresentationBaseNode *self =
55       GST_MPD_REPRESENTATION_BASE_NODE (object);
56   switch (prop_id) {
57     case PROP_MPD_REPRESENTATION_BASE_PROFILES:
58       g_free (self->profiles);
59       self->profiles = g_value_dup_string (value);
60       break;
61     case PROP_MPD_REPRESENTATION_BASE_WIDTH:
62       self->width = g_value_get_uint (value);
63       break;
64     case PROP_MPD_REPRESENTATION_BASE_HEIGHT:
65       self->height = g_value_get_uint (value);
66       break;
67     case PROP_MPD_REPRESENTATION_BASE_SAR:
68       g_slice_free (GstXMLRatio, self->sar);
69       self->sar = gst_xml_helper_clone_ratio (g_value_get_pointer (value));
70       break;
71     case PROP_MPD_REPRESENTATION_BASE_MIN_FRAME_RATE:
72       g_slice_free (GstXMLFrameRate, self->minFrameRate);
73       self->minFrameRate =
74           gst_xml_helper_clone_frame_rate (g_value_get_pointer (value));
75       break;
76     case PROP_MPD_REPRESENTATION_BASE_MAX_FRAME_RATE:
77       g_slice_free (GstXMLFrameRate, self->maxFrameRate);
78       self->maxFrameRate =
79           gst_xml_helper_clone_frame_rate (g_value_get_pointer (value));
80       break;
81     case PROP_MPD_REPRESENTATION_BASE_FRAME_RATE:
82       g_slice_free (GstXMLFrameRate, self->frameRate);
83       self->frameRate =
84           gst_xml_helper_clone_frame_rate (g_value_get_pointer (value));
85       break;
86     case PROP_MPD_REPRESENTATION_BASE_AUDIO_SAMPLING_RATE:
87       g_free (self->audioSamplingRate);
88       self->audioSamplingRate =
89           g_strdup_printf ("%u", g_value_get_uint (value));
90       break;
91     case PROP_MPD_REPRESENTATION_BASE_MIMETYPE:
92       g_free (self->mimeType);
93       self->mimeType = g_value_dup_string (value);
94       break;
95     case PROP_MPD_REPRESENTATION_BASE_SEGMENT_PROFILES:
96       g_free (self->segmentProfiles);
97       self->segmentProfiles = g_value_dup_string (value);
98       break;
99     case PROP_MPD_REPRESENTATION_BASE_CODECS:
100       g_free (self->codecs);
101       self->codecs = g_value_dup_string (value);
102       break;
103     case PROP_MPD_REPRESENTATION_BASE_MAX_SAP_PERIOD:
104       self->maximumSAPPeriod = g_value_get_double (value);
105       break;
106     case PROP_MPD_REPRESENTATION_BASE_START_WITH_SAP:
107       self->startWithSAP = g_value_get_int (value);
108       break;
109     case PROP_MPD_REPRESENTATION_BASE_MAX_PLAYOUT_RATE:
110       self->maxPlayoutRate = g_value_get_double (value);
111       break;
112     case PROP_MPD_REPRESENTATION_BASE_CODING_DEPENDENCY:
113       self->codingDependency = g_value_get_boolean (value);
114       break;
115     case PROP_MPD_REPRESENTATION_BASE_SCAN_TYPE:
116       g_free (self->scanType);
117       self->scanType = g_value_dup_string (value);
118       break;
119     default:
120       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
121       break;
122   }
123 }
124 
125 static void
gst_mpd_representation_base_node_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)126 gst_mpd_representation_base_node_get_property (GObject * object, guint prop_id,
127     GValue * value, GParamSpec * pspec)
128 {
129   GstMPDRepresentationBaseNode *self =
130       GST_MPD_REPRESENTATION_BASE_NODE (object);
131   switch (prop_id) {
132     case PROP_MPD_REPRESENTATION_BASE_PROFILES:
133       g_value_set_string (value, self->profiles);
134       break;
135     case PROP_MPD_REPRESENTATION_BASE_WIDTH:
136       g_value_set_uint (value, self->width);
137       break;
138     case PROP_MPD_REPRESENTATION_BASE_HEIGHT:
139       g_value_set_uint (value, self->height);
140       break;
141     case PROP_MPD_REPRESENTATION_BASE_SAR:
142       g_value_set_pointer (value, self->sar);
143       break;
144     case PROP_MPD_REPRESENTATION_BASE_MIN_FRAME_RATE:
145       g_value_set_pointer (value, self->minFrameRate);
146       break;
147     case PROP_MPD_REPRESENTATION_BASE_MAX_FRAME_RATE:
148       g_value_set_pointer (value, self->maxFrameRate);
149       break;
150     case PROP_MPD_REPRESENTATION_BASE_FRAME_RATE:
151       g_value_set_pointer (value, self->frameRate);
152       break;
153     case PROP_MPD_REPRESENTATION_BASE_AUDIO_SAMPLING_RATE:
154       g_value_set_uint (value, atoi (self->audioSamplingRate));
155       break;
156     case PROP_MPD_REPRESENTATION_BASE_MIMETYPE:
157       g_value_set_string (value, self->mimeType);
158       break;
159     case PROP_MPD_REPRESENTATION_BASE_SEGMENT_PROFILES:
160       g_value_set_string (value, self->segmentProfiles);
161       break;
162     case PROP_MPD_REPRESENTATION_BASE_CODECS:
163       g_value_set_string (value, self->codecs);
164       break;
165     case PROP_MPD_REPRESENTATION_BASE_MAX_SAP_PERIOD:
166       g_value_set_double (value, self->maximumSAPPeriod);
167       break;
168     case PROP_MPD_REPRESENTATION_BASE_START_WITH_SAP:
169       g_value_set_int (value, self->startWithSAP);
170       break;
171     case PROP_MPD_REPRESENTATION_BASE_MAX_PLAYOUT_RATE:
172       g_value_set_double (value, self->maxPlayoutRate);
173       break;
174     case PROP_MPD_REPRESENTATION_BASE_CODING_DEPENDENCY:
175       g_value_set_boolean (value, self->codingDependency);
176       self->codingDependency = g_value_get_boolean (value);
177       break;
178     case PROP_MPD_REPRESENTATION_BASE_SCAN_TYPE:
179       g_value_set_string (value, self->scanType);
180       break;
181     default:
182       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
183       break;
184   }
185 }
186 
187 static void
gst_mpd_representation_base_node_finalize(GObject * object)188 gst_mpd_representation_base_node_finalize (GObject * object)
189 {
190   GstMPDRepresentationBaseNode *self =
191       GST_MPD_REPRESENTATION_BASE_NODE (object);
192 
193   if (self->profiles)
194     xmlFree (self->profiles);
195   g_slice_free (GstXMLRatio, self->sar);
196   g_slice_free (GstXMLFrameRate, self->frameRate);
197   g_slice_free (GstXMLFrameRate, self->minFrameRate);
198   g_slice_free (GstXMLFrameRate, self->maxFrameRate);
199   if (self->audioSamplingRate)
200     xmlFree (self->audioSamplingRate);
201   if (self->mimeType)
202     xmlFree (self->mimeType);
203   if (self->segmentProfiles)
204     xmlFree (self->segmentProfiles);
205   if (self->codecs)
206     xmlFree (self->codecs);
207   if (self->scanType)
208     xmlFree (self->scanType);
209   g_list_free_full (self->FramePacking,
210       (GDestroyNotify) gst_mpd_descriptor_type_node_free);
211   g_list_free_full (self->AudioChannelConfiguration,
212       (GDestroyNotify) gst_mpd_descriptor_type_node_free);
213   g_list_free_full (self->ContentProtection,
214       (GDestroyNotify) gst_mpd_descriptor_type_node_free);
215 
216   G_OBJECT_CLASS (gst_mpd_representation_base_node_parent_class)->finalize
217       (object);
218 }
219 
220 /* Base class */
221 
222 static void
gst_mpd_representation_base_get_xml_node(GstMPDNode * node,xmlNodePtr representation_base_node)223 gst_mpd_representation_base_get_xml_node (GstMPDNode * node,
224     xmlNodePtr representation_base_node)
225 {
226   GstMPDRepresentationBaseNode *self = GST_MPD_REPRESENTATION_BASE_NODE (node);
227 
228   if (self->profiles)
229     gst_xml_helper_set_prop_string (representation_base_node, "profiles",
230         self->profiles);
231   if (self->width)
232     gst_xml_helper_set_prop_uint (representation_base_node, "width",
233         self->width);
234   if (self->height)
235     gst_xml_helper_set_prop_uint (representation_base_node, "height",
236         self->height);
237 
238   gst_xml_helper_set_prop_ratio (representation_base_node, "sar", self->sar);
239   gst_xml_helper_set_prop_framerate (representation_base_node, "minFrameRate",
240       self->minFrameRate);
241   gst_xml_helper_set_prop_framerate (representation_base_node, "maxFrameRate",
242       self->maxFrameRate);
243   gst_xml_helper_set_prop_framerate (representation_base_node, "frameRate",
244       self->frameRate);
245 
246   gst_xml_helper_set_prop_string (representation_base_node,
247       "audioSamplingRate", self->audioSamplingRate);
248   gst_xml_helper_set_prop_string (representation_base_node, "mimeType",
249       self->mimeType);
250   gst_xml_helper_set_prop_string (representation_base_node, "segmentProfiles",
251       self->segmentProfiles);
252   gst_xml_helper_set_prop_string (representation_base_node, "codecs",
253       self->codecs);
254   if (self->maximumSAPPeriod)
255     gst_xml_helper_set_prop_double (representation_base_node,
256         "maximumSAPPeriod", self->maximumSAPPeriod);
257   if (self->startWithSAP)
258     gst_xml_helper_set_prop_int (representation_base_node, "startWithSAP",
259         self->startWithSAP);
260   if (self->maxPlayoutRate)
261     gst_xml_helper_set_prop_double (representation_base_node, "maxPlayoutRate",
262         self->maxPlayoutRate);
263   if (self->codingDependency)
264     gst_xml_helper_set_prop_boolean (representation_base_node,
265         "codingDependency", self->codingDependency);
266 
267   gst_xml_helper_set_prop_string (representation_base_node, "scanType",
268       self->scanType);
269 
270   g_list_foreach (self->FramePacking,
271       gst_mpd_node_get_list_item, representation_base_node);
272   g_list_foreach (self->AudioChannelConfiguration,
273       gst_mpd_node_get_list_item, representation_base_node);
274   g_list_foreach (self->ContentProtection,
275       gst_mpd_node_get_list_item, representation_base_node);
276 }
277 
278 static void
gst_mpd_representation_base_node_class_init(GstMPDRepresentationBaseNodeClass * klass)279 gst_mpd_representation_base_node_class_init (GstMPDRepresentationBaseNodeClass *
280     klass)
281 {
282   GObjectClass *object_class;
283 
284   object_class = G_OBJECT_CLASS (klass);
285 
286   object_class->finalize = gst_mpd_representation_base_node_finalize;
287   object_class->set_property = gst_mpd_representation_base_node_set_property;
288   object_class->get_property = gst_mpd_representation_base_node_get_property;
289 
290 
291   g_object_class_install_property (object_class,
292       PROP_MPD_REPRESENTATION_BASE_WIDTH, g_param_spec_uint ("width",
293           "width", "representation width", 0, G_MAXUINT, 0,
294           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
295   g_object_class_install_property (object_class,
296       PROP_MPD_REPRESENTATION_BASE_HEIGHT, g_param_spec_uint ("height",
297           "height", "representation height", 0, G_MAXUINT, 0,
298           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
299   g_object_class_install_property (object_class,
300       PROP_MPD_REPRESENTATION_BASE_MIMETYPE, g_param_spec_string ("mime-type",
301           "mimetype", "representation mimetype", NULL,
302           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
303   g_object_class_install_property (object_class,
304       PROP_MPD_REPRESENTATION_BASE_CODECS, g_param_spec_string ("codecs",
305           "codecs", "representation codec", NULL,
306           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
307   g_object_class_install_property (object_class,
308       PROP_MPD_REPRESENTATION_BASE_AUDIO_SAMPLING_RATE,
309       g_param_spec_uint ("audio-sampling-rate", "audio sampling rate",
310           "representation audio sampling rate", 0, G_MAXUINT, 0,
311           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
312 }
313 
314 static void
gst_mpd_representation_base_node_init(GstMPDRepresentationBaseNode * self)315 gst_mpd_representation_base_node_init (GstMPDRepresentationBaseNode * self)
316 {
317   self->profiles = NULL;
318   self->width = 0;
319   self->height = 0;
320   self->sar = NULL;
321   self->minFrameRate = NULL;
322   self->maxFrameRate = NULL;
323   self->frameRate = NULL;
324   self->audioSamplingRate = NULL;
325   self->mimeType = NULL;
326   self->segmentProfiles = NULL;
327   self->codecs = NULL;
328   self->maximumSAPPeriod = 0;
329   self->startWithSAP = GST_SAP_TYPE_0;
330   self->maxPlayoutRate = 0.0;
331   self->codingDependency = FALSE;
332   self->scanType = NULL;
333   self->FramePacking = NULL;
334   self->AudioChannelConfiguration = NULL;
335   self->ContentProtection = NULL;
336 }
337 
338 void
gst_mpd_representation_base_node_get_list_item(gpointer data,gpointer user_data)339 gst_mpd_representation_base_node_get_list_item (gpointer data,
340     gpointer user_data)
341 {
342   GstMPDNode *node = (GstMPDNode *) data;
343   xmlNodePtr parent_xml_node = (xmlNodePtr) user_data;
344   xmlNodePtr new_xml_node = gst_mpd_node_get_xml_pointer (node);
345 
346   gst_mpd_representation_base_get_xml_node (node, new_xml_node);
347   xmlAddChild (parent_xml_node, new_xml_node);
348 }
349