From 8fc4b9792044d82e729e8b4ef993c6391d711c5b Mon Sep 17 00:00:00 2001 From: metamuffin Date: Fri, 13 Jan 2023 18:06:11 +0100 Subject: started writing a proc_macro now --- Cargo.lock | 16 +++++- Cargo.toml | 2 +- ebml/Cargo.toml | 3 + ebml/src/bin/experiment.rs | 3 +- ebml/src/lib.rs | 49 ++++++++++++++++ ebml/src/matroska.rs | 6 +- ebml/src/mod.rs | 48 ---------------- ebml/src/read.rs | 3 +- ebml_derive/src/lib.rs | 63 +++++++++++++++++++++ ebml_derive/src/main.rs | 6 -- remuxer/Cargo.toml | 3 +- remuxer/src/lib.rs | 135 ++++++++++++++++++++++----------------------- server/src/main.rs | 2 +- 13 files changed, 203 insertions(+), 136 deletions(-) create mode 100644 ebml/src/lib.rs delete mode 100644 ebml/src/mod.rs create mode 100644 ebml_derive/src/lib.rs delete mode 100644 ebml_derive/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index a52ce47..51c59ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -349,6 +349,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "ebml" +version = "0.1.0" +dependencies = [ + "anyhow", + "ebml_derive", + "env_logger", + "log", +] + [[package]] name = "ebml-iterable" version = "0.4.2" @@ -381,6 +391,10 @@ dependencies = [ [[package]] name = "ebml_derive" version = "0.1.0" +dependencies = [ + "quote", + "syn", +] [[package]] name = "either" @@ -830,11 +844,9 @@ name = "jellyremuxer" version = "0.1.0" dependencies = [ "anyhow", - "env_logger", "jellycommon", "log", "tokio", - "webm-iterable", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 17429e6..db44f21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,2 @@ [workspace] -members = ["server", "remuxer", "common", "tools", "remuxer/ebml_derive"] +members = ["server", "remuxer", "common", "tools", "ebml", "ebml_derive"] diff --git a/ebml/Cargo.toml b/ebml/Cargo.toml index b01d4a3..ec58cc4 100644 --- a/ebml/Cargo.toml +++ b/ebml/Cargo.toml @@ -5,3 +5,6 @@ edition = "2021" [dependencies] ebml_derive = { path = "../ebml_derive" } +anyhow = "1.0.68" +log = "0.4.17" +env_logger = "0.10.0" diff --git a/ebml/src/bin/experiment.rs b/ebml/src/bin/experiment.rs index 7d8cede..d332b41 100644 --- a/ebml/src/bin/experiment.rs +++ b/ebml/src/bin/experiment.rs @@ -1,6 +1,5 @@ use std::fs::File; - -use jellyremuxer::format::matroska::read::EbmlReader; +use ebml::read::EbmlReader; fn main() { env_logger::init_from_env("LOG"); diff --git a/ebml/src/lib.rs b/ebml/src/lib.rs new file mode 100644 index 0000000..116b8e2 --- /dev/null +++ b/ebml/src/lib.rs @@ -0,0 +1,49 @@ +use crate::read::EbmlSize; + +use self::read::EbmlReader; +use anyhow::{bail, Result}; +use log::debug; + +pub mod matroska; +pub mod read; +pub mod write; + +#[derive(Debug, Clone)] +pub enum Master { + Start, + End, +} + +#[derive(Debug, Clone)] +pub enum MatroskaTag { + Ebml(Master), + EbmlVersion(u64), + EbmlReadVersion(u64), + EbmlMaxIdLength(u64), + EbmlMaxSizeLength(u64), + DocType(String), + DocTypeVersion(u64), + DocTypeReadVersion(u64), + DocTypeExtension(Master), +} + +impl EbmlReader { + pub fn read_tag(&mut self) -> Result { + let id = self.read_tag_id()?; + let size = EbmlSize::from_vint(self.read_vint_len()?); + debug!("tag id={id:x}, size={size:?}"); + Ok(match id { + 0x1a45dfa3 => MatroskaTag::Ebml(Master::Start), + 0x4286 => MatroskaTag::EbmlVersion(self.read_vint()?), + 0x42f7 => MatroskaTag::EbmlReadVersion(self.read_vint()?), + 0x42f2 => MatroskaTag::EbmlMaxIdLength(self.read_vint()?), + 0x42f3 => MatroskaTag::EbmlMaxSizeLength(self.read_vint()?), + 0x4282 => MatroskaTag::DocType(self.read_utf8(size)?), + 0x4287 => MatroskaTag::DocTypeVersion(self.read_vint()?), + 0x4285 => MatroskaTag::DocTypeReadVersion(self.read_vint()?), + 0x4281 => MatroskaTag::DocTypeExtension(Master::Start), + + _ => bail!("thats not a tag we know..."), + }) + } +} diff --git a/ebml/src/matroska.rs b/ebml/src/matroska.rs index f53a1e8..802ce6a 100644 --- a/ebml/src/matroska.rs +++ b/ebml/src/matroska.rs @@ -1,11 +1,10 @@ - - +use ebml_derive::define_ebml; define_ebml! { global Crc32[0xbf]: Binary, global Void[0xec]: Binary, - Ebml[0x1a45dfa3] { + Ebml[0x1a45dfa3]: { EbmlVersion[0x4286]: u64, EbmlReadVersion[0x42f7]: u64, EbmlMaxIdLength[0x42f2]: u64, @@ -19,6 +18,7 @@ define_ebml! { }, }, } + // #[id=0x18538067] Segment(Master), // #[id=0x1941A469] Segment/Attachments(Master), // #[id=0x61A7] Segment/Attachments/AttachedFile(Master), diff --git a/ebml/src/mod.rs b/ebml/src/mod.rs deleted file mode 100644 index 5da6809..0000000 --- a/ebml/src/mod.rs +++ /dev/null @@ -1,48 +0,0 @@ -use crate::format::matroska::read::EbmlSize; - -use self::read::EbmlReader; -use anyhow::{bail, Result}; -use log::debug; - -pub mod matroska; -pub mod read; - -#[derive(Debug, Clone)] -pub enum Master { - Start, - End, -} - -#[derive(Debug, Clone)] -pub enum MatroskaTag { - Ebml(Master), - EbmlVersion(u64), - EbmlReadVersion(u64), - EbmlMaxIdLength(u64), - EbmlMaxSizeLength(u64), - DocType(String), - DocTypeVersion(u64), - DocTypeReadVersion(u64), - DocTypeExtension(Master), -} - -impl EbmlReader { - pub fn read_tag(&mut self) -> Result { - let id = self.read_tag_id()?; - let size = EbmlSize::from_vint(self.read_vint_len()?); - debug!("tag id={id:x}, size={size:?}"); - Ok(match id { - 0x1a45dfa3 => MatroskaTag::Ebml(Master::Start), - 0x4286 => MatroskaTag::EbmlVersion(self.read_vint()?), - 0x42f7 => MatroskaTag::EbmlReadVersion(self.read_vint()?), - 0x42f2 => MatroskaTag::EbmlMaxIdLength(self.read_vint()?), - 0x42f3 => MatroskaTag::EbmlMaxSizeLength(self.read_vint()?), - 0x4282 => MatroskaTag::DocType(self.read_utf8(size)?), - 0x4287 => MatroskaTag::DocTypeVersion(self.read_vint()?), - 0x4285 => MatroskaTag::DocTypeReadVersion(self.read_vint()?), - 0x4281 => MatroskaTag::DocTypeExtension(Master::Start), - - _ => bail!("thats not a tag we know..."), - }) - } -} diff --git a/ebml/src/read.rs b/ebml/src/read.rs index 0ffb24c..9864ea5 100644 --- a/ebml/src/read.rs +++ b/ebml/src/read.rs @@ -2,9 +2,8 @@ use std::io::{Read, Seek}; use anyhow::{bail, Result}; use log::debug; -use webm_iterable::matroska_spec::MatroskaSpec; -use crate::format::matroska::{Master, MatroskaTag}; +// use crate::matroska::{Master, MatroskaTag}; trait ReadAndSeek: Read + Seek {} impl ReadAndSeek for T {} diff --git a/ebml_derive/src/lib.rs b/ebml_derive/src/lib.rs new file mode 100644 index 0000000..2c9dd9c --- /dev/null +++ b/ebml_derive/src/lib.rs @@ -0,0 +1,63 @@ +use proc_macro::{Delimiter, TokenStream, TokenTree}; +use quote::quote; + +struct Tag { + id: u64, + path: Vec, + name: String, + r#type: Option, // None -> Master +} + +#[proc_macro] +pub fn define_ebml(ts: TokenStream) -> TokenStream { + let mut next_glob = false; + let mut ts = ts.into_iter(); + + let mut tags = vec![]; + + while let Some(t) = ts.next() { + match t { + TokenTree::Ident(ident) => { + let ident = ident.to_string(); + if &ident == "global" { + next_glob = true; + } else { + let glob = next_glob; + next_glob = false; + let id = if let Some(TokenTree::Group(gr)) = ts.next() { + assert_eq!(gr.delimiter(), Delimiter::Bracket); + let mut ts = gr.stream().into_iter(); + if let TokenTree::Literal(lit) = ts.next().unwrap() { + u64::from_str_radix(&lit.to_string()[2..], 16).unwrap() + } else { + panic!("literal expected") + } + } else { + panic!("group expected") + }; + if let Some(TokenTree::Punct(p)) = ts.next() { + assert_eq!(p.as_char(), ':') + } else { + panic!("colon expected") + } + match ts.next() { + Some(TokenTree::Group(_)) => {} + Some(TokenTree::Ident(ident)) => { + let r#type = ident.to_string(); + eprintln!("global={glob} id={id}, type={}", r#type); + + } + _ => panic!("group or ident expected"), + } + if let Some(TokenTree::Punct(p)) = ts.next() { + assert_eq!(p.as_char(), ',') + } else { + panic!("colon expected") + } + } + } + x => panic!("unexpected {x:?}"), + } + } + quote! {}.into() +} diff --git a/ebml_derive/src/main.rs b/ebml_derive/src/main.rs deleted file mode 100644 index ac0ea26..0000000 --- a/ebml_derive/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ - -#[proc_macro] -fn define_ebml(tt: TokenStream) { - -} - diff --git a/remuxer/Cargo.toml b/remuxer/Cargo.toml index e98b3f7..4327779 100644 --- a/remuxer/Cargo.toml +++ b/remuxer/Cargo.toml @@ -8,4 +8,5 @@ tokio = { version = "1.24.1", features = ["io-util"] } jellycommon = { path = "../common" } anyhow = "1.0.68" -env_logger = "0.10.0" +log = "0.4.17" + diff --git a/remuxer/src/lib.rs b/remuxer/src/lib.rs index aa22b3b..749e04f 100644 --- a/remuxer/src/lib.rs +++ b/remuxer/src/lib.rs @@ -1,10 +1,5 @@ use jellycommon::ItemInfo; -use log::{debug, info}; -use std::{fs::File, io::Write, path::PathBuf, sync::Arc}; -use webm_iterable::{ - matroska_spec::{Block, Master, MatroskaSpec}, - WebmIterator, WebmWriter, -}; +use std::{io::Write, path::PathBuf, sync::Arc}; pub struct RemuxerContext {} @@ -21,73 +16,73 @@ impl RemuxerContext { item: ItemInfo, selection: Vec, ) -> anyhow::Result<()> { - let source_path = path_base.join(item.source.path); - info!("remuxing {source_path:?} to have tracks {selection:?}"); - let mut input = File::open(source_path)?; + // let source_path = path_base.join(item.source.path); + // info!("remuxing {source_path:?} to have tracks {selection:?}"); + // let mut input = File::open(source_path)?; - let tags = WebmIterator::new(&mut input, &[MatroskaSpec::TrackEntry(Master::Start)]); - let mut output = WebmWriter::new(writer); + // 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; + // 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; - for c in &children { - if let MatroskaSpec::TrackNumber(n) = c { - number = Some(*n) - } - } - let number = number.unwrap(); - if selection.contains(&number) { - output.write(&MatroskaSpec::TrackEntry(Master::Full(children)))?; - } - } - MatroskaSpec::Block(ref data) => { - let data: &[u8] = &data; - let block: Block = data.try_into()?; - 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 => { - if !ignore { - debug!("{x:?}"); - output.write(&x)?; - } - } - } - } + // 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; + // for c in &children { + // if let MatroskaSpec::TrackNumber(n) = c { + // number = Some(*n) + // } + // } + // let number = number.unwrap(); + // if selection.contains(&number) { + // output.write(&MatroskaSpec::TrackEntry(Master::Full(children)))?; + // } + // } + // MatroskaSpec::Block(ref data) => { + // let data: &[u8] = &data; + // let block: Block = data.try_into()?; + // 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 => { + // if !ignore { + // debug!("{x:?}"); + // output.write(&x)?; + // } + // } + // } + // } Ok(()) } } diff --git a/server/src/main.rs b/server/src/main.rs index 6243b3f..edf562a 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -52,7 +52,7 @@ fn stream( tokio::task::spawn_blocking(move || { if let Err(e) = remuxer.generate_into( b, - offset, + 0, item.fs_path.parent().unwrap().to_path_buf(), item.data.clone(), selection, -- cgit v1.2.3-70-g09d2