use super::segment::CompositionState;
use crate::utils::BigEndianReader;
#[derive(Debug, Clone, Copy, Default)]
pub struct CompositionObject {
pub object_id: u16,
pub window_id: u8,
pub cropped_flag: u8,
pub x: u16,
pub y: u16,
pub crop_x: u16,
pub crop_y: u16,
pub crop_width: u16,
pub crop_height: u16,
}
impl CompositionObject {
#[inline]
pub fn has_cropping(&self) -> bool {
(self.cropped_flag & 0x80) != 0
}
}
#[derive(Debug, Clone)]
pub struct PresentationCompositionSegment {
pub width: u16,
pub height: u16,
pub frame_rate: u8,
pub composition_number: u16,
pub composition_state: u8,
pub palette_update_flag: u8,
pub palette_id: u8,
pub composition_objects: Vec<CompositionObject>,
}
impl PresentationCompositionSegment {
pub fn parse(reader: &mut BigEndianReader, _length: usize) -> Option<Self> {
let width = reader.read_u16()?;
let height = reader.read_u16()?;
let frame_rate = reader.read_u8()?;
let composition_number = reader.read_u16()?;
let composition_state = reader.read_u8()?;
let palette_update_flag = reader.read_u8()?;
let palette_id = reader.read_u8()?;
let count = reader.read_u8()? as usize;
let mut composition_objects = Vec::with_capacity(count);
for _ in 0..count {
let object_id = reader.read_u16()?;
let window_id = reader.read_u8()?;
let cropped_flag = reader.read_u8()?;
let x = reader.read_u16()?;
let y = reader.read_u16()?;
let (crop_x, crop_y, crop_width, crop_height) = if (cropped_flag & 0x80) != 0 {
(
reader.read_u16()?,
reader.read_u16()?,
reader.read_u16()?,
reader.read_u16()?,
)
} else {
(0, 0, 0, 0)
};
composition_objects.push(CompositionObject {
object_id,
window_id,
cropped_flag,
x,
y,
crop_x,
crop_y,
crop_width,
crop_height,
});
}
Some(Self {
width,
height,
frame_rate,
composition_number,
composition_state,
palette_update_flag,
palette_id,
composition_objects,
})
}
pub fn get_composition_state(&self) -> Option<CompositionState> {
CompositionState::try_from(self.composition_state).ok()
}
#[inline]
pub fn is_epoch_start(&self) -> bool {
self.composition_state == CompositionState::EpochStart as u8
}
#[inline]
pub fn is_acquisition_point(&self) -> bool {
self.composition_state == CompositionState::AcquisitionPoint as u8
}
#[inline]
pub fn is_palette_update_only(&self) -> bool {
(self.palette_update_flag & 0x80) != 0
}
}