Skip to content

Commit 4fcf6e6

Browse files
committed
Optimize NV12 conversion, RGBA path & WebGPU tweaks
1 parent 8b630d2 commit 4fcf6e6

3 files changed

Lines changed: 212 additions & 112 deletions

File tree

apps/desktop/src/utils/frame-worker.ts

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ interface ResetFrameStateMessage {
3737
type: "reset-frame-state";
3838
}
3939

40+
interface WakeMessage {
41+
type: "wake";
42+
}
43+
4044
interface ReadyMessage {
4145
type: "ready";
4246
}
@@ -90,7 +94,8 @@ type IncomingMessage =
9094
| ResizeMessage
9195
| InitSharedBufferMessage
9296
| CleanupMessage
93-
| ResetFrameStateMessage;
97+
| ResetFrameStateMessage
98+
| WakeMessage;
9499

95100
interface FrameTiming {
96101
frameNumber: number;
@@ -307,23 +312,21 @@ function convertNv12ToRgba(
307312

308313
for (let row = 0; row < height; row++) {
309314
const yRowOffset = row * yStride;
310-
const uvRowOffset = Math.floor(row / 2) * uvStride;
315+
const uvRowOffset = (row >> 1) * uvStride;
311316
const rgbaRowOffset = row * width * 4;
312317

313-
for (let col = 0; col < width; col++) {
314-
const y = yPlane[yRowOffset + col] - 16;
315-
316-
const uvCol = Math.floor(col / 2) * 2;
318+
for (let col = 0; col < width; col += 2) {
319+
const uvCol = (col >> 1) * 2;
317320
const u = uvPlane[uvRowOffset + uvCol] - 128;
318321
const v = uvPlane[uvRowOffset + uvCol + 1] - 128;
319-
320-
const c = 298 * y;
321322
const d = u;
322323
const e = v;
323324

324-
let r = (c + 409 * e + 128) >> 8;
325-
let g = (c - 100 * d - 208 * e + 128) >> 8;
326-
let b = (c + 516 * d + 128) >> 8;
325+
const y0 = yPlane[yRowOffset + col] - 16;
326+
const c0 = 298 * y0;
327+
let r = (c0 + 409 * e + 128) >> 8;
328+
let g = (c0 - 100 * d - 208 * e + 128) >> 8;
329+
let b = (c0 + 516 * d + 128) >> 8;
327330

328331
r = r < 0 ? 0 : r > 255 ? 255 : r;
329332
g = g < 0 ? 0 : g > 255 ? 255 : g;
@@ -334,6 +337,25 @@ function convertNv12ToRgba(
334337
rgba[rgbaOffset + 1] = g;
335338
rgba[rgbaOffset + 2] = b;
336339
rgba[rgbaOffset + 3] = 255;
340+
341+
const nextCol = col + 1;
342+
if (nextCol < width) {
343+
const y1 = yPlane[yRowOffset + nextCol] - 16;
344+
const c1 = 298 * y1;
345+
let nextR = (c1 + 409 * e + 128) >> 8;
346+
let nextG = (c1 - 100 * d - 208 * e + 128) >> 8;
347+
let nextB = (c1 + 516 * d + 128) >> 8;
348+
349+
nextR = nextR < 0 ? 0 : nextR > 255 ? 255 : nextR;
350+
nextG = nextG < 0 ? 0 : nextG > 255 ? 255 : nextG;
351+
nextB = nextB < 0 ? 0 : nextB > 255 ? 255 : nextB;
352+
353+
const nextRgbaOffset = rgbaOffset + 4;
354+
rgba[nextRgbaOffset] = nextR;
355+
rgba[nextRgbaOffset + 1] = nextG;
356+
rgba[nextRgbaOffset + 2] = nextB;
357+
rgba[nextRgbaOffset + 3] = 255;
358+
}
337359
}
338360
}
339361

@@ -1095,6 +1117,11 @@ self.onmessage = async (e: MessageEvent<IncomingMessage>) => {
10951117
return;
10961118
}
10971119

1120+
if (e.data.type === "wake") {
1121+
startRenderLoop();
1122+
return;
1123+
}
1124+
10981125
if (e.data.type === "init-shared-buffer") {
10991126
consumer = createConsumer(e.data.buffer);
11001127
useSharedBuffer = true;

0 commit comments

Comments
 (0)