{"record":{"id":"bc420c4ef17cb5de","repo":"rustdesk/rustdesk","slug":"encoder-type-mismatch-bc420c","errorCode":null,"errorMessage":"encoder type mismatch","messagePattern":"encoder type mismatch","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"libs/scrap/src/common/vpxcodec.rs","lineNumber":170,"sourceCode":"                        VP9E_SET_TILE_COLUMNS as _,\n                        4 as c_int\n                    ));\n                } else if config.codec == VpxVideoCodecId::VP8 {\n                    // https://github.com/webmproject/libvpx/blob/972149cafeb71d6f08df89e91a0130d6a38c4b15/vpx/vp8cx.h#L172\n                    // https://groups.google.com/a/webmproject.org/g/webm-discuss/c/DJhSrmfQ61M\n                    call_vpx!(vpx_codec_control_(&mut ctx, VP8E_SET_CPUUSED as _, 12,));\n                }\n\n                Ok(Self {\n                    ctx,\n                    width: config.width as _,\n                    height: config.height as _,\n                    id: config.codec,\n                    i444,\n                    yuvfmt: Self::get_yuvfmt(config.width, config.height, i444),\n                })\n            }\n            _ => Err(anyhow!(\"encoder type mismatch\")),\n        }\n    }\n\n    fn encode_to_message(&mut self, input: EncodeInput, ms: i64) -> ResultType<VideoFrame> {\n        let mut frames = Vec::new();\n        for ref frame in self\n            .encode(ms, input.yuv()?, STRIDE_ALIGN)\n            .with_context(|| \"Failed to encode\")?\n        {\n            frames.push(VpxEncoder::create_frame(frame));\n        }\n        for ref frame in self.flush().with_context(|| \"Failed to flush\")? {\n            frames.push(VpxEncoder::create_frame(frame));\n        }\n\n        // to-do: flush periodically, e.g. 1 second\n        if frames.len() > 0 {\n            Ok(VpxEncoder::create_video_frame(self.id, frames))","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/rustdesk/rustdesk/blob/7aa98d43cf1962a7a29ec16ffef42974377ef11e/libs/scrap/src/common/vpxcodec.rs#L152-L188","documentation":"VpxEncoder::new (libs/scrap/src/common/vpxcodec.rs) accepts only EncoderCfg::VPX(config); the catch-all arm returns 'encoder type mismatch'. Same constructor-level variant check pattern used by AomEncoder and HwRamEncoder: the EncoderCfg enum variant must correspond to the concrete encoder type being constructed.","triggerScenarios":"Constructing VpxEncoder with EncoderCfg::AOM or EncoderCfg::HWRAM — dispatch layer mapped the negotiated codec (AV1 or hardware) to the libvpx encoder struct.","commonSituations":"Codec-selection refactors; new EncoderCfg variants added without updating the match in the creation layer; defaults that assume VPX everywhere.","solutions":["Route only EncoderCfg::VPX to VpxEncoder; check the creation dispatch (codec id -> EncoderCfg variant -> encoder struct).","Make the dispatch match exhaustive over EncoderCfg so the compiler flags missing routes.","Add a regression test per codec id asserting the returned encoder's type."],"exampleFix":"// before\nlet enc = VpxEncoder::new(cfg, i444)?; // cfg is EncoderCfg::AOM -> 'encoder type mismatch'\n\n// after\nmatch cfg {\n    EncoderCfg::VPX(c) => Box::new(VpxEncoder::new(EncoderCfg::VPX(c), i444)?),\n    EncoderCfg::AOM(c) => Box::new(AomEncoder::new(EncoderCfg::AOM(c), i444)?),\n    EncoderCfg::HWRAM(c) => Box::new(HwRamEncoder::new(EncoderCfg::HWRAM(c), i444)?),\n}","handlingStrategy":"type-guard","validationCode":"if !matches!(cfg, EncoderCfg::VPX(_)) {\n    return Err(anyhow!(\"VpxEncoder requires EncoderCfg::VPX\"));\n}","typeGuard":"fn is_vpx_cfg(cfg: &EncoderCfg) -> bool {\n    matches!(cfg, EncoderCfg::VPX(_))\n}","tryCatchPattern":null,"preventionTips":["Maintain a single exhaustive codec-dispatch match; no '_' arms.","When adding encoders (AOM, HWRAM), wire them into the same match in one change.","Cover the dispatch with unit tests per codec id."],"tags":["encoder","vpx","vp8","vp9","type-mismatch","rust"],"backgroundTag":null,"analyzedSha":"7aa98d43cf1962a7a29ec16ffef42974377ef11e","analyzedAt":"2026-08-16T06:17:34.842Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}