Migrate all codec data parsing logic into new file

This commit is contained in:
Vanilagy
2025-05-12 15:09:04 +02:00
parent b0a6cf8535
commit fd159ecce3
10 changed files with 600 additions and 593 deletions
+3 -2
View File
@@ -1,4 +1,5 @@
import { OPUS_INTERNAL_SAMPLE_RATE, parseOpusIdentificationHeader } from '../codec';
import { OPUS_INTERNAL_SAMPLE_RATE } from '../codec';
import { parseModesFromVorbisSetupPacket, parseOpusIdentificationHeader } from '../codec-data';
import { Demuxer } from '../demuxer';
import { Input } from '../input';
import { InputAudioTrack, InputAudioTrackBacking } from '../input-track';
@@ -6,7 +7,7 @@ import { PacketRetrievalOptions } from '../media-sink';
import { assert, AsyncMutex, findLast, roundToPrecision, toDataView, UNDETERMINED_LANGUAGE } from '../misc';
import { EncodedPacket, PLACEHOLDER_DATA } from '../packet';
import { Reader } from '../reader';
import { computeOggPageCrc, extractSampleMetadata, OggCodecInfo, parseModesFromVorbisSetupPacket } from './ogg-misc';
import { computeOggPageCrc, extractSampleMetadata, OggCodecInfo } from './ogg-misc';
import { MAX_PAGE_HEADER_SIZE, MAX_PAGE_SIZE, MIN_PAGE_HEADER_SIZE, OggReader, Page } from './ogg-reader';
type LogicalBitstream = {
+2 -90
View File
@@ -1,5 +1,5 @@
import { parseOpusTocByte } from '../codec';
import { assert, Bitstream, ilog, toDataView } from '../misc';
import { parseOpusTocByte } from '../codec-data';
import { assert, ilog, toDataView } from '../misc';
export const OGGS = 0x5367674f; // 'OggS'
@@ -93,91 +93,3 @@ export const extractSampleMetadata = (
vorbisBlockSize: currentBlocksize,
};
};
// Based on vorbis_parser.c from FFmpeg.
export const parseModesFromVorbisSetupPacket = (setupHeader: Uint8Array) => {
// Verify that this is a Setup header.
if (setupHeader.length < 7) {
throw new Error('Setup header is too short.');
}
if (setupHeader[0] !== 5) {
throw new Error('Wrong packet type in Setup header.');
}
const signature = String.fromCharCode(...setupHeader.slice(1, 7));
if (signature !== 'vorbis') {
throw new Error('Invalid packet signature in Setup header.');
}
// Reverse the entire buffer.
const bufSize = setupHeader.length;
const revBuffer = new Uint8Array(bufSize);
for (let i = 0; i < bufSize; i++) {
revBuffer[i] = setupHeader[bufSize - 1 - i]!;
}
// Initialize a Bitstream on the reversed buffer.
const bitstream = new Bitstream(revBuffer);
// --- Find the framing bit.
// In FFmpeg code, we scan until get_bits1() returns 1.
let gotFramingBit = 0;
while (bitstream.getBitsLeft() > 97) {
if (bitstream.readBits(1) === 1) {
gotFramingBit = bitstream.pos;
break;
}
}
if (gotFramingBit === 0) {
throw new Error('Invalid Setup header: framing bit not found.');
}
// --- Search backwards for a valid mode header.
// We try to “guess” the number of modes by reading a fixed pattern.
let modeCount = 0;
let gotModeHeader = false;
let lastModeCount = 0;
while (bitstream.getBitsLeft() >= 97) {
const tempPos = bitstream.pos;
const a = bitstream.readBits(8);
const b = bitstream.readBits(16);
const c = bitstream.readBits(16);
// If a > 63 or b or c nonzero, assume we’ve gone too far.
if (a > 63 || b !== 0 || c !== 0) {
bitstream.pos = tempPos;
break;
}
bitstream.skipBits(1);
modeCount++;
if (modeCount > 64) {
break;
}
const bsClone = bitstream.clone();
const candidate = bsClone.readBits(6) + 1;
if (candidate === modeCount) {
gotModeHeader = true;
lastModeCount = modeCount;
}
}
if (!gotModeHeader) {
throw new Error('Invalid Setup header: mode header not found.');
}
if (lastModeCount > 63) {
throw new Error(`Unsupported mode count: ${lastModeCount}.`);
}
const finalModeCount = lastModeCount;
// --- Reinitialize the bitstream.
bitstream.pos = 0;
// Skip the bits up to the found framing bit.
bitstream.skipBits(gotFramingBit);
// --- Now read, for each mode (in reverse order), 40 bits then one bit.
// That one bit is the mode blockflag.
const modeBlockflags = Array(finalModeCount).fill(0) as number[];
for (let i = finalModeCount - 1; i >= 0; i--) {
bitstream.skipBits(40);
modeBlockflags[i] = bitstream.readBits(1);
}
return { modeBlockflags };
};
+2 -2
View File
@@ -1,4 +1,5 @@
import { OPUS_INTERNAL_SAMPLE_RATE, parseOpusIdentificationHeader, validateAudioChunkMetadata } from '../codec';
import { OPUS_INTERNAL_SAMPLE_RATE, validateAudioChunkMetadata } from '../codec';
import { parseModesFromVorbisSetupPacket, parseOpusIdentificationHeader } from '../codec-data';
import { assert, setInt64, toDataView, toUint8Array } from '../misc';
import { Muxer } from '../muxer';
import { Output, OutputAudioTrack } from '../output';
@@ -10,7 +11,6 @@ import {
extractSampleMetadata,
OggCodecInfo,
OGGS,
parseModesFromVorbisSetupPacket,
} from './ogg-misc';
import { MAX_PAGE_SIZE } from './ogg-reader';