Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] scte214 - use supplemental codec instead of base codec if it's supported #1307

Merged
merged 20 commits into from
Nov 13, 2023

Conversation

Florent-Bouisset
Copy link
Collaborator

Context

This PR add partial support for the SCTE-214 related to Dash.
This PR add in particular the support of the scte214:supplementalCodecs attribute in .mpd Manifests

Supplemental codecs are defined as backwards-compatible codecs enhancing the experience of a base layer codec.
If the supplemental codecs are supported by the device, we should use them instead of the base codec, this would allow to play the medias with a better experience for users.

SCTE-214: https://www.scte.org/standards/library/catalog/scte-214-1-mpeg-dash-for-ip-based-cable-services-part1-mpd-constraints-and-extensions/


Implementation

The proposed logic for this improvement is:

  1. On a representation, check if there is a supplementalCodec.
  2. If there is none, use the base codec for the sourceBuffer and abort all remaining steps.
  3. If there is one, use MediaSource.isTypeSupported on the supplementalCodec to verify if it's supported.
  4. If the supplementalCodec is not supported, use the base codec for the sourceBuffer and abort all remaining steps.
  5. If the supplementalCodec is supported, use the supplemental for the sourceBuffer.

Example

Given the following Manifest:

<Representation id="hvc1_850800=8" bandwidth="850800" width="640" height="360" sar="1:1"
        frameRate="25" codecs="hvc1.2.4.L63.B0" scte214:supplementalCodecs="dvh1.08.01"
        scte214:supplementalProfiles="db1p" segmentProfiles="chd1" />
  • On a device that does not support the codecs dvh1.08.01 the used codec should be hvc1.2.4.L63.B0
  • On a device that supports the codecs dvh1.08.01 the used codec should be dvh1.08.01

Work in progress

  • What about the supplementalProfiles, do we need to have the same logic ?
  • Should also parse the supplementalCodecs on the AdaptationSet
  • Documentation

Copy link
Collaborator

@peaBerberian peaBerberian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also have two other questions:

  • Can supplementalCodec be defined at the AdaptationSet level in an MPD (like codec I think)? In which case we should also parse it when found there.
  • The WASM DASH parser also has to be updated, do you know how to do it or do you want me to do it instead?

src/manifest/representation.ts Outdated Show resolved Hide resolved
src/manifest/representation.ts Outdated Show resolved Hide resolved
src/manifest/representation.ts Outdated Show resolved Hide resolved
test/suppCodec.mpd Outdated Show resolved Hide resolved
@peaBerberian peaBerberian added the Priority: 1 (High) This issue or PR has a high priority. label Nov 7, 2023
@Florent-Bouisset
Copy link
Collaborator Author

I also have two other questions:

  • Can supplementalCodec be defined at the AdaptationSet level in an MPD (like codec I think)? In which case we should also parse it when found there.
  • The WASM DASH parser also has to be updated, do you know how to do it or do you want me to do it instead?

Yes the supplementalCodec can be defined at the AdaptationSet level.
There is example of it in the SCTE 214, so we should parse it.

@peaBerberian
Copy link
Collaborator

peaBerberian commented Nov 7, 2023

I also found out that both SCTE 214 and HLS* indicate the possibility of having multiple supplemental codecs, with a given separator (I think space for DASH SCTE214, and a comma for HLS).
I'm guessing we will repeat here spaces if we have them, so we may want to check what would be the isTypeSupported / addSourceBuffer behavior when encountering a space in the codecs part of the given type. This character may need to be replaced.

* note: we do not offer first class support for HLS yet - putting directfile mode on Safari aside, yet we still consider it as a possible future feature when architecturing things as long as it doesn't sacrifice too much maintainability, in case it become an important subject for us

@@ -213,6 +213,17 @@ export default function parseRepresentations(
codecs = codecs === "mp4a.40.02" ? "mp4a.40.2" : codecs;
parsedRepresentation.codecs = codecs;
}

let supplementalCodecs: string | undefined;
if (representation.attributes.supplementalCodecs != null) {
Copy link

@myoann myoann Nov 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't you use a !==, in order to verify also the type or the existing isNullOrUndefined method in the utils?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used to check if the value is either null or undefined,
@peaBerberian is there any recommandations about using != or the function !isNullOrUndefined ?
Both syntax exists in the project

Copy link
Collaborator

@peaBerberian peaBerberian Nov 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we now try to avoid relying on double equals in the RxPlayer as:

  • double equals' behavior might not be understood by every dev
  • it's more explicit when reading to have the exact conditions written
  • it avoid some classes of bug where we wrote double equals just by lazyness.
    Here the intent is to have to check explicitely for what can happen. In some situations where only null xor undefined are possible at first, we may create a bug in future code if ever the other value become possible.

There are some areas of the code still relying on the == null trick, but that's old logic we ultimately want to replace them by more explicit code.

Copy link
Collaborator Author

@Florent-Bouisset Florent-Bouisset Nov 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, should I change all the != to !isNullOrUndefined in the parse_representation.ts file, or should I do another MR for this change ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you want, both are good to me

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here isn't it only undefined though? I'm unsure

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I think too it's only undefined but as a precaution I didn't want to change the behavior of the API.

@@ -120,19 +122,19 @@ export default function parseRepresentations(
const parsedRepresentations : IParsedRepresentation[] = [];
for (const representation of representationsIR) {
// Compute Representation ID
let representationID = representation.attributes.id != null ?
let representationID = !isNullOrUndefined(representation.attributes.id) ?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm under the impression than none of those attributes can be set to null, in which case the proper way of fixing that double equal to make it more explicit would be to just check against undefined instead

@peaBerberian
Copy link
Collaborator

I've been wondering.

Do we ever want to rely on the old codec value here if the supplementalCodec is used instead?
If yes, for what reason, to add more precision?

The only case we've now seen of actual supplementalCodec usage is for Dolby Vision, where the supplementalCodec seems to always be sufficient in itself, yet it's true we don't know what will come tomorrow.

In the scenario where we never want to rely on the non-used codec anyway, because it is already known which one we use on Representation instanciation, wouldn't it be less error-prone to just set codec to the actually used codec, without considering SCTE214 anymore at this level?

@Florent-Bouisset
Copy link
Collaborator Author

I've been wondering.

Do we ever want to rely on the old codec value here if the supplementalCodec is used instead? If yes, for what reason, to add more precision?

The only case we've now seen of actual supplementalCodec usage is for Dolby Vision, where the supplementalCodec seems to always be sufficient in itself, yet it's true we don't know what will come tomorrow.

In the scenario where we never want to rely on the non-used codec anyway, because it is already known which one we use on Representation instanciation, wouldn't it be less error-prone to just set codec to the actually used codec, without considering SCTE214 anymore at this level?

I think we can set codec with the used codec. It won't change the behavior and it will be simpler for other parts of the code relying on codec

One thing that I was wondering is about changing the device:
If the user is playing a video with the base codec on his mobile phone, and then cast to a TV that is compatible with the supplemental codec (ex: dolby vision), will we re-instanciate the representations ? If we don't, isSupplementalCodecSupported will still be set to false and we will be playing the base codec rather that the supplementalCodec on the TV that was compatible with both.

@peaBerberian
Copy link
Collaborator

If the user is playing a video with the base codec on his mobile phone, and then cast to a TV that is compatible with the supplemental codec (ex: dolby vision), will we re-instanciate the representations ?

All those kinds of usages I know of for now work with two pages, one on the sending device, and one on the receiving device, which both would run their RxPlayer locally.

Though I guess sending chunks from a sender to be decoded in a receiver should theoretically be possible, I'm unsure of how it would interact with the blocking MediaSource.isTypeSupported API. Though I don't remember if the new remote playback API will handle such cases.

@@ -30,3 +31,33 @@ export function getSegmentTimeRoundingError(timescale: number): number {
return config.getCurrent().DEFAULT_MAXIMUM_TIME_ROUNDING_ERROR * timescale;
}

const supplementalCodecSeparator = /[, ]+/g;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, just the indexes directory is normally only for what we call the segment "index" here, which the way segments are announced in the MPD.

So that's probably not the right place for this util

@peaBerberian
Copy link
Collaborator

LGTM, just I had one last comment about the file where one of the utils is declared

@Florent-Bouisset Florent-Bouisset changed the title [WIP][Proposal] scte214 - use supplemental codec instead of base codec if it's supported [Proposal] scte214 - use supplemental codec instead of base codec if it's supported Nov 13, 2023
@peaBerberian
Copy link
Collaborator

I forgot can you unstage dist/mpd-parser.wasm ? We only update files in the dist directory at release time.

@peaBerberian peaBerberian merged commit 491945b into master Nov 13, 2023
2 of 3 checks passed
@peaBerberian peaBerberian deleted the feature-use-supplemental-codec-scte214 branch January 5, 2024 13:57
@peaBerberian peaBerberian restored the feature-use-supplemental-codec-scte214 branch January 5, 2024 13:57
@peaBerberian peaBerberian mentioned this pull request Jan 24, 2024
@peaBerberian peaBerberian deleted the feature-use-supplemental-codec-scte214 branch February 7, 2024 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority: 1 (High) This issue or PR has a high priority.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants