/* This file is part of jellything (https://codeberg.org/metamuffin/jellything) which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2025 metamuffin */ use crate::{ read::ReadExt, write::{vint_length, write_vint}, ReadValue, Result, WriteValue, }; use std::io::{Cursor, Write}; #[derive(Debug, PartialEq, Clone, Copy)] pub enum LacingType { None, Xiph, FixedSize, Ebml, } #[derive(Debug, PartialEq, Clone)] pub struct Block { pub track: u64, pub flags: Flags, pub timestamp_off: i16, pub data: Vec, } #[derive(Debug, PartialEq, Clone)] pub struct Flags(u8); impl Flags { pub fn keyframe(&self) -> bool { self.0 & 0b10000000 != 0 } pub fn lacing(&self) -> LacingType { match self.0 & 0b00000110 { 0b000 => LacingType::None, 0b010 => LacingType::Xiph, 0b100 => LacingType::FixedSize, 0b110 => LacingType::Ebml, _ => unreachable!(), } } pub fn discardable(&self) -> bool { self.0 & 0b00000001 != 0 } pub fn invisible(&self) -> bool { self.0 & 0b00001000 != 0 } } impl ReadValue for Block { fn from_buf(buf: &[u8]) -> Result { let (track, c) = Cursor::new(buf).read_vint_len()?; let timestamp_off = i16::from_be_bytes(buf[c..c + 2].try_into().unwrap()); let flags = Flags(buf[c + 2]); let data = Vec::from(&buf[c + 3..]); Ok(Self { track, data, flags, timestamp_off, }) } } impl WriteValue for Block { fn write_to(&self, w: &mut impl Write) -> Result<()> { write_vint(w, self.inner_len() as u64)?; write_vint(w, self.track)?; w.write_all(&self.timestamp_off.to_be_bytes())?; w.write_all(&[self.flags.0])?; w.write_all(&self.data)?; Ok(()) } fn size(&self) -> usize { let il = self.inner_len(); vint_length(il as u64) + il } } impl Block { fn inner_len(&self) -> usize { vint_length(self.track) + 2 // timestamp + 1 // flags + self.data.len() } }