diff options
Diffstat (limited to 'remuxer/src/lib.rs')
-rw-r--r-- | remuxer/src/lib.rs | 76 |
1 files changed, 32 insertions, 44 deletions
diff --git a/remuxer/src/lib.rs b/remuxer/src/lib.rs index ead0051..03d469e 100644 --- a/remuxer/src/lib.rs +++ b/remuxer/src/lib.rs @@ -14,8 +14,9 @@ use crate::{ use anyhow::{anyhow, Context}; use jellycommon::{BlockIndex, ItemInfo, SeekIndex, SourceTrack, SourceTrackKind}; use jellymatroska::{ + block::Block, read::EbmlReader, - unflatten::{IterWithPos, Unflatten}, + unflatten::Unflatten, write::{vint_length, EbmlWriter}, Master, MatroskaTag, }; @@ -136,6 +137,7 @@ impl RemuxerContext { struct ClusterLayout { position: usize, timestamp: u64, + source_offsets: Vec<Option<usize>>, blocks: Vec<(usize, BlockIndex)>, } @@ -143,6 +145,7 @@ impl RemuxerContext { let mut cluster_pts = 0; let mut clusters = vec![]; let mut cluster = vec![]; + let mut source_offsets = vec![None; inputs.len()]; let mut gp = 0usize; // cluster position (in the segment) let mut p = 0usize; // block position (in the cluster) loop { @@ -161,6 +164,7 @@ impl RemuxerContext { }; } inputs[best_index].temp_index += 1; + source_offsets[best_index].get_or_insert(best_block.source_off); if best_block.pts > cluster_pts + 2_000 { let cluster_content_size = 1 + 1 // timestamp {tag, size} + vint_length(cluster_pts) // timestamp tag value @@ -171,10 +175,12 @@ impl RemuxerContext { clusters.push(ClusterLayout { position: gp, timestamp: cluster_pts, + source_offsets, blocks: std::mem::take(&mut cluster), }); cluster_pts = best_block.pts; + source_offsets = vec![None; inputs.len()]; gp += cluster_header_size; p = 0; } @@ -201,26 +207,18 @@ impl RemuxerContext { segment_layout .iter() .map(|cluster| { - MatroskaTag::CuePoint(Master::Collected( - [ - MatroskaTag::CueTime(cluster.timestamp), - MatroskaTag::CueTrackPositions(Master::Collected( - [ - MatroskaTag::CueTrack(0), - MatroskaTag::CueClusterPosition(cluster.position as u64), - ] - .to_vec(), - )), - MatroskaTag::CueTrackPositions(Master::Collected( - [ - MatroskaTag::CueTrack(1), - MatroskaTag::CueClusterPosition(cluster.position as u64), - ] - .to_vec(), - )), - ] - .to_vec(), - )) + // TODO this is hardcoded for now + MatroskaTag::CuePoint(Master::Collected(vec![ + MatroskaTag::CueTime(cluster.timestamp), + MatroskaTag::CueTrackPositions(Master::Collected(vec![ + MatroskaTag::CueTrack(0), + MatroskaTag::CueClusterPosition(cluster.position as u64), + ])), + MatroskaTag::CueTrackPositions(Master::Collected(vec![ + MatroskaTag::CueTrack(1), + MatroskaTag::CueClusterPosition(cluster.position as u64), + ])), + ])) }) .collect(), )))?; @@ -240,36 +238,27 @@ impl RemuxerContext { struct ReaderD<'a> { _info: SourceTrack, - peek: Option<AbsoluteBlock>, + peek: Option<Block>, stream: SegmentExtractIter<'a>, mapped: u64, } // read until start of the segment let mut ks = vec![]; - for i in &mut inputs { - loop { - let t = i.reader.next().ok_or(anyhow!("early eof"))??; - if let MatroskaTag::Segment(Master::Start) = t { - break; - } - } - i.reader + for (i, inp) in inputs.iter_mut().enumerate() { + inp.reader .seek( - segment_layout[skip].position, - MatroskaTag::Segment(Master::Start), + segment_layout[skip].source_offsets[i].unwrap(), // TODO will crash if there is a "hole" + MatroskaTag::Cluster(Master::Start), ) .context("seeking in input")?; - let mut stream = SegmentExtractIter::new( - Unflatten::new_with_end(&mut i.reader, MatroskaTag::Segment(Master::Start)), - i.info.track_number, - ); + let mut stream = SegmentExtractIter::new(&mut inp.reader, inp.info.track_number); ks.push(ReaderD { - mapped: i.mapped, + mapped: inp.mapped, peek: Some(stream.next()?), stream, - _info: i.info.clone(), + _info: inp.info.clone(), }); } info!( @@ -295,13 +284,12 @@ impl RemuxerContext { .replace(kn.stream.next()?) .expect("source file too short"); - assert_eq!(iblock.size, block.inner.data.len(), "seek index is wrong"); - assert_eq!(iblock.pts, block.pts(), "seek index is wrong"); + assert_eq!(iblock.size, block.data.len(), "seek index is wrong"); - block.inner.track = kn.mapped; - block.inner.timestamp_off = (iblock.pts - cluster.timestamp).try_into().unwrap(); - trace!("n={} tso={}", block.inner.track, block.inner.timestamp_off); - let buf = block.inner.dump(); + block.track = kn.mapped; + block.timestamp_off = (iblock.pts - cluster.timestamp).try_into().unwrap(); + trace!("n={} tso={}", block.track, block.timestamp_off); + let buf = block.dump(); cluster_blocks.push(MatroskaTag::SimpleBlock(buf)) } output.write_tag(&MatroskaTag::Cluster(Master::Collected(cluster_blocks)))?; |