aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-04-19 14:40:34 +0200
committermetamuffin <metamuffin@disroot.org>2025-04-19 14:40:34 +0200
commite4d60fc1a59f1c747c81871118512ef543e48e05 (patch)
treeedae7c6308af119b06a4ee7c7b61820717cc24ce
parent121722729caaacbbd430b0a58c302389575acd05 (diff)
downloadjellything-e4d60fc1a59f1c747c81871118512ef543e48e05.tar
jellything-e4d60fc1a59f1c747c81871118512ef543e48e05.tar.bz2
jellything-e4d60fc1a59f1c747c81871118512ef543e48e05.tar.zst
lazy block flags parsing
-rw-r--r--matroska/src/bin/mkvdump.rs7
-rw-r--r--matroska/src/block.rs64
-rw-r--r--remuxer/src/lib.rs1
-rw-r--r--remuxer/src/seek_index.rs17
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 {