blob: 15f5bb348a1f169d8f96c8641f4a9866eaa5d80a [file] [log] [blame]
From a816d8dab6bb33770150289a4aede43e2f7ae478 Mon Sep 17 00:00:00 2001
From: Charlie Turner <chturne@gmail.com>
Date: Fri, 10 May 2019 23:34:43 +0200
Subject: [PATCH] Check if an upstream demuxer provided a default kid.
Smooth streaming demuxers do not send boxes containing metadata about
the stream. They have to send metadata "out-of-band".
For piff encoded streams, if no box has been found containing a default
kid for the sample, check if an upstream demuxer has provided one via a
protection event, and use this as a fallback.
Signed-off-by: Xabier Rodriguez Calvar <calvaris@igalia.com>
---
gst/isomp4/qtdemux.c | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index cf15fad46..e449b480c 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -451,6 +451,7 @@ struct _QtDemuxStream
guint32 protection_scheme_version;
gpointer protection_scheme_info; /* specific to the protection scheme */
GQueue protection_scheme_event_queue;
+ GstBuffer *default_kid;
gint ref_count; /* atomic */
};
@@ -2008,6 +2009,7 @@ _create_stream (GstQTDemux * demux, guint32 track_id)
stream->stream_tags = gst_tag_list_new_empty ();
gst_tag_list_set_scope (stream->stream_tags, GST_TAG_SCOPE_STREAM);
g_queue_init (&stream->protection_scheme_event_queue);
+ stream->default_kid = NULL;
stream->ref_count = 1;
/* consistent default for push based mode */
gst_segment_init (&stream->segment, GST_FORMAT_TIME);
@@ -2476,6 +2478,32 @@ gst_qtdemux_handle_sink_event (GstPad * sinkpad, GstObject * parent,
case GST_EVENT_PROTECTION:
{
const gchar *system_id = NULL;
+ GstBuffer *default_key_id = NULL;
+ const GstStructure *structure;
+ QtDemuxStream *stream = NULL;
+ GstMapInfo map;
+
+ structure = gst_event_get_structure (event);
+ if (gst_structure_has_field_typed (structure, "key_id", GST_TYPE_BUFFER)) {
+ gst_structure_get (structure, "key_id", GST_TYPE_BUFFER,
+ &default_key_id, NULL);
+ GST_DEBUG_OBJECT (demux,
+ "received a default key id of size %" G_GSIZE_FORMAT,
+ gst_buffer_get_size (default_key_id));
+
+ if (gst_debug_category_get_threshold (GST_CAT_DEFAULT) >=
+ GST_LEVEL_MEMDUMP) {
+ gst_buffer_map (default_key_id, &map, GST_MAP_READ);
+ GST_MEMDUMP_OBJECT (demux, "default key id", (guint8 *) map.data,
+ map.size);
+ gst_buffer_unmap (default_key_id, &map);
+ }
+
+ if (QTDEMUX_N_STREAMS (demux)) {
+ stream = QTDEMUX_NTH_STREAM (demux, 0);
+ stream->default_kid = default_key_id;
+ }
+ }
gst_event_parse_protection (event, &system_id, NULL, NULL);
GST_DEBUG_OBJECT (demux, "Received protection event for system ID %s",
@@ -2688,6 +2716,8 @@ gst_qtdemux_stream_clear (QtDemuxStream * stream)
g_queue_foreach (&stream->protection_scheme_event_queue,
(GFunc) gst_event_unref, NULL);
g_queue_clear (&stream->protection_scheme_event_queue);
+ if (stream->default_kid)
+ gst_buffer_unref (stream->default_kid);
gst_qtdemux_stream_flush_segments_data (stream);
gst_qtdemux_stream_flush_samples_data (stream);
}
@@ -2954,6 +2984,19 @@ qtdemux_parse_piff (GstQTDemux * qtdemux, const guint8 * buffer, gint length,
uses_sub_sample_encryption = TRUE;
}
+ // In the case of smooth streaming, we never get moov boxes and their
+ // default encryption metadata. Instead, the demuxer has to parse this
+ // information out of the playready specific payloads and make it availble
+ // somehow to us.
+ if (!gst_structure_has_field (ss_info->default_properties, "kid")) {
+ if (!stream->default_kid) {
+ GST_WARNING_OBJECT (qtdemux, "No available key id for sample");
+ } else {
+ gst_structure_set (ss_info->default_properties, "kid", GST_TYPE_BUFFER,
+ stream->default_kid, NULL);
+ }
+ }
+
if (!gst_structure_get_uint (ss_info->default_properties, "iv_size",
&iv_size)) {
GST_ERROR_OBJECT (qtdemux, "Error getting encryption IV size field");
--
2.20.1