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

Initial selection and level filtering based on preferred codecs and MediaCapabilities #5704

Merged
merged 12 commits into from
Aug 21, 2023

Conversation

robwalch
Copy link
Collaborator

@robwalch robwalch commented Jul 27, 2023

This PR will...

Make initial variant selection based on preferred codec rather than the first variant in the multivariant playlist

  • hls.firstAutoLevel is used to evaluate first level based on available codecs, resolution, framerate, default or autoselect audio options, audio channels, video-range, and score, not exceeding 1080p*, 30fps*, SDR, or stereo when possible.
    * Resolution and frame-rate of first auto level may exceed 1080p/30fps when initial bandwidth estimate allows and capLevelToPlayerSize is not enabled.

MediaCapabilities support

  • Run mediaCapabilities.decodingInfo checks for UHD, HFR, and HDR variants, as well as multi-channel-audio renditions
    • Auto adaptations will not occur on variants running tests until they have passed
    • Failed checks will result in the level being removed

MediaCapabilities checks will be added to another PR to prevent switching up to UHD and HFR variants on constrained devices.

API enhancements

  • Adds hls.firstAutoLevel getter, used internally to get the starting level index.
  • hls.levels are sorted on height, frame rate, preferred codec, and video-range to infer order by quality. Height-first sorting allows cap-level-lontroller to set a max quality index at the maximum allowed resolution.
  • Adds getters for all audio tracks and all subtitle tracks: hls.allAudioTracks and hls.allSubtitleTracks.
  • In Base initial bandwidth estimate on first level bitrate #5649 abrEwmaDefaultEstimateMax was added. HLS.js will no longer start on the first variant (hls.firstLevel), or any variant of a preferred codec, if its BANDWIDTH exceeds this value.

Changes to Level parsing

  • Level.bitrate uses variant BANDWIDTH (required peak bitrate) before falling back to optional AVERAGE-BANDWIDTH.
  • Level.averageBitrate returns parsed AVERAGE-BANDWIDTH. Falls back to runtime average Level.realBitrate (which is only set when config.abrMaxWithRealBitrate is enabled) and finally Level.bitrate (BANDWIDTH).
  • Added Level.frameRate returns parsed FRAME-RATE number or 0.
  • Added Level.codecs returns parsed CODECS or emptry string.
  • Added Level.score returns parsed SCORE number or 0.

Performance Improvements

  • Reduced the number of times nextAutoLevel is evaluated.

Error handling improvements

  • Switch back to auto mode when erroring in manual mode.
  • Find alternate on BUFFER_APPEND_ERROR and BUFFER_ADD_CODEC_ERROR errors.
  • Do not switch to playlists that have errored or failed to append media.
  • Only reset level|track.fragmentError count on successful append.
  • Reset append error count on successful appends for mixed muxed/unmuxed error handling

Why is this Pull Request needed?

HLS.js is expected to select more efficient codecs from the start of playback.

Are there any points in the code the reviewer needs to double check?

Switching from SDR to HDR, stereo to multi-channel audio, or from one codec family to another, requires a manual level change. Options to auto-select or prefer these configurations may be added in the future. Auto codec switching may be added after implementing MediaCapabilities MediaCapabilitiesDecodingInfo.transition if it proves to be well supported and implemented.

Additional MediaCapabilities options, like blocking and filtering levels before start (MANIFEST_PARSED), or choosing which variants to run checks on and what to do with supported results that are not smooth or power efficient will be considered upon request. Currently, all checks are performed after startup, and do not prevent manual selection of variants (levels) and renditions (audio tracks).

Resolves issues:

Related issues (may not resolve but should improve)

Checklist

  • changes have been done against master branch, and PR does not conflict
  • new unit / functional tests have been added (whenever applicable)
  • API or design changes are documented in API.md

@robwalch robwalch added this to the 1.5.0 milestone Jul 27, 2023
Comment on lines 198 to 199
({ videoCodec, videoRange, width, height }) =>
!!videoCodec || !!(width && height) || !isVideoRange(videoRange)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I may not be following this correctly, but is the !isVideoRange(videoReange) portion of this filter correct? The comment says "remove invalid video-range levels", but this logic seems to do the opposite.

Copy link
Collaborator Author

@robwalch robwalch Jul 28, 2023

Choose a reason for hiding this comment

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

Thanks for catching that. It's not doing anything because of the OR. Just pushed a test and fix: 823472d bde0ad2

Note: VIDEO-RANGE is optional, with an assumed value of 'SDR' when not specified. The point here is to remove variants with invalid or unknown values.

@robwalch robwalch force-pushed the feature/initial-quality-selection branch from 823472d to bde0ad2 Compare August 2, 2023 01:04
@robwalch robwalch force-pushed the feature/initial-quality-selection branch from 529fa70 to cbd916a Compare August 3, 2023 01:08
@robwalch robwalch force-pushed the feature/initial-quality-selection branch 2 times, most recently from 6d12749 to cc59087 Compare August 4, 2023 20:03
robwalch added a commit that referenced this pull request Aug 9, 2023
@robwalch robwalch changed the title Initial selection based on preferred codecs Initial selection and level filtering based on preferred codecs and MediaCapabilities Aug 9, 2023
robwalch added a commit that referenced this pull request Aug 15, 2023
@robwalch robwalch force-pushed the feature/initial-quality-selection branch from b5964c9 to 1610b01 Compare August 15, 2023 01:33
@robwalch robwalch force-pushed the feature/initial-quality-selection branch from 1610b01 to 6061fef Compare August 17, 2023 00:18
@robwalch robwalch merged commit b536883 into master Aug 21, 2023
@robwalch robwalch deleted the feature/initial-quality-selection branch August 21, 2023 22:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants