diff options
Diffstat (limited to 'remuxer')
-rw-r--r-- | remuxer/src/extract.rs | 24 | ||||
-rw-r--r-- | remuxer/src/import/mod.rs | 4 | ||||
-rw-r--r-- | remuxer/src/remux.rs | 6 | ||||
-rw-r--r-- | remuxer/src/seek_index.rs | 44 | ||||
-rw-r--r-- | remuxer/src/segment_extractor.rs | 4 |
5 files changed, 53 insertions, 29 deletions
diff --git a/remuxer/src/extract.rs b/remuxer/src/extract.rs index 108b76c..1b2b50c 100644 --- a/remuxer/src/extract.rs +++ b/remuxer/src/extract.rs @@ -6,8 +6,8 @@ use crate::seek_index::get_seek_index; use anyhow::{anyhow, bail}; use jellycommon::LocalTrack; -use jellymatroska::{block::Block, read::EbmlReader, unflatten::IterWithPos, Master, MatroskaTag}; -use log::{debug, info}; +use jellymatroska::{block::Block, read::EbmlReader, Master, MatroskaTag}; +use log::debug; use std::{fs::File, io::BufReader, path::PathBuf}; pub fn extract_track( @@ -20,12 +20,16 @@ pub fn extract_track( let index = get_seek_index(&source_path)?; let index = index .get(&(track_info.track as u64)) - .ok_or(anyhow!("track missing 4"))?; + .ok_or(anyhow!("track missing"))?; let mut out = Vec::new(); for b in &index.blocks { - reader.seek(b.source_off, MatroskaTag::Cluster(Master::Start))?; + reader.seek(b.source_off, MatroskaTag::BlockGroup(Master::Start))?; let (duration, block) = read_group(&mut reader)?; + assert_eq!( + track_info.track, block.track as usize, + "seek index is wrong" + ); out.push((b.pts, duration, block.data)) } Ok(out) @@ -33,23 +37,25 @@ pub fn extract_track( pub fn read_group(segment: &mut EbmlReader) -> anyhow::Result<(u64, Block)> { let (mut dur, mut block) = (None, None); - loop { - let item = segment.next().ok_or(anyhow!("eof"))??; + for _ in 0..10 { + let (_, item) = segment.next().ok_or(anyhow!("eof"))??; match item { MatroskaTag::Void(_) => (), MatroskaTag::Crc32(_) => (), - MatroskaTag::Cluster(_) => (), + MatroskaTag::Cluster(_) => bail!("unexpected cluster"), MatroskaTag::Timestamp(_) => (), MatroskaTag::SimpleBlock(_buf) => { - // bail!("unexpected simpleblock, where a group was expected") + let block = Block::parse(&_buf)?; + return Ok((1000, block)); // HDMV/PGS does not use duration?! } MatroskaTag::BlockGroup(Master::Start) => (), MatroskaTag::BlockGroup(Master::End) => return Ok((dur.unwrap(), block.unwrap())), MatroskaTag::BlockDuration(duration) => dur = Some(duration), MatroskaTag::Block(buf) => block = Some(Block::parse(&buf)?), MatroskaTag::Cues(_) => bail!("reached cues, this is the end"), - MatroskaTag::Segment(Master::End) => info!("extractor reached segment end"), + MatroskaTag::Segment(Master::End) => bail!("extractor reached segment end"), _ => debug!("(rs) tag ignored: {item:?}"), } } + bail!(".") } diff --git a/remuxer/src/import/mod.rs b/remuxer/src/import/mod.rs index 2981cea..d6fa2d0 100644 --- a/remuxer/src/import/mod.rs +++ b/remuxer/src/import/mod.rs @@ -9,7 +9,7 @@ use jellycommon::{Chapter, LocalTrack, SourceTrack, SourceTrackKind}; use jellymatroska::{ matroska::MatroskaTag, read::EbmlReader, - unflatten::{IterWithPos, Unflat, Unflatten}, + unflatten::{Unflat, Unflatten}, }; use log::{debug, error, info, warn}; use std::{path::PathBuf, time::Instant}; @@ -30,7 +30,7 @@ pub struct MatroskaMetadata { pub fn import_metadata(input: &mut EbmlReader) -> Result<MatroskaMetadata> { while let Some(item) = input.next() { let item = match item { - Ok(item) => item, + Ok((_, item)) => item, Err(e) => { if !matches!(e, jellymatroska::error::Error::Io(_)) { warn!("{e}"); diff --git a/remuxer/src/remux.rs b/remuxer/src/remux.rs index 8273c9e..851b43d 100644 --- a/remuxer/src/remux.rs +++ b/remuxer/src/remux.rs @@ -31,7 +31,7 @@ use std::{ struct ClusterLayout { position: usize, timestamp: u64, - source_offsets: Vec<Option<usize>>, + source_offsets: Vec<Option<u64>>, blocks: Vec<(usize, BlockIndex)>, } @@ -277,7 +277,7 @@ pub fn remux_stream_into( // this should be fine since tracks are only read according to segment_layout find_first_cluster_with_off(&segment_layout, skip, i) .ok_or(anyhow!("cluster hole at eof"))?, - MatroskaTag::Cluster(Master::Start), + MatroskaTag::Cluster(Master::Start), // TODO shouldn't this be a child of cluster? ) .context("seeking in input")?; let mut stream = @@ -333,7 +333,7 @@ fn find_first_cluster_with_off( segment_layout: &[ClusterLayout], skip: usize, track: usize, -) -> Option<usize> { +) -> Option<u64> { for skip in skip..segment_layout.len() { if let Some(off) = segment_layout[skip].source_offsets[track] { return Some(off); diff --git a/remuxer/src/seek_index.rs b/remuxer/src/seek_index.rs index eba7344..7e9cee1 100644 --- a/remuxer/src/seek_index.rs +++ b/remuxer/src/seek_index.rs @@ -9,7 +9,7 @@ use jellycommon::seek_index::{BlockIndex, SeekIndex}; use jellymatroska::{ block::Block, read::EbmlReader, - unflatten::{IterWithPos, Unflat, Unflatten}, + unflatten::{Unflat, Unflatten}, MatroskaTag, }; use log::{debug, info, trace, warn}; @@ -30,7 +30,7 @@ pub fn import_seek_index(input: &mut EbmlReader) -> Result<BTreeMap<u64, SeekInd let mut seek_index = BTreeMap::new(); while let Some(item) = input.next() { let item = match item { - Ok(item) => item, + Ok((_, item)) => item, Err(e) => { if !matches!(e, jellymatroska::error::Error::Io(_)) { warn!("{e}"); @@ -67,20 +67,20 @@ fn import_seek_index_segment( MatroskaTag::Cluster(_) => { let mut children = children.unwrap(); let mut pts = 0; - let mut position = children.position(); - loop { - if let Some(Ok(Unflat { children, item, .. })) = children.n() { + if let Some(Ok(Unflat { + children, + item, + position, + })) = children.n() + { match item { MatroskaTag::Timestamp(ts) => pts = ts, MatroskaTag::BlockGroup(_) => { trace!("group"); let mut children = children.unwrap(); - // let position = children.position(); //? TODO where should this point to? cluster or block? // probably block while let Some(Ok(Unflat { - children: _, - item, - position: _block_position, + children: _, item, .. })) = children.n() { match item { @@ -90,7 +90,12 @@ fn import_seek_index_segment( "block: track={} tso={}", block.track, block.timestamp_off ); - seek_index_add(seek_index, &block, position, pts); + seek_index_add( + seek_index, + &block, + position.unwrap(), + pts, + ); } _ => trace!("{item:?}"), } @@ -104,14 +109,13 @@ fn import_seek_index_segment( block.timestamp_off ); trace!("{pts} {}", block.timestamp_off); - seek_index_add(seek_index, &block, position, pts); + seek_index_add(seek_index, &block, position.unwrap(), pts); } _ => trace!("(rsc) tag ignored: {item:?}"), } } else { break; } - position = children.position(); } } _ => debug!("(rs) tag ignored: {item:?}"), @@ -123,9 +127,23 @@ fn import_seek_index_segment( fn seek_index_add( seek_index: &mut BTreeMap<u64, SeekIndex>, block: &Block, - position: usize, + 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_insert(SeekIndex::default()); diff --git a/remuxer/src/segment_extractor.rs b/remuxer/src/segment_extractor.rs index 89d5784..ec645c3 100644 --- a/remuxer/src/segment_extractor.rs +++ b/remuxer/src/segment_extractor.rs @@ -4,7 +4,7 @@ Copyright (C) 2024 metamuffin <metamuffin.org> */ use anyhow::{anyhow, bail, Result}; -use jellymatroska::{block::Block, read::EbmlReader, unflatten::IterWithPos, Master, MatroskaTag}; +use jellymatroska::{block::Block, read::EbmlReader, Master, MatroskaTag}; use log::{debug, info, trace}; pub struct SegmentExtractIter<'a> { @@ -23,7 +23,7 @@ impl<'a> SegmentExtractIter<'a> { let mut group = false; let mut saved_block = None; loop { - let item = self.segment.next().ok_or(anyhow!("eof"))??; + let (_, item) = self.segment.next().ok_or(anyhow!("eof"))??; match item { MatroskaTag::Void(_) => (), MatroskaTag::Crc32(_) => (), |