Skip to content

feat(stream): experimental Framegen WebGPU frame interpolation - #718

Open
MONZikWasTaken wants to merge 3 commits into
OpenCloudGaming:devfrom
MONZikWasTaken:feat/experimental-framegen-webgpu-interpolation
Open

feat(stream): experimental Framegen WebGPU frame interpolation#718
MONZikWasTaken wants to merge 3 commits into
OpenCloudGaming:devfrom
MONZikWasTaken:feat/experimental-framegen-webgpu-interpolation

Conversation

@MONZikWasTaken

@MONZikWasTaken MONZikWasTaken commented Aug 8, 2026

Copy link
Copy Markdown

Summary

Adds optional experimental client-side neural frame interpolation for the embedded Chromium WebRTC stream path, powered by the Framegen hand-written WGSL/WebGPU runtime (framegen npm).

This is intentionally scoped like the existing video-filter pipeline:

  • Web client mode only (disabled when native streamer / GStreamer path is active)
  • Off by default
  • Settings under Settings → Video
  • Clear non-commercial weights notice in the UI + third_party/framegen/

User-facing behavior

  • Toggle Frame Interpolation (experimental)
  • Factor: 2× / 3× / 4×
  • Model quality: 360p / 480p / 720p (internal inference resolution)
  • Overlay canvas presents synthetic mids between consecutive decoded frames

Implementation notes

  • Shared settings: frameInterpolation on Settings with normalize helpers + unit tests
  • Runtime: FrameInterpolationPipeline next to VideoShaderPipeline
  • Weights: copied at postinstall into src/renderer/public/framegen-weights/ (gitignored); runtime falls back to pinned jsDelivr if missing
  • Runtime code license: MIT; model weights: non-commercial (Framegen WEIGHTS_LICENSE)

Trade-offs (documented in UI)

  • Adds display latency (needs a frame pair)
  • Extra GPU load
  • Mid presentation currently uses GPU→CPU readback at the reduced model resolution (experimental quality; can be upgraded to a pure WebGPU present path later)

Test plan

  • npm --prefix opennow-stable run typecheck
  • npm --prefix opennow-stable test (includes new frameInterpolation normalize tests)
  • Manual: web streamer, enable Frame Interpolation, confirm overlay activates and stream remains controllable
  • Manual: native streamer mode — control disabled / pipeline inactive
  • Manual: machine without WebGPU — graceful disable + no crash

Add optional client-side neural frame interpolation for the embedded
WebRTC stream path using the Framegen WGSL runtime (npm framegen).

- New frameInterpolation settings (factor 2-4x, quality 360/480/720)
- WebGPU pipeline overlay (web client only; disabled for native streamer)
- Settings UI under Video with license notice for non-commercial weights
- postinstall copies weights into public/; CDN fallback if missing
- Unit tests for settings normalization

Off by default. Adds display latency and GPU load when enabled.
@capy-ai

capy-ai Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Capy auto-review is paused for this organization because the usage-cycle auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e8f4bb2f-460c-48da-afbf-3b88c69388af

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@zortos293

Copy link
Copy Markdown
Collaborator

@capyai review pr

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added 2 comments

Comment thread opennow-stable/src/renderer/src/platforms/gfn/frameInterpolationPipeline.ts Outdated
- Update bun.lock so CI `bun install --frozen-lockfile` succeeds
- Abort in-flight frame steps after dispose/settings generation bumps
- Clear sticky rejected weights cache and stop loops on hard runtime failure
Address remaining race and failure-path issues:
- generation gate after every await; drop stale present queues
- rebuild runtime when factor changes (not only resolution)
- clear sticky rejected weights cache; set initFailed and stop loops
- safer texture readback cleanup; device-lost invalidation
@MONZikWasTaken

Copy link
Copy Markdown
Author

Follow-up fixes pushed

Addressed the Capy medium findings and CI lockfile issue:

  1. bun.lock updated so bun install --frozen-lockfile succeeds
  2. Lifecycle races: generation counter checked after every await; dispose/settings/device-lost invalidate generation; stale GPU work and present queues are dropped
  3. Weights cache: rejected promises are not sticky; hard runtime failure sets initFailed, stops loops, and can retry on re-enable
  4. Factor changes rebuild the runtime (mid texture count), not only quality/resolution

Local verification

  • npm run typecheck
  • npm test ✅ (337)
  • npm run build ✅ (framegen-weights present in dist/)
  • bun install --frozen-lockfile

Note for maintainers

CI shows action_required for this fork PR (first-time contributor / workflow approval). Please Approve and run workflows on the latest head so the green checks can land.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an optional experimental WebGPU neural frame interpolation overlay (Framegen) for the embedded Chromium WebRTC streaming path, wiring it through shared settings, main-process settings migration, and renderer UI/pipeline code. This extends the existing “video shader pipeline” approach with a second overlay pipeline that can synthesize intermediate frames and present them on a canvas above the decoded <video>.

Changes:

  • Introduces shared frameInterpolation settings (defaults + normalization + tests) and migrates persisted settings in main.
  • Adds a renderer-side FrameInterpolationPipeline using Framegen (framegen npm) and exposes controls in Settings → Video; integrates pipeline activation into StreamView.
  • Adds postinstall weight-copy script + third-party notices, plus dependency and TypeScript/WebGPU typing updates.

Reviewed changes

Copilot reviewed 21 out of 25 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
opennow-stable/tsconfig.json Adds framegen type shim path mapping and enables @webgpu/types.
opennow-stable/third_party/framegen/WEIGHTS_LICENSE.md Adds a local notice for non-commercial model weights licensing.
opennow-stable/third_party/framegen/README.md Documents Framegen usage and licensing split (runtime vs weights).
opennow-stable/src/shared/gfn/settings.ts Adds frameInterpolation to Settings and default settings creation.
opennow-stable/src/shared/gfn/settings.test.ts Ensures nested frameInterpolation defaults are fresh/mutable per instance.
opennow-stable/src/shared/gfn/index.ts Re-exports new frameInterpolation module from the shared barrel.
opennow-stable/src/shared/gfn/frameInterpolation.ts Defines types/defaults and normalization helpers for persisted/user-provided settings.
opennow-stable/src/shared/gfn/frameInterpolation.test.ts Adds unit tests for normalization and activation helper.
opennow-stable/src/renderer/src/vite-env.d.ts Adds WebGPU ambient types to the renderer environment.
opennow-stable/src/renderer/src/types/framegen.d.ts Provides a local declare module "framegen" typing surface.
opennow-stable/src/renderer/src/platforms/gfn/index.ts Exports the new renderer pipeline from the platform barrel.
opennow-stable/src/renderer/src/platforms/gfn/frameInterpolationPipeline.ts Implements the WebGPU/Framegen runtime pipeline and presentation loop.
opennow-stable/src/renderer/src/components/StreamView.tsx Activates/deactivates the pipeline based on settings + streaming mode.
opennow-stable/src/renderer/src/components/settings/stream/StreamVideoSection.tsx Adds the new interpolation controls into the Video settings section.
opennow-stable/src/renderer/src/components/settings/stream/FrameInterpolationControls.tsx Implements UI controls for enable/factor/quality and weights notice.
opennow-stable/src/renderer/src/App.tsx Plumbs settings.frameInterpolation into StreamView.
opennow-stable/src/renderer/public/.gitkeep Adds a placeholder file for the renderer public/ directory.
opennow-stable/src/main/settings.ts Normalizes/migrates persisted frameInterpolation settings.
opennow-stable/scripts/copy-framegen-weights.mjs Copies Framegen weights into public/ at install time and writes a notice file.
opennow-stable/package.json Adds framegen dependency + runs the weight-copy script on postinstall.
opennow-stable/package-lock.json Locks framegen and @webgpu/types additions.
opennow-stable/electron.vite.config.ts Adds framegen to optimizeDeps.include for the renderer build.
opennow-stable/bun.lock Updates Bun lockfile for new deps (even though npm is primary).
opennow-stable/.gitignore Ignores copied weights directory under renderer public assets.
locales/en.json Adds English UI strings for the new Frame Interpolation settings controls.
Files not reviewed (1)
  • opennow-stable/package-lock.json: Generated file
Suppressed comments (1)

opennow-stable/src/renderer/src/components/settings/stream/FrameInterpolationControls.tsx:102

  • Same issue as above: htmlFor points at an id on a <button> chip, which isn’t a labelable form control. Removing htmlFor + the dynamic id will avoid a misleading association for assistive tech.
              <label className="settings-label" htmlFor="settings-stream-frame-interpolation-quality">
                {t("settings.frameInterpolation.quality")}
              </label>
              <span className="settings-value-badge">{fi.quality}p</span>
            </div>
            <div className="settings-chip-row">
              {QUALITY_OPTIONS.map((quality) => (
                <button
                  key={quality}
                  type="button"

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +42 to +44
function align16(value: number): number {
return Math.max(16, Math.floor(value / 16) * 16);
}
Comment on lines +66 to +80
<label className="settings-label" htmlFor="settings-stream-frame-interpolation-factor">
{t("settings.frameInterpolation.factor")}
</label>
<span className="settings-value-badge">{fi.factor}×</span>
</div>
<div className="settings-chip-row">
{FACTOR_OPTIONS.map((factor) => (
<button
key={factor}
type="button"
id={
factor === fi.factor
? "settings-stream-frame-interpolation-factor"
: undefined
}
Comment thread locales/en.json
},
"frameInterpolation": {
"title": "Frame Interpolation",
"hint": "Experimental neural frame interpolation (Framegen WebGPU runtime) that synthesizes extra frames between decoded stream frames for smoother motion. Adds display latency and GPU load. Web client mode only; requires WebGPU + shader-f16.",
Comment on lines +24 to +39
mkdirSync(noticeDir, { recursive: true });
writeFileSync(
join(noticeDir, "WEIGHTS_LICENSE.md"),
`# Framegen model weights

The files under \`src/renderer/public/framegen-weights/\` are the Framegen
v7-small neural frame-interpolation weights, redistributed from the
[\`framegen\`](https://www.npmjs.com/package/framegen) npm package.

**Non-commercial research and personal use only.** See the upstream notice:
https://github.com/MONZikWasTaken/Framegen/blob/main/WEIGHTS_LICENSE.md

Framegen **runtime code** (JavaScript/WGSL) is MIT-licensed separately.
`,
"utf8",
);
@@ -0,0 +1 @@

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.

3 participants