use crate::shared::protocol::frame::Segment;
pub fn full_frame_segment(
full_frame_data: &[u8],
frame_width: usize,
frame_height: usize,
) -> Vec<Segment> {
vec![Segment {
x: 0,
y: 0,
width: frame_width as u32,
height: frame_height as u32,
data: full_frame_data.to_vec(),
}]
}
pub fn optimize_segments(
full_frame_data: &[u8],
frame_width: usize,
frame_height: usize,
prev_frame: &mut Vec<u8>,
pixel_bytes: usize,
) -> Vec<Segment> {
const MIN_SEGMENT_ROWS: usize = 4; const MAX_SEGMENT_COUNT: usize = 50; let mut optimized_segments = Vec::new();
let mut current_segment: Option<Segment> = None;
for y in 0..frame_height {
let start = y * frame_width * pixel_bytes;
let end = start + frame_width * pixel_bytes;
if let Some(prev_frame) = prev_frame.get(start..end) {
if *prev_frame != full_frame_data[start..end] {
let segment_data = full_frame_data[start..end].to_vec();
if let Some(ref mut segment) = current_segment {
if segment.y + segment.height as i32 == y as i32
&& segment.width as usize == frame_width
{
segment.height += 1;
segment.data.extend(segment_data);
} else {
if optimized_segments.len() + 1 > MAX_SEGMENT_COUNT {
return full_frame_segment(full_frame_data, frame_width, frame_height);
}
if segment.height as usize >= MIN_SEGMENT_ROWS {
optimized_segments.push(segment.clone());
}
*segment = Segment {
x: 0,
y: y as i32,
width: frame_width as u32,
height: 1,
data: segment_data,
};
}
} else {
current_segment = Some(Segment {
x: 0,
y: y as i32,
width: frame_width as u32,
height: 1,
data: segment_data,
});
}
}
} else {
let segment_data = full_frame_data[start..end].to_vec();
if let Some(ref mut segment) = current_segment {
if segment.y + segment.height as i32 == y as i32
&& segment.width as usize == frame_width
{
segment.height += 1;
segment.data.extend(segment_data);
} else {
if optimized_segments.len() + 1 > MAX_SEGMENT_COUNT {
return full_frame_segment(full_frame_data, frame_width, frame_height);
}
if segment.height as usize >= MIN_SEGMENT_ROWS {
optimized_segments.push(segment.clone());
}
*segment = Segment {
x: 0,
y: y as i32,
width: frame_width as u32,
height: 1,
data: segment_data,
};
}
} else {
current_segment = Some(Segment {
x: 0,
y: y as i32,
width: frame_width as u32,
height: 1,
data: segment_data,
});
}
}
}
if let Some(segment) = current_segment {
optimized_segments.push(segment);
}
prev_frame.resize(full_frame_data.len(), 0);
prev_frame.copy_from_slice(full_frame_data);
optimized_segments
}