aboutsummaryrefslogtreecommitdiff
path: root/remuxer/src
diff options
context:
space:
mode:
Diffstat (limited to 'remuxer/src')
-rw-r--r--remuxer/src/format.rs20
-rw-r--r--remuxer/src/import/mod.rs79
-rw-r--r--remuxer/src/lib.rs1
3 files changed, 71 insertions, 29 deletions
diff --git a/remuxer/src/format.rs b/remuxer/src/format.rs
new file mode 100644
index 0000000..f6cc411
--- /dev/null
+++ b/remuxer/src/format.rs
@@ -0,0 +1,20 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct TrackIndex {
+ pub clusters: Vec<ClusterIndex>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct ClusterIndex {
+ pub timestamp: usize,
+ pub blocks: BlockIndex,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct BlockIndex {
+ pub timestamp_off: usize,
+ pub offset: usize,
+}
+
+pub struct FBlock {}
diff --git a/remuxer/src/import/mod.rs b/remuxer/src/import/mod.rs
index 8a5cd54..bd22cf5 100644
--- a/remuxer/src/import/mod.rs
+++ b/remuxer/src/import/mod.rs
@@ -1,18 +1,24 @@
+use std::collections::HashMap;
+
use anyhow::{anyhow, bail, Result};
use jellycommon::{ItemInfo, SourceTrack, SourceTrackKind};
use jellymatroska::{
matroska::MatroskaTag,
read::EbmlReader,
unflatten::{Unflat, Unflatten},
- Master,
};
-use log::{debug, error, info, trace};
+use log::{debug, error, info, trace, warn};
pub fn import_read(input: &mut EbmlReader, iteminfo: &mut ItemInfo) -> Result<()> {
// TODO dont traverse the entire file, if the tracks are listed at the end
- let (mut timestamp_scale, mut duration) = (None, None);
while let Some(item) = input.next() {
- let item = item?;
+ let item = match item {
+ Ok(item) => item,
+ Err(e) => {
+ warn!("{e}");
+ break;
+ }
+ };
match item {
MatroskaTag::Ebml(_) => {
let mut iter = Unflatten::new_with_end(input, item);
@@ -27,28 +33,44 @@ pub fn import_read(input: &mut EbmlReader, iteminfo: &mut ItemInfo) -> Result<()
}
}
}
- MatroskaTag::SeekHead(_) => {
- Unflatten::new_with_end(input, item);
+ MatroskaTag::Segment(_) => {
+ info!("segment start");
+ let mut children = Unflatten::new_with_end(input, item);
+ import_read_segment(&mut children, iteminfo)?;
+ info!("segment end");
}
+ _ => debug!("(r) tag ignored: {item:?}"),
+ }
+ }
+
+ Ok(())
+}
+
+fn import_read_segment(children: &mut Unflatten, iteminfo: &mut ItemInfo) -> Result<()> {
+ let mut track_mapping = HashMap::<u64, usize>::new(); // maps matroska track id to item track id
+ let (mut timestamp_scale, mut duration) = (None, None);
+ while let Some(Ok(Unflat { children, item })) = children.next() {
+ match item {
+ MatroskaTag::SeekHead(_) => {}
MatroskaTag::Info(_) => {
- let mut iter = Unflatten::new_with_end(input, item);
- while let Some(Ok(Unflat { children, item })) = iter.next() {
+ let mut children = children.unwrap();
+ while let Some(Ok(Unflat { children, item })) = children.next() {
match item {
MatroskaTag::TimestampScale(v) => timestamp_scale = Some(v),
MatroskaTag::Duration(v) => duration = Some(v),
- _ => debug!("(ri) tag ignored: {item:?}"),
+ _ => debug!("(rsi) tag ignored: {item:?}"),
}
}
}
MatroskaTag::Cluster(_) => {
info!("start of cluster found");
- let mut iter = Unflatten::new_with_end(input, item);
- while let Some(Ok(Unflat { children, item })) = iter.next() {
+ let mut children = children.unwrap();
+ while let Some(Ok(Unflat { children, item })) = children.next() {
match item {
MatroskaTag::BlockGroup(_) => {
debug!("group");
- let mut iter = children.unwrap();
- while let Some(Ok(Unflat { children, item })) = iter.next() {
+ let mut children = children.unwrap();
+ while let Some(Ok(Unflat { children, item })) = children.next() {
match item {
MatroskaTag::Block(_) => (),
_ => trace!("{item:?}"),
@@ -58,16 +80,14 @@ pub fn import_read(input: &mut EbmlReader, iteminfo: &mut ItemInfo) -> Result<()
MatroskaTag::SimpleBlock(_) => {
// debug!("simple");
}
- _ => debug!("(rc) tag ignored: {item:?}"),
+ _ => debug!("(rsc) tag ignored: {item:?}"),
}
}
}
- MatroskaTag::Tags(_) => {
- Unflatten::new_with_end(input, item);
- }
+ MatroskaTag::Tags(_) => {}
MatroskaTag::Cues(_) => {
- let mut iter = Unflatten::new_with_end(input, item);
- while let Some(Ok(Unflat { children, item })) = iter.next() {
+ let mut children = children.unwrap();
+ while let Some(Ok(Unflat { children, item })) = children.next() {
match item {
MatroskaTag::CuePoint(_) => {
let mut children = children.unwrap();
@@ -79,12 +99,10 @@ pub fn import_read(input: &mut EbmlReader, iteminfo: &mut ItemInfo) -> Result<()
}
}
}
- MatroskaTag::Chapters(_) => {
- Unflatten::new_with_end(input, item);
- }
+ MatroskaTag::Chapters(_) => {}
MatroskaTag::Tracks(_) => {
- let mut iter = Unflatten::new_with_end(input, item);
- while let Some(Ok(Unflat { children, item })) = iter.next() {
+ let mut children = children.unwrap();
+ while let Some(Ok(Unflat { children, item })) = children.next() {
match item {
MatroskaTag::TrackEntry(_) => {
let mut children = children.unwrap();
@@ -139,7 +157,8 @@ pub fn import_read(input: &mut EbmlReader, iteminfo: &mut ItemInfo) -> Result<()
_ => (),
}
}
- let index = index.unwrap();
+ let itrack_index = iteminfo.tracks.len();
+ let mtrack_index = index.unwrap();
let kind = match kind.ok_or(anyhow!("track type required"))? {
1 => SourceTrackKind::Video {
fps: fps.unwrap_or(f64::NAN), // TODO
@@ -154,8 +173,9 @@ pub fn import_read(input: &mut EbmlReader, iteminfo: &mut ItemInfo) -> Result<()
17 => SourceTrackKind::Subtitles,
_ => bail!("invalid track type"),
};
+ track_mapping.insert(mtrack_index, itrack_index);
iteminfo.tracks.insert(
- index,
+ itrack_index,
SourceTrack {
name: name.unwrap_or_else(|| "unnamed".to_string()),
codec: codec.unwrap(),
@@ -164,13 +184,14 @@ pub fn import_read(input: &mut EbmlReader, iteminfo: &mut ItemInfo) -> Result<()
},
);
}
- _ => debug!("(rt) tag ignored: {item:?}"),
+ _ => debug!("(rst) tag ignored: {item:?}"),
}
}
}
- MatroskaTag::Segment(Master::End) => break,
- _ => debug!("(r) tag ignored: {item:?}"),
+ _ => debug!("(rs) tag ignored: {item:?}"),
}
}
+ iteminfo.duration =
+ (duration.unwrap() * timestamp_scale.unwrap() as f64) as f64 / 1_000_000_000 as f64;
Ok(())
}
diff --git a/remuxer/src/lib.rs b/remuxer/src/lib.rs
index cc189a3..cc508e8 100644
--- a/remuxer/src/lib.rs
+++ b/remuxer/src/lib.rs
@@ -1,4 +1,5 @@
pub mod import;
+pub mod format;
use jellycommon::ItemInfo;
use std::{io::Write, path::PathBuf, sync::Arc};