rustdesk/rustdesk · error · anyhow::Error

don't support h264!

Error message

don't support h264!

What it means

Decoder::decode_video_frame in libs/scrap/src/common/codec.rs matched an incoming video_frame::Union::H264s message, but neither the vram decoder (self.h264_vram, feature vram) nor the hwcodec RAM decoder (self.h264_ram, feature hwcodec) is present. The H264 arm only exists when one of those cargo features is compiled in, and it still errors when the decoder slots are None — i.e. the build has no usable H264 decoder for this frame.

Source

Thrown at libs/scrap/src/common/codec.rs:673

                if let Some(av1) = &mut self.av1 {
                    Decoder::handle_av1s_video_frame(av1, av1s, rgb, chroma)
                } else {
                    bail!("av1 decoder not available");
                }
            }
            #[cfg(any(feature = "hwcodec", feature = "vram"))]
            video_frame::Union::H264s(h264s) => {
                *chroma = Some(Chroma::I420);
                #[cfg(feature = "vram")]
                if let Some(decoder) = &mut self.h264_vram {
                    *_pixelbuffer = false;
                    return Decoder::handle_vram_video_frame(decoder, h264s, _texture);
                }
                #[cfg(feature = "hwcodec")]
                if let Some(decoder) = &mut self.h264_ram {
                    return Decoder::handle_hwram_video_frame(decoder, h264s, rgb, &mut self.i420);
                }
                Err(anyhow!("don't support h264!"))
            }
            #[cfg(any(feature = "hwcodec", feature = "vram"))]
            video_frame::Union::H265s(h265s) => {
                *chroma = Some(Chroma::I420);
                #[cfg(feature = "vram")]
                if let Some(decoder) = &mut self.h265_vram {
                    *_pixelbuffer = false;
                    return Decoder::handle_vram_video_frame(decoder, h265s, _texture);
                }
                #[cfg(feature = "hwcodec")]
                if let Some(decoder) = &mut self.h265_ram {
                    return Decoder::handle_hwram_video_frame(decoder, h265s, rgb, &mut self.i420);
                }
                Err(anyhow!("don't support h265!"))
            }
            #[cfg(feature = "mediacodec")]
            video_frame::Union::H264s(h264s) => {
                *chroma = Some(Chroma::I420);

View on GitHub (pinned to 7aa98d43cf)

Solutions

  1. Build with the hwcodec feature (default on desktop targets) so h264_ram can be populated.
  2. Ensure the negotiated codec falls back to VP9/VP8 when local H264 decode capability is absent — check the capability exchange before accepting H264.
  3. If hardware decode init failed, retry or clear the hwcodec config cache (HwCodecConfig::clear) so detection runs again, then recreate the Decoder.
  4. As a last resort, have the remote side switch to a codec this build supports (VPX).

Example fix

// before
let rgb = decoder.decode_video_frame(&vf, &mut rgb, &mut chroma, false)?; // H264s -> Err

// after: advertise capability before the session starts
let prefer_h264 = Decoder::video_codec_state(|c| c.score_h264 > 0); // only accept H264 if decodable
if !prefer_h264 { options.lock().unwrap().insert("video-codec", "vp9"); }
Defensive patterns

Strategy: fallback

Validate before calling

// before the session, check local H264 decode capability
let h264_capable = cfg!(feature = "hwcodec") && hwcodec::Decoder::info(0, false).is_some();
if !h264_capable { opts.insert("custom-recv-codec", "vp9"); }

Try / catch

match decoder.decode_video_frame(&vf, &mut rgb, &mut chroma, false) {
    Ok(done) => done,
    Err(e) if e.to_string().contains("don't support h264") => request_codec_switch(Codec::VP9),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: The remote peer encodes H264 (hwcodec negotiated) while the local Decoder was created without H264 support: hwcodec/vram features disabled at compile time, hardware H264 decode not found at startup, or the HwRamDecoder creation failed so self.h264_ram stayed None.

Common situations: Software-only build (no hwcodec feature) connecting to a peer that sends H264s; VMs or hosts without GPU decode; codec negotiation mismatch after one side updated and began preferring H264.

Related errors


AI-assisted analysis of rustdesk/rustdesk@7aa98d43cf (2026-08-16). Data as JSON: /api/errors/4a8304ad8a292fcc. Report an issue: GitHub.