Skip to content

egfx client: one H.264 decoder shared by all surfaces breaks multi-surface streams #2033

Open

Description

GraphicsPipelineClient holds a single H.264 decoder (h264_decoder: Option<Box<dyn H264Decoder>> in crates/ironrdp-egfx/src/client.rs) and feeds it the AVC420/AVC444 payloads of every surface. A server that encodes each surface as its own H.264 stream, as MS-RDPEGFX allows (each WireToSurface1 names its surfaceId, and the surfaces can differ in size), interleaves independent streams into that one decoder. The second stream's SPS/PPS and reference frames replace the first's, and decoding fails.

Seen with a two-monitor server session (two surfaces, 1280x720 each at x=0 and x=1280, each with its own AVC420 stream): an IronRDP-based client fails within a second with OpenH264 decode failed (native error 2), while xfreerdp3 /multimon displays both monitors correctly. FreeRDP keeps an H.264 context per surface.

A decoder per surface, created when the surface is created and dropped with it, would match. That likely needs a decoder factory rather than a single decoder instance passed to GraphicsPipelineClient::new, so it is an API question as much as an implementation one.

Activity

  1. pgaskin commented on Oct 26, 2026

    @pgaskin

    I ran into this while adding EGFX support to the IronRDP backend for Vento, my Android (and now Linux too) remote desktop client.

    See https://github.com/pgaskin/vento/blob/master/patches/ironrdp/0001-feat-egfx-decode-AVC-per-surface-through-a-per-surfa.patch.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions