Skip to content

Commit d740ddb

Browse files
committed
fix(desktop): NV12 stride alignment for correct YUV rendering
1 parent e87c7b0 commit d740ddb

6 files changed

Lines changed: 13 additions & 12 deletions

File tree

apps/desktop/src-tauri/src/frame_ws.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ fn pack_nv12_frame_ref(
3030
data: &[u8],
3131
width: u32,
3232
height: u32,
33+
y_stride: u32,
3334
frame_number: u32,
3435
target_time_ns: u64,
3536
) -> Vec<u8> {
36-
let y_stride = width;
3737
let metadata_size = 28;
3838
let mut output = Vec::with_capacity(data.len() + metadata_size);
3939
output.extend_from_slice(data);
@@ -90,6 +90,7 @@ fn pack_ws_frame_ref(frame: &WSFrame) -> Vec<u8> {
9090
&frame.data,
9191
frame.width,
9292
frame.height,
93+
frame.stride,
9394
frame.frame_number,
9495
frame.target_time_ns,
9596
),

apps/desktop/src/routes/editor/context.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export const getPreviewResolution = (
8080
quality: EditorPreviewQuality,
8181
): XY<number> => {
8282
const scale = previewQualityScale[quality];
83-
const width = (Math.max(2, Math.round(OUTPUT_SIZE.x * scale)) + 1) & ~1;
83+
const width = (Math.max(4, Math.round(OUTPUT_SIZE.x * scale)) + 3) & ~3;
8484
const height = (Math.max(2, Math.round(OUTPUT_SIZE.y * scale)) + 1) & ~1;
8585

8686
return { x: width, y: height };

apps/desktop/src/routes/screenshot-editor/context.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function convertNv12ToRgba(
3838
const ySize = yStride * height;
3939
const yPlane = nv12Data;
4040
const uvPlane = nv12Data.subarray(ySize);
41-
const uvStride = width;
41+
const uvStride = yStride;
4242

4343
for (let row = 0; row < height; row++) {
4444
const yRowOffset = row * yStride;
@@ -285,7 +285,7 @@ function createScreenshotEditorContext() {
285285
if (!width || !height) return;
286286

287287
const ySize = yStride * height;
288-
const uvSize = width * (height / 2);
288+
const uvSize = yStride * (height / 2);
289289
const totalSize = ySize + uvSize;
290290

291291
const nv12Data = new Uint8ClampedArray(buffer, 0, totalSize);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ function parseFrameMetadata(bytes: Uint8Array): FrameMetadata | null {
231231
if (!width || !height) return null;
232232

233233
const ySize = yStride * height;
234-
const uvSize = width * (height / 2);
234+
const uvSize = yStride * (height / 2);
235235
const totalSize = ySize + uvSize;
236236

237237
if (bytes.byteLength - 28 < totalSize) {
@@ -303,7 +303,7 @@ function convertNv12ToRgba(
303303
const ySize = yStride * height;
304304
const yPlane = nv12Data;
305305
const uvPlane = nv12Data.subarray(ySize);
306-
const uvStride = width;
306+
const uvStride = yStride;
307307

308308
for (let row = 0; row < height; row++) {
309309
const yRowOffset = row * yStride;

apps/desktop/src/utils/socket.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ function convertNv12ToRgbaMainThread(
6262
const ySize = yStride * height;
6363
const yPlane = nv12Data;
6464
const uvPlane = nv12Data.subarray(ySize);
65-
const uvStride = width;
65+
const uvStride = yStride;
6666

6767
for (let row = 0; row < height; row++) {
6868
const yRowOffset = row * yStride;
@@ -308,7 +308,7 @@ export function createImageDataWS(
308308

309309
if (width > 0 && height > 0) {
310310
const ySize = yStride * height;
311-
const uvSize = width * (height / 2);
311+
const uvSize = yStride * (height / 2);
312312
const totalSize = ySize + uvSize;
313313

314314
const frameData = new Uint8ClampedArray(buffer, 0, totalSize);
@@ -351,7 +351,7 @@ export function createImageDataWS(
351351

352352
if (width > 0 && height > 0) {
353353
const ySize = yStride * height;
354-
const uvSize = width * (height / 2);
354+
const uvSize = yStride * (height / 2);
355355
const totalSize = ySize + uvSize;
356356

357357
const frameData = new Uint8ClampedArray(buffer, 0, totalSize);
@@ -669,7 +669,7 @@ export function createImageDataWS(
669669

670670
if (width > 0 && height > 0) {
671671
const ySize = yStride * height;
672-
const uvSize = width * (height / 2);
672+
const uvSize = yStride * (height / 2);
673673
const totalSize = ySize + uvSize;
674674

675675
const frameData = new Uint8ClampedArray(buffer, 0, totalSize);
@@ -735,7 +735,7 @@ export function createImageDataWS(
735735

736736
if (width > 0 && height > 0) {
737737
const ySize = yStride * height;
738-
const uvSize = width * (height / 2);
738+
const uvSize = yStride * (height / 2);
739739
const totalSize = ySize + uvSize;
740740

741741
const nv12Data = new Uint8ClampedArray(buffer, 0, totalSize);

apps/desktop/src/utils/webgpu-renderer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ export function renderNv12FrameWebGPU(
380380
const ySize = yStride * height;
381381
const uvWidth = width / 2;
382382
const uvHeight = height / 2;
383-
const uvStride = width;
383+
const uvStride = yStride;
384384
const uvSize = uvStride * uvHeight;
385385

386386
if (data.byteLength < ySize + uvSize) {

0 commit comments

Comments
 (0)