|
1 | 1 | use ironrdp_core::{cast_length, other_err, EncodeResult};
|
2 | 2 | use ironrdp_graphics::color_conversion::to_64x64_ycbcr_tile;
|
3 | 3 | use ironrdp_graphics::rfx_encode_component;
|
| 4 | +use ironrdp_graphics::rlgr::RlgrError; |
4 | 5 | use ironrdp_pdu::codecs::rfx::{self, OperatingMode, RfxChannel, RfxChannelHeight, RfxChannelWidth};
|
5 | 6 | use ironrdp_pdu::rdp::capability_sets::EntropyBits;
|
6 | 7 | use ironrdp_pdu::PduBufferParsing;
|
@@ -59,44 +60,24 @@ impl RfxEncoder {
|
59 | 60 | let region = rfx::RegionPdu { rectangles };
|
60 | 61 | let quant = rfx::Quant::default();
|
61 | 62 |
|
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(); |
68 | 65 | let ntiles = tiles_x * tiles_y;
|
69 | 66 | let mut tiles = Vec::with_capacity(ntiles);
|
70 | 67 | 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); |
72 | 71 |
|
73 | 72 | for tile_y in 0..tiles_y {
|
74 | 73 | 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()) |
98 | 80 | .map_err(|e| other_err!("rfxenc", source: e))?;
|
99 |
| - let cr_data = &cr_data[..len]; |
100 | 81 |
|
101 | 82 | let tile = rfx::Tile {
|
102 | 83 | y_quant_index: 0,
|
@@ -148,3 +129,69 @@ impl RfxEncoder {
|
148 | 129 | )
|
149 | 130 | }
|
150 | 131 | }
|
| 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