| /* 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); | |
| enum | |
| { | |
| PROP_MPD_REPRESENTATION_BASE_0 = 100, | |
| PROP_MPD_REPRESENTATION_BASE_PROFILES, | |
| PROP_MPD_REPRESENTATION_BASE_WIDTH, | |
| PROP_MPD_REPRESENTATION_BASE_HEIGHT, | |
| PROP_MPD_REPRESENTATION_BASE_SAR, | |
| PROP_MPD_REPRESENTATION_BASE_MIN_FRAME_RATE, | |
| PROP_MPD_REPRESENTATION_BASE_MAX_FRAME_RATE, | |
| PROP_MPD_REPRESENTATION_BASE_FRAME_RATE, | |
| PROP_MPD_REPRESENTATION_BASE_AUDIO_SAMPLING_RATE, | |
| PROP_MPD_REPRESENTATION_BASE_MIMETYPE, | |
| PROP_MPD_REPRESENTATION_BASE_SEGMENT_PROFILES, | |
| PROP_MPD_REPRESENTATION_BASE_CODECS, | |
| PROP_MPD_REPRESENTATION_BASE_MAX_SAP_PERIOD, | |
| PROP_MPD_REPRESENTATION_BASE_START_WITH_SAP, | |
| PROP_MPD_REPRESENTATION_BASE_MAX_PLAYOUT_RATE, | |
| PROP_MPD_REPRESENTATION_BASE_CODING_DEPENDENCY, | |
| PROP_MPD_REPRESENTATION_BASE_SCAN_TYPE, | |
| }; | |
| /* GObject VMethods */ | |
| static void | |
| gst_mpd_representation_base_node_set_property (GObject * object, guint prop_id, | |
| const GValue * value, GParamSpec * pspec) | |
| { | |
| GstMPDRepresentationBaseNode *self = | |
| GST_MPD_REPRESENTATION_BASE_NODE (object); | |
| switch (prop_id) { | |
| case PROP_MPD_REPRESENTATION_BASE_PROFILES: | |
| g_free (self->profiles); | |
| self->profiles = g_value_dup_string (value); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_WIDTH: | |
| self->width = g_value_get_uint (value); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_HEIGHT: | |
| self->height = g_value_get_uint (value); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_SAR: | |
| g_slice_free (GstXMLRatio, self->sar); | |
| self->sar = gst_xml_helper_clone_ratio (g_value_get_pointer (value)); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_MIN_FRAME_RATE: | |
| g_slice_free (GstXMLFrameRate, self->minFrameRate); | |
| self->minFrameRate = | |
| gst_xml_helper_clone_frame_rate (g_value_get_pointer (value)); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_MAX_FRAME_RATE: | |
| g_slice_free (GstXMLFrameRate, self->maxFrameRate); | |
| self->maxFrameRate = | |
| gst_xml_helper_clone_frame_rate (g_value_get_pointer (value)); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_FRAME_RATE: | |
| g_slice_free (GstXMLFrameRate, self->frameRate); | |
| self->frameRate = | |
| gst_xml_helper_clone_frame_rate (g_value_get_pointer (value)); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_AUDIO_SAMPLING_RATE: | |
| g_free (self->audioSamplingRate); | |
| self->audioSamplingRate = | |
| g_strdup_printf ("%u", g_value_get_uint (value)); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_MIMETYPE: | |
| g_free (self->mimeType); | |
| self->mimeType = g_value_dup_string (value); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_SEGMENT_PROFILES: | |
| g_free (self->segmentProfiles); | |
| self->segmentProfiles = g_value_dup_string (value); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_CODECS: | |
| g_free (self->codecs); | |
| self->codecs = g_value_dup_string (value); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_MAX_SAP_PERIOD: | |
| self->maximumSAPPeriod = g_value_get_double (value); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_START_WITH_SAP: | |
| self->startWithSAP = g_value_get_int (value); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_MAX_PLAYOUT_RATE: | |
| self->maxPlayoutRate = g_value_get_double (value); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_CODING_DEPENDENCY: | |
| self->codingDependency = g_value_get_boolean (value); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_SCAN_TYPE: | |
| g_free (self->scanType); | |
| self->scanType = g_value_dup_string (value); | |
| break; | |
| default: | |
| G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | |
| break; | |
| } | |
| } | |
| static void | |
| gst_mpd_representation_base_node_get_property (GObject * object, guint prop_id, | |
| GValue * value, GParamSpec * pspec) | |
| { | |
| GstMPDRepresentationBaseNode *self = | |
| GST_MPD_REPRESENTATION_BASE_NODE (object); | |
| switch (prop_id) { | |
| case PROP_MPD_REPRESENTATION_BASE_PROFILES: | |
| g_value_set_string (value, self->profiles); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_WIDTH: | |
| g_value_set_uint (value, self->width); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_HEIGHT: | |
| g_value_set_uint (value, self->height); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_SAR: | |
| g_value_set_pointer (value, self->sar); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_MIN_FRAME_RATE: | |
| g_value_set_pointer (value, self->minFrameRate); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_MAX_FRAME_RATE: | |
| g_value_set_pointer (value, self->maxFrameRate); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_FRAME_RATE: | |
| g_value_set_pointer (value, self->frameRate); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_AUDIO_SAMPLING_RATE: | |
| g_value_set_uint (value, atoi (self->audioSamplingRate)); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_MIMETYPE: | |
| g_value_set_string (value, self->mimeType); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_SEGMENT_PROFILES: | |
| g_value_set_string (value, self->segmentProfiles); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_CODECS: | |
| g_value_set_string (value, self->codecs); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_MAX_SAP_PERIOD: | |
| g_value_set_double (value, self->maximumSAPPeriod); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_START_WITH_SAP: | |
| g_value_set_int (value, self->startWithSAP); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_MAX_PLAYOUT_RATE: | |
| g_value_set_double (value, self->maxPlayoutRate); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_CODING_DEPENDENCY: | |
| g_value_set_boolean (value, self->codingDependency); | |
| self->codingDependency = g_value_get_boolean (value); | |
| break; | |
| case PROP_MPD_REPRESENTATION_BASE_SCAN_TYPE: | |
| g_value_set_string (value, self->scanType); | |
| break; | |
| default: | |
| G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | |
| break; | |
| } | |
| } | |
| 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; | |
| object_class->set_property = gst_mpd_representation_base_node_set_property; | |
| object_class->get_property = gst_mpd_representation_base_node_get_property; | |
| g_object_class_install_property (object_class, | |
| PROP_MPD_REPRESENTATION_BASE_WIDTH, g_param_spec_uint ("width", | |
| "width", "representation width", 0, G_MAXUINT, 0, | |
| G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); | |
| g_object_class_install_property (object_class, | |
| PROP_MPD_REPRESENTATION_BASE_HEIGHT, g_param_spec_uint ("height", | |
| "height", "representation height", 0, G_MAXUINT, 0, | |
| G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); | |
| g_object_class_install_property (object_class, | |
| PROP_MPD_REPRESENTATION_BASE_MIMETYPE, g_param_spec_string ("mime-type", | |
| "mimetype", "representation mimetype", NULL, | |
| G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); | |
| g_object_class_install_property (object_class, | |
| PROP_MPD_REPRESENTATION_BASE_CODECS, g_param_spec_string ("codecs", | |
| "codecs", "representation codec", NULL, | |
| G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); | |
| g_object_class_install_property (object_class, | |
| PROP_MPD_REPRESENTATION_BASE_AUDIO_SAMPLING_RATE, | |
| g_param_spec_uint ("audio-sampling-rate", "audio sampling rate", | |
| "representation audio sampling rate", 0, G_MAXUINT, 0, | |
| G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); | |
| } | |
| 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); | |
| } |