aboutsummaryrefslogtreecommitdiff
path: root/remuxer/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'remuxer/src/lib.rs')
-rw-r--r--remuxer/src/lib.rs76
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)))?;