fix(flac): add FLAC frame-sync scan to getAlignedSegmentSize; extend IFormatDecoder rawData param
StreamDecoder peeks candidate bytes; FlacFormatDecoder scans backward for 0xFF/0xF8 sync. Fixes mid-stream decode failure where segments started mid-frame.
This commit is contained in:
@@ -244,20 +244,31 @@ export class StreamDecoder {
|
||||
|
||||
const segmentSize = 64 * 1024; // 64KB segments
|
||||
const availableBytes = this.totalRawBytes - this.processedBytes;
|
||||
|
||||
// Peek the candidate window first so the aligner can scan for a format-specific
|
||||
// frame boundary (FLAC). extractAlignedData is non-destructive — it reads from
|
||||
// rawChunks without advancing processedBytes — so reading before alignment is safe.
|
||||
const peekSize = Math.min(segmentSize, availableBytes);
|
||||
if (peekSize === 0) return null;
|
||||
const peekBytes = this.extractAlignedData(peekSize);
|
||||
|
||||
// Passing streamComplete lets the aligner relax the min-frame guard
|
||||
// for the final tail; otherwise residual <512-byte tails get dropped.
|
||||
const alignedSize = this.formatDecoder!.getAlignedSegmentSize(
|
||||
this.formatInfo,
|
||||
availableBytes,
|
||||
segmentSize,
|
||||
this.streamComplete
|
||||
this.streamComplete,
|
||||
peekBytes
|
||||
);
|
||||
|
||||
if (alignedSize <= 0) return null;
|
||||
|
||||
const segmentOffset = this.processedBytes;
|
||||
|
||||
const rawSegment = this.extractAlignedData(alignedSize);
|
||||
// alignedSize is always ≤ peekSize ≤ peekBytes.length, so subarray is in-bounds
|
||||
// and zero-copy — no second extraction needed.
|
||||
const rawSegment = peekBytes.subarray(0, alignedSize);
|
||||
const decodableSegment = this.formatDecoder!.wrapSegment(this.formatInfo, rawSegment);
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user