Skip to content

Commit f03ee39

Browse files
elmarcoCBenoit
authored andcommitted
refactor!: add supported codecs in BitmapConfig
"session" has a fixed set of supported codecs with associated IDs. "connector" must expose the set of codecs during capabilities exchange. It currently uses hard-codes codec IDs in different places. Move the BitmapCodecs set to ironrdp-pdu. Shared code will be used by the server, so this is a suitable common place. Signed-off-by: Marc-André Lureau <[email protected]>
1 parent d995265 commit f03ee39

File tree

10 files changed

+71
-37
lines changed

10 files changed

+71
-37
lines changed

crates/ironrdp-client/src/config.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use anyhow::Context as _;
55
use clap::clap_derive::ValueEnum;
66
use clap::Parser;
77
use ironrdp::connector::{self, Credentials};
8-
use ironrdp::pdu::rdp::capability_sets::MajorPlatformType;
8+
use ironrdp::pdu::rdp::capability_sets::{client_codecs_capabilities, MajorPlatformType};
99
use ironrdp::pdu::rdp::client_info::PerformanceFlags;
1010
use tap::prelude::*;
1111
use url::Url;
@@ -271,6 +271,7 @@ impl Config {
271271
Some(connector::BitmapConfig {
272272
color_depth,
273273
lossy_compression: true,
274+
codecs: client_codecs_capabilities(),
274275
})
275276
} else {
276277
None

crates/ironrdp-connector/src/connection_activation.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -355,16 +355,13 @@ fn create_client_confirm_active(
355355
CapabilitySet::SurfaceCommands(SurfaceCommands {
356356
flags: CmdFlags::SET_SURFACE_BITS | CmdFlags::STREAM_SURFACE_BITS | CmdFlags::FRAME_MARKER,
357357
}),
358-
CapabilitySet::BitmapCodecs(BitmapCodecs(vec![Codec {
359-
id: 0x03, // RemoteFX
360-
property: CodecProperty::RemoteFx(RemoteFxContainer::ClientContainer(RfxClientCapsContainer {
361-
capture_flags: CaptureFlags::empty(),
362-
caps_data: RfxCaps(RfxCapset(vec![RfxICap {
363-
flags: RfxICapFlags::empty(),
364-
entropy_bits: EntropyBits::Rlgr3,
365-
}])),
366-
})),
367-
}])),
358+
CapabilitySet::BitmapCodecs(
359+
config
360+
.bitmap
361+
.as_ref()
362+
.map(|b| b.codecs.clone())
363+
.unwrap_or_else(client_codecs_capabilities),
364+
),
368365
CapabilitySet::FrameAcknowledge(FrameAcknowledge {
369366
// FIXME(#447): Revert this to 2 per FreeRDP.
370367
// This is a temporary hack to fix a resize bug, see:

crates/ironrdp-connector/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use std::sync::Arc;
2323

2424
use ironrdp_core::{encode_buf, encode_vec, Encode, WriteBuf};
2525
use ironrdp_pdu::nego::NegoRequestData;
26-
use ironrdp_pdu::rdp::capability_sets;
26+
use ironrdp_pdu::rdp::capability_sets::{self, BitmapCodecs};
2727
use ironrdp_pdu::rdp::client_info::PerformanceFlags;
2828
use ironrdp_pdu::x224::X224;
2929
use ironrdp_pdu::{gcc, x224, PduHint};
@@ -43,11 +43,12 @@ pub struct DesktopSize {
4343
pub height: u16,
4444
}
4545

46-
#[derive(Debug, Clone, Copy)]
46+
#[derive(Debug, Clone)]
4747
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
4848
pub struct BitmapConfig {
4949
pub lossy_compression: bool,
5050
pub color_depth: u32,
51+
pub codecs: BitmapCodecs,
5152
}
5253

5354
#[derive(Debug, Clone)]

crates/ironrdp-pdu/src/rdp/capability_sets.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ pub use self::bitmap_cache::{
3232
BitmapCache, BitmapCacheRev2, CacheEntry, CacheFlags, CellInfo, BITMAP_CACHE_ENTRIES_NUM,
3333
};
3434
pub use self::bitmap_codecs::{
35-
BitmapCodecs, CaptureFlags, Codec, CodecProperty, EntropyBits, Guid, NsCodec, RemoteFxContainer, RfxCaps,
36-
RfxCapset, RfxClientCapsContainer, RfxICap, RfxICapFlags,
35+
client_codecs_capabilities, BitmapCodecs, CaptureFlags, Codec, CodecId, CodecProperty, EntropyBits, Guid, NsCodec,
36+
RemoteFxContainer, RfxCaps, RfxCapset, RfxClientCapsContainer, RfxICap, RfxICapFlags, CODEC_ID_NONE,
37+
CODEC_ID_REMOTEFX,
3738
};
3839
pub use self::brush::{Brush, SupportLevel};
3940
pub use self::frame_acknowledge::FrameAcknowledge;

crates/ironrdp-pdu/src/rdp/capability_sets/bitmap_codecs.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#[cfg(test)]
22
mod tests;
33

4+
use core::fmt::{self, Debug};
5+
46
use bitflags::bitflags;
57
use ironrdp_core::{
68
cast_length, decode, ensure_fixed_part_size, ensure_size, invalid_field_err, other_err, Decode, DecodeResult,
@@ -97,7 +99,7 @@ impl<'de> Decode<'de> for Guid {
9799
}
98100
}
99101

100-
#[derive(Debug, PartialEq, Eq, Clone)]
102+
#[derive(Debug, PartialEq, Eq, Clone, Default)]
101103
pub struct BitmapCodecs(pub Vec<Codec>);
102104

103105
impl BitmapCodecs {
@@ -617,3 +619,47 @@ bitflags! {
617619
const CODEC_MODE = 2;
618620
}
619621
}
622+
623+
// Those IDs are hard-coded for practical reasons, they are implementation
624+
// details of the IronRDP client. The server should respect the client IDs.
625+
#[derive(Copy, Clone, PartialEq, Eq)]
626+
pub struct CodecId(u8);
627+
628+
pub const CODEC_ID_NONE: CodecId = CodecId(0);
629+
pub const CODEC_ID_REMOTEFX: CodecId = CodecId(3);
630+
631+
impl Debug for CodecId {
632+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
633+
let name = match self.0 {
634+
0 => "None",
635+
3 => "RemoteFx",
636+
_ => "unknown",
637+
};
638+
write!(f, "CodecId({})", name)
639+
}
640+
}
641+
642+
impl CodecId {
643+
pub const fn from_u8(value: u8) -> Option<Self> {
644+
match value {
645+
0 => Some(CODEC_ID_NONE),
646+
3 => Some(CODEC_ID_REMOTEFX),
647+
_ => None,
648+
}
649+
}
650+
}
651+
652+
pub fn client_codecs_capabilities() -> BitmapCodecs {
653+
let codecs = vec![Codec {
654+
id: CODEC_ID_REMOTEFX.0,
655+
property: CodecProperty::RemoteFx(RemoteFxContainer::ClientContainer(RfxClientCapsContainer {
656+
capture_flags: CaptureFlags::empty(),
657+
caps_data: RfxCaps(RfxCapset(vec![RfxICap {
658+
flags: RfxICapFlags::empty(),
659+
entropy_bits: EntropyBits::Rlgr3,
660+
}])),
661+
})),
662+
}];
663+
664+
BitmapCodecs(codecs)
665+
}

crates/ironrdp-session/src/fast_path.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ use ironrdp_pdu::codecs::rfx::FrameAcknowledgePdu;
99
use ironrdp_pdu::fast_path::{FastPathHeader, FastPathUpdate, FastPathUpdatePdu, Fragmentation};
1010
use ironrdp_pdu::geometry::{InclusiveRectangle, Rectangle as _};
1111
use ironrdp_pdu::pointer::PointerUpdateData;
12+
use ironrdp_pdu::rdp::capability_sets::{CodecId, CODEC_ID_NONE, CODEC_ID_REMOTEFX};
1213
use ironrdp_pdu::rdp::headers::ShareDataPdu;
1314
use ironrdp_pdu::surface_commands::{FrameAction, FrameMarkerPdu, SurfaceCommand};
1415

1516
use crate::image::DecodedImage;
1617
use crate::pointer::PointerCache;
17-
use crate::utils::CodecId;
1818
use crate::{rfx, SessionError, SessionErrorExt, SessionResult};
1919

2020
#[derive(Debug)]
@@ -337,7 +337,7 @@ impl Processor {
337337
bottom: destination.bottom - 1,
338338
};
339339
match codec_id {
340-
CodecId::None => {
340+
CODEC_ID_NONE => {
341341
let ext_data = bits.extended_bitmap_data;
342342
match ext_data.bpp {
343343
32 => {
@@ -352,7 +352,7 @@ impl Processor {
352352
}
353353
}
354354
}
355-
CodecId::RemoteFx => {
355+
CODEC_ID_REMOTEFX => {
356356
let mut data = ReadCursor::new(bits.extended_bitmap_data.data);
357357
while !data.is_empty() {
358358
let (_frame_id, rectangle) = self.rfx_handler.decode(image, &destination, &mut data)?;
@@ -361,6 +361,9 @@ impl Processor {
361361
.or(Some(rectangle));
362362
}
363363
}
364+
_ => {
365+
warn!("Unsupported codec ID: {}", bits.extended_bitmap_data.codec_id);
366+
}
364367
}
365368
}
366369
SurfaceCommand::FrameMarker(marker) => {

crates/ironrdp-session/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ pub mod image;
1313
pub mod legacy;
1414
pub mod pointer;
1515
pub mod rfx; // FIXME: maybe this module should not be in this crate
16-
pub mod utils;
1716
pub mod x224;
1817

1918
mod active_stage;

crates/ironrdp-session/src/utils.rs

Lines changed: 0 additions & 16 deletions
This file was deleted.

crates/ironrdp-web/src/session.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use ironrdp::displaycontrol::client::DisplayControlClient;
2222
use ironrdp::dvc::DrdynvcClient;
2323
use ironrdp::graphics::image_processing::PixelFormat;
2424
use ironrdp::pdu::input::fast_path::FastPathInputEvent;
25+
use ironrdp::pdu::rdp::capability_sets::client_codecs_capabilities;
2526
use ironrdp::pdu::rdp::client_info::PerformanceFlags;
2627
use ironrdp::session::image::DecodedImage;
2728
use ironrdp::session::{fast_path, ActiveStage, ActiveStageOutput, GracefulDisconnectReason};
@@ -838,6 +839,7 @@ fn build_config(
838839
bitmap: Some(connector::BitmapConfig {
839840
color_depth: 16,
840841
lossy_compression: true,
842+
codecs: client_codecs_capabilities(),
841843
}),
842844
#[allow(clippy::arithmetic_side_effects)] // fine unless we end up with an insanely big version
843845
client_build: semver::Version::parse(env!("CARGO_PKG_VERSION"))

ffi/src/connector/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ pub mod ffi {
125125
}
126126

127127
pub fn set_bitmap_config(&mut self, bitmap: &BitmapConfig) {
128-
self.bitmap = Some(bitmap.0);
128+
self.bitmap = Some(bitmap.0.clone());
129129
}
130130

131131
pub fn set_client_build(&mut self, client_build: u32) {

0 commit comments

Comments
 (0)