Auto-throttle visualizer under sustained Opus decode pressure; strip streaming investigation instrumentation
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
*/
|
||||
|
||||
import { AudioContextManager } from './AudioContextManager.js';
|
||||
import { decodePressure } from './decodePressure.js';
|
||||
import { IStreamingDecoder } from './IStreamingDecoder.js';
|
||||
import { OggDemuxer, OpusPacket, extractOpusHead, opusHeadChannelCount } from './OggDemuxer.js';
|
||||
import { OpusSeekData, OPUS_SAMPLE_RATE } from './OpusSidecar.js';
|
||||
@@ -163,11 +164,6 @@ 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 [];
|
||||
}
|
||||
@@ -178,8 +174,6 @@ 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) {
|
||||
@@ -382,12 +376,12 @@ 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.
|
||||
// Hitting the 200 ms ceiling with the decode queue still non-empty means the WebCodecs
|
||||
// decoder is falling behind realtime — the decode-starvation symptom that worsens with
|
||||
// HW accel off (software WebGL render contending for the main thread). Report it as
|
||||
// decode pressure so the visualizer throttles and yields the main thread back to decode.
|
||||
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)`);
|
||||
decodePressure.report();
|
||||
}
|
||||
resolve();
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user