Skip to content

Commit 2f98acf

Browse files
committed
refactor(server): factor out remotefx tile encoding
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
1 parent f679c9a commit 2f98acf

File tree

1 file changed

+78
-31
lines changed
  • crates/ironrdp-server/src/encoder

1 file changed

+78
-31
lines changed

crates/ironrdp-server/src/encoder/rfx.rs

Lines changed: 78 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use ironrdp_core::{cast_length, other_err, EncodeResult};
22
use ironrdp_graphics::color_conversion::to_64x64_ycbcr_tile;
33
use ironrdp_graphics::rfx_encode_component;
4+
use ironrdp_graphics::rlgr::RlgrError;
45
use ironrdp_pdu::codecs::rfx::{self, OperatingMode, RfxChannel, RfxChannelHeight, RfxChannelWidth};
56
use ironrdp_pdu::rdp::capability_sets::EntropyBits;
67
use ironrdp_pdu::PduBufferParsing;
@@ -59,44 +60,24 @@ impl RfxEncoder {
5960
let region = rfx::RegionPdu { rectangles };
6061
let quant = rfx::Quant::default();
6162

62-
let bpp = usize::from(bitmap.format.bytes_per_pixel());
63-
let width = usize::from(bitmap.width.get());
64-
let height = usize::from(bitmap.height.get());
65-
66-
let tiles_x = (width + 63) / 64;
67-
let tiles_y = (height + 63) / 64;
63+
let tiles_x: usize = bitmap.width.get().div_ceil(64).into();
64+
let tiles_y: usize = bitmap.height.get().div_ceil(64).into();
6865
let ntiles = tiles_x * tiles_y;
6966
let mut tiles = Vec::with_capacity(ntiles);
7067
let mut data = vec![0u8; 64 * 64 * 3 * ntiles];
71-
let mut rest = data.as_mut_slice();
68+
let mut buf = data.chunks_exact_mut(64 * 64 * 3);
69+
70+
let encoder = UpdateEncoder::new(bitmap, quant.clone(), entropy_algorithm);
7271

7372
for tile_y in 0..tiles_y {
7473
for tile_x in 0..tiles_x {
75-
let x = tile_x * 64;
76-
let y = tile_y * 64;
77-
let tile_width = std::cmp::min(width - x, 64);
78-
let tile_height = std::cmp::min(height - y, 64);
79-
80-
let input = &bitmap.data[y * bitmap.stride + x * bpp..];
81-
82-
let y = &mut [0i16; 4096];
83-
let cb = &mut [0i16; 4096];
84-
let cr = &mut [0i16; 4096];
85-
to_64x64_ycbcr_tile(input, tile_width, tile_height, bitmap.stride, bitmap.format, y, cb, cr);
86-
87-
let (y_data, new_rest) = rest.split_at_mut(4096);
88-
let (cb_data, new_rest) = new_rest.split_at_mut(4096);
89-
let (cr_data, new_rest) = new_rest.split_at_mut(4096);
90-
rest = new_rest;
91-
let len = rfx_encode_component(y, y_data, &quant, entropy_algorithm)
92-
.map_err(|e| other_err!("rfxenc", source: e))?;
93-
let y_data = &y_data[..len];
94-
let len = rfx_encode_component(cb, cb_data, &quant, entropy_algorithm)
95-
.map_err(|e| other_err!("rfxenc", source: e))?;
96-
let cb_data = &cb_data[..len];
97-
let len = rfx_encode_component(cr, cr_data, &quant, entropy_algorithm)
74+
let EncodedTile {
75+
y_data,
76+
cb_data,
77+
cr_data,
78+
} = encoder
79+
.encode(tile_x, tile_y, buf.next().unwrap())
9880
.map_err(|e| other_err!("rfxenc", source: e))?;
99-
let cr_data = &cr_data[..len];
10081

10182
let tile = rfx::Tile {
10283
y_quant_index: 0,
@@ -148,3 +129,69 @@ impl RfxEncoder {
148129
)
149130
}
150131
}
132+
133+
struct UpdateEncoder<'a> {
134+
bitmap: &'a BitmapUpdate,
135+
quant: rfx::Quant,
136+
entropy_algorithm: rfx::EntropyAlgorithm,
137+
}
138+
139+
struct EncodedTile<'a> {
140+
y_data: &'a [u8],
141+
cb_data: &'a [u8],
142+
cr_data: &'a [u8],
143+
}
144+
145+
impl<'a> UpdateEncoder<'a> {
146+
fn new(bitmap: &'a BitmapUpdate, quant: rfx::Quant, entropy_algorithm: rfx::EntropyAlgorithm) -> Self {
147+
Self {
148+
bitmap,
149+
quant,
150+
entropy_algorithm,
151+
}
152+
}
153+
154+
fn encode<'b>(&self, tile_x: usize, tile_y: usize, buf: &'b mut [u8]) -> Result<EncodedTile<'b>, RlgrError> {
155+
assert!(buf.len() >= 4096 * 3);
156+
157+
let bpp: usize = self.bitmap.format.bytes_per_pixel().into();
158+
let width: usize = self.bitmap.width.get().into();
159+
let height: usize = self.bitmap.height.get().into();
160+
161+
let x = tile_x * 64;
162+
let y = tile_y * 64;
163+
let tile_width = std::cmp::min(width - x, 64);
164+
let tile_height = std::cmp::min(height - y, 64);
165+
let input = &self.bitmap.data[y * self.bitmap.stride + x * bpp..];
166+
167+
let y = &mut [0i16; 4096];
168+
let cb = &mut [0i16; 4096];
169+
let cr = &mut [0i16; 4096];
170+
to_64x64_ycbcr_tile(
171+
input,
172+
tile_width,
173+
tile_height,
174+
self.bitmap.stride,
175+
self.bitmap.format,
176+
y,
177+
cb,
178+
cr,
179+
);
180+
181+
let (y_data, buf) = buf.split_at_mut(4096);
182+
let (cb_data, cr_data) = buf.split_at_mut(4096);
183+
184+
let len = rfx_encode_component(y, y_data, &self.quant, self.entropy_algorithm)?;
185+
let y_data = &y_data[..len];
186+
let len = rfx_encode_component(cb, cb_data, &self.quant, self.entropy_algorithm)?;
187+
let cb_data = &cb_data[..len];
188+
let len = rfx_encode_component(cr, cr_data, &self.quant, self.entropy_algorithm)?;
189+
let cr_data = &cr_data[..len];
190+
191+
Ok(EncodedTile {
192+
y_data,
193+
cb_data,
194+
cr_data,
195+
})
196+
}
197+
}

0 commit comments

Comments
 (0)