aboutsummaryrefslogtreecommitdiff
path: root/remuxer/src
diff options
context:
space:
mode:
Diffstat (limited to 'remuxer/src')
-rw-r--r--remuxer/src/remux.rs6
-rw-r--r--remuxer/src/seek_index.rs2
-rw-r--r--remuxer/src/segment_extractor.rs22
-rw-r--r--remuxer/src/snippet.rs13
4 files changed, 32 insertions, 11 deletions
diff --git a/remuxer/src/remux.rs b/remuxer/src/remux.rs
index f944899..1e75b06 100644
--- a/remuxer/src/remux.rs
+++ b/remuxer/src/remux.rs
@@ -273,7 +273,7 @@ pub fn remux_stream_into(
.map(|(i, inp)| {
inp.reader
.seek(
- // the seek target might be a hole; we continue until the next clust of that track.
+ // the seek target might be a hole; we continue until the next cluster 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"))?,
@@ -285,7 +285,7 @@ pub fn remux_stream_into(
Ok(ReaderD {
mapped: inp.mapped,
- peek: Some(stream.next()?),
+ peek: Some(stream.next()?.0), // TODO handle duration
stream,
})
})
@@ -311,7 +311,7 @@ pub fn remux_stream_into(
let track_reader = &mut track_readers[block_track];
let mut block = track_reader
.peek
- .replace(track_reader.stream.next()?)
+ .replace(track_reader.stream.next()?.0) // TODO handle duration
.expect("source file too short");
assert_eq!(index_block.size, block.data.len(), "seek index is wrong");
diff --git a/remuxer/src/seek_index.rs b/remuxer/src/seek_index.rs
index b2ece4b..eba7344 100644
--- a/remuxer/src/seek_index.rs
+++ b/remuxer/src/seek_index.rs
@@ -80,7 +80,7 @@ fn import_seek_index_segment(
while let Some(Ok(Unflat {
children: _,
item,
- position,
+ position: _block_position,
})) = children.n()
{
match item {
diff --git a/remuxer/src/segment_extractor.rs b/remuxer/src/segment_extractor.rs
index bc5b44f..d176b3a 100644
--- a/remuxer/src/segment_extractor.rs
+++ b/remuxer/src/segment_extractor.rs
@@ -17,7 +17,11 @@ impl<'a> SegmentExtractIter<'a> {
Self { segment, extract }
}
- pub fn next(&mut self) -> Result<Block> {
+ /// Returns the next block and sometimes its duration too.
+ pub fn next(&mut self) -> Result<(Block, Option<u64>)> {
+ let mut duration = None;
+ let mut group = false;
+ let mut saved_block = None;
loop {
let item = self.segment.next().ok_or(anyhow!("eof"))??;
match item {
@@ -25,13 +29,23 @@ impl<'a> SegmentExtractIter<'a> {
MatroskaTag::Crc32(_) => (),
MatroskaTag::Cluster(_) => (),
MatroskaTag::Timestamp(_) => (),
- MatroskaTag::BlockGroup(_) => (),
- MatroskaTag::BlockDuration(_) => (),
+ MatroskaTag::BlockGroup(Master::Start) => group = true,
+ MatroskaTag::BlockGroup(Master::End) => {
+ assert!(group, "group end without start");
+ let block = saved_block.expect("blockgroup without any block");
+ return Ok((block, duration));
+ }
+ MatroskaTag::BlockDuration(d) => duration = Some(d),
MatroskaTag::SimpleBlock(buf) | MatroskaTag::Block(buf) => {
let block = Block::parse(&buf)?;
if block.track == self.extract {
trace!("block: track={} tso={}", block.track, block.timestamp_off);
- return Ok(block);
+ if group {
+ // can't return yet; there might be a BlockDuration coming
+ saved_block = Some(block);
+ } else {
+ return Ok((block, duration));
+ }
}
}
MatroskaTag::Cues(_) => bail!("reached cues, this is the end"),
diff --git a/remuxer/src/snippet.rs b/remuxer/src/snippet.rs
index 5b271e4..8fcb109 100644
--- a/remuxer/src/snippet.rs
+++ b/remuxer/src/snippet.rs
@@ -160,7 +160,7 @@ pub fn write_snippet_into(
let mut reader = SegmentExtractIter::new(&mut reader, local_track.track as u64);
{
- // TODO this one caused snippets to get dropped MSE for no reason
+ // TODO this one caused snippets to get dropped by MSE for no reason
// for i in start_block_index..end_block_index {
// let index_block = &index.blocks[i];
// let mut block = reader.next()?;
@@ -179,14 +179,21 @@ pub fn write_snippet_into(
let mut blocks = vec![MatroskaTag::Timestamp(0)];
for i in start_block_index..end_block_index {
let index_block = &index.blocks[i];
- let mut block = reader.next()?;
+ let (mut block, duration) = reader.next()?;
assert_eq!(index_block.size, block.data.len(), "seek index is wrong");
block.track = 1;
// TODO this does generate overflows sometimes
block.timestamp_off = (index_block.pts - start_block.pts).try_into().unwrap();
- blocks.push(MatroskaTag::SimpleBlock(block.dump()))
+ if let Some(duration) = duration {
+ blocks.push(MatroskaTag::BlockGroup(Master::Collected(vec![
+ MatroskaTag::BlockDuration(duration),
+ MatroskaTag::Block(block.dump()),
+ ])))
+ } else {
+ blocks.push(MatroskaTag::SimpleBlock(block.dump()))
+ }
}
output.write_tag(&MatroskaTag::Cluster(Master::Collected(blocks)))?;
}