audio: widen forward decode cushion 30/15->60/30s + add [BP-DIAG] back-pressure instrumentation
Byte cap (96MB) unchanged as the hard OOM bound; the wider time window only lets sparse Opus use existing memory headroom to ride out decode jitter. Diag logs pin whether the block is back-pressure or decode throughput.
This commit is contained in:
@@ -163,6 +163,11 @@ export class OpusStreamDecoder implements IStreamingDecoder {
|
||||
// order-sensitive). configure() is deferred too — no need to spin up the decoder while
|
||||
// throttled. The C# loop also stops reading above high-water, so the stash stays small.
|
||||
if (this.isSchedulerFull?.()) {
|
||||
// [BP-DIAG] First stash since last drain — production is now throttled and decode is parked.
|
||||
// Trivially removable.
|
||||
if (this.pendingBytes.length === 0) {
|
||||
console.log('[BP-DIAG] Opus stash START (scheduler full, decode parked)');
|
||||
}
|
||||
this.pendingBytes.push(chunk);
|
||||
return [];
|
||||
}
|
||||
@@ -173,6 +178,8 @@ export class OpusStreamDecoder implements IStreamingDecoder {
|
||||
// the new chunk, through the demuxer as one contiguous feed.
|
||||
const out: AudioBuffer[] = [];
|
||||
if (this.pendingBytes.length > 0) {
|
||||
// [BP-DIAG] Scheduler drained below low-water — replaying the stash. Trivially removable.
|
||||
console.log(`[BP-DIAG] Opus stash DRAIN ${this.pendingBytes.length} chunks`);
|
||||
const stashed = this.pendingBytes;
|
||||
this.pendingBytes = [];
|
||||
for (const bytes of stashed) {
|
||||
@@ -375,6 +382,13 @@ export class OpusStreamDecoder implements IStreamingDecoder {
|
||||
let iters = 0;
|
||||
const poll = () => {
|
||||
if (!this.decoder || this.decoder.decodeQueueSize === 0 || iters >= MAX_YIELD_ITERS) {
|
||||
// [BP-DIAG] If we hit the 200 ms ceiling with the decode queue still non-empty, the
|
||||
// WebCodecs decoder is falling behind realtime (the throughput suspect for sustained
|
||||
// underrun — worse with HW accel off). Frequent CAP lines pin decode, not back-pressure,
|
||||
// as the block. Trivially removable.
|
||||
if (this.decoder && iters >= MAX_YIELD_ITERS && this.decoder.decodeQueueSize > 0) {
|
||||
console.log(`[BP-DIAG] Opus yield CAP hit, decodeQueueSize=${this.decoder.decodeQueueSize} (decoder behind realtime)`);
|
||||
}
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user