diff options
Diffstat (limited to 'remuxer')
-rw-r--r-- | remuxer/Cargo.toml | 2 | ||||
-rw-r--r-- | remuxer/src/format.rs | 25 | ||||
-rw-r--r-- | remuxer/src/import/mod.rs | 122 | ||||
-rw-r--r-- | remuxer/src/lib.rs | 17 |
4 files changed, 82 insertions, 84 deletions
diff --git a/remuxer/Cargo.toml b/remuxer/Cargo.toml index b4ee07e..f60340b 100644 --- a/remuxer/Cargo.toml +++ b/remuxer/Cargo.toml @@ -12,4 +12,4 @@ anyhow = "1.0.68" log = "0.4.17" serde = { version = "1.0.152", features = ["derive"] } -bincode = "2.0.0-rc.2"
\ No newline at end of file +bincode = { version = "2.0.0-rc.2", features = ["serde"] } diff --git a/remuxer/src/format.rs b/remuxer/src/format.rs deleted file mode 100644 index 22527f7..0000000 --- a/remuxer/src/format.rs +++ /dev/null @@ -1,25 +0,0 @@ -/* - 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) 2023 metamuffin <metamuffin.org> -*/ -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct TrackIndex { - pub clusters: Vec<ClusterIndex>, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ClusterIndex { - pub timestamp: usize, - pub blocks: BlockIndex, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct BlockIndex { - pub timestamp_off: usize, - pub offset: usize, -} - -pub struct FBlock {} diff --git a/remuxer/src/import/mod.rs b/remuxer/src/import/mod.rs index 65fc455..04fb88c 100644 --- a/remuxer/src/import/mod.rs +++ b/remuxer/src/import/mod.rs @@ -4,15 +4,15 @@ Copyright (C) 2023 metamuffin <metamuffin.org> */ use anyhow::{anyhow, bail, Result}; -use jellycommon::{ItemInfo, SourceTrack, SourceTrackKind}; +use jellycommon::{BlockIndex, ItemInfo, SeekIndex, SourceTrack, SourceTrackKind}; use jellymatroska::{ block::Block, matroska::MatroskaTag, read::EbmlReader, - unflatten::{Unflat, Unflatten}, + unflatten::{IterWithPos, Unflat, Unflatten}, }; use log::{debug, error, info, trace, warn}; -use std::path::PathBuf; +use std::{collections::HashMap, fs::File, path::PathBuf}; pub fn import_read(path: &PathBuf, input: &mut EbmlReader, iteminfo: &mut ItemInfo) -> Result<()> { // TODO dont traverse the entire file, if the tracks are listed at the end @@ -57,6 +57,8 @@ fn import_read_segment( iteminfo: &mut ItemInfo, ) -> Result<()> { let (mut timestamp_scale, mut duration) = (None, None); + let mut seek_index = HashMap::new(); + while let Some(Ok(Unflat { children, item })) = children.next() { match item { MatroskaTag::SeekHead(_) => {} @@ -70,57 +72,8 @@ fn import_read_segment( } } } - MatroskaTag::Cluster(_) => { - info!("start of cluster found"); - let mut children = children.unwrap(); - while let Some(Ok(Unflat { children, item })) = children.next() { - match item { - MatroskaTag::BlockGroup(_) => { - debug!("group"); - let mut children = children.unwrap(); - while let Some(Ok(Unflat { children: _, item })) = children.next() { - match item { - MatroskaTag::Block(buf) => { - let block = Block::parse(&buf)?; - debug!( - "block: track={} tso={}", - block.track, block.timestamp_off - ) - } - _ => trace!("{item:?}"), - } - } - } - MatroskaTag::SimpleBlock(buf) => { - let block = Block::parse(&buf)?; - debug!( - "simple block: track={} tso={}", - block.track, block.timestamp_off - ) - } - _ => debug!("(rsc) tag ignored: {item:?}"), - } - } - } MatroskaTag::Tags(_) => {} - MatroskaTag::Cues(_) => { - let mut children = children.unwrap(); - while let Some(Ok(Unflat { children, item })) = children.next() { - match item { - MatroskaTag::CuePoint(_) => { - let mut children = children.unwrap(); - while let Some(Ok(Unflat { - children: _, - item: _, - })) = children.next() - { - // error!("{item:?}") - } - } - _ => (), - } - } - } + MatroskaTag::Cues(_) => {} MatroskaTag::Chapters(_) => {} MatroskaTag::Tracks(_) => { let mut children = children.unwrap(); @@ -218,9 +171,72 @@ fn import_read_segment( } } } + MatroskaTag::Cluster(_) => { + let mut children = children.unwrap(); + let mut pts = 0; + + while let Some(Ok(Unflat { children, item })) = children.next() { + match item { + MatroskaTag::Timestamp(ts) => pts = ts, + MatroskaTag::BlockGroup(_) => { + debug!("group"); + let mut children = children.unwrap(); + let pos = children.position(); + while let Some(Ok(Unflat { children: _, item })) = children.next() { + match item { + MatroskaTag::Block(ref buf) => { + let block = Block::parse(buf)?; + debug!( + "block: track={} tso={}", + block.track, block.timestamp_off + ); + seek_index + .entry(block.track) + .or_insert(SeekIndex { blocks: vec![] }) + .blocks + .push(BlockIndex { + pts: pts + block.timestamp_off as u64, + source_off: pos, + size: block.data.len(), + }); + } + _ => trace!("{item:?}"), + } + } + } + MatroskaTag::SimpleBlock(buf) => { + let block = Block::parse(&buf)?; + debug!( + "simple block: track={} tso={}", + block.track, block.timestamp_off + ); + seek_index + .entry(block.track) + .or_insert(SeekIndex { blocks: vec![] }) + .blocks + .push(BlockIndex { + pts: pts + block.timestamp_off as u64, + source_off: 0, + size: block.data.len(), + }); + } + _ => debug!("(rsc) tag ignored: {item:?}"), + } + } + } + _ => debug!("(rs) tag ignored: {item:?}"), } } + + for (tn, index) in seek_index { + bincode::encode_into_std_write( + index, + &mut File::create(path.with_extension(&format!("si.{}", tn)))?, + bincode::config::standard(), + )?; + } + iteminfo.duration = (duration.unwrap() * timestamp_scale.unwrap() as f64) as f64 / 1_000_000_000 as f64; Ok(()) diff --git a/remuxer/src/lib.rs b/remuxer/src/lib.rs index be1ecc0..2c2e6d0 100644 --- a/remuxer/src/lib.rs +++ b/remuxer/src/lib.rs @@ -3,15 +3,14 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2023 metamuffin <metamuffin.org> */ -pub mod format; pub mod import; -use anyhow::{anyhow, Result}; -use jellycommon::{ItemInfo, SourceTrack, SourceTrackKind}; +use anyhow::{anyhow, Context, Result}; +use jellycommon::{ItemInfo, SeekIndex, SourceTrack, SourceTrackKind}; use jellymatroska::{ block::Block, read::EbmlReader, - unflatten::{Unflat, Unflatten}, + unflatten::{IterWithPos, Unflat, Unflatten}, write::EbmlWriter, Master, MatroskaTag, }; @@ -42,6 +41,7 @@ impl RemuxerContext { info: SourceTrack, reader: EbmlReader, mapped: u64, + index: SeekIndex, } let mut inputs = selection @@ -60,9 +60,16 @@ impl RemuxerContext { info.track_number ); info!("\t {}", info); - let file = File::open(source_path)?; + let file = File::open(&source_path).context("opening source file")?; + let mut index = File::open(source_path.with_extension(&format!("si.{}", info.track_number))) + .context("opening seek index file")?; + let index = bincode::decode_from_std_read::<SeekIndex, _, _>( + &mut index, + bincode::config::standard(), + )?; let reader = EbmlReader::new(file); Ok(ReaderC { + index, reader, info, mapped, |