MPEG-TS demuxer optimizations: faster Annex B segmentation, better NALU iteration

This commit is contained in:
Vanilagy
2026-01-16 13:26:58 +01:00
parent e3ee9d91a9
commit ae37973878
7 changed files with 267 additions and 238 deletions
+18 -12
View File
@@ -11,11 +11,11 @@ import {
concatAvcNalUnits,
deserializeAvcDecoderConfigurationRecord,
determineVideoPacketType,
extractAvcNalUnits,
extractHevcNalUnits,
extractNalUnitTypeForAvc,
extractNalUnitTypeForHevc,
HevcNalUnitType,
iterateAvcNalUnits,
iterateHevcNalUnits,
parseAvcSps,
} from './codec-data';
import { CustomVideoDecoder, customVideoDecoders, CustomAudioDecoder, customAudioDecoders } from './custom-coder';
@@ -945,12 +945,15 @@ class VideoDecoderWrapper extends DecoderWrapper<VideoSample> {
// Workaround for https://issues.chromium.org/issues/470109459
if (isChromium() && this.currentPacketIndex === 0 && this.codec === 'avc') {
const nalUnits = extractAvcNalUnits(packet.data, this.decoderConfig);
const filteredNalUnits = nalUnits.filter((x) => {
const type = extractNalUnitTypeForAvc(x);
const filteredNalUnits: Uint8Array[] = [];
for (const loc of iterateAvcNalUnits(packet.data, this.decoderConfig)) {
const type = extractNalUnitTypeForAvc(packet.data[loc.offset]!);
// These trip up Chromium's key frame detection, so let's strip them
return !(type >= 20 && type <= 31);
});
if (!(type >= 20 && type <= 31)) {
filteredNalUnits.push(packet.data.subarray(loc.offset, loc.offset + loc.length));
}
}
const newData = concatAvcNalUnits(filteredNalUnits, this.decoderConfig);
packet = new EncodedPacket(newData, packet.type, packet.timestamp, packet.duration);
@@ -1081,11 +1084,14 @@ class VideoDecoderWrapper extends DecoderWrapper<VideoSample> {
* and causes bugs upstream. So, let's take the dropping into our own hands.
*/
hasHevcRaslPicture(packetData: Uint8Array) {
const nalUnits = extractHevcNalUnits(packetData, this.decoderConfig);
return nalUnits.some((x) => {
const type = extractNalUnitTypeForHevc(x);
return type === HevcNalUnitType.RASL_N || type === HevcNalUnitType.RASL_R;
});
for (const loc of iterateHevcNalUnits(packetData, this.decoderConfig)) {
const type = extractNalUnitTypeForHevc(packetData[loc.offset]!);
if (type === HevcNalUnitType.RASL_N || type === HevcNalUnitType.RASL_R) {
return true;
}
}
return false;
}
/** Handler for the WebCodecs VideoDecoder for ironing out browser differences. */