aboutsummaryrefslogtreecommitdiff
path: root/remuxer
diff options
context:
space:
mode:
authortpart <tpart120@proton.me>2023-12-09 11:37:51 +0100
committertpart <tpart120@proton.me>2023-12-09 11:37:51 +0100
commit2d853f3a20e1e4810dc75941bde8adc7390e8d76 (patch)
tree2caf79d512368d63a93ac6fb6f9a25eea8c4775e /remuxer
parenta2fca8bf6b62538ddeadac8155c3b3e653ef4511 (diff)
parent9b1310a6e1a6065c541ad35bdf274f7941a26ef4 (diff)
downloadjellything-2d853f3a20e1e4810dc75941bde8adc7390e8d76.tar
jellything-2d853f3a20e1e4810dc75941bde8adc7390e8d76.tar.bz2
jellything-2d853f3a20e1e4810dc75941bde8adc7390e8d76.tar.zst
Merge branch 'master' of codeberg.org:metamuffin/jellything
Diffstat (limited to 'remuxer')
-rw-r--r--remuxer/src/extract.rs69
-rw-r--r--remuxer/src/remux.rs32
2 files changed, 24 insertions, 77 deletions
diff --git a/remuxer/src/extract.rs b/remuxer/src/extract.rs
index 66c0526..6bd7b59 100644
--- a/remuxer/src/extract.rs
+++ b/remuxer/src/extract.rs
@@ -48,72 +48,3 @@ pub fn read_group(segment: &mut EbmlReader) -> anyhow::Result<(u64, Block)> {
}
}
}
-
-// fn import_seek_index_segment(
-// segment: &mut Unflatten,
-// seek_index: &mut BTreeMap<u64, SeekIndex>,
-// ) -> Result<()> {
-// while let Some(Ok(Unflat { children, item, .. })) = segment.n() {
-// match item {
-// MatroskaTag::SeekHead(_) => {}
-// MatroskaTag::Info(_) => {}
-// MatroskaTag::Tags(_) => {}
-// MatroskaTag::Cues(_) => {}
-// MatroskaTag::Chapters(_) => {}
-// MatroskaTag::Tracks(_) => {}
-// MatroskaTag::Void(_) => {}
-// 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() {
-// 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,
-// })) = children.n()
-// {
-// match item {
-// MatroskaTag::Block(ref buf) => {
-// let block = Block::parse(buf)?;
-// debug!(
-// "block: track={} tso={}",
-// block.track, block.timestamp_off
-// );
-// seek_index_add(seek_index, &block, position, pts);
-// }
-// _ => trace!("{item:?}"),
-// }
-// }
-// }
-// MatroskaTag::SimpleBlock(buf) => {
-// let block = Block::parse(&buf)?;
-// trace!(
-// "simple block: track={} tso={}",
-// block.track,
-// block.timestamp_off
-// );
-// trace!("{pts} {}", block.timestamp_off);
-// seek_index_add(seek_index, &block, position, pts);
-// }
-// _ => trace!("(rsc) tag ignored: {item:?}"),
-// }
-// } else {
-// break;
-// }
-// position = children.position();
-// }
-// }
-// _ => debug!("(rs) tag ignored: {item:?}"),
-// };
-// }
-// Ok(())
-// }
diff --git a/remuxer/src/remux.rs b/remuxer/src/remux.rs
index df4f67d..0e7877d 100644
--- a/remuxer/src/remux.rs
+++ b/remuxer/src/remux.rs
@@ -28,6 +28,13 @@ use std::{
time::Instant,
};
+struct ClusterLayout {
+ position: usize,
+ timestamp: u64,
+ source_offsets: Vec<Option<usize>>,
+ blocks: Vec<(usize, BlockIndex)>,
+}
+
pub fn remux_stream_into(
writer: impl Write,
range: Range<usize>,
@@ -113,13 +120,6 @@ pub fn remux_stream_into(
.collect();
output.write_tag(&MatroskaTag::Tracks(Master::Collected(tracks_header)))?;
- struct ClusterLayout {
- position: usize,
- timestamp: u64,
- source_offsets: Vec<Option<usize>>,
- blocks: Vec<(usize, BlockIndex)>,
- }
-
let mut segment_layout: Vec<ClusterLayout> = {
let mut cluster_pts = 0;
let mut clusters = vec![];
@@ -273,7 +273,10 @@ pub fn remux_stream_into(
.map(|(i, inp)| {
inp.reader
.seek(
- segment_layout[skip].source_offsets[i].unwrap(), // TODO will crash if there is a "hole"
+ // the seek target might be a hole; we continue until the next clust of that track.
+ // 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),
)
.context("seeking in input")?;
@@ -325,3 +328,16 @@ pub fn remux_stream_into(
output.write_tag(&MatroskaTag::Segment(Master::End))?;
Ok(())
}
+
+fn find_first_cluster_with_off(
+ segment_layout: &[ClusterLayout],
+ skip: usize,
+ track: usize,
+) -> Option<usize> {
+ for skip in skip..segment_layout.len() {
+ if let Some(off) = segment_layout[skip].source_offsets[track] {
+ return Some(off);
+ }
+ }
+ None
+}