Fix async race condition in transparency code, reduce HEVC conversion duration

This commit is contained in:
Vanilagy
2026-05-12 00:24:03 +02:00
parent 4e5f894d7a
commit 5599e52a1a
4 changed files with 68 additions and 62 deletions
+3 -3
View File
@@ -1036,8 +1036,6 @@ class VideoDecoderWrapper extends DecoderWrapper<VideoSample> {
if (!this.alphaDecoder) {
const alphaHandler = (frame: VideoFrame) => {
this.frameHandlerSerializer.call(async () => {
this.alphaDecoderQueueSize--;
if (this.colorQueue.length > 0) {
const colorFrame = this.colorQueue.shift();
assert(colorFrame !== undefined);
@@ -1064,6 +1062,8 @@ class VideoDecoderWrapper extends DecoderWrapper<VideoSample> {
this.alphaQueue.push(null);
}
}
this.alphaDecoderQueueSize--;
}).catch((error: Error) => this.onError(error));
};
@@ -1266,7 +1266,7 @@ let mergerGpuUnavailable = false;
/** Utility class that merges together color and alpha information using simple WebGL 2 shaders. */
export class ColorAlphaMerger {
static forceCpu = false;
static forceCpu = true;
canvas: OffscreenCanvas | HTMLCanvasElement | null = null;
private gl: WebGL2RenderingContext | null = null;
+1 -1
View File
@@ -877,7 +877,7 @@ let splitterGpuUnavailable = false;
/** Utility class for splitting a composite frame into separate color and alpha components. */
export class ColorAlphaSplitter {
static forceCpu = false;
static forceCpu = true;
canvas: OffscreenCanvas | HTMLCanvasElement | null = null;
+3
View File
@@ -202,6 +202,8 @@ test('Can encode transparent video, forced CPU path', async () => {
});
test('Can encode video with alternating transparency', async () => {
// This test is already brutal when it comes to finding async race conditions, so run it thrice to be MORE brutal
for (let j = 0; j < 3; j++) {
const output = new Output({
format: new WebMOutputFormat(),
target: new BufferTarget(),
@@ -270,6 +272,7 @@ test('Can encode video with alternating transparency', async () => {
i++;
}
}
});
test('Can encode transparent video with odd dimensions', async () => {
+5 -2
View File
@@ -593,7 +593,7 @@ describe('Video', async () => {
});
test('HEVC conversion roundtrip', { timeout: 20_000 }, async () => {
await conversionRoundtrip('hevc');
await conversionRoundtrip('hevc', 1); // GitHub is extremely slow on this one
});
test('VP8 conversion roundtrip', { timeout: 20_000 }, async () => {
@@ -608,7 +608,7 @@ describe('Video', async () => {
await conversionRoundtrip('av1');
});
const conversionRoundtrip = async (codec: VideoCodec) => {
const conversionRoundtrip = async (codec: VideoCodec, duration?: number) => {
using input = new Input({
source: new FilePathSource('./test/public/video.mp4'),
formats: ALL_FORMATS,
@@ -640,6 +640,9 @@ describe('Video', async () => {
}, audio: {
discard: true,
},
trim: {
end: duration,
},
});
await conversion.execute();