Skip to content

feat(cef): expose frame IOSurface id to Dart for WebRTC streaming#12

Merged
wenkaifan0720 merged 2 commits into
mainfrom
feat/osr-rtc-video-source
Jun 25, 2026
Merged

feat(cef): expose frame IOSurface id to Dart for WebRTC streaming#12
wenkaifan0720 merged 2 commits into
mainfrom
feat/osr-rtc-video-source

Conversation

@wenkaifan0720

Copy link
Copy Markdown
Collaborator

Adds CefWebController.getFrameSurface() + an onSurface callback (and the CefSurfaceInfo model) that surface the existing global IOSurface id of the live OSR CVPixelBuffer.

A host app can then IOSurfaceLookup that surface and feed it to a libwebrtc RTCVideoSourcewith no webrtc dependency added to flutter_cef. onSurface fires on each (re)allocation, so consumers re-resolve after a resize realloc.

This is the engine-side primitive behind streaming a live Chromium tile to remote peers / a mobile companion in the consumer app (work_canvas).

Changes

  • lib/src/cef_web_controller.dartgetFrameSurface() + onSurface setter
  • lib/src/cef_events.dartCefSurfaceInfo (surfaceId + physical w/h)
  • macos/Classes/CefWebSession.swift — emit the surface id on alloc/realloc
  • macos/Classes/FlutterCefPlugin.swift — wire the channel event + getter

No webrtc dep; additive API; existing behavior unchanged.

🤖 Generated with Claude Code

wenkaifan0720 and others added 2 commits June 24, 2026 23:43
Add CefWebController.getFrameSurface() + an onSurface callback (and the
CefSurfaceInfo model) that surface the existing global IOSurface id, so a
host app can IOSurfaceLookup the live OSR CVPixelBuffer and feed it to a
libwebrtc RTCVideoSource — with no webrtc dependency in flutter_cef.
onSurface fires on each (re)allocation so consumers re-resolve after a
resize realloc.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ceInfo

The onSurface callback was effectively dead: it fired only from the init publish
(before the plugin wired the callback) and never on resize (sendResize swaps the
surface inline; promotion happens in handleFrame(opPresent)/the resize watchdog,
neither of which called publishBuffers). So a consumer's resize re-point (R2)
never triggered — after any resize the freed/stale surface kept being sampled.

- Route both resize-promotion paths (opPresent + watchdog force-promote) through a
  notifySurface() helper so onSurface fires on every realloc.
- Add emitCurrentSurface(); the plugin calls it right after wiring onSurface so the
  initial surface (whose publish predated the callback) is delivered.
- Export CefSurfaceInfo from the public barrel (was unreferenceable by consumers).

Now matches the documented "fires on init + each resize" contract.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@wenkaifan0720 wenkaifan0720 merged commit 71af1dd into main Jun 25, 2026
1 check passed
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.

1 participant