After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 770107 - qtdemux: reports only one encryption system even if it can support more than one
qtdemux: reports only one encryption system even if it can support more than one
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
git master
Other Linux
: Normal normal
: 1.15.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2016-08-18 17:50 UTC by Xabier Rodríguez Calvar
Modified: 2018-08-17 22:30 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
1/1 gst-plugins-good (8.50 KB, patch)
2016-09-16 14:47 UTC, Xabier Rodríguez Calvar
none Details | Review
1/1 gst-plugins-good qtdemux patch (11.95 KB, patch)
2016-12-05 18:20 UTC, Xabier Rodríguez Calvar
none Details | Review
2/2 gstreamer (11.95 KB, patch)
2016-12-07 19:27 UTC, Xabier Rodríguez Calvar
none Details | Review
2/2 gstreamer (2.39 KB, patch)
2017-01-27 13:29 UTC, Xabier Rodríguez Calvar
none Details | Review
1/3 protection: added function to filter system ids (2.42 KB, patch)
2017-05-21 09:43 UTC, Enrique Ocaña González
none Details | Review
2/3 qtdemux: add context for a preferred protection (13.56 KB, patch)
2017-05-21 09:48 UTC, Enrique Ocaña González
none Details | Review
3/3 qtdemux: also push buffers without encryption info instead of dropping them (3.45 KB, patch)
2017-05-21 09:50 UTC, Enrique Ocaña González
committed Details | Review
1/3 protection: added function to filter system ids (review suggestions applied) (4.13 KB, patch)
2017-05-21 13:16 UTC, Enrique Ocaña González
none Details | Review
1/3 protection: added function to filter system ids (review suggestions applied) (4.13 KB, patch)
2017-05-21 13:35 UTC, Enrique Ocaña González
none Details | Review
2/3 qtdemux: add context for a preferred protection (review suggestions applied) (13.35 KB, patch)
2017-05-21 17:19 UTC, Enrique Ocaña González
none Details | Review
2/3 qtdemux: add context for a preferred protection (review suggestions applied) (12.88 KB, patch)
2017-06-22 11:04 UTC, Xabier Rodríguez Calvar
none Details | Review
1/3 protection: added function to filter system ids (review suggestions applied) (4.13 KB, patch)
2017-06-28 08:05 UTC, Xabier Rodríguez Calvar
committed Details | Review
2/3 qtdemux: add context for a preferred protection (review suggestions applied) (12.67 KB, patch)
2017-07-04 15:04 UTC, Xabier Rodríguez Calvar
committed Details | Review

Description Xabier Rodríguez Calvar 2016-08-18 17:50:43 UTC
Imagine a file that is encrypted with more than one encryption system, say Widevine, PlayReady and Clearkey. We have decryptors for two of them available. Qtdemux will select the first factory that can provide a decryptor that the stream reported it is encrypted with (this happens in gst_protection_select_system).

In some cases it can be a bad idea because even when the file claims that it supports three encryption systems, the user should be who decides with which of those systems it wants to decrypt, meaning that the stream should provide caps with three structures, one of each stream if those can be used.

How I found that this is a problem: YouTube EME tests. Many files used in those tests are encrypted for the three systems I mentioned above and used indistinctly in different tests for different key systems. It can happen that the same file is used for PlayReady and ClearKey tests, for example. If we always select ClearKey decryptor because we select the first that matches and the PlayReady test won't provide a key for it, we are screwed :)

As I said, I think the solution is providing more than one structure at the caps for the outgoing stream. This will be a nightmare in WebKit too, but life sucks sometimes ;)
Comment 1 Tim-Philipp Müller 2016-08-18 18:10:00 UTC
I'm not sure how you envision "providing more than one structure at the caps for the outgoing stream" will work.

The way this works was a design decision and done on purpose.

We may have to add some way to query whether a key is available then or something when selecting the system.

I presume the version was supposed to be 1.8.0?
Comment 2 Sebastian Dröge (slomo) 2016-08-18 18:12:29 UTC
The idea was that qtdemux checks for which DRM schemes a decryptor exists, and exposes caps according to the highest-ranked one. This could probably be extended via some magic with GstContext to allow the application to give its own preferences per pipeline.

Why is it always exposing the first for you? You have decryptors for all 3, but only one is going to work?
Comment 3 Sebastian Dröge (slomo) 2016-08-18 18:13:04 UTC
(In reply to Tim-Philipp Müller from comment #1)
> I'm not sure how you envision "providing more than one structure at the caps
> for the outgoing stream" will work.

Mixed caps :)
Comment 4 Thiago Sousa Santos 2016-08-18 18:35:03 UTC
(In reply to Sebastian Dröge (slomo) from comment #3)
> (In reply to Tim-Philipp Müller from comment #1)
> > I'm not sure how you envision "providing more than one structure at the caps
> > for the outgoing stream" will work.
> 
> Mixed caps :)

Is there any docs on mixed caps yet? I never looked at how it is supposed to work and handle intersections and similar operations we do in caps.


We could use a GstContext... or a bus sync message. Isn't a GstContext just like the order of the element ranks? Except that it would be per-pipeline rather than system wide. The message would be stream specific and seems more direct to the point IMHO.
Comment 5 Xabier Rodríguez Calvar 2016-08-19 10:49:56 UTC
(In reply to Tim-Philipp Müller from comment #1)
> I'm not sure how you envision "providing more than one structure at the caps
> for the outgoing stream" will work.
> 
> The way this works was a design decision and done on purpose.
> 
> We may have to add some way to query whether a key is available then or
> something when selecting the system.

Caps can have more than one structure, right? Usually people access only the first, meaning index 0.

My proposal would be to duplicate the structure for all the usable decryption systems. Pardon my ignorance if this is not possible or it does more harm than good.

> I presume the version was supposed to be 1.8.0?

I am trying with 1.8.2.

(In reply to Sebastian Dröge (slomo) from comment #2)
> The idea was that qtdemux checks for which DRM schemes a decryptor exists,
> and exposes caps according to the highest-ranked one. This could probably be
> extended via some magic with GstContext to allow the application to give its
> own preferences per pipeline.
> 
> Why is it always exposing the first for you?

According to this function that is used in qtdemux, it seems to use the first or am I wrong?:

const gchar *
gst_protection_select_system (const gchar ** system_identifiers)
{
  GList *decryptors, *walk;
  const gchar *retval = NULL;

  decryptors =
      gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_DECRYPTOR,
      GST_RANK_MARGINAL);

  for (walk = decryptors; !retval && walk; walk = g_list_next (walk)) {
    GstElementFactory *fact = (GstElementFactory *) walk->data;
    retval = gst_protection_factory_check (fact, system_identifiers);
  }

  gst_plugin_feature_list_free (decryptors);

  return retval;
}

> You have decryptors for all 3,
> but only one is going to work?

We have for two, but it is a combination of JS app and WebKit that decides which one should be used (I didn't check yet how that can be handled).
Comment 6 Tim-Philipp Müller 2016-08-19 11:02:40 UTC
Caps describing an actual output media format (sent downstream as CAPS event) must be fixed caps, which implies one structure.
Comment 7 Xabier Rodríguez Calvar 2016-08-19 14:29:07 UTC
(In reply to Tim-Philipp Müller from comment #6)
> Caps describing an actual output media format (sent downstream as CAPS
> event) must be fixed caps, which implies one structure.

I was afraid of this :)

So I guess a message answered thru the sync handler could be an option, or at least a list of possible alternative decryptors in another element of the structure that wouldn't break ABI.
Comment 8 Xabier Rodríguez Calvar 2016-09-08 17:11:47 UTC
Ok, my plans are:

* Creating and interface that will allow other demuxers to follow the same approach. This interface will have a method to set the preferred system id.
* qtdemux will implement this interface and at the moment of selecting the decryptor, it will send a message to the bus that shall be answered in the sync handler. If we don't get a satisfactory answer, we proceed as we do now, if not, we select the handler specified by the user. Of course, the interface will provide a helper to send that message.

How does this sound? If I don't get an answer I will begin with this.
Comment 9 Sebastian Dröge (slomo) 2016-09-10 08:32:21 UTC
Sounds like a job for GstContext to me, if you want to implement something like your plan. It has all the pieces you need for that already.


Alternatively this could be implemented with mixed-caps, but then someone would have to finish the design and implementation of those first.
Comment 10 Xabier Rodríguez Calvar 2016-09-16 14:47:14 UTC
Created attachment 335704 [details] [review]
1/1 gst-plugins-good

I am uploading this patch cause I had already cooked it but it is useless for the use case I explained. The patch checks for a preferred system id when it is going to configure the protected caps and if it is not available it will ask for the context. After that, if there is that preferred system, it will use it and if not it will use the other path.

Why do I say this is useless?

In our test case:

1. The stream is injected.
2. qtdemux detects the protection system ids, generates events for them and keeps them until the streams are set up.
3. It selects the system system (with or without my patch) and creates the protected caps.
4. The streams are set up and the events are emitted.

For us and according to the spec (the old one and I haven't checked the new one thoroughly but I bet it would be similar, you only have to see the diagram at https://www.w3.org/TR/encrypted-media/stack_overview.svg to realize that it is always the media system telling the upper layers if the media is encrypted or not) we cannot know in advance if the stream is encrypted and there is no [old] spec to see what happens when you find more than one encryption system (if you fire the needkey events and so on).
Comment 11 Xabier Rodríguez Calvar 2016-09-16 14:48:34 UTC
Summing up, I will close this bug for now and leave the patch there in case you find it is interesting now or in the future.
Comment 12 Xabier Rodríguez Calvar 2016-12-05 18:20:33 UTC
Created attachment 341420 [details] [review]
1/1 gst-plugins-good qtdemux patch

I got this patch working with WebKit for ARM and thanks to it I manage to pass some more YouTube tests.

The good thing is that this patch does not modify any API/ABI so it won't make other implementations stop working.
Comment 13 Xabier Rodríguez Calvar 2016-12-07 19:27:46 UTC
Created attachment 341576 [details] [review]
2/2 gstreamer

I had forgotten to add this patch that would be also needed for GStreamer core.
Comment 14 Xabier Rodríguez Calvar 2017-01-27 13:29:48 UTC
Created attachment 344417 [details] [review]
2/2 gstreamer
Comment 15 Xabier Rodríguez Calvar 2017-01-27 13:31:09 UTC
(In reply to Xabier Rodríguez Calvar from comment #14)
> Created attachment 344417 [details] [review] [review]
> 2/2 gstreamer

I was about to put these patches into WebKit internal jhbuild and realized that the patch was duplicated and incorrectly labeled. Now both are ok.
Comment 16 Enrique Ocaña González 2017-05-21 09:43:50 UTC
Created attachment 352261 [details] [review]
1/3 protection: added function to filter system ids

Previous patch for gstreamer by Calvaris rebased to latest master (e3ab5e4d)
Comment 17 Enrique Ocaña González 2017-05-21 09:48:13 UTC
Created attachment 352262 [details] [review]
2/3 qtdemux: add context for a preferred protection

Previous patch for gstreamer by Calvaris rebased to latest gst-plugins-good master (4f713717), plus some minor modifications by Enrique to allow selection of undetected key systems.
Comment 18 Enrique Ocaña González 2017-05-21 09:50:27 UTC
Created attachment 352263 [details] [review]
3/3 qtdemux: also push buffers without encryption info instead of dropping them

Test "17. PlayReadyH264Video" in YouTube leanback EME conformance tests 2016
for H.264[1] uses a media file[2] with cenc encryption whose first two 'moof'
boxes have no encryption information (no 'saiz' and 'saio' boxes).

Those boxes are actually not encrypted and the current qtdemux implementation
was just dropping them, breaking the test use case.

This patch detects those kind of situations and just lets the unencrypted
buffers pass. Of course, this needs some collaboration by the decryptors,
which should also do the same and not to try to decrypt those clear buffers.

[1] http://yt-dash-mse-test.commondatastorage.googleapis.com/unit-tests/2016.html?test_type=encryptedmedia-test&webm=false
[2] http://yt-dash-mse-test.commondatastorage.googleapis.com/unit-tests/media/oops_cenc-20121114-142.mp4

This patch depends on the previous two patches being applied.
Comment 19 Tim-Philipp Müller 2017-05-21 11:22:02 UTC
Comment on attachment 352261 [details] [review]
1/3 protection: added function to filter system ids

Looks fine, just some minor niggles:

> 
>+gchar **
>+gst_protection_filter_systems_by_available_decryptors (const gchar **
>+    system_identifiers)
>+{

Need a gtk-doc blurb here for the new API with 'Since: 1.14' marker at end, and add it to the -sections.txt file in docs/gst/ 

>+  GList *decryptors, *walk;
>+  gchar **retval;
>+  guint i = 0, decryptors_number;
>+
>+  decryptors =
>+      gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_DECRYPTOR,
>+      GST_RANK_MARGINAL);
>+
>+  decryptors_number = g_list_length (decryptors);
>+  retval = g_new (gchar *, decryptors_number + 1);
>+
>+  GST_TRACE ("found %u decrytors", decryptors_number);
>+
>+  for (walk = decryptors; walk; walk = g_list_next (walk)) {
>+    GstElementFactory *fact = (GstElementFactory *) walk->data;
>+
>+    const char *found_sys_id =
>+        gst_protection_factory_check (fact, system_identifiers);
>+    GST_TRACE ("factory %s is valid for %s", GST_OBJECT_NAME (fact),
>+        found_sys_id);

Newline after variable declaration above please, and you can probably use GST_DEBUG or GST_LOG here, unless this is called a lot.


>--- a/gst/gstprotection.h
>+++ b/gst/gstprotection.h
>@@ -71,5 +71,8 @@ GstProtectionMeta * gst_buffer_add_protection_meta (GstBuffer * buffer,
> GST_EXPORT
> const gchar * gst_protection_select_system (const gchar ** system_identifiers);
> 
>+gchar ** gst_protection_filter_systems_by_available_decryptors (
>+    const gchar ** system_identifiers);
>+

This needs a GST_EXPORT, and you'll also need to run 'make update-exports' (there should be a new entry in the win32 .def file for the new function).
Comment 20 Tim-Philipp Müller 2017-05-21 12:30:13 UTC
Comment on attachment 352262 [details] [review]
2/3 qtdemux: add context for a preferred protection

Again mostly style niggles, otherwise I'm fine with it:
 
> static void
>+gst_qtdemux_set_context (GstElement * element, GstContext * context)
>+{
>+  GstQTDemux *qtdemux = GST_QTDEMUX (element);
>+
>+  g_return_if_fail (GST_IS_CONTEXT (context));
>+
>+  if (g_strcmp0 (gst_context_get_context_type (context),
>+          "drm-preferred-decryption-system-id") == 0) {

Use gst_context_has_context_type(). If you rename 'context' to 'ctx' it might even fit into a single line without getting indented ;)


>+    const GstStructure *s;
>+
>+    s = gst_context_get_structure (context);
>+    qtdemux->preferred_protection_system_id =
>+        g_strdup (gst_structure_get_string (s, "decryption-system-id"));

Should probably free any previously-saved id here?

What about locking?


>+  GST_TRACE_OBJECT (element, "chaining set_context to superclass %p or %p",
>+      GST_ELEMENT_GET_CLASS (element), parent_class);

Does this trace statement add anything? It looks like it should be removed.



>+static void
> qtdemux_parse_ftyp (GstQTDemux * qtdemux, const guint8 * buffer, gint length)
> {
>   /* counts as header data */
>@@ -3820,6 +3851,8 @@ qtdemux_parse_pssh (GstQTDemux * qtdemux, GNode * node)
>   event = gst_event_new_protection (sysid_string, pssh,
>       (parent_box_type == FOURCC_moov) ? "isobmff/moov" : "isobmff/moof");
>   for (i = 0; i < qtdemux->n_streams; ++i) {
>+    GST_TRACE_OBJECT (qtdemux,
>+        "adding protection event for stream %d and system %s", i, sysid_string);
>     g_queue_push_tail (&qtdemux->streams[i]->protection_scheme_event_queue,
>         gst_event_ref (event));
>   }
>@@ -5530,6 +5563,12 @@ gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
>     GstEvent *event;
> 
>     while ((event = g_queue_pop_head (&stream->protection_scheme_event_queue))) {
>+#if (!GST_DISABLE_GST_DEBUG)
>+      const gchar *system_id = NULL;
>+      gst_event_parse_protection (event, &system_id, NULL, NULL);
>+      GST_TRACE_OBJECT (qtdemux, "pushing again protection event for system %s",
>+          system_id);
>+#endif

How about just:

        GST_TRACE_OBJECT (stream->pad, "pushing protection event: %" GST_PTR_FORMAT, event);

or somesuch? Without the #if (which should probably also be #ifdef)

 
>+static gboolean
>+gst_qtdemux_run_query (GstElement * element, GstQuery * query,
>+    GstPadDirection direction)
>+{
>+  ...
>+  GValue res = { 0, };
>+
>+  g_value_init (&res, G_TYPE_BOOLEAN);
>+  ...
>+  return g_value_get_boolean (&res);
>+}

Strictly speaking we're missing a g_value_unset() here, but it's fine to skip it in this case.


>+static void
>+gst_qtdemux_request_protection_context_if_needed (GstQTDemux * qtdemux,
>+    QtDemuxStream * stream)
>+{

We can probably drop the _if_needed() here?


>+  GST_TRACE_OBJECT (qtdemux, "currently we have detected %u protection systems",
>+      qtdemux->protection_system_ids->len);

Maybe drop "currently we have" (seems overly verbose).


>+  if (stream->protection_scheme_event_queue.length) {
>+    ...
>+    walk = stream->protection_scheme_event_queue.tail;
>+  } else {
>+    ...
>+    walk = qtdemux->protection_event_queue.tail;
>+  }
>+
>+  g_value_init (&event_list, GST_TYPE_LIST);
>+  for (; walk; walk = g_list_previous (walk)) {
>+    ...
>+  }

OOC, what is the reason we're walking the event queues backwards here?


>+  /*  2a) Query downstream with GST_QUERY_CONTEXT for the context and
>+   *      check if downstream already has a context of the specific type
>+   *  2b) Query upstream as above.
>+   */
>+  query = gst_query_new_context ("drm-preferred-decryption-system-id");
>+  st = (GstStructure *) gst_query_get_structure (query);

st = gst_query_writable_structure (query);



>+  gst_qtdemux_request_protection_context_if_needed (qtdemux, stream);
>+  if (qtdemux->preferred_protection_system_id != NULL) {
>+    guint i;

newline after declaration (gst-indent doesn't do that, sorry)

>+    for (i = 0; i < qtdemux->protection_system_ids->len; i++) {
>+      if (g_strcmp0 (g_ptr_array_index (qtdemux->protection_system_ids, i),
>+              qtdemux->preferred_protection_system_id) == 0) {
>+        const gchar *preferred_system_array[] =
>+            { qtdemux->preferred_protection_system_id, NULL };
>+        selected_system = gst_protection_select_system (preferred_system_array);
>+        break;
>+      }
>+    }
>+  }

Wonder if this could be written a bit nicer with some temp variables, but not a dealbreaker :)
Comment 21 Enrique Ocaña González 2017-05-21 13:16:19 UTC
Created attachment 352272 [details] [review]
1/3 protection: added function to filter system ids (review suggestions applied)

Thanks for the review. Here's the 1/3 patch with the applied suggestions.
Comment 22 Xabier Rodríguez Calvar 2017-05-21 13:34:36 UTC
(In reply to Tim-Philipp Müller from comment #20)
> >+  if (stream->protection_scheme_event_queue.length) {
> >+    ...
> >+    walk = stream->protection_scheme_event_queue.tail;
> >+  } else {
> >+    ...
> >+    walk = qtdemux->protection_event_queue.tail;
> >+  }
> >+
> >+  g_value_init (&event_list, GST_TYPE_LIST);
> >+  for (; walk; walk = g_list_previous (walk)) {
> >+    ...
> >+  }
> 
> OOC, what is the reason we're walking the event queues backwards here?

Cause that way, we queue the protection events in the same order they are found in the media. If we don't walk the queue backwards, we'll have to do it in the client, but I think pushing the events in the same order they are found is a good idea.
Comment 23 Enrique Ocaña González 2017-05-21 13:35:17 UTC
Created attachment 352274 [details] [review]
1/3 protection: added function to filter system ids (review suggestions applied)
Comment 24 Enrique Ocaña González 2017-05-21 17:19:18 UTC
Created attachment 352311 [details] [review]
2/3 qtdemux: add context for a preferred protection (review suggestions applied)

Applied the review suggestions except the event queues backward walking (Calvaris commented the rationale of iterating backwards) and the lack of locking.

We discussed in person about this lack of locking and realized that gst_qtdemux_set_context() could actually be called from any thread (eg: by the application from the main thread, not just by qtdemux in the streaming thread) and that's why some locking on the object (on qtdemux) would be needed. However, locks aren't recursive and it's not clear how we would detect if recursion is happening and the lock is already acquired. The summary of the discussion was to forget about locking by now and just assume that the only caller of gst_qtdemux_set_context() will be the streaming thread.
Comment 25 Xabier Rodríguez Calvar 2017-06-22 11:04:50 UTC
Created attachment 354242 [details] [review]
2/3 qtdemux: add context for a preferred protection (review suggestions applied)

I reworked the patch to make it more efficient since there were some checks that had sense before but they don't since we are going to try what is preferred by the context even it wasn't reported as encryption system by the media. I also fixed the case about not having a recommendation from the app that was ending in an error. As it is now:

1- runs the context query if no context was set to the demuxer with all the encryption information found on the media
2- checks if there's a decryptor for the preferred encryption system if any. If it can find the decryptor, ok, if it can't then it warns
3- if there is no preferred selected system, it runs the old algorithm to keep the same behavior that it had so far

According to our last conversations with Tim during the hackfest, this would "landable" as it is now.
Comment 26 Tim-Philipp Müller 2017-06-26 10:37:03 UTC
Comment on attachment 352274 [details] [review]
1/3 protection: added function to filter system ids (review suggestions applied)

>+/**
>+ * gst_protection_filter_systems_by_available_decryptors

This needs a colon at the end I believe?

>+ * Returns: (transfer full): A null terminated array containing all the
>+ * @system_identifiers supported by the set of available decryptors.

Apologies if I've asked this before already, but it seems if there are not matches we currently return an array with str[0] = NULL. Wouldn't it be better to return NULL in case there are no matches?
Comment 27 Xabier Rodríguez Calvar 2017-06-28 08:05:14 UTC
Created attachment 354610 [details] [review]
1/3 protection: added function to filter system ids (review suggestions applied)

Complied with suggestions
Comment 28 Tim-Philipp Müller 2017-06-28 09:53:26 UTC
Comment on attachment 354610 [details] [review]
1/3 protection: added function to filter system ids (review suggestions applied)

commit bda8440f1f0de5be8036acfd78ec1d72929558ec
Author: Xabier Rodriguez Calvar <calvaris@igalia.com>
Date:   Wed Jun 28 09:54:56 2017 +0200

    protection: add function to filter system ids
    
    gst_protection_filter_systems_by_available_decryptors() takes an array
    of strings and returns a new array of strings filtered by the available
    decryptors for them so the ones you get are the ones that you should be
    able to decrypt.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=770107
Comment 29 Xabier Rodríguez Calvar 2017-07-04 09:36:48 UTC
Comment on attachment 354242 [details] [review]
2/3 qtdemux: add context for a preferred protection (review suggestions applied)

There's a funny thing with W3C tests that renders 2/3 patch useless without changes, therefore I am marking it as obsolete until I change it for the purpose I'll state next.

We use W3C tests in WebKit upstream and media used in them is encrypted with Widevine and PlayReady but tests will decrypt them with ClearKey. We don't provide decryptors neither for PlayReady nor for Widevine (yet) upstream so in this case the patch does not trigger the context query because it thinks there is no decryptor for that. I'll rework this to trigger the query anyway which should be harmless and won't change current behavior.
Comment 30 Xabier Rodríguez Calvar 2017-07-04 15:04:08 UTC
Created attachment 354878 [details] [review]
2/3 qtdemux: add context for a preferred protection (review suggestions applied)

Removed the requirement of having a valid decryptor to run the context query. In this case we could be able do decrypt with another available decryptor that is not reported by the media.
Comment 31 Thibault Saunier 2018-05-17 20:38:27 UTC
Review of attachment 354878 [details] [review]:

Looks good, I just have the impression locking will need fixing in all the protection system related code as thread safety looks fishy there, I do not see any locking around the arrays/fields which doesn't sound right at first sight. This patch doesn't make it better nor worth afaics so I would not block on that.
Comment 32 Thibault Saunier 2018-05-17 20:38:32 UTC
Review of attachment 354878 [details] [review]:

Looks good, I just have the impression locking will need fixing in all the protection system related code as thread safety looks fishy there, I do not see any locking around the arrays/fields which doesn't sound right at first sight. This patch doesn't make it better nor worth afaics so I would not block on that.
Comment 33 Thibault Saunier 2018-05-17 20:49:21 UTC
Review of attachment 352263 [details] [review]:

This makes sense, let's get it in.
Comment 34 Michael Catanzaro 2018-08-17 18:30:24 UTC
All patches have been committed... does this need to still be open?
Comment 35 Thibault Saunier 2018-08-17 19:42:16 UTC
Sorry about that, something went wrong while merging with git-bz I have the impression. Let's close and add commit refs:


commit ee4b45da24cb7465b416c230597f8efc7b2c45cb
Author: Xabier Rodriguez Calvar <calvaris@igalia.com>
Date:   Wed Jun 21 17:59:21 2017 +0200

    qtdemux: add context for a preferred protection

    qtdemux selected the first system corresponding to a working GStreamer
    decryptor. With this change, before selecting that decryptor, qtdemux
    will check if it has context (a preferred decryptor id) and if not, it
    will request it.

    The request includes track-id, available key system ids for the
    available decryptors and even the events so that the init data is
    accessible.

    [eocanha@igalia.com: select the preferred protection system even if not available]

    Test "4. ClearKeyVideo" in YouTube leanback EME conformance tests 2016 for
    H.264[1] uses a media file[2] with cenc encryption which embeds 'pssh' boxes
    with the init data for the Playready and Widevine encryption systems, but not
    for the ClearKey encryption system (as defined by the EMEv0.1b spec[3] and with
    the encryption system id defined in [4]).

    Instead, the ClearKey encryption system is manually selected by the web page
    code (even if not originally detected by qtdemux) and the proper decryption key
    is dispatched to the decryptor, which can then decrypt the video successfully.

    [1] http://yt-dash-mse-test.commondatastorage.googleapis.com/unit-tests/2016.html?test_type=encryptedmedia-test&webm=false
    [2] http://yt-dash-mse-test.commondatastorage.googleapis.com/unit-tests/media/car_cenc-20120827-86.mp4
    [3] https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html#simple-decryption-clear-key
    [4] https://www.w3.org/Bugs/Public/show_bug.cgi?id=24027#c2

    https://bugzilla.gnome.org/show_bug.cgi?id=770107

---

commit 844423ff99e281fc831303b92861ed43ce5c1518
Author: Enrique Ocaña González <eocanha@igalia.com>
Date:   Sat May 20 16:55:40 2017 +0000

    qtdemux: also push buffers without encryption info instead of dropping them

    Test "17. PlayReadyH264Video" in YouTube leanback EME conformance tests 2016
    for H.264[1] uses a media file[2] with cenc encryption whose first two 'moof'
    boxes have no encryption information (no 'saiz' and 'saio' boxes).

    Those boxes are actually not encrypted and the current qtdemux implementation
    was just dropping them, breaking the test use case.

    This patch detects those kind of situations and just lets the unencrypted
    buffers pass. Of course, this needs some collaboration by the decryptors,
    which should also do the same and not to try to decrypt those clear buffers.

    [1] http://yt-dash-mse-test.commondatastorage.googleapis.com/unit-tests/2016.html?test_type=encryptedmedia-test&webm=false
    [2] http://yt-dash-mse-test.commondatastorage.googleapis.com/unit-tests/media/oops_cenc-20121114-142.mp4

    https://bugzilla.gnome.org/show_bug.cgi?id=770107
Comment 36 Michael Catanzaro 2018-08-17 22:30:57 UTC
(In reply to Thibault Saunier from comment #35)
> Let's close

Let me help you with that? :P