diff --git a/electron/ipc/export/native-video.ts b/electron/ipc/export/native-video.ts index 847b491c..57d1ea93 100644 --- a/electron/ipc/export/native-video.ts +++ b/electron/ipc/export/native-video.ts @@ -3671,7 +3671,6 @@ export async function exportNativeStaticLayoutVideo( "Experimental NVIDIA CUDA compositor produced an empty output file", ); } - videoOutputValidated = true; console.info( "[native-static-layout-export] NVIDIA CUDA compositor completed", { @@ -3767,7 +3766,6 @@ export async function exportNativeStaticLayoutVideo( "Experimental Windows GPU compositor produced an empty output file", ); } - videoOutputValidated = true; const verifiedNvidiaAdapter = isNvidiaVendorId( gpuResult.summary.adapterVendorId, ); diff --git a/electron/native/bin/win32-x64/helpers-manifest.json b/electron/native/bin/win32-x64/helpers-manifest.json index ccea1d3a..46148e8c 100644 --- a/electron/native/bin/win32-x64/helpers-manifest.json +++ b/electron/native/bin/win32-x64/helpers-manifest.json @@ -26,10 +26,10 @@ }, "recordly-nvidia-cuda-compositor": { "binaryName": "recordly-nvidia-cuda-compositor.exe", - "binarySha256": "d974a16ddf45891e3aca19fbb79539c547968cc4dab89a2762bdd738a4dcc9f3", + "binarySha256": "3f087c65e054d748bb02d507d4925bbb0b495a9b0e0eae5a8ed118fa4637f34b", "sourceDir": "electron/native/nvidia-cuda-compositor", - "sourceFingerprint": "2782dae39e51f2dec6d64ca8307e0ec628d9b245b77beec31bb44103fa1323f4", - "updatedAt": "2026-05-12T19:26:46.482Z" + "sourceFingerprint": "fc3ae59b700c9c25c5228e074f8976b7aa9ef20bc18af0732eca74e2e34e3f80", + "updatedAt": "2026-05-12T20:05:02.218Z" } } } diff --git a/electron/native/bin/win32-x64/recordly-nvidia-cuda-compositor.exe b/electron/native/bin/win32-x64/recordly-nvidia-cuda-compositor.exe index 65271347..3dca234e 100644 Binary files a/electron/native/bin/win32-x64/recordly-nvidia-cuda-compositor.exe and b/electron/native/bin/win32-x64/recordly-nvidia-cuda-compositor.exe differ diff --git a/electron/native/nvidia-cuda-compositor/src/main.cu b/electron/native/nvidia-cuda-compositor/src/main.cu index 356593f4..a90c16e5 100644 --- a/electron/native/nvidia-cuda-compositor/src/main.cu +++ b/electron/native/nvidia-cuda-compositor/src/main.cu @@ -1027,13 +1027,13 @@ __global__ void copyNv12Kernel( const float sy = mapScaledCoordinate(static_cast(y), srcHeight, dstHeight); dst[y * dstPitch + x] = samplePlaneCubic(src, srcPitch, srcWidth, srcHeight, sx, sy); - if ((x % 2) == 0 && (y % 2) == 0) { - unsigned char* dstUv = dst + dstChromaOffset + (y / 2) * dstPitch + x; - const float suvX = mapScaledCoordinate(static_cast(x + 1), srcWidth, dstWidth); - const float suvY = mapScaledCoordinate(static_cast(y + 1), srcHeight, dstHeight); - sampleNv12UvBilinear( - src, - srcPitch, + if ((x % 2) == 0 && (y % 2) == 0) { + unsigned char* dstUv = dst + dstChromaOffset + (y / 2) * dstPitch + x; + const float suvX = mapScaledCoordinate(static_cast(x), srcWidth, dstWidth); + const float suvY = mapScaledCoordinate(static_cast(y), srcHeight, dstHeight); + sampleNv12UvBilinear( + src, + srcPitch, srcSurfaceHeight, srcWidth, srcHeight, @@ -1269,17 +1269,15 @@ __global__ void overlayContentRectNv12Kernel( mapScaledCoordinate(static_cast(localY), cropHeight, contentHeight); dst[y * dstPitch + x] = samplePlaneCubic(src, srcPitch, srcWidth, srcHeight, srcX, srcY); - if ((x % 2) == 0 && (y % 2) == 0) { - const int localUvX = max(0, min(contentWidth - 1, localX + 1)); - const int localUvY = max(0, min(contentHeight - 1, localY + 1)); - unsigned char* dstUv = dst + dstChromaOffset + (y / 2) * dstPitch + x; - const float srcUvLumaX = static_cast(cropX) + - mapScaledCoordinate(static_cast(localUvX), cropWidth, contentWidth); - const float srcUvLumaY = static_cast(cropY) + - mapScaledCoordinate(static_cast(localUvY), cropHeight, contentHeight); - sampleNv12UvBilinear( - src, - srcPitch, + if ((x % 2) == 0 && (y % 2) == 0) { + unsigned char* dstUv = dst + dstChromaOffset + (y / 2) * dstPitch + x; + const float srcUvLumaX = static_cast(cropX) + + mapScaledCoordinate(static_cast(localX), cropWidth, contentWidth); + const float srcUvLumaY = static_cast(cropY) + + mapScaledCoordinate(static_cast(localY), cropHeight, contentHeight); + sampleNv12UvBilinear( + src, + srcPitch, srcSurfaceHeight, srcWidth, srcHeight, diff --git a/src/lib/exporter/audioEncoder.test.ts b/src/lib/exporter/audioEncoder.test.ts index e762f63b..309ff8fe 100644 --- a/src/lib/exporter/audioEncoder.test.ts +++ b/src/lib/exporter/audioEncoder.test.ts @@ -59,6 +59,7 @@ describe("AudioProcessor offline render preparation", () => { expect(prepared.mainBufferEntry?.gain).toBe(1); expect(prepared.companionEntries).toHaveLength(1); expect(prepared.companionEntries[0]?.buffer).toBe(micBuffer); + expect(prepared.companionEntries[0]?.gain).toBe(1); expect(decodeAudioFromUrl).toHaveBeenCalledWith("file:///tmp/recording.mp4"); expect(decodeAudioFromUrl).toHaveBeenCalledWith("/tmp/recording.mic.wav"); expect(decodeAudioFromUrl).not.toHaveBeenCalledWith("/tmp/recording.mp4");