Skip to content

Commit

Permalink
Add mp4 "stsd" codec parsing for Dolby Vision, VP9, AV1, and audio co…
Browse files Browse the repository at this point in the history
…dec passthrough

Update contributed mp4a, avc, and hevc mp4 "stsd" codec parsing
Clean up mp4 init segment track parsed codec handling
Clean up SourceBuffer `changeType` detection and appends
  • Loading branch information
robwalch committed Jun 1, 2023
1 parent fe6f333 commit b8d101f
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 264 deletions.
7 changes: 4 additions & 3 deletions src/controller/buffer-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ import type Hls from '../hls';
import type { LevelDetails } from '../loader/level-details';

const MediaSource = getMediaSource();
const VIDEO_CODEC_PROFILE_REPACE = /([ha]vc.)(?:\.[^.,]+)+/;
const VIDEO_CODEC_PROFILE_REPLACE =
/(avc[1234]|hvc1|hev1|dvh[1e]|vp09|av01)(?:\.[^.,]+)+/;

export default class BufferController implements ComponentAPI {
// The level details used to determine duration, target-duration and live
Expand Down Expand Up @@ -261,11 +262,11 @@ export default class BufferController implements ComponentAPI {
const { id, codec, levelCodec, container, metadata } =
data[trackName];
const currentCodec = (track.levelCodec || track.codec).replace(
VIDEO_CODEC_PROFILE_REPACE,
VIDEO_CODEC_PROFILE_REPLACE,
'$1'
);
const nextCodec = (levelCodec || codec).replace(
VIDEO_CODEC_PROFILE_REPACE,
VIDEO_CODEC_PROFILE_REPLACE,
'$1'
);
if (currentCodec !== nextCodec) {
Expand Down
2 changes: 1 addition & 1 deletion src/controller/error-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ export default class ErrorController implements NetworkComponentAPI {
const { hls, penalizedRenditions } = this;
const levelIndex: number =
data.parent === PlaylistLevelType.MAIN
? (data.level as number)
? (data.level as number) || 0
: hls.loadLevel;
const level = hls.levels[levelIndex];
const redundantLevels = level.url.length;
Expand Down
29 changes: 19 additions & 10 deletions src/remux/passthrough-remuxer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ class PassThroughRemuxer implements Remuxer {
const initData = (this.initData = parseInitSegment(initSegment));

// Get codec from initSegment or fallback to default
if (!audioCodec) {
if (!audioCodec && initData.audio) {
audioCodec = getParsedTrackCodec(
initData.audio,
ElementaryStreamTypes.AUDIO
);
}

if (!videoCodec) {
if (!videoCodec && initData.video) {
videoCodec = getParsedTrackCodec(
initData.video,
ElementaryStreamTypes.VIDEO
Expand Down Expand Up @@ -263,27 +263,36 @@ function isInvalidInitPts(
}

function getParsedTrackCodec(
track: InitDataTrack | undefined,
track: InitDataTrack,
type: ElementaryStreamTypes.AUDIO | ElementaryStreamTypes.VIDEO
): string {
const parsedCodec = track?.codec;
if (parsedCodec && parsedCodec.length > 4) {
return parsedCodec;
}
if (type === ElementaryStreamTypes.AUDIO) {
if (
parsedCodec === 'ec-3' ||
parsedCodec === 'ac-3' ||
parsedCodec === 'alac'
) {
return parsedCodec;
}
if (parsedCodec === 'fLaC' || parsedCodec === 'Opus') {
return getCodecCompatibleName(parsedCodec);
}
logger.warn(`Unhandled audio codec "${parsedCodec}" or audio object type`);
return 'mp4a.40.5';
}
// Provide defaults based on codec type
// This allows for some playback of some fmp4 playlists without CODECS defined in manifest
logger.warn(`Unhandled video codec "${parsedCodec}"`);
if (parsedCodec === 'hvc1' || parsedCodec === 'hev1') {
return 'hvc1.1.6.L120.90';
}
if (parsedCodec === 'av01') {
return 'av01.0.04M.08';
}
if (parsedCodec === 'avc1' || type === ElementaryStreamTypes.VIDEO) {
return 'avc1.42e01e';
}
if (parsedCodec === 'fLaC' || parsedCodec === 'Opus') {
return getCodecCompatibleName(parsedCodec);
}
return 'mp4a.40.5';
return 'avc1.42e01e';
}
export default PassThroughRemuxer;
Loading

0 comments on commit b8d101f

Please sign in to comment.