mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-10-03 13:53:53 +02:00
Adjust media sink max queue size logic to prevent playback stalls
This commit is contained in:
+11
-4
@@ -264,7 +264,6 @@ export abstract class BaseMediaSampleSink<
|
|||||||
validateTimestamp(startTimestamp);
|
validateTimestamp(startTimestamp);
|
||||||
validateTimestamp(endTimestamp);
|
validateTimestamp(endTimestamp);
|
||||||
|
|
||||||
const MAX_QUEUE_SIZE = 8;
|
|
||||||
const sampleQueue: MediaSample[] = [];
|
const sampleQueue: MediaSample[] = [];
|
||||||
let firstSampleQueued = false;
|
let firstSampleQueued = false;
|
||||||
let lastSample: MediaSample | null = null;
|
let lastSample: MediaSample | null = null;
|
||||||
@@ -355,7 +354,8 @@ export abstract class BaseMediaSampleSink<
|
|||||||
await packets.next(); // Skip the start packet as we already have it
|
await packets.next(); // Skip the start packet as we already have it
|
||||||
|
|
||||||
while (currentPacket && !ended) {
|
while (currentPacket && !ended) {
|
||||||
if (sampleQueue.length + decoder.getDecodeQueueSize() > MAX_QUEUE_SIZE) {
|
const maxQueueSize = computeMaxQueueSize(sampleQueue.length);
|
||||||
|
if (sampleQueue.length + decoder.getDecodeQueueSize() > maxQueueSize) {
|
||||||
({ promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers());
|
({ promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers());
|
||||||
await queueDequeue;
|
await queueDequeue;
|
||||||
continue;
|
continue;
|
||||||
@@ -438,7 +438,6 @@ export abstract class BaseMediaSampleSink<
|
|||||||
const timestampIterator = toAsyncIterator(timestamps);
|
const timestampIterator = toAsyncIterator(timestamps);
|
||||||
const timestampsOfInterest: number[] = [];
|
const timestampsOfInterest: number[] = [];
|
||||||
|
|
||||||
const MAX_QUEUE_SIZE = 8;
|
|
||||||
const sampleQueue: (MediaSample | null)[] = [];
|
const sampleQueue: (MediaSample | null)[] = [];
|
||||||
let { promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers();
|
let { promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers();
|
||||||
let { promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers();
|
let { promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers();
|
||||||
@@ -499,7 +498,8 @@ export abstract class BaseMediaSampleSink<
|
|||||||
for await (const timestamp of timestampIterator) {
|
for await (const timestamp of timestampIterator) {
|
||||||
validateTimestamp(timestamp);
|
validateTimestamp(timestamp);
|
||||||
|
|
||||||
while (sampleQueue.length + decoder.getDecodeQueueSize() > MAX_QUEUE_SIZE && !terminated) {
|
const maxQueueSize = computeMaxQueueSize(sampleQueue.length);
|
||||||
|
while (sampleQueue.length + decoder.getDecodeQueueSize() > maxQueueSize && !terminated) {
|
||||||
({ promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers());
|
({ promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers());
|
||||||
await queueDequeue;
|
await queueDequeue;
|
||||||
}
|
}
|
||||||
@@ -618,6 +618,13 @@ export abstract class BaseMediaSampleSink<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const computeMaxQueueSize = (decodedSampleQueueSize: number) => {
|
||||||
|
// If we have decoded samples lying around, limit the total queue size to a small value (decoded samples can use up
|
||||||
|
// a lot of memory). If not, we're fine with a much bigger queue of encoded packets waiting to be decoded. In fact,
|
||||||
|
// some decoders only start flushing out decoded chunks when the packet queue is large enough.
|
||||||
|
return decodedSampleQueueSize === 0 ? 40 : 8;
|
||||||
|
};
|
||||||
|
|
||||||
class VideoDecoderWrapper extends DecoderWrapper<VideoSample> {
|
class VideoDecoderWrapper extends DecoderWrapper<VideoSample> {
|
||||||
decoder: VideoDecoder | null = null;
|
decoder: VideoDecoder | null = null;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user