()
| 450 | } |
| 451 | |
| 452 | function renderPendingNv12Frame() { |
| 453 | if (!pendingNv12Frame || !mainThreadWebGPU || !directCanvas) return; |
| 454 | |
| 455 | const { buffer, receivedAt } = pendingNv12Frame; |
| 456 | pendingNv12Frame = null; |
| 457 | |
| 458 | const metadata = readNv12Metadata(buffer); |
| 459 | if (!metadata) return; |
| 460 | |
| 461 | const { yStride, height, width, fullRange } = metadata; |
| 462 | |
| 463 | if (width > 0 && height > 0) { |
| 464 | const ySize = yStride * height; |
| 465 | const uvSize = yStride * (height / 2); |
| 466 | const totalSize = ySize + uvSize; |
| 467 | |
| 468 | const frameData = new Uint8ClampedArray(buffer, 0, totalSize); |
| 469 | const renderStart = performance.now(); |
| 470 | |
| 471 | if (directCanvas.width !== width || directCanvas.height !== height) { |
| 472 | directCanvas.width = width; |
| 473 | directCanvas.height = height; |
| 474 | } |
| 475 | |
| 476 | const timing = renderNv12FrameWebGPU( |
| 477 | mainThreadWebGPU, |
| 478 | frameData, |
| 479 | width, |
| 480 | height, |
| 481 | yStride, |
| 482 | fullRange, |
| 483 | ); |
| 484 | |
| 485 | storeRenderedFrame(frameData, width, height, yStride, true, fullRange); |
| 486 | recordRender( |
| 487 | performance.now() - renderStart, |
| 488 | "webgpu", |
| 489 | timing, |
| 490 | receivedAt, |
| 491 | ); |
| 492 | onmessage({ width, height }); |
| 493 | } |
| 494 | } |
| 495 | |
| 496 | function schedulePendingNv12Frame(buffer: ArrayBuffer, receivedAt: number) { |
| 497 | pendingNv12Frame = { buffer, receivedAt }; |
no test coverage detected