DASH: Implement Content Protection References #1439
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This Pull Request implements the Content Protection referencing logic as for example specified in the ISO/IEC 23009-1:2022 DASH spec at chapter 5.8.4.1.3.
The idea is to reduce the size of an MPD for encrypted contents by preventing the repetition of similar
<ContentProtection>
elements in it. Because ContentProtection can become big due to them containing Base64-encoded binary data (e.g. the PSSH), this can save a lot of space on multi-Period contents with repeating DRM information.This size-saving mechanism works by adding a system of "references" which are
<ContentProtection>
elements that can be "referenced" by other<ContentProtection>
- which simply means that the latter inherits from the former.In appearance simple, this
<ContentProtection>
referencing concept has some edge cases, from how I understood the specification, that complexified its implementation:<ContentProtection>
elements can now be at the<MPD>
and<Period>
levels, in which case it only acts as reference, or at the<AdaptationSet>
and<Representation>
level, in which case it acts as both a reference object and an object to actually apply on the corresponding element.This means that those elements have to be processed differently based on which levels they are found.
It seems that the spec allows some form of what I would call forward-referencing, where a
<ContentProtection>
inherits from another<ContentProtection>
that has not yet been encountered by our current parsing pass.This was the main complexity here as to stay readable I didn't want to add another parsing pass just to resolve all ContentProtection elements (e.g. other loops through all the Periods -> AdaptationSets -> Representation just to parse that single object).
I ended up adding another class, the
ContentProtectionParser
, whose role will be to keep track of references and parse lazily (as soon as all referenced ContentProtection are known) the ContentProtection elements. This is still a little awkward as it means that aRepresentation
that has theoretically already been parsed could be updated after parsing a laterRepresentation
- which seems unnatural and may break some developers' expectations - yet which seems kind of unavoidable (well, in the forward-referencing edge case which is a situation that would probably never happen).Technically, ContentProtection references act as an inheritance system, in the way that it merges attributes from both a referencer and a referenced, with priority for the referencer (if an attribute is found in both). This means that some logic has to be added for the inheritance to be performed (as opposed to just replace the referencer by the referenced).