mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 00:06:36 +00:00
dashdemux: corrected computation of period's duration
According to ISO/IEC 23009-1:2014(E), chapter 5.3.2.1 "The Period extends until the PeriodStart of the next Period, or until the end of the Media Presentation in the case of the last Period." This means that a configured value for optional attribute period duration should be ignored if the next period contains a start attribute or it is the last period and the MPD contains a mediaPresentationDuration attribute. https://bugzilla.gnome.org/show_bug.cgi?id=750797
This commit is contained in:
parent
0a5b6d9344
commit
8336d7a60b
2 changed files with 116 additions and 3 deletions
|
@ -3391,6 +3391,12 @@ gst_mpd_client_setup_media_presentation (GstMpdClient * client)
|
||||||
period_node = (GstPeriodNode *) list->data;
|
period_node = (GstPeriodNode *) list->data;
|
||||||
if (period_node->start != -1) {
|
if (period_node->start != -1) {
|
||||||
/* we have a regular period */
|
/* we have a regular period */
|
||||||
|
/* start cannot be smaller than previous start */
|
||||||
|
if (list != g_list_first (client->mpd_node->Periods)
|
||||||
|
&& start >= period_node->start * GST_MSECOND) {
|
||||||
|
/* Invalid MPD file: duration would be negative or zero */
|
||||||
|
goto syntax_error;
|
||||||
|
}
|
||||||
start = period_node->start * GST_MSECOND;
|
start = period_node->start * GST_MSECOND;
|
||||||
} else if (duration != GST_CLOCK_TIME_NONE) {
|
} else if (duration != GST_CLOCK_TIME_NONE) {
|
||||||
/* start time inferred from previous period, this is still a regular period */
|
/* start time inferred from previous period, this is still a regular period */
|
||||||
|
@ -3405,13 +3411,26 @@ gst_mpd_client_setup_media_presentation (GstMpdClient * client)
|
||||||
goto early;
|
goto early;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (period_node->duration != -1) {
|
/* compute duration.
|
||||||
duration = period_node->duration * GST_MSECOND;
|
If there is a start time for the next period, or this is the last period
|
||||||
} else if ((next = g_list_next (list)) != NULL) {
|
and mediaPresentationDuration was set, those values will take precedence
|
||||||
|
over a configured period duration in computing this period's duration
|
||||||
|
|
||||||
|
ISO/IEC 23009-1:2014(E), chapter 5.3.2.1
|
||||||
|
"The Period extends until the PeriodStart of the next Period, or until
|
||||||
|
the end of the Media Presentation in the case of the last Period."
|
||||||
|
*/
|
||||||
|
if ((next = g_list_next (list)) != NULL) {
|
||||||
/* try to infer this period duration from the start time of the next period */
|
/* try to infer this period duration from the start time of the next period */
|
||||||
GstPeriodNode *next_period_node = next->data;
|
GstPeriodNode *next_period_node = next->data;
|
||||||
if (next_period_node->start != -1) {
|
if (next_period_node->start != -1) {
|
||||||
|
if (start >= next_period_node->start * GST_MSECOND) {
|
||||||
|
/* Invalid MPD file: duration would be negative or zero */
|
||||||
|
goto syntax_error;
|
||||||
|
}
|
||||||
duration = next_period_node->start * GST_MSECOND - start;
|
duration = next_period_node->start * GST_MSECOND - start;
|
||||||
|
} else if (period_node->duration != -1) {
|
||||||
|
duration = period_node->duration * GST_MSECOND;
|
||||||
} else if (client->mpd_node->type == GST_MPD_FILE_TYPE_DYNAMIC) {
|
} else if (client->mpd_node->type == GST_MPD_FILE_TYPE_DYNAMIC) {
|
||||||
/* might be a live file, ignore unspecified duration */
|
/* might be a live file, ignore unspecified duration */
|
||||||
} else {
|
} else {
|
||||||
|
@ -3420,8 +3439,14 @@ gst_mpd_client_setup_media_presentation (GstMpdClient * client)
|
||||||
}
|
}
|
||||||
} else if (client->mpd_node->mediaPresentationDuration != -1) {
|
} else if (client->mpd_node->mediaPresentationDuration != -1) {
|
||||||
/* last Period of the Media Presentation */
|
/* last Period of the Media Presentation */
|
||||||
|
if (client->mpd_node->mediaPresentationDuration * GST_MSECOND <= start) {
|
||||||
|
/* Invalid MPD file: duration would be negative or zero */
|
||||||
|
goto syntax_error;
|
||||||
|
}
|
||||||
duration =
|
duration =
|
||||||
client->mpd_node->mediaPresentationDuration * GST_MSECOND - start;
|
client->mpd_node->mediaPresentationDuration * GST_MSECOND - start;
|
||||||
|
} else if (period_node->duration != -1) {
|
||||||
|
duration = period_node->duration * GST_MSECOND;
|
||||||
} else if (client->mpd_node->type == GST_MPD_FILE_TYPE_DYNAMIC) {
|
} else if (client->mpd_node->type == GST_MPD_FILE_TYPE_DYNAMIC) {
|
||||||
/* might be a live file, ignore unspecified duration */
|
/* might be a live file, ignore unspecified duration */
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -499,6 +499,90 @@ GST_START_TEST (dash_mpdparser_no_default_namespace)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test handling wrong period duration during attempts to
|
||||||
|
* infer a period duration from the start time of the next period
|
||||||
|
*/
|
||||||
|
GST_START_TEST (dash_mpdparser_wrong_period_duration_inferred_from_next_period)
|
||||||
|
{
|
||||||
|
const gchar *periodName;
|
||||||
|
|
||||||
|
const gchar *xml =
|
||||||
|
"<?xml version=\"1.0\"?>"
|
||||||
|
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
|
||||||
|
" profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
|
||||||
|
" availabilityStartTime=\"2015-03-24T0:0:0\""
|
||||||
|
" mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
|
||||||
|
"<Period id=\"Period0\" duration=\"P0Y0M0DT1H1M0S\"></Period>"
|
||||||
|
"<Period id=\"Period1\"></Period>"
|
||||||
|
"<Period id=\"Period2\" start=\"P0Y0M0DT0H0M10S\"></Period></MPD>";
|
||||||
|
|
||||||
|
gboolean ret;
|
||||||
|
GstMpdClient *mpdclient = gst_mpd_client_new ();
|
||||||
|
|
||||||
|
ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
|
||||||
|
|
||||||
|
assert_equals_int (ret, TRUE);
|
||||||
|
|
||||||
|
/* period_idx should be 0 and we should have no active periods */
|
||||||
|
assert_equals_uint64 (mpdclient->period_idx, 0);
|
||||||
|
fail_unless (mpdclient->periods == NULL);
|
||||||
|
|
||||||
|
/* process the xml data */
|
||||||
|
ret = gst_mpd_client_setup_media_presentation (mpdclient);
|
||||||
|
assert_equals_int (ret, TRUE);
|
||||||
|
|
||||||
|
/* Period0 should be present */
|
||||||
|
fail_unless (mpdclient->periods != NULL);
|
||||||
|
periodName = gst_mpd_client_get_period_id (mpdclient);
|
||||||
|
assert_equals_string (periodName, "Period0");
|
||||||
|
|
||||||
|
/* Period1 should not be present due to wrong duration */
|
||||||
|
ret = gst_mpd_client_set_period_index (mpdclient, 1);
|
||||||
|
assert_equals_int (ret, FALSE);
|
||||||
|
|
||||||
|
gst_mpd_client_free (mpdclient);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test handling wrong period duration during attempts to
|
||||||
|
* infer a period duration from the mediaPresentationDuration
|
||||||
|
*/
|
||||||
|
GST_START_TEST
|
||||||
|
(dash_mpdparser_wrong_period_duration_inferred_from_next_mediaPresentationDuration)
|
||||||
|
{
|
||||||
|
const gchar *xml =
|
||||||
|
"<?xml version=\"1.0\"?>"
|
||||||
|
"<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
|
||||||
|
" profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
|
||||||
|
" availabilityStartTime=\"2015-03-24T0:0:0\""
|
||||||
|
" mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
|
||||||
|
"<Period id=\"Period0\" start=\"P0Y0M0DT4H0M0S\"></Period></MPD>";
|
||||||
|
|
||||||
|
gboolean ret;
|
||||||
|
GstMpdClient *mpdclient = gst_mpd_client_new ();
|
||||||
|
|
||||||
|
ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
|
||||||
|
|
||||||
|
assert_equals_int (ret, TRUE);
|
||||||
|
|
||||||
|
/* period_idx should be 0 and we should have no active periods */
|
||||||
|
assert_equals_uint64 (mpdclient->period_idx, 0);
|
||||||
|
fail_unless (mpdclient->periods == NULL);
|
||||||
|
|
||||||
|
/* process the xml data
|
||||||
|
* should fail due to wrong duration in Period0 (start > mediaPresentationDuration)
|
||||||
|
*/
|
||||||
|
ret = gst_mpd_client_setup_media_presentation (mpdclient);
|
||||||
|
assert_equals_int (ret, FALSE);
|
||||||
|
|
||||||
|
gst_mpd_client_free (mpdclient);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* create a test suite containing all dash testcases
|
* create a test suite containing all dash testcases
|
||||||
*/
|
*/
|
||||||
|
@ -534,6 +618,10 @@ dash_suite (void)
|
||||||
tcase_add_test (tc_negativeTests, dash_mpdparser_missing_mpd);
|
tcase_add_test (tc_negativeTests, dash_mpdparser_missing_mpd);
|
||||||
tcase_add_test (tc_negativeTests, dash_mpdparser_no_end_tag);
|
tcase_add_test (tc_negativeTests, dash_mpdparser_no_end_tag);
|
||||||
tcase_add_test (tc_negativeTests, dash_mpdparser_no_default_namespace);
|
tcase_add_test (tc_negativeTests, dash_mpdparser_no_default_namespace);
|
||||||
|
tcase_add_test (tc_negativeTests,
|
||||||
|
dash_mpdparser_wrong_period_duration_inferred_from_next_period);
|
||||||
|
tcase_add_test (tc_negativeTests,
|
||||||
|
dash_mpdparser_wrong_period_duration_inferred_from_next_mediaPresentationDuration);
|
||||||
|
|
||||||
suite_add_tcase (s, tc_simpleMPD);
|
suite_add_tcase (s, tc_simpleMPD);
|
||||||
suite_add_tcase (s, tc_complexMPD);
|
suite_add_tcase (s, tc_complexMPD);
|
||||||
|
|
Loading…
Reference in a new issue