aboutsummaryrefslogtreecommitdiff
path: root/remuxer/src/remux.rs
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/src/remux.rs
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/src/remux.rs')
-rw-r--r--remuxer/src/remux.rs32
1 files changed, 24 insertions, 8 deletions
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
+}