mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
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
This commit is contained in:
parent
3191440485
commit
0f36b16a29
4 changed files with 169 additions and 0 deletions
122
gst/gstevent.c
122
gst/gstevent.c
|
@ -109,6 +109,7 @@ static GstEventQuarks event_quarks[] = {
|
||||||
{GST_EVENT_SEGMENT, "segment", 0},
|
{GST_EVENT_SEGMENT, "segment", 0},
|
||||||
{GST_EVENT_TAG, "tag", 0},
|
{GST_EVENT_TAG, "tag", 0},
|
||||||
{GST_EVENT_TOC, "toc", 0},
|
{GST_EVENT_TOC, "toc", 0},
|
||||||
|
{GST_EVENT_PROTECTION, "protection", 0},
|
||||||
{GST_EVENT_BUFFERSIZE, "buffersize", 0},
|
{GST_EVENT_BUFFERSIZE, "buffersize", 0},
|
||||||
{GST_EVENT_SINK_MESSAGE, "sink-message", 0},
|
{GST_EVENT_SINK_MESSAGE, "sink-message", 0},
|
||||||
{GST_EVENT_EOS, "eos", 0},
|
{GST_EVENT_EOS, "eos", 0},
|
||||||
|
@ -1690,6 +1691,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:
|
* gst_event_new_segment_done:
|
||||||
* @format: The format of the position being done
|
* @format: The format of the position being done
|
||||||
|
|
|
@ -99,6 +99,8 @@ typedef enum {
|
||||||
* @GST_EVENT_GAP: Marks a gap in the datastream.
|
* @GST_EVENT_GAP: Marks a gap in the datastream.
|
||||||
* @GST_EVENT_TOC: An event which indicates that a new table of contents (TOC)
|
* @GST_EVENT_TOC: An event which indicates that a new table of contents (TOC)
|
||||||
* was found or updated.
|
* 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
|
* @GST_EVENT_QOS: A quality message. Used to indicate to upstream elements
|
||||||
* that the downstream elements should adjust their processing
|
* that the downstream elements should adjust their processing
|
||||||
* rate.
|
* 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_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_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_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 */
|
/* non-sticky downstream serialized */
|
||||||
GST_EVENT_SEGMENT_DONE = GST_EVENT_MAKE_TYPE (150, FLAG(DOWNSTREAM) | FLAG(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);
|
GstEvent* gst_event_new_toc (GstToc *toc, gboolean updated);
|
||||||
void gst_event_parse_toc (GstEvent *event, 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 */
|
/* buffer */
|
||||||
GstEvent * gst_event_new_buffer_size (GstFormat format, gint64 minsize, gint64 maxsize,
|
GstEvent * gst_event_new_buffer_size (GstFormat format, gint64 minsize, gint64 maxsize,
|
||||||
|
|
|
@ -235,6 +235,42 @@ GST_START_TEST (create_events)
|
||||||
gst_event_unref (event);
|
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 */
|
/* Custom event types */
|
||||||
{
|
{
|
||||||
structure = gst_structure_new_empty ("application/x-custom");
|
structure = gst_structure_new_empty ("application/x-custom");
|
||||||
|
|
|
@ -559,6 +559,7 @@ EXPORTS
|
||||||
gst_event_new_gap
|
gst_event_new_gap
|
||||||
gst_event_new_latency
|
gst_event_new_latency
|
||||||
gst_event_new_navigation
|
gst_event_new_navigation
|
||||||
|
gst_event_new_protection
|
||||||
gst_event_new_qos
|
gst_event_new_qos
|
||||||
gst_event_new_reconfigure
|
gst_event_new_reconfigure
|
||||||
gst_event_new_seek
|
gst_event_new_seek
|
||||||
|
@ -576,6 +577,7 @@ EXPORTS
|
||||||
gst_event_parse_gap
|
gst_event_parse_gap
|
||||||
gst_event_parse_group_id
|
gst_event_parse_group_id
|
||||||
gst_event_parse_latency
|
gst_event_parse_latency
|
||||||
|
gst_event_parse_protection
|
||||||
gst_event_parse_qos
|
gst_event_parse_qos
|
||||||
gst_event_parse_seek
|
gst_event_parse_seek
|
||||||
gst_event_parse_segment
|
gst_event_parse_segment
|
||||||
|
|
Loading…
Reference in a new issue