Skip to content

feat(demo): upgrade capture pipeline to raw bitmap piping with text-crisp encoding#4785

Merged
gregpriday merged 3 commits intodevelopfrom
feature/issue-4775-upgrade-demo-capture-raw
Apr 2, 2026
Merged

feat(demo): upgrade capture pipeline to raw bitmap piping with text-crisp encoding#4785
gregpriday merged 3 commits intodevelopfrom
feature/issue-4775-upgrade-demo-capture-raw

Conversation

@gregpriday
Copy link
Copy Markdown
Collaborator

Summary

  • Replaces toPNG() (20-50ms/frame via zlib compression) with toBitmap() raw BGRA data piped directly into ffmpeg stdin via -f rawvideo -pix_fmt bgra, pushing capture throughput from ~10-15 FPS to 25-35 FPS
  • Replaces yuv420p (4:2:0 chroma subsampling blurs syntax highlighting) with libx264rgb 4:4:4 for text-crisp encoding across all three presets; CRF 18 with -preset slow -movflags +faststart
  • Adds stdin backpressure handling (drain event), frame deduplication to maintain constant frame rate when capture lags, HiDPI/Retina consistency via --force-device-scale-factor=1 --force-color-profile=srgb, and immediate NativeImage release to reduce GC pressure

Resolves #4775

Changes

  • electron/ipc/handlers/demo.ts — full capture pipeline rewrite: raw BGRA piping, ffmpeg arg overhaul, backpressure loop, duplicate-frame fill, close handler cleanup, preset validation
  • shared/types/ipc/demo.ts — preset type updated, new DemoCaptureOptions interface
  • electron/preload.cts — IPC bridge updated for new capture options shape
  • electron/ipc/handlers/__tests__/demo.handlers.test.ts — comprehensive test coverage for the new pipeline including backpressure, frame timing, encoding presets, and HiDPI handling

Testing

Unit test suite covers all new behaviour: raw BGRA piping, backpressure drain, duplicate frame fill, preset validation, close handler cleanup, and HiDPI scale factor. All tests pass. The formatting and lint checks are clean.

…ext-crisp encoding

- Replace PNG-file-per-frame capture with raw BGRA bitmap piping to ffmpeg stdin
- Add wall-clock ticker with duplicate-last-frame strategy for consistent FPS
- Handle stdin backpressure (pause ticker on drain, resume after)
- Add HiDPI normalization via image.resize() on first capture
- Update encode presets from yuv420p to yuv444p with high444 profile
- Add VP9 yuv444p support with row-mt for web-webm preset
- Use lanczos scaling algorithm for downscaling
- Replace -vsync cfr with -fps_mode cfr (FFmpeg 6.0 deprecation)
- Make stopCapture async (awaits ffmpeg close for finalized output)
- Update IPC types: outputDir -> outputPath, add preset to start payload
- Update preload.cts inline types for new capture API
- Rewrite capture tests for piped architecture (34 tests passing)
… validation

- Add ticker cleanup and stopping flag to ffmpeg close handler (critical: prevented orphaned interval on unexpected exit)
- Add preset validation guard in handleStartCapture
- Add test for first capturePage failure rejection
- Fix TS18048 on mock.calls.at(-1) return type
@gregpriday gregpriday force-pushed the feature/issue-4775-upgrade-demo-capture-raw branch from 8e82f8b to b808f24 Compare April 2, 2026 04:27
@gregpriday gregpriday merged commit e57665d into develop Apr 2, 2026
3 checks passed
@gregpriday gregpriday deleted the feature/issue-4775-upgrade-demo-capture-raw branch April 2, 2026 04:27
@gregpriday
Copy link
Copy Markdown
Collaborator Author

gregpriday commented Apr 7, 2026

Capture pipeline rewrite changed frame naming to frame-000001.png but the encoder still expected frame_0001.png. Naming contract wasn't kept in sync. Fixed in #4782.

Regression audit for training data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upgrade demo capture to raw bitmap piping with text-crisp encoding

1 participant