From: Alex Ashley Date: Mon, 16 Mar 2015 12:35:27 +0000 (+0000) Subject: event: add new GST_EVENT_PROTECTION X-Git-Tag: 1.6.1~373 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0f36b16a29d86a0050b8978781339616233b1db5;p=platform%2Fupstream%2Fgstreamer.git event: add new GST_EVENT_PROTECTION In order for a decrypter element to decrypt media protected using a specific protection system, it first needs all the protection system specific information necessary (E.g. information on how to acquire the decryption keys) for that stream. The GST_EVENT_PROTECTION defined in this commit enables this information to be passed from elements that extract it (e.g. qtdemux, dashdemux) to elements that use it (E.g. a decrypter element). API: GST_EVENT_PROTECTION API: gst_event_new_protection() API: gst_event_parse_protection() https://bugzilla.gnome.org/show_bug.cgi?id=705991 --- diff --git a/gst/gstevent.c b/gst/gstevent.c index 4d48b9a..725679a 100644 --- a/gst/gstevent.c +++ b/gst/gstevent.c @@ -109,6 +109,7 @@ static GstEventQuarks event_quarks[] = { {GST_EVENT_SEGMENT, "segment", 0}, {GST_EVENT_TAG, "tag", 0}, {GST_EVENT_TOC, "toc", 0}, + {GST_EVENT_PROTECTION, "protection", 0}, {GST_EVENT_BUFFERSIZE, "buffersize", 0}, {GST_EVENT_SINK_MESSAGE, "sink-message", 0}, {GST_EVENT_EOS, "eos", 0}, @@ -1691,6 +1692,127 @@ gst_event_parse_toc_select (GstEvent * event, gchar ** uid) } /** + * SECTION:gstprotectionevent + * @short_description: Functions to support the passing of + * protection system specific information via events. + * + * In order for a decryption element to decrypt media + * protected using a specific system, it first needs all the + * protection system specific information necessary to acquire the decryption + * key(s) for that stream. The functions defined here enable this information + * to be passed in events from elements that extract it + * (e.g., ISOBMFF demuxers, MPEG DASH demuxers) to protection decrypter + * elements that use it. + * + * Events containing protection system specific information are created using + * #gst_event_new_protection, and they can be parsed by downstream elements + * using #gst_event_parse_protection. + * + * In Common Encryption, protection system specific information may be located + * within ISOBMFF files, both in movie (moov) boxes and movie fragment (moof) + * boxes; it may also be contained in ContentProtection elements within MPEG + * DASH MPDs. The events created by #gst_event_new_protection contain data + * identifying from which of these locations the encapsulated protection system + * specific information originated. This origin information is required as + * some protection systems use different encodings depending upon where the + * information originates. + * + * The events returned by #gst_event_new_protection are implemented + * in such a way as to ensure that the most recently-pushed protection info + * event of a particular @origin and @system_id will + * be stuck to the output pad of the sending element. + * + * Since: 1.6 + */ + +/** + * gst_event_new_protection: + * @system_id: (transfer none): a string holding a UUID that uniquely + * identifies a protection system. + * @data: (transfer none): a #GstBuffer holding protection system specific + * information. The reference count of the buffer will be incremented by one. + * @origin: a string indicating where the protection + * information carried in the event was extracted from. The allowed values + * of this string will depend upon the protection scheme. + * + * Creates a new event containing information specific to a particular + * protection system (uniquely identified by @system_id), by which that + * protection system can acquire key(s) to decrypt a protected stream. + * + * Returns: a #GST_EVENT_PROTECTION event, if successful; %NULL + * if unsuccessful. + * + * Since: 1.6 + */ +GstEvent * +gst_event_new_protection (const gchar * system_id, + GstBuffer * data, const gchar * origin) +{ + gchar *event_name; + GstEvent *event; + GstStructure *s; + + g_return_val_if_fail (system_id != NULL, NULL); + g_return_val_if_fail (data != NULL, NULL); + + event_name = + g_strconcat ("GstProtectionEvent", origin ? "-" : "", + origin ? origin : "", "-", system_id, NULL); + + GST_CAT_INFO (GST_CAT_EVENT, "creating protection event %s", event_name); + + s = gst_structure_new (event_name, "data", GST_TYPE_BUFFER, data, + "system_id", G_TYPE_STRING, system_id, NULL); + if (origin) + gst_structure_set (s, "origin", G_TYPE_STRING, origin, NULL); + event = gst_event_new_custom (GST_EVENT_PROTECTION, s); + + g_free (event_name); + return event; +} + +/** + * gst_event_parse_protection: + * @event: a #GST_EVENT_PROTECTION event. + * @system_id: (out) (allow-none) (transfer none): pointer to store the UUID + * string uniquely identifying a content protection system. + * @data: (out) (allow-none) (transfer none): pointer to store a #GstBuffer + * holding protection system specific information. + * @origin: (allow-none) (transfer none): pointer to store a value that + * indicates where the protection information carried by @event was extracted + * from. + * + * Parses an event containing protection system specific information and stores + * the results in @system_id, @data and @origin. The data stored in @system_id, + * @origin and @data are valid until @event is released. + * + * Since: 1.6 + */ +void +gst_event_parse_protection (GstEvent * event, const gchar ** system_id, + GstBuffer ** data, const gchar ** origin) +{ + const GstStructure *s; + + g_return_if_fail (event != NULL); + g_return_if_fail (GST_IS_EVENT (event)); + g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_PROTECTION); + + s = gst_event_get_structure (event); + + if (origin) + *origin = gst_structure_get_string (s, "origin"); + + if (system_id) + *system_id = gst_structure_get_string (s, "system_id"); + + if (data) { + const GValue *value = gst_structure_get_value (s, "data"); + *data = gst_value_get_buffer (value); + } +} + +/** * gst_event_new_segment_done: * @format: The format of the position being done * @position: The position of the segment being done diff --git a/gst/gstevent.h b/gst/gstevent.h index ee7e8e0..67d70d7 100644 --- a/gst/gstevent.h +++ b/gst/gstevent.h @@ -99,6 +99,8 @@ typedef enum { * @GST_EVENT_GAP: Marks a gap in the datastream. * @GST_EVENT_TOC: An event which indicates that a new table of contents (TOC) * was found or updated. + * @GST_EVENT_PROTECTION: An event which indicates that new or updated + * encryption information has been found in the stream. * @GST_EVENT_QOS: A quality message. Used to indicate to upstream elements * that the downstream elements should adjust their processing * rate. @@ -147,6 +149,7 @@ typedef enum { GST_EVENT_SINK_MESSAGE = GST_EVENT_MAKE_TYPE (100, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY) | FLAG(STICKY_MULTI)), GST_EVENT_EOS = GST_EVENT_MAKE_TYPE (110, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)), GST_EVENT_TOC = GST_EVENT_MAKE_TYPE (120, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY) | FLAG(STICKY_MULTI)), + GST_EVENT_PROTECTION = GST_EVENT_MAKE_TYPE (130, FLAG (DOWNSTREAM) | FLAG (SERIALIZED) | FLAG (STICKY) | FLAG (STICKY_MULTI)), /* non-sticky downstream serialized */ GST_EVENT_SEGMENT_DONE = GST_EVENT_MAKE_TYPE (150, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), @@ -530,6 +533,12 @@ void gst_event_parse_tag (GstEvent *event, GstTagList **t GstEvent* gst_event_new_toc (GstToc *toc, gboolean updated); void gst_event_parse_toc (GstEvent *event, GstToc **toc, gboolean *updated); +/* Protection event */ + GstEvent *gst_event_new_protection (const gchar * system_id, + GstBuffer * data, const gchar * origin); + + void gst_event_parse_protection (GstEvent * event, + const gchar ** system_id, GstBuffer ** data, const gchar ** origin); /* buffer */ GstEvent * gst_event_new_buffer_size (GstFormat format, gint64 minsize, gint64 maxsize, diff --git a/tests/check/gst/gstevent.c b/tests/check/gst/gstevent.c index 7aae693..0983a69 100644 --- a/tests/check/gst/gstevent.c +++ b/tests/check/gst/gstevent.c @@ -235,6 +235,42 @@ GST_START_TEST (create_events) gst_event_unref (event); } + /* Protection */ + { + GstBuffer *data; + GstMemory *mem; + const gchar *parsed_origin; + const gchar *parsed_id; + GstBuffer *parsed_data; + const gchar clearkey_sys_id[] = "78f32170-d883-11e0-9572-0800200c9a66"; + + data = gst_buffer_new (); + mem = gst_allocator_alloc (NULL, 40, NULL); + gst_buffer_insert_memory (data, -1, mem); + for (gsize offset = 0; offset < 40; offset += 4) { + gst_buffer_fill (data, offset, "pssi", 4); + } + ASSERT_MINI_OBJECT_REFCOUNT (data, "data", 1); + event = gst_event_new_protection (clearkey_sys_id, data, "test"); + fail_if (event == NULL); + ASSERT_MINI_OBJECT_REFCOUNT (data, "data", 2); + fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_PROTECTION); + fail_unless (GST_EVENT_IS_DOWNSTREAM (event)); + fail_unless (GST_EVENT_IS_SERIALIZED (event)); + gst_event_parse_protection (event, &parsed_id, &parsed_data, + &parsed_origin); + fail_if (parsed_id == NULL); + fail_unless (g_strcmp0 (clearkey_sys_id, parsed_id) == 0); + fail_if (parsed_data == NULL); + fail_if (parsed_data != data); + ASSERT_MINI_OBJECT_REFCOUNT (data, "data", 2); + fail_if (parsed_origin == NULL); + fail_unless (g_strcmp0 ("test", parsed_origin) == 0); + gst_event_unref (event); + ASSERT_MINI_OBJECT_REFCOUNT (data, "data", 1); + gst_buffer_unref (data); + } + /* Custom event types */ { structure = gst_structure_new_empty ("application/x-custom"); diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index ebb0063..f567fda 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -559,6 +559,7 @@ EXPORTS gst_event_new_gap gst_event_new_latency gst_event_new_navigation + gst_event_new_protection gst_event_new_qos gst_event_new_reconfigure gst_event_new_seek @@ -576,6 +577,7 @@ EXPORTS gst_event_parse_gap gst_event_parse_group_id gst_event_parse_latency + gst_event_parse_protection gst_event_parse_qos gst_event_parse_seek gst_event_parse_segment