From dd0c56b4a2a506bdb2168441c18b791bc1369fb1 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Fri, 4 Nov 2016 09:56:33 +0100 Subject: [PATCH] mpdparser: MS PlayReady ContentProtection parsing The "pro" (PlayReady Object) element contents are now base64-decoded and properly stored in Protection events. https://bugzilla.gnome.org/show_bug.cgi?id=773936 --- ext/dash/gstmpdparser.c | 39 ++++++++++++++++++++++++++++++- tests/check/elements/dash_demux.c | 9 ++++++- tests/check/elements/dash_mpd.c | 6 ++++- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/ext/dash/gstmpdparser.c b/ext/dash/gstmpdparser.c index e6d7283dec..f3a4b849aa 100644 --- a/ext/dash/gstmpdparser.c +++ b/ext/dash/gstmpdparser.c @@ -1733,6 +1733,43 @@ error: return FALSE; } +static void +gst_mpdparser_parse_content_protection_node (GList ** list, xmlNode * a_node) +{ + gchar *value = NULL; + if (gst_mpdparser_get_xml_prop_string (a_node, "value", &value)) { + if (!g_strcmp0 (value, "MSPR 2.0")) { + xmlNode *cur_node; + for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) { + if (cur_node->type == XML_ELEMENT_NODE) { + if (xmlStrcmp (cur_node->name, (xmlChar *) "pro") == 0) { + gsize decoded_len; + GstDescriptorType *new_descriptor; + new_descriptor = g_slice_new0 (GstDescriptorType); + *list = g_list_append (*list, new_descriptor); + + gst_mpdparser_get_xml_prop_string_stripped (a_node, "schemeIdUri", + &new_descriptor->schemeIdUri); + + gst_mpdparser_get_xml_node_content (cur_node, + &new_descriptor->value); + g_base64_decode_inplace (new_descriptor->value, &decoded_len); + *(new_descriptor->value + decoded_len) = '\0'; + goto beach; + } + } + } + } else { + gst_mpdparser_parse_descriptor_type_node (list, a_node); + } + } else { + gst_mpdparser_parse_descriptor_type_node (list, a_node); + } +beach: + if (value) + g_free (value); +} + static void gst_mpdparser_parse_representation_base_type (GstRepresentationBaseType ** pointer, xmlNode * a_node) @@ -1788,7 +1825,7 @@ gst_mpdparser_parse_representation_base_type (GstRepresentationBaseType ** (&representation_base->AudioChannelConfiguration, cur_node); } else if (xmlStrcmp (cur_node->name, (xmlChar *) "ContentProtection") == 0) { - gst_mpdparser_parse_descriptor_type_node + gst_mpdparser_parse_content_protection_node (&representation_base->ContentProtection, cur_node); } } diff --git a/tests/check/elements/dash_demux.c b/tests/check/elements/dash_demux.c index 7733044c19..ae89ced095 100644 --- a/tests/check/elements/dash_demux.c +++ b/tests/check/elements/dash_demux.c @@ -1380,6 +1380,9 @@ testContentProtectionDashdemuxSendsEvent (GstAdaptiveDemuxTestEngine * engine, fail_if (str == NULL); str = strstr (value, ""); fail_if (str == NULL); + } else if (g_strcmp0 (system_id, "9a04f079-9840-4286-ab92-e65be0885f95") == 0) { + fail_unless (g_strcmp0 (origin, "dash/mpd") == 0); + fail_unless (g_strcmp0 (value, "test") == 0); } else { fail ("unexpected content protection event '%s'", system_id); } @@ -1412,6 +1415,7 @@ GST_START_TEST (testContentProtection) "" "urn:marlin:kid:02020202020202020202020202020202" " " " " + " " + " dGVzdA==" + " " " countContentProtectionEvents, "video_00", &event_count); - fail_unless (event_count == 2); + fail_unless (event_count == 3); g_object_unref (testData); if (http_src_test_data.data) diff --git a/tests/check/elements/dash_mpd.c b/tests/check/elements/dash_mpd.c index 783ecae659..5585f49803 100644 --- a/tests/check/elements/dash_mpd.c +++ b/tests/check/elements/dash_mpd.c @@ -1301,6 +1301,7 @@ GST_START_TEST (dash_mpdparser_contentProtection_no_value) const gchar *xml = "" "" " " " " @@ -1309,6 +1310,9 @@ GST_START_TEST (dash_mpdparser_contentProtection_no_value) " " " urn:marlin:kid:02020202020202020202020202020202" " " + " " + " " + " dGVzdA==" " " ""; gboolean ret; @@ -1321,7 +1325,7 @@ GST_START_TEST (dash_mpdparser_contentProtection_no_value) periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; representationBase = adaptationSet->RepresentationBase; - assert_equals_int (g_list_length (representationBase->ContentProtection), 2); + assert_equals_int (g_list_length (representationBase->ContentProtection), 3); contentProtection = (GstDescriptorType *) g_list_nth (representationBase->ContentProtection, 1)->data;