mpdparser: Handle invalid external xml link for SegmentList element

Ignore invalid xml link for SegmentList likewise external Period without error.

https://bugzilla.gnome.org/show_bug.cgi?id=774463
This commit is contained in:
Seungha Yang 2016-11-19 23:04:04 +09:00 committed by Sebastian Dröge
parent ae8759c33e
commit 3c31c47259

View file

@ -2547,21 +2547,18 @@ gst_mpd_client_fetch_external_segment_list (GstMpdClient * client,
GstPeriodNode * Period, GstPeriodNode * Period,
GstAdaptationSetNode * AdaptationSet, GstAdaptationSetNode * AdaptationSet,
GstRepresentationNode * Representation, GstRepresentationNode * Representation,
GstSegmentListNode * parent, GstSegmentListNode * segment_list, GstSegmentListNode * parent, GstSegmentListNode * segment_list)
gboolean * error)
{ {
GstFragment *download; GstFragment *download;
GstBuffer *segment_list_buffer; GstBuffer *segment_list_buffer;
GstMapInfo map; GstMapInfo map;
GError *err = NULL; GError *err = NULL;
xmlDocPtr doc; xmlDocPtr doc = NULL;
GstUri *base_uri, *uri; GstUri *base_uri, *uri;
gchar *query = NULL; gchar *query = NULL;
gchar *uri_string; gchar *uri_string;
GstSegmentListNode *new_segment_list = NULL; GstSegmentListNode *new_segment_list = NULL;
*error = FALSE;
/* ISO/IEC 23009-1:2014 5.5.3 4) /* ISO/IEC 23009-1:2014 5.5.3 4)
* Remove nodes that resolve to nothing when resolving * Remove nodes that resolve to nothing when resolving
*/ */
@ -2571,7 +2568,6 @@ gst_mpd_client_fetch_external_segment_list (GstMpdClient * client,
} }
if (!client->downloader) { if (!client->downloader) {
*error = TRUE;
return NULL; return NULL;
} }
@ -2615,7 +2611,6 @@ gst_mpd_client_fetch_external_segment_list (GstMpdClient * client,
GST_ERROR ("Failed to download external SegmentList node at '%s': %s", GST_ERROR ("Failed to download external SegmentList node at '%s': %s",
segment_list->xlink_href, err->message); segment_list->xlink_href, err->message);
g_clear_error (&err); g_clear_error (&err);
*error = TRUE;
return NULL; return NULL;
} }
@ -2627,31 +2622,36 @@ gst_mpd_client_fetch_external_segment_list (GstMpdClient * client,
doc = doc =
xmlReadMemory ((const gchar *) map.data, map.size, "noname.xml", NULL, xmlReadMemory ((const gchar *) map.data, map.size, "noname.xml", NULL,
XML_PARSE_NONET); XML_PARSE_NONET);
gst_buffer_unmap (segment_list_buffer, &map);
gst_buffer_unref (segment_list_buffer);
/* NOTE: ISO/IEC 23009-1:2014 5.3.9.3.2 is saying that one or multiple SegmentList
* in external xml is allowed, however, multiple SegmentList does not make sense
* because Period/AdaptationSet/Representation allow only one SegmentList */
if (doc) { if (doc) {
xmlNode *root_element = xmlDocGetRootElement (doc); xmlNode *root_element = xmlDocGetRootElement (doc);
if (root_element->type != XML_ELEMENT_NODE || if (root_element->type != XML_ELEMENT_NODE ||
xmlStrcmp (root_element->name, (xmlChar *) "SegmentList") != 0) { xmlStrcmp (root_element->name, (xmlChar *) "SegmentList") != 0) {
xmlFreeDoc (doc); goto error;
gst_buffer_unmap (segment_list_buffer, &map);
gst_buffer_unref (segment_list_buffer);
*error = TRUE;
return NULL;
} }
gst_mpdparser_parse_segment_list_node (&new_segment_list, root_element, gst_mpdparser_parse_segment_list_node (&new_segment_list, root_element,
parent); parent);
} else { } else {
GST_ERROR ("Failed to parse adaptation set node XML"); goto error;
gst_buffer_unmap (segment_list_buffer, &map);
gst_buffer_unref (segment_list_buffer);
*error = TRUE;
return NULL;
} }
gst_buffer_unmap (segment_list_buffer, &map);
gst_buffer_unref (segment_list_buffer); done:
if (doc)
xmlFreeDoc (doc);
return new_segment_list; return new_segment_list;
error:
GST_ERROR ("Failed to parse segment list node XML");
goto done;
} }
static GstSegmentListNode * static GstSegmentListNode *
@ -2678,11 +2678,14 @@ gst_mpdparser_get_segment_list (GstMpdClient * client, GstPeriodNode * Period,
/* Resolve external segment list here. */ /* Resolve external segment list here. */
if (*SegmentList && (*SegmentList)->xlink_href) { if (*SegmentList && (*SegmentList)->xlink_href) {
GstSegmentListNode *new_segment_list; GstSegmentListNode *new_segment_list;
gboolean error;
/* TODO: Use SegmentList of parent if
* - Parent has its own SegmentList
* - Fail to get SegmentList from external xml
*/
new_segment_list = new_segment_list =
gst_mpd_client_fetch_external_segment_list (client, Period, gst_mpd_client_fetch_external_segment_list (client, Period,
AdaptationSet, Representation, ParentSegmentList, *SegmentList, &error); AdaptationSet, Representation, ParentSegmentList, *SegmentList);
gst_mpdparser_free_segment_list_node (*SegmentList); gst_mpdparser_free_segment_list_node (*SegmentList);
*SegmentList = new_segment_list; *SegmentList = new_segment_list;
@ -3671,14 +3674,10 @@ gst_mpd_client_fetch_on_load_external_resources (GstMpdClient * client)
if (period->SegmentList && period->SegmentList->xlink_href if (period->SegmentList && period->SegmentList->xlink_href
&& period->SegmentList->actuate == GST_XLINK_ACTUATE_ON_LOAD) { && period->SegmentList->actuate == GST_XLINK_ACTUATE_ON_LOAD) {
GstSegmentListNode *new_segment_list; GstSegmentListNode *new_segment_list;
gboolean error;
new_segment_list = new_segment_list =
gst_mpd_client_fetch_external_segment_list (client, period, NULL, gst_mpd_client_fetch_external_segment_list (client, period, NULL,
NULL, NULL, period->SegmentList, &error); NULL, NULL, period->SegmentList);
if (!new_segment_list && error)
goto syntax_error;
gst_mpdparser_free_segment_list_node (period->SegmentList); gst_mpdparser_free_segment_list_node (period->SegmentList);
period->SegmentList = new_segment_list; period->SegmentList = new_segment_list;
@ -3727,15 +3726,10 @@ gst_mpd_client_fetch_on_load_external_resources (GstMpdClient * client)
if (adapt_set->SegmentList && adapt_set->SegmentList->xlink_href if (adapt_set->SegmentList && adapt_set->SegmentList->xlink_href
&& adapt_set->SegmentList->actuate == GST_XLINK_ACTUATE_ON_LOAD) { && adapt_set->SegmentList->actuate == GST_XLINK_ACTUATE_ON_LOAD) {
GstSegmentListNode *new_segment_list; GstSegmentListNode *new_segment_list;
gboolean error;
new_segment_list = new_segment_list =
gst_mpd_client_fetch_external_segment_list (client, period, gst_mpd_client_fetch_external_segment_list (client, period,
adapt_set, NULL, period->SegmentList, adapt_set->SegmentList, adapt_set, NULL, period->SegmentList, adapt_set->SegmentList);
&error);
if (!new_segment_list && error)
goto syntax_error;
gst_mpdparser_free_segment_list_node (adapt_set->SegmentList); gst_mpdparser_free_segment_list_node (adapt_set->SegmentList);
adapt_set->SegmentList = new_segment_list; adapt_set->SegmentList = new_segment_list;
@ -3750,15 +3744,11 @@ gst_mpd_client_fetch_on_load_external_resources (GstMpdClient * client)
GST_XLINK_ACTUATE_ON_LOAD) { GST_XLINK_ACTUATE_ON_LOAD) {
GstSegmentListNode *new_segment_list; GstSegmentListNode *new_segment_list;
gboolean error;
new_segment_list = new_segment_list =
gst_mpd_client_fetch_external_segment_list (client, period, gst_mpd_client_fetch_external_segment_list (client, period,
adapt_set, representation, adapt_set->SegmentList, adapt_set, representation, adapt_set->SegmentList,
representation->SegmentList, &error); representation->SegmentList);
if (!new_segment_list && error)
goto syntax_error;
gst_mpdparser_free_segment_list_node (representation->SegmentList); gst_mpdparser_free_segment_list_node (representation->SegmentList);
representation->SegmentList = new_segment_list; representation->SegmentList = new_segment_list;