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

Force media capabilities check for HEVC to avoid failure on Windows #6849

Merged
merged 1 commit into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions api-extractor/report/hls.js.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -3237,6 +3237,8 @@ export interface LevelLoadedData {
// (undocumented)
level: number;
// (undocumented)
levelInfo: Level;
// (undocumented)
networkDetails: any;
// (undocumented)
stats: LoaderStats;
Expand All @@ -3253,6 +3255,8 @@ export interface LevelLoadingData {
// (undocumented)
level: number;
// (undocumented)
levelInfo: Level;
// (undocumented)
pathwayId: string | undefined;
// (undocumented)
url: string;
Expand Down Expand Up @@ -4141,6 +4145,8 @@ export interface PlaylistLoaderContext extends LoaderContext {
// (undocumented)
levelDetails?: LevelDetails;
// (undocumented)
levelOrTrack: Level | MediaPlaylist | null;
// (undocumented)
pathwayId?: string;
// (undocumented)
type: PlaylistContextType;
Expand Down Expand Up @@ -4626,6 +4632,8 @@ export interface TrackLoadedData {
networkDetails: any;
// (undocumented)
stats: LoaderStats;
// (undocumented)
track: MediaPlaylist;
}

// Warning: (ae-missing-release-tag) "TrackLoadingData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
Expand All @@ -4639,6 +4647,8 @@ export interface TrackLoadingData {
// (undocumented)
id: number;
// (undocumented)
track: MediaPlaylist;
// (undocumented)
url: string;
}

Expand Down
8 changes: 6 additions & 2 deletions src/controller/abr-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -794,14 +794,15 @@ class AbrController extends Logger implements AbrComponentAPI {
| undefined;
if (
typeof mediaCapabilities?.decodingInfo === 'function' &&
requiresMediaCapabilitiesDecodingInfo(
(requiresMediaCapabilitiesDecodingInfo(
levelInfo,
audioTracksByGroup,
currentVideoRange,
currentFrameRate,
currentBw,
audioPreference,
)
) ||
levelInfo.videoCodec?.substring(0, 4) === 'hvc1') // Force media capabilities check for HEVC to avoid failure on Windows
) {
levelInfo.supportedPromise = getMediaDecodingInfoPromise(
levelInfo,
Expand Down Expand Up @@ -830,6 +831,9 @@ class AbrController extends Logger implements AbrComponentAPI {
if (index > -1 && levels.length > 1) {
this.log(`Removing unsupported level ${index}`);
this.hls.removeLevel(index);
if (this.hls.loadLevel === -1) {
this.hls.nextLoadLevel = 0;
}
}
}
});
Expand Down
1 change: 1 addition & 0 deletions src/controller/audio-track-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ class AudioTrackController extends BasePlaylistController {
id,
groupId,
deliveryDirectives: hlsUrlParameters || null,
track: audioTrack,
});
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/controller/level-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ export default class LevelController extends BasePlaylistController {

protected onLevelLoaded(event: Events.LEVEL_LOADED, data: LevelLoadedData) {
const { level, details } = data;
const curLevel = this._levels[level];
const curLevel = data.levelInfo;

if (!curLevel) {
this.warn(`Invalid level index ${level}`);
Expand All @@ -612,7 +612,7 @@ export default class LevelController extends BasePlaylistController {
}

// only process level loaded events matching with expected level
if (level === this.currentLevelIndex) {
if (curLevel === this.currentLevel) {
// reset level load error counter on successful level loaded only if there is no issues with fragments
if (curLevel.fragmentError === 0) {
curLevel.loadError = 0;
Expand Down Expand Up @@ -665,6 +665,7 @@ export default class LevelController extends BasePlaylistController {
this.hls.trigger(Events.LEVEL_LOADING, {
url,
level: currentLevelIndex,
levelInfo: currentLevel,
pathwayId: currentLevel.attrs['PATHWAY-ID'],
id: 0, // Deprecated Level urlId
deliveryDirectives: hlsUrlParameters || null,
Expand Down
4 changes: 2 additions & 2 deletions src/controller/stream-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ export default class StreamController
if (!levels || this.state !== State.IDLE) {
return;
}
const level = levels[data.level];
const level = data.levelInfo;
if (
!level.details ||
(level.details.live && this.levelLastLoaded !== level) ||
Expand Down Expand Up @@ -667,7 +667,7 @@ export default class StreamController
}, cc [${newDetails.startCC}, ${newDetails.endCC}] duration:${duration}`,
);

const curLevel = levels[newLevelId];
const curLevel = data.levelInfo;
const fragCurrent = this.fragCurrent;
if (
fragCurrent &&
Expand Down
1 change: 1 addition & 0 deletions src/controller/subtitle-track-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ class SubtitleTrackController extends BasePlaylistController {
id,
groupId,
deliveryDirectives: hlsUrlParameters || null,
track: currentTrack,
});
}
}
Expand Down
46 changes: 38 additions & 8 deletions src/loader/playlist-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ import type { NetworkComponentAPI } from '../types/component-api';
import type {
ErrorData,
LevelLoadingData,
LevelsUpdatedData,
ManifestLoadingData,
TrackLoadingData,
} from '../types/events';
import type { LevelParsed, VariableMap } from '../types/level';
import type { Level, LevelParsed, VariableMap } from '../types/level';
import type {
Loader,
LoaderCallbacks,
Expand All @@ -31,7 +32,7 @@ import type {
LoaderStats,
PlaylistLoaderContext,
} from '../types/loader';
import type { MediaAttributes } from '../types/media-playlist';
import type { MediaAttributes, MediaPlaylist } from '../types/media-playlist';

function mapContextToLevelType(
context: PlaylistLoaderContext,
Expand Down Expand Up @@ -86,6 +87,7 @@ class PlaylistLoader implements NetworkComponentAPI {
hls.on(Events.LEVEL_LOADING, this.onLevelLoading, this);
hls.on(Events.AUDIO_TRACK_LOADING, this.onAudioTrackLoading, this);
hls.on(Events.SUBTITLE_TRACK_LOADING, this.onSubtitleTrackLoading, this);
hls.on(Events.LEVELS_UPDATED, this.onLevelsUpdated, this);
}

private unregisterListeners() {
Expand All @@ -94,6 +96,7 @@ class PlaylistLoader implements NetworkComponentAPI {
hls.off(Events.LEVEL_LOADING, this.onLevelLoading, this);
hls.off(Events.AUDIO_TRACK_LOADING, this.onAudioTrackLoading, this);
hls.off(Events.SUBTITLE_TRACK_LOADING, this.onSubtitleTrackLoading, this);
hls.off(Events.LEVELS_UPDATED, this.onLevelsUpdated, this);
}

/**
Expand All @@ -118,7 +121,7 @@ class PlaylistLoader implements NetworkComponentAPI {
return this.loaders[context.type];
}

private resetInternalLoader(contextType): void {
private resetInternalLoader(contextType: PlaylistContextType): void {
if (this.loaders[contextType]) {
delete this.loaders[contextType];
}
Expand All @@ -134,7 +137,7 @@ class PlaylistLoader implements NetworkComponentAPI {
loader.destroy();
}

this.resetInternalLoader(contextType);
this.resetInternalLoader(contextType as PlaylistContextType);
}
}

Expand All @@ -157,11 +160,12 @@ class PlaylistLoader implements NetworkComponentAPI {
type: PlaylistContextType.MANIFEST,
url,
deliveryDirectives: null,
levelOrTrack: null,
});
}

private onLevelLoading(event: Events.LEVEL_LOADING, data: LevelLoadingData) {
const { id, level, pathwayId, url, deliveryDirectives } = data;
const { id, level, pathwayId, url, deliveryDirectives, levelInfo } = data;
this.load({
id,
level,
Expand All @@ -170,14 +174,15 @@ class PlaylistLoader implements NetworkComponentAPI {
type: PlaylistContextType.LEVEL,
url,
deliveryDirectives,
levelOrTrack: levelInfo,
});
}

private onAudioTrackLoading(
event: Events.AUDIO_TRACK_LOADING,
data: TrackLoadingData,
) {
const { id, groupId, url, deliveryDirectives } = data;
const { id, groupId, url, deliveryDirectives, track } = data;
this.load({
id,
groupId,
Expand All @@ -186,14 +191,15 @@ class PlaylistLoader implements NetworkComponentAPI {
type: PlaylistContextType.AUDIO_TRACK,
url,
deliveryDirectives,
levelOrTrack: track,
});
}

private onSubtitleTrackLoading(
event: Events.SUBTITLE_TRACK_LOADING,
data: TrackLoadingData,
) {
const { id, groupId, url, deliveryDirectives } = data;
const { id, groupId, url, deliveryDirectives, track } = data;
this.load({
id,
groupId,
Expand All @@ -202,9 +208,30 @@ class PlaylistLoader implements NetworkComponentAPI {
type: PlaylistContextType.SUBTITLE_TRACK,
url,
deliveryDirectives,
levelOrTrack: track,
});
}

private onLevelsUpdated(
event: Events.LEVELS_UPDATED,
data: LevelsUpdatedData,
) {
// abort and delete loader of removed levels
const loader = this.loaders[PlaylistContextType.LEVEL];
if (loader) {
const context = loader.context;
if (
context &&
!data.levels.some(
(lvl) => lvl === (context as PlaylistLoaderContext).levelOrTrack,
)
) {
loader.abort();
delete this.loaders[PlaylistContextType.LEVEL];
}
}
}

private load(context: PlaylistLoaderContext): void {
const config = this.hls.config;

Expand All @@ -217,7 +244,7 @@ class PlaylistLoader implements NetworkComponentAPI {
if (
loaderContext &&
loaderContext.url === context.url &&
loaderContext.level === context.level
loaderContext.levelOrTrack === context.levelOrTrack
) {
// same URL can't overlap
this.hls.logger.trace('[playlist-loader]: playlist request ongoing');
Expand Down Expand Up @@ -680,6 +707,7 @@ class PlaylistLoader implements NetworkComponentAPI {
case PlaylistContextType.LEVEL:
hls.trigger(Events.LEVEL_LOADED, {
details: levelDetails,
levelInfo: (context.levelOrTrack as Level) || hls.levels[0],
level: levelIndex || 0,
id: id || 0,
stats,
Expand All @@ -690,6 +718,7 @@ class PlaylistLoader implements NetworkComponentAPI {
case PlaylistContextType.AUDIO_TRACK:
hls.trigger(Events.AUDIO_TRACK_LOADED, {
details: levelDetails,
track: context.levelOrTrack as MediaPlaylist,
id: id || 0,
groupId: groupId || '',
stats,
Expand All @@ -700,6 +729,7 @@ class PlaylistLoader implements NetworkComponentAPI {
case PlaylistContextType.SUBTITLE_TRACK:
hls.trigger(Events.SUBTITLE_TRACK_LOADED, {
details: levelDetails,
track: context.levelOrTrack as MediaPlaylist,
id: id || 0,
groupId: groupId || '',
stats,
Expand Down
4 changes: 4 additions & 0 deletions src/types/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,13 +188,15 @@ export interface LevelSwitchedData {
export interface TrackLoadingData {
id: number;
groupId: string;
track: MediaPlaylist;
url: string;
deliveryDirectives: HlsUrlParameters | null;
}

export interface LevelLoadingData {
id: number;
level: number;
levelInfo: Level;
pathwayId: string | undefined;
url: string;
deliveryDirectives: HlsUrlParameters | null;
Expand All @@ -207,12 +209,14 @@ export interface TrackLoadedData {
networkDetails: any;
stats: LoaderStats;
deliveryDirectives: HlsUrlParameters | null;
track: MediaPlaylist;
}

export interface LevelLoadedData {
details: LevelDetails;
id: number;
level: number;
levelInfo: Level;
networkDetails: any;
stats: LoaderStats;
deliveryDirectives: HlsUrlParameters | null;
Expand Down
5 changes: 4 additions & 1 deletion src/types/loader.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { LoaderConfig } from '../config';
import type { HlsUrlParameters } from './level';
import type { HlsUrlParameters, Level } from './level';
import type { MediaPlaylist } from './media-playlist';
import type { Fragment } from '../loader/fragment';
import type { Part } from '../loader/fragment';
import type { KeyLoaderInfo } from '../loader/key-loader';
Expand Down Expand Up @@ -191,4 +192,6 @@ export interface PlaylistLoaderContext extends LoaderContext {
levelDetails?: LevelDetails;
// Blocking playlist request delivery directives (or null id none were added to playlist url
deliveryDirectives: HlsUrlParameters | null;
// Reference to level or track object in hls.levels, hls.allAudioTracks, or hls.allSubtitleTracks (null when loading MVP)
levelOrTrack: Level | MediaPlaylist | null;
}
1 change: 1 addition & 0 deletions tests/unit/controller/audio-stream-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ describe('AudioStreamController', function () {
},
targetduration: 100,
} as unknown as LevelDetails,
track: {} as any,
};

audioStreamController.levels = tracks;
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/controller/audio-track-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ describe('AudioTrackController', function () {
networkDetails: null,
stats: { loading: {} } as any,
deliveryDirectives: null,
track: {} as any,
});
expect(audioTrackController.tracksInGroup[0], 'tracksInGroup[0]')
.to.have.property('details')
Expand All @@ -299,6 +300,7 @@ describe('AudioTrackController', function () {
networkDetails: null,
stats: { loading: {} } as any,
deliveryDirectives: null,
track: {} as any,
});
expect(audioTrackController.tracksInGroup[1], 'tracksInGroup[1]')
.to.have.property('details')
Expand Down
12 changes: 12 additions & 0 deletions tests/unit/controller/stream-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ describe('StreamController', function () {
networkDetails: {},
stats: new LoadStats(),
deliveryDirectives: null,
levelInfo: new Level({
name: '',
url: '',
attrs,
bitrate: 500000,
}),
});
expect(streamController['startPosition']).to.equal(130.5);
expect(streamController['nextLoadPosition']).to.equal(130.5);
Expand Down Expand Up @@ -174,6 +180,12 @@ describe('StreamController', function () {
networkDetails: {},
stats: new LoadStats(),
deliveryDirectives: null,
levelInfo: new Level({
name: '',
url: '',
attrs,
bitrate: 500000,
}),
});
expect(streamController['startPosition']).to.equal(18);
expect(streamController['nextLoadPosition']).to.equal(18);
Expand Down
Loading
Loading