aboutsummaryrefslogtreecommitdiff
path: root/remuxer
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-01-12 22:05:32 +0100
committermetamuffin <metamuffin@disroot.org>2023-01-12 22:05:32 +0100
commit7ca91b6f33bb260bc966e853c832b4339c1c2ae0 (patch)
tree573eea3ea72a55fff4d43f42de4ae6fe0af4b2d9 /remuxer
parent047cb61bcf0ca61c58566ef5ca5d236234e46b21 (diff)
downloadjellything-7ca91b6f33bb260bc966e853c832b4339c1c2ae0.tar
jellything-7ca91b6f33bb260bc966e853c832b4339c1c2ae0.tar.bz2
jellything-7ca91b6f33bb260bc966e853c832b4339c1c2ae0.tar.zst
implementing my own ebml library
Diffstat (limited to 'remuxer')
-rw-r--r--remuxer/src/format/ebml/matroska.rs39
-rw-r--r--remuxer/src/format/ebml/mod.rs3
-rw-r--r--remuxer/src/format/ebml/read.rs44
-rw-r--r--remuxer/src/format/ebml/write.rs38
-rw-r--r--remuxer/src/format/mod.rs1
-rw-r--r--remuxer/src/lib.rs59
6 files changed, 167 insertions, 17 deletions
diff --git a/remuxer/src/format/ebml/matroska.rs b/remuxer/src/format/ebml/matroska.rs
new file mode 100644
index 0000000..50aa783
--- /dev/null
+++ b/remuxer/src/format/ebml/matroska.rs
@@ -0,0 +1,39 @@
+pub enum TagType {
+ Master,
+ UnsignedInt,
+ Integer,
+ Utf8,
+ Binary,
+ Float,
+}
+
+macro_rules! define_ebml {
+ ($master:ident { $($name:ident: $kind:ty = $id:literal),* }) => {
+ pub enum $master {
+ $($name($kind)),*
+ }
+ impl $master {
+
+ }
+ };
+}
+
+// 0x1a45dfa3
+define_ebml! {
+ Ebml {
+ EbmlVersion: u64 = 0x4286,
+ EbmlReadVersion: u64 = 0x42f7,
+ EbmlMaxIdLength: u64 = 0x42f2,
+ EbmlMaxSizeLength: u64 = 0x42f3,
+ DocType: String = 0x4282,
+ DocTypeVersion: u64 = 0x4287,
+ DocTypeReadVersion: u64 = 0x4285,
+ DocTypeExtension: DocTypeExtension = 0x4281
+ }
+}
+define_ebml! {
+ DocTypeExtension {
+ Name: String = 0x4283,
+ Version: u64 = 0x4284
+ }
+}
diff --git a/remuxer/src/format/ebml/mod.rs b/remuxer/src/format/ebml/mod.rs
new file mode 100644
index 0000000..d8a703a
--- /dev/null
+++ b/remuxer/src/format/ebml/mod.rs
@@ -0,0 +1,3 @@
+pub mod read;
+pub mod write;
+pub mod matroska;
diff --git a/remuxer/src/format/ebml/read.rs b/remuxer/src/format/ebml/read.rs
new file mode 100644
index 0000000..06ccf2f
--- /dev/null
+++ b/remuxer/src/format/ebml/read.rs
@@ -0,0 +1,44 @@
+use std::io::{Read, Seek};
+
+use anyhow::Result;
+
+pub struct EbmlReader<T> {
+ inner: T,
+ position: usize,
+}
+
+impl<T: Read + Seek> EbmlReader<T> {
+ pub fn new(inner: T) -> Self {
+ Self { inner, position: 0 }
+ }
+
+ pub fn read_byte(&mut self) -> Result<u8> {
+ let mut b = [0u8];
+ self.inner.read_exact(&mut b)?;
+ Ok(b[0])
+ }
+ pub fn read_vint(&mut self) -> Result<(u64, u64)> {
+ let s = self.read_byte()? as u64;
+ let len = s.leading_zeros() + 1;
+ let mut value = s;
+ value -= 1 << (8 - len);
+ for _ in 0..(len - 1) {
+ value <<= 8;
+ value += self.read_byte()? as u64;
+ }
+ Ok((value, len.into()))
+ }
+
+ pub fn read_tag_id(&mut self) -> Result<u64> {
+ let (value, len) = self.read_vint()?;
+ Ok(value + (1 << (7 * len)))
+ }
+
+ pub fn read_tag(&mut self) -> Result<()> {
+ let id = self.read_tag_id()?;
+
+ Ok(())
+
+ }
+}
+
diff --git a/remuxer/src/format/ebml/write.rs b/remuxer/src/format/ebml/write.rs
new file mode 100644
index 0000000..1dee225
--- /dev/null
+++ b/remuxer/src/format/ebml/write.rs
@@ -0,0 +1,38 @@
+use anyhow::{bail, Result};
+use std::io::Write;
+
+pub struct EbmlWriter<T> {
+ inner: T,
+ position: usize,
+}
+
+impl<T: Write> EbmlWriter<T> {
+ pub fn new(inner: T, position: usize) -> Self {
+ Self { inner, position }
+ }
+
+ pub fn write(&mut self, data: &[u8]) -> Result<()> {
+ self.inner.write_all(data)?;
+ self.position += data.len();
+ Ok(())
+ }
+
+ pub fn write_vint(&mut self, i: u64) -> Result<()> {
+ if i > (1 << 56) - 1 {
+ bail!("vint does not fit");
+ }
+ let mut len = 1;
+ while len <= 8 {
+ if i < (1 << ((7 * len) - 1)) {
+ break;
+ }
+ len += 1;
+ }
+ let mut bytes = i.to_be_bytes();
+ bytes[0] |= 1 << (8 - len);
+ self.write(&bytes)
+ }
+
+}
+
+
diff --git a/remuxer/src/format/mod.rs b/remuxer/src/format/mod.rs
new file mode 100644
index 0000000..faec908
--- /dev/null
+++ b/remuxer/src/format/mod.rs
@@ -0,0 +1 @@
+pub mod ebml;
diff --git a/remuxer/src/lib.rs b/remuxer/src/lib.rs
index 95bd1ff..95e6e8b 100644
--- a/remuxer/src/lib.rs
+++ b/remuxer/src/lib.rs
@@ -1,9 +1,10 @@
+pub mod format;
+
use jellycommon::ItemInfo;
use log::{debug, info};
use std::{fs::File, io::Write, path::PathBuf, sync::Arc};
-use tokio::sync::mpsc::Sender;
use webm_iterable::{
- matroska_spec::{Master, MatroskaSpec, Block},
+ matroska_spec::{Block, Master, MatroskaSpec},
WebmIterator, WebmWriter,
};
@@ -17,6 +18,7 @@ impl RemuxerContext {
pub fn generate_into(
&self,
writer: impl Write,
+ offset: usize,
path_base: PathBuf,
item: ItemInfo,
selection: Vec<u64>,
@@ -28,9 +30,19 @@ impl RemuxerContext {
let tags = WebmIterator::new(&mut input, &[MatroskaSpec::TrackEntry(Master::Start)]);
let mut output = WebmWriter::new(writer);
+ let mut tscale = None;
+ let mut duration = None;
+ let mut ignore = false;
+
for tag in tags {
let tag = tag.unwrap();
match tag {
+ MatroskaSpec::SeekHead(Master::Start) | MatroskaSpec::Cues(Master::Start) => {
+ ignore = true
+ }
+ MatroskaSpec::SeekHead(Master::End) | MatroskaSpec::Cues(Master::End) => {
+ ignore = false
+ }
MatroskaSpec::TrackEntry(master) => {
let children = master.get_children();
let mut number = None;
@@ -50,17 +62,31 @@ impl RemuxerContext {
if selection.contains(&block.track) {
output.write(&tag)?;
}
- },
+ }
MatroskaSpec::SimpleBlock(ref data) => {
let data: &[u8] = &data;
let block: Block = data.try_into()?;
if selection.contains(&block.track) {
output.write(&tag)?;
}
- },
+ }
+ MatroskaSpec::Info(Master::Start) => (),
+ MatroskaSpec::TimestampScale(n) => tscale = Some(n),
+ MatroskaSpec::Duration(n) => duration = Some(n),
+ MatroskaSpec::Info(Master::End) => {
+ output.write(&MatroskaSpec::Info(Master::Full(vec![
+ MatroskaSpec::TimestampScale(tscale.unwrap()),
+ MatroskaSpec::Title(item.title.clone()),
+ MatroskaSpec::Duration(duration.unwrap()),
+ MatroskaSpec::MuxingApp("jellyremux".to_string()),
+ MatroskaSpec::WritingApp("jellything".to_string()),
+ ])))?;
+ }
x => {
- // debug!("tag");
- output.write(&x)?;
+ if !ignore {
+ debug!("{x:?}");
+ output.write(&x)?;
+ }
}
}
}
@@ -68,16 +94,15 @@ impl RemuxerContext {
}
}
-pub struct SendWriter(pub Sender<Vec<u8>>);
+// pub struct SendWriter(pub Sender<Vec<u8>>);
-impl Write for SendWriter {
- fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
- debug!("write {buf:?}");
- self.0.blocking_send(buf.to_owned()).unwrap();
- Ok(buf.len())
- }
+// impl Write for SendWriter {
+// fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
+// self.0.blocking_send(buf.to_owned()).unwrap();
+// Ok(buf.len())
+// }
- fn flush(&mut self) -> std::io::Result<()> {
- Ok(()) // TODO should we actually do something here?
- }
-}
+// fn flush(&mut self) -> std::io::Result<()> {
+// Ok(()) // TODO should we actually do something here?
+// }
+// }