diff --git a/src/controller/abr-controller.ts b/src/controller/abr-controller.ts index 90f19ca5319..a4917e73c8a 100644 --- a/src/controller/abr-controller.ts +++ b/src/controller/abr-controller.ts @@ -612,6 +612,9 @@ class AbrController implements AbrComponentAPI { lastLoadedFragLevel === -1 ? this.hls.firstLevel : lastLoadedFragLevel; const { fragCurrent, partCurrent } = this; const { levels, allAudioTracks, loadLevel } = this.hls; + if (levels.length === 1) { + return 0; + } const level: Level | undefined = levels[selectionBaseLevel]; const live = !!level?.details?.live; const firstSelection = loadLevel === -1 || lastLoadedFragLevel === -1; diff --git a/src/demux/video/avc-video-parser.ts b/src/demux/video/avc-video-parser.ts index f326dba315d..d9774ce315d 100644 --- a/src/demux/video/avc-video-parser.ts +++ b/src/demux/video/avc-video-parser.ts @@ -8,10 +8,9 @@ import { appendUint8Array, parseSEIMessageFromNALu, } from '../../utils/mp4-tools'; - -import type { PES } from '../tsdemuxer'; - import ExpGolomb from './exp-golomb'; +import { logger } from '../../utils/logger'; +import type { PES } from '../tsdemuxer'; class AvcVideoParser extends BaseVideoParser { public parseAVCPES( @@ -133,17 +132,23 @@ class AvcVideoParser extends BaseVideoParser { break; // SPS } - case 7: + case 7: { push = true; spsfound = true; if (debug && VideoSample) { VideoSample.debug += 'SPS '; } + const sps = unit.data; + const expGolombDecoder = new ExpGolomb(sps); + const config = expGolombDecoder.readSPS(); - if (!track.sps) { - const sps = unit.data; - const expGolombDecoder = new ExpGolomb(sps); - const config = expGolombDecoder.readSPS(); + if ( + !track.sps || + track.width !== config.width || + track.height !== config.height || + track.pixelRatio?.[0] !== config.pixelRatio[0] || + track.pixelRatio?.[1] !== config.pixelRatio[1] + ) { track.width = config.width; track.height = config.height; track.pixelRatio = config.pixelRatio; @@ -161,7 +166,9 @@ class AvcVideoParser extends BaseVideoParser { } track.codec = codecstring; } + break; + } // PPS case 8: push = true; @@ -169,9 +176,7 @@ class AvcVideoParser extends BaseVideoParser { VideoSample.debug += 'PPS '; } - if (!track.pps) { - track.pps = [unit.data]; - } + track.pps = [unit.data]; break; // AUD diff --git a/src/remux/mp4-remuxer.ts b/src/remux/mp4-remuxer.ts index 44708230c17..aa890f27159 100644 --- a/src/remux/mp4-remuxer.ts +++ b/src/remux/mp4-remuxer.ts @@ -50,6 +50,11 @@ export default class MP4Remuxer implements Remuxer { private videoSampleDuration: number | null = null; private isAudioContiguous: boolean = false; private isVideoContiguous: boolean = false; + private videoTrackConfig?: { + width?: number; + height?: number; + pixelRatio?: [number, number]; + }; constructor( observer: HlsEventEmitter, @@ -73,7 +78,10 @@ export default class MP4Remuxer implements Remuxer { } } - destroy() {} + destroy() { + // @ts-ignore + this.config = this.videoTrackConfig = this._initPTS = this._initDTS = null; + } resetTimeStamp(defaultTimeStamp: RationalTimestamp | null) { logger.log('[mp4-remuxer]: initPTS & initDTS reset'); @@ -89,6 +97,7 @@ export default class MP4Remuxer implements Remuxer { resetInitSegment() { logger.log('[mp4-remuxer]: ISGenerated flag reset'); this.ISGenerated = false; + this.videoTrackConfig = undefined; } getVideoStartPts(videoSamples) { @@ -147,7 +156,18 @@ export default class MP4Remuxer implements Remuxer { flush; if (canRemuxAvc) { - if (!this.ISGenerated) { + if (this.ISGenerated) { + const config = this.videoTrackConfig; + if ( + config && + (videoTrack.width !== config.width || + videoTrack.height !== config.height || + videoTrack.pixelRatio?.[0] !== config.pixelRatio?.[0] || + videoTrack.pixelRatio?.[1] !== config.pixelRatio?.[1]) + ) { + this.resetInitSegment(); + } + } else { initSegment = this.generateIS( audioTrack, videoTrack, @@ -385,6 +405,11 @@ export default class MP4Remuxer implements Remuxer { computePTSDTS = false; } } + this.videoTrackConfig = { + width: videoTrack.width, + height: videoTrack.height, + pixelRatio: videoTrack.pixelRatio, + }; } if (Object.keys(tracks).length) {