The dateTime data type is used to specify a date and a time.
- The dateTime is specified in the following form "YYYY-MM-DDThh:mm:ss" where:
+ The lexical form of xs:dateTime is YYYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm]
* YYYY indicates the year
* MM indicates the month
* mm indicates the minute
* ss indicates the second
- Note: All components are required!
+ The time zone may be specified as Z (UTC) or (+|-)hh:mm
*/
static gboolean
gst_mpdparser_get_xml_prop_dateTime (xmlNode * a_node,
gint year, month, day, hour, minute;
gdouble second;
gboolean exists = FALSE;
+ gfloat tzoffset = 0.0;
+ gint gmt_offset_hour = -99, gmt_offset_min = -99;
prop_string = xmlGetProp (a_node, (const xmlChar *) property_name);
if (prop_string) {
GST_LOG (" - %s: %4d/%02d/%02d %02d:%02d:%09.6lf", property_name,
year, month, day, hour, minute, second);
+ if (strrchr (str, '+') || strrchr (str, '-')){
+ /* reuse some code from gst-plugins-base/gst-libs/gst/tag/gstxmptag.c */
+ gint gmt_offset = -1;
+ gchar *plus_pos = NULL;
+ gchar *neg_pos = NULL;
+ gchar *pos = NULL;
+
+ GST_LOG ("Checking for timezone information");
+
+ /* check if there is timezone info */
+ plus_pos = strrchr (str, '+');
+ neg_pos = strrchr (str, '-');
+ if (plus_pos)
+ pos = plus_pos + 1;
+ else if (neg_pos)
+ pos = neg_pos + 1;
+
+ if (pos && strlen (pos) >= 3) {
+ gint ret_tz;
+ if (pos[2] == ':')
+ ret_tz = sscanf (pos, "%d:%d", &gmt_offset_hour, &gmt_offset_min);
+ else
+ ret_tz = sscanf (pos, "%02d%02d", &gmt_offset_hour, &gmt_offset_min);
+
+ GST_DEBUG ("Parsing timezone: %s", pos);
+
+ if (ret_tz == 2) {
+ if (neg_pos != NULL && neg_pos + 1 == pos) {
+ gmt_offset_hour *= -1;
+ gmt_offset_min *= -1;
+ }
+ gmt_offset = gmt_offset_hour * 60 + gmt_offset_min;
+
+ tzoffset = gmt_offset / 60.0;
+
+ GST_LOG ("Timezone offset: %f (%d minutes)", tzoffset, gmt_offset);
+ } else
+ GST_WARNING ("Failed to parse timezone information");
+ }
+ }
+
exists = TRUE;
*property_value =
- gst_date_time_new (0, year, month, day, hour, minute, second);
+ gst_date_time_new (tzoffset, year, month, day, hour, minute, second);
xmlFree (prop_string);
}
return FALSE;
}
+
/*
Duration Data Type
GST_END_TEST;
+
+/*
+ * Test parsing xsd:datetime with timezoneoffset.
+ *
+ */
+GST_START_TEST (dash_mpdparser_datetime_with_tz_offset)
+{
+ GstDateTime *availabilityStartTime;
+ GstDateTime *availabilityEndTime;
+ 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\"></MPD>";
+
+ gboolean ret;
+ GstMpdClient *mpdclient = gst_mpd_client_new ();
+
+ ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
+ assert_equals_int (ret, TRUE);
+
+ availabilityStartTime = mpdclient->mpd_node->availabilityStartTime;
+ assert_equals_int (gst_date_time_get_year (availabilityStartTime), 2015);
+ assert_equals_int (gst_date_time_get_month (availabilityStartTime), 3);
+ assert_equals_int (gst_date_time_get_day (availabilityStartTime), 24);
+ assert_equals_int (gst_date_time_get_hour (availabilityStartTime), 1);
+ assert_equals_int (gst_date_time_get_minute (availabilityStartTime), 10);
+ assert_equals_int (gst_date_time_get_second (availabilityStartTime), 50);
+ assert_equals_int (gst_date_time_get_microsecond (availabilityStartTime), 0);
+ assert_equals_float (gst_date_time_get_time_zone_offset (availabilityStartTime), 8.0);
+
+ availabilityEndTime = mpdclient->mpd_node->availabilityEndTime;
+ assert_equals_int (gst_date_time_get_year (availabilityEndTime), 2015);
+ assert_equals_int (gst_date_time_get_month (availabilityEndTime), 3);
+ assert_equals_int (gst_date_time_get_day (availabilityEndTime), 24);
+ assert_equals_int (gst_date_time_get_hour (availabilityEndTime), 1);
+ assert_equals_int (gst_date_time_get_minute (availabilityEndTime), 10);
+ assert_equals_int (gst_date_time_get_second (availabilityEndTime), 50);
+ assert_equals_int (gst_date_time_get_microsecond (availabilityEndTime),
+ 123456);
+ assert_equals_float (gst_date_time_get_time_zone_offset (availabilityEndTime), -4.5);
+
+ gst_mpd_client_free (mpdclient);
+}
+
+GST_END_TEST;
+
+
+
/*
* create a test suite containing all dash testcases
*/
/* 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);
tcase_add_test (tc_simpleMPD, dash_mpdparser_programInformation);
tcase_add_test (tc_simpleMPD, dash_mpdparser_baseURL);
tcase_add_test (tc_simpleMPD, dash_mpdparser_location);