Skip to content

feat: account for display pixel density in adaptive stream#1098

Draft
hiroshihorie wants to merge 7 commits into
hiroshi/better-track-settingsfrom
hiroshi/adaptive-stream-pixel-density
Draft

feat: account for display pixel density in adaptive stream#1098
hiroshihorie wants to merge 7 commits into
hiroshi/better-track-settingsfrom
hiroshi/adaptive-stream-pixel-density

Conversation

@hiroshihorie
Copy link
Copy Markdown
Member

@hiroshihorie hiroshihorie commented May 29, 2026

The adaptive-stream visibility observer fed each view's logical (DIP) size straight to the server, so on retina/HiDPI displays it under-requested by the device pixel ratio and the server returned an upscaled/soft layer. Server layers are sized in physical pixels.

  • Add AdaptiveStreamPixelDensity (auto | fixed(double)) mirroring the JS SDK's pixelDensity option, plus VideoTrackRenderer.adaptiveStreamPixelDensity (default: auto), set per-view rather than room-wide. Fractional densities are supported and the resolved value is capped at 3x to bound bandwidth.
  • In auto mode the view's real devicePixelRatio is read per-view via MediaQuery; fixed modes use a constant multiplier.
  • _computeVideoViewVisibility now scales each view's logical size by the resolved density before computing the largest requested dimensions.

@hiroshihorie hiroshihorie force-pushed the hiroshi/adaptive-stream-pixel-density branch from 1fdd82b to 86a4ee3 Compare May 29, 2026 09:24
The adaptive-stream visibility observer fed each view's logical (DIP) size
straight to the server, so on retina/HiDPI displays it under-requested by the
device pixel ratio and the server returned an upscaled/soft layer. Server
layers are sized in physical pixels.

- Add AdaptiveStreamPixelDensity (auto | fixed(double)) capped at 3x, mirroring
  the JS pixelDensity option.
- Add a per-view VideoTrackRenderer.adaptiveStreamPixelDensity (default auto);
  the density is stored per view-key on the track.
- _computeVideoViewVisibility scales each view's logical size by its own
  resolved density (auto = that view's MediaQuery devicePixelRatio) before
  taking the largest size across the track's views.

Because density is resolved per view, a track shown on screens with different
scales (e.g. built-in retina + external 1x) requests correctly for each.
@hiroshihorie hiroshihorie force-pushed the hiroshi/adaptive-stream-pixel-density branch from 86a4ee3 to a4c0dbe Compare May 29, 2026 09:41
Comment thread lib/src/track/local/local.dart Outdated

@internal
void updateViewKeyPixelDensity(GlobalKey key, AdaptiveStreamPixelDensity pixelDensity) {
if (viewPixelDensities.containsKey(key)) viewPixelDensities[key] = pixelDensity;
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.

should we log or handle the case where if (!viewPixelDensities.containsKey(key)) ?

Copy link
Copy Markdown
Contributor

@xianshijing-lk xianshijing-lk left a comment

Choose a reason for hiding this comment

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

one question, lgtm in general

…tion

The map().nonNulls iterable was lazy and consumed three times per 300ms visibility tick (length, isNotEmpty, reduce), re-running findRenderObject and MediaQuery lookups on each pass. Materialize once with toList().
Use MediaQuery.maybeDevicePixelRatioOf instead of maybeOf(context)?.devicePixelRatio so the view depends only on the pixel ratio rather than every MediaQuery field (padding, text scale, etc.).
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.

2 participants