From 6e404cbf0e9dafcf26f10433dc32e75e905f77bc Mon Sep 17 00:00:00 2001 From: erankor Date: Mon, 17 Oct 2022 18:51:19 +0300 Subject: [PATCH] mp4-tools: fix hevc 608 captions hevc nal header is different than avc. avc nal header has the format - forbidden_zero_bit All f(1) nal_ref_idc All u(2) nal_unit_type All u(5) while hevc nal header has the format - forbidden_zero_bit f(1) nal_unit_type u(6) nuh_layer_id u(6) nuh_temporal_id_plus1 u(3) therefore - 1. need to skip 2 bytes instead of 1 when parsing the SEI body 2. to get the nal unit type, need to do (x >> 1) & 0x3f, instead of x & 0x1f --- src/demux/tsdemuxer.ts | 1 + src/utils/mp4-tools.ts | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/demux/tsdemuxer.ts b/src/demux/tsdemuxer.ts index a7204668fde..105f401701c 100644 --- a/src/demux/tsdemuxer.ts +++ b/src/demux/tsdemuxer.ts @@ -575,6 +575,7 @@ class TSDemuxer implements Demuxer { } parseSEIMessageFromNALu( discardEPB(unit.data), + 1, pes.pts as number, textTrack.samples ); diff --git a/src/utils/mp4-tools.ts b/src/utils/mp4-tools.ts index f38b1c303a0..55785bbd673 100644 --- a/src/utils/mp4-tools.ts +++ b/src/utils/mp4-tools.ts @@ -681,14 +681,14 @@ export function parseSamples( while (naluTotalSize < sampleSize) { const naluSize = readUint32(videoData, sampleOffset); sampleOffset += 4; - const naluType = videoData[sampleOffset] & 0x1f; - if (isSEIMessage(isHEVCFlavor, naluType)) { + if (isSEIMessage(isHEVCFlavor, videoData[sampleOffset])) { const data = videoData.subarray( sampleOffset, sampleOffset + naluSize ); parseSEIMessageFromNALu( data, + isHEVCFlavor ? 2 : 1, timeOffset + compositionOffset / timescale, seiSamples ); @@ -723,19 +723,26 @@ function isHEVC(codec: string) { ); } -function isSEIMessage(isHEVCFlavor: boolean, naluType: number) { - return isHEVCFlavor ? naluType === 39 || naluType === 40 : naluType === 6; +function isSEIMessage(isHEVCFlavor: boolean, naluHeader: number) { + if (isHEVCFlavor) { + const naluType = (naluHeader >> 1) & 0x3f; + return naluType === 39 || naluType === 40; + } else { + const naluType = naluHeader & 0x1f; + return naluType === 6; + } } export function parseSEIMessageFromNALu( unescapedData: Uint8Array, + headerSize: number, pts: number, samples: UserdataSample[] ) { const data = discardEPB(unescapedData); let seiPtr = 0; - // skip frameType - seiPtr++; + // skip nal header + seiPtr += headerSize; let payloadType = 0; let payloadSize = 0; let endOfCaptions = false;