CloudXR 6.2.1 auto-webrtc: H.264 / HEVC hit per-eye width cap at 2048 (0xF22300), AV1 allows higher resolutions like 2816×2816

Environment

- CloudXR Runtime (server): 6.2.1, device-profile=auto-webrtc

- CloudXR.js (web client): 6.2.0

- Server GPU: NVIDIA RTX 4090 (driver 5xx.x, Vulkan 1.3.312)

- OpenXR app: Autodesk VRED 2027 (openxr_cloudxr.json)

- Client HMD: Pico 4 Ultra (Pico built-in browser, WebXR immersive-vr)

- Codec test matrix: H.264, HEVC(H.265), AV1

- runtime.cfg relevant keys: runtime-foveation=true, runtime-foveation-unwarped-width=2560, disable-alpha=true, max-fps=0, enable-ice=true

Symptom

The stream works reliably at per-eye 2048×1792 for H.264 and HEVC.

As soon as per-eye width exceeds 2048 (e.g. 2160×1792, height unchanged), the WebRTC stream drops with client error 0xF22300 = StreamDisconnectedFromServer.

But under AV1 codec with the exact same stack and runtime config, we can successfully run much higher per-eye resolutions such as 2816×2816 without hitting this disconnect error.

Packed frame formula used by CloudXR.js with foveation enabled:

packedWidth = perEyeWidth × 2

packedHeight = perEyeHeight × 9/4

Tested cases:

- 2048 × 1792 → packed 4096 × 4032 ✅ H.264 / HEVC works

- 2160 × 1792 → packed 4320 × 4032 ❌ H.264 / HEVC → 0xF22300

- 2816 × 2816 → packed 5632 × 6336 ✅ AV1 works fine

Questions:

What supported methods or configuration options exist to bypass / remove the per-eye resolution limit of 2048×1792 when using H.264 or HEVC under auto-webrtc?

Thanks

Good day!

I can provide some additional information on this.

  • h264: The standard and NVIDIA encoders (both hardware and software) for this codec do not support streaming resolutions over 4096x4096, and this simply cannot be changed.
  • hevc/h265: As far as we’re aware, the Pico browser does not support the HEVC codec. When HEVC is selected, the implementation silently downgrades to h264.
  • av1: While AV1 will stream at higher resolutions, I would caution against it, and make sure performance on the client device is not suffering. The Pico 4 Ultra has some hardware decoder resolution limits (8192x4320 or 4320x8192), but the chromium-based Browser can silently transition to software-based decoding, resulting in much lower performance.

So, upshot, 4096x4096 is a hard limit for h264, hevc becomes h264 and hits 4096x4096 again, and av1 can silently transition to software decoding above certain resolution thresholds.

That said, 2048x1792 is a fairly high pixel density for the Pico 4 Ultra, especially with foveated streaming assigning most of the pixel density to the center of the view. If I were to guess, the real issue is that streaming has a low visual quality?

Thanks for the details.
The real issue is visual quality. At H.264 perEye 2048×1792, VRED automotive content looks blurry, dark, washed out, and low-contrast compared with ALVR. For these captures we used H.264, perEye 2048×1792, 100 Mbps, client target 72 Hz, Framebuffer Scale 1.0. The server log reports Color Space Mode = 2 (LIMITED_YCBCR_BT709).

I’ve attached two side-by-side captures (left CloudXR, right ALVR default) of the same scene — the gap is consistent in all three.

We have already tried the obvious client-side knobs without meaningful improvement:

  • Requesting 150/200 Mbps is rejected by the runtime and clamped to 100 Mbps.
  • Increasing Framebuffer Scale Factor does not change streaming resolution and only adds local compositor cost.
  • Client FFR is already disabled (fixedFoveation=0).
  • 90 Hz performs worse than 72 Hz on the Pico browser.
  • runtime-foveation=false does not disable QuadView; it only stops dynamic gaze-driven resolution changes.
  • Changing runtime-foveation-unwarped-width independently causes either upscale-before-encode blur or wasted VRED render time / stalls.

Totally understand the frustration.

For our ability to compare and reproduce: What does your ALVR stack look like? Are you using a side-loaded native client, or the ALVR fork with WebXR support?

rinsuki-lab/ALVR web research

Thanks. The ALVR side is the official native stack (alvr-org/ALVR, alvr_streamer_windows on the same RTX 4090 PC + the sideloaded Android client on Pico 4 Ultra), not the WebXR fork — so I understand it’s not strictly apples-to-apples with the browser path.

For an accurate comparison, here are ALVR’s actual encoder settings from session.json (v20.14.1), which I re-checked before posting:

  • Codec: HEVC, hardware decode
  • Bitrate: 50 Mbps, ConstantMbps (CBR) — so this isn’t a VBR-vs-CBR difference
  • NVENC preset: P1, tuning LowLatency, multi-pass QuarterResolution (i.e. its fastest preset, not a quality preset)
  • Spatial AQ enabled (adaptive_quantization_mode: Spatial); VBAQ off
  • Full-range output (use_full_range: true)
  • View resolution scale 1.25 (~3000²-equivalent), 72 Hz
  • Client-side FFR off, client post-processing off

The point I’d like your guidance on: ALVR achieves the sharper, better-contrasted image in the captures using a lower bitrate and the fastest NVENC preset — so the gap doesn’t appear to be bitrate, bpp, or preset effort. The two concrete differences I can point to are HEVC + Spatial AQ and Full-range vs Limited color, all of which show up as locked in the CloudXR streamsdk log (PRESET_NVENC_P4, CBR, no AQ, Color Space Mode = 2 (LIMITED_YCBCR_BT709)).

So my question is straightforward: is the current blurry/dark result a configuration problem on my side (something in 6.2.1 I haven’t tried), or is it effectively the quality ceiling of the auto-webrtc + Pico-browser path today?

Separately, would going back to CloudXR 4.x with its native Android client likely improve image quality on Pico 4 Ultra?

@changqing91

We’re looking into ways to improve visual quality on the Pico 4 Ultra, but there are some hard limitations of that platform. Among other things, the Browser is currently on Chromium 125 (compared to e.g. 151 for my current desktop browser), which lacks several crucial Android graphics improvements that make a big difference in performance which in turn frees up resources to chase quality.

I can’t recommend doing anything with the CloudXR 4.0.x stack, as it’s fully deprecated and unsupported at this point. If you happen to have it already, I suspect you could get to higher quality than the current WebXR client, due primarily to the native/web performance gap.

I thought we had achieved a higher visual quality in the WebXR, and I will be digging into that on my side. I see similar disappointing visual quality when I run tests, so we at least are reproducing the behavior.

There is thing I’m curious about: While it is true that Framebuffer Scale Factor will not change the streaming resolution, it does change the resolution used by the WebXR compositor when submitting to the system runtime/compositor. Because of limited performance onboard the devices, the baseline/recommended/default resolution/framebuffer-size on most Android HMDs is significantly lower than the display/panel resolution. It will incur a significant performance penalty, but it should be a blocker for higher quality visuals. IIRC, at the 2048x1792 resolution, the streaming resolution is higher than the default framebuffer resolution, but I’d have to check.

Thanks for your detailed response and for reproducing the quality issue.

We are looking forward to future official improvements or viable production‑grade workarounds for Android‑based headsets like Pico 4 Ultra and Quest.