diff options
author | metamuffin <metamuffin@disroot.org> | 2025-04-19 14:40:34 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-04-19 14:40:34 +0200 |
commit | e4d60fc1a59f1c747c81871118512ef543e48e05 (patch) | |
tree | edae7c6308af119b06a4ee7c7b61820717cc24ce | |
parent | 121722729caaacbbd430b0a58c302389575acd05 (diff) | |
download | jellything-e4d60fc1a59f1c747c81871118512ef543e48e05.tar jellything-e4d60fc1a59f1c747c81871118512ef543e48e05.tar.bz2 jellything-e4d60fc1a59f1c747c81871118512ef543e48e05.tar.zst |
lazy block flags parsing
-rw-r--r-- | matroska/src/bin/mkvdump.rs | 7 | ||||
-rw-r--r-- | matroska/src/block.rs | 64 | ||||
-rw-r--r-- | remuxer/src/lib.rs | 1 | ||||
-rw-r--r-- | remuxer/src/seek_index.rs | 17 |
4 files changed, 37 insertions, 52 deletions
diff --git a/matroska/src/bin/mkvdump.rs b/matroska/src/bin/mkvdump.rs index 923e48f..48420c6 100644 --- a/matroska/src/bin/mkvdump.rs +++ b/matroska/src/bin/mkvdump.rs @@ -15,7 +15,12 @@ fn main() { let (position, tag) = tag.unwrap(); match tag { MatroskaTag::SimpleBlock(b) | MatroskaTag::Block(b) => { - println!("block kf={} ts_off={}", b.keyframe, b.timestamp_off) + println!( + "block t={} kf={} ts_off={}", + b.track, + b.flags.keyframe(), + b.timestamp_off + ) } _ => println!("{} {tag:?}", position.unwrap_or(0)), } diff --git a/matroska/src/block.rs b/matroska/src/block.rs index 51bea84..54d9de5 100644 --- a/matroska/src/block.rs +++ b/matroska/src/block.rs @@ -12,6 +12,7 @@ use std::io::{Cursor, Write}; #[derive(Debug, PartialEq, Clone, Copy)] pub enum LacingType { + None, Xiph, FixedSize, Ebml, @@ -20,39 +21,46 @@ pub enum LacingType { #[derive(Debug, PartialEq, Clone)] pub struct Block { pub track: u64, - pub keyframe: bool, - pub discardable: bool, + pub flags: Flags, pub timestamp_off: i16, - pub invisible: bool, - pub lacing: Option<LacingType>, pub data: Vec<u8>, } +#[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<Self> { 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 = buf[c + 2]; + let flags = Flags(buf[c + 2]); let data = Vec::from(&buf[c + 3..]); - let invisible = (flags & 0b1000) == 0b1000; - let lacing = match flags & 0b110 { - 0b000 => None, - 0b010 => Some(LacingType::Xiph), - 0b100 => Some(LacingType::FixedSize), - 0b110 => Some(LacingType::Ebml), - _ => unreachable!(), - }; - let keyframe = (flags & 0b10000000) == 0b10000000; - let discardable = (flags & 0b1) == 0b1; - Ok(Self { - keyframe, - discardable, track, data, - invisible, - lacing, + flags, timestamp_off, }) } @@ -63,21 +71,7 @@ impl WriteValue for Block { 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(&[match self.discardable { - true => 0b1, - false => 0b0, - } | match self.keyframe { - true => 0b10000000, - false => 0b00000000, - } | match self.invisible { - true => 0b1000, - false => 0b0000, - } | match self.lacing { - Some(LacingType::Xiph) => 0b010, - Some(LacingType::Ebml) => 0b100, - Some(LacingType::FixedSize) => 0b110, - None => 0b0000, - }])?; + w.write_all(&[self.flags.0])?; w.write_all(&self.data)?; Ok(()) } diff --git a/remuxer/src/lib.rs b/remuxer/src/lib.rs index 1824365..bb732d7 100644 --- a/remuxer/src/lib.rs +++ b/remuxer/src/lib.rs @@ -48,6 +48,7 @@ pub fn ebml_segment_info(title: String, duration: f64) -> MatroskaTag { pub fn ebml_track_entry(number: u64, track: &TrackEntry) -> MatroskaTag { let mut els = vec![ MatroskaTag::TrackNumber(number), + MatroskaTag::TrackUID(number * 100), // TODO is this ok? MatroskaTag::FlagLacing(track.flag_lacing), MatroskaTag::Language(track.language.clone()), MatroskaTag::CodecID(track.codec_id.clone()), diff --git a/remuxer/src/seek_index.rs b/remuxer/src/seek_index.rs index 33c1189..c09fdf9 100644 --- a/remuxer/src/seek_index.rs +++ b/remuxer/src/seek_index.rs @@ -140,23 +140,8 @@ fn seek_index_add( position: u64, pts_base: u64, ) { - //* I heard this helped debugging once. - // { - // let mut f = File::open("/home/muffin/videos/itte-yorushika.mkv").unwrap(); - // f.seek(std::io::SeekFrom::Start(position.try_into().unwrap())) - // .unwrap(); - // let mut buf = [0u8]; - // f.read_exact(&mut buf).unwrap(); - - // eprintln!("{}", buf[0]); - // if buf[0] != 0xa0 && buf[0] != 0xa3 { - // warn!("invalid position {position}") - // } - // } - let trs = seek_index.entry(block.track).or_default(); - - if block.keyframe { + if block.flags.keyframe() { trs.keyframes.push(trs.blocks.len()); } trs.blocks.push(BlockIndex { |