diff --git a/src/encode/cmds.rs b/src/encode/cmds.rs index f7f8d67..60df077 100644 --- a/src/encode/cmds.rs +++ b/src/encode/cmds.rs @@ -6,7 +6,7 @@ use crate::util; use crate::encode::codecs::Encoder; use crate::encode::codecs; -pub fn spawn(metadata: Arc, v_target: util::VideoCodec, a_target: util::AudioCodec) -> Result<(impl Encoder, impl Encoder), Box> { +pub fn spawn(metadata: Arc, v_target: util::VideoCodec, a_target: util::AudioCodec) -> Result<(impl Encoder + Send, impl Encoder + Send), Box> { let v = match v_target { util::VideoCodec::AV1 => codecs::video::new_av1(metadata.clone())?, _ => return Err(Box::new(util::EncoderError::CodecNotSupported)) @@ -18,9 +18,13 @@ pub fn spawn(metadata: Arc, v_target: util::VideoCodec, a_target Ok((v, a)) } -pub fn handle_encoder(mut encoder: impl Encoder, c_in: mpsc::Receiver, c_out: mpsc::Sender, c_err: mpsc::Sender>) { +pub fn handle_encoder(mut encoder: impl Encoder + Send + 'static, c_in: mpsc::Receiver, c_out: mpsc::Sender, c_err: mpsc::Sender>) { let stdin = encoder.stdin(); + let c_err2 = c_err.clone(); thread::spawn(move || { codecs::read_raw_loop(stdin, c_in, c_err); }); + thread::spawn(move || { + encoder.write_nalu_loop(c_out, c_err2); + }); } diff --git a/src/encode/codecs/audio.rs b/src/encode/codecs/audio.rs index edb12ad..b833681 100644 --- a/src/encode/codecs/audio.rs +++ b/src/encode/codecs/audio.rs @@ -32,25 +32,29 @@ impl Encoder for OpusEncoder { let num_segments = buff[buff.len() - 1] as usize; let mut segment_table_buff = vec![0u8; num_segments]; stdout.read_exact(&mut segment_table_buff)?; - let mut data = vec![0u8; segment_table_buff.iter().sum::() as usize]; + let mut page_size:usize = 0; + for i in segment_table_buff { + page_size += i as usize; + } + let mut data = vec![0u8; page_size]; stdout.read_exact(&mut data)?; return Ok(util::NALUPacket {packet_type: util::NALUPacketType::Audio(util::AudioCodec::OPUS), packet_data: data}); } } pub fn new_opus(metadata: Arc) -> Result> { - let f = File::create("dump.opus")?; let channels = metadata.audio.channels.to_string(); let samplerate = metadata.audio.samplerate.to_string(); let cmd = Command::new("opusenc") .args([ + "--quiet", "--raw", "--raw-bits", "16", "--raw-rate", samplerate.as_str(), "--raw-chan", channels.as_str(), "--max-delay", "1", "-", "-" - ]).stdin(Stdio::piped()).stdout(f).spawn()?; + ]).stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?; return Ok(OpusEncoder {cmd: cmd}); } diff --git a/src/encode/codecs/mod.rs b/src/encode/codecs/mod.rs index 5146823..bc4f215 100644 --- a/src/encode/codecs/mod.rs +++ b/src/encode/codecs/mod.rs @@ -39,10 +39,6 @@ fn write_raw(cmd_in: &mut ChildStdin, media: util::RawMedia) -> Result<(), Box Result> { - todo!(); -} - pub fn read_raw_loop(mut cmd_in: ChildStdin, c_in: mpsc::Receiver, c_err: mpsc::Sender>) { loop { let media = match c_in.recv() { @@ -55,7 +51,3 @@ pub fn read_raw_loop(mut cmd_in: ChildStdin, c_in: mpsc::Receiver, c_err: mpsc::Sender>) { - todo!(); -} diff --git a/src/encode/codecs/video.rs b/src/encode/codecs/video.rs index 491366b..c31081f 100644 --- a/src/encode/codecs/video.rs +++ b/src/encode/codecs/video.rs @@ -1,7 +1,6 @@ use std::error::Error; use std::process::{Child, Command, Stdio, ChildStdin}; use std::sync::Arc; -use std::fs::File; use std::io::Read; use std::io; @@ -29,13 +28,13 @@ impl Encoder for AV1Encoder { fn read_nalu(&mut self) -> Result> { let mut stdout = self.cmd.stdout.as_mut().unwrap(); - let mut buff = [0u8; 11]; + let mut buff = [0u8; 12]; match stdout.read_exact(&mut buff) { Ok(_) => (), Err(err) if err.kind() == io::ErrorKind::UnexpectedEof => return Err(Box::new(util::EncoderError::EOF)), Err(err) => return Err(Box::new(err)) } - let nalu_len = (u32::from_le_bytes(buff[..4].try_into().unwrap()) & 0xffffff) as usize; + let nalu_len = u32::from_le_bytes(buff[..4].try_into().unwrap()) as usize; let mut data = vec![0u8; nalu_len]; stdout.read_exact(data.as_mut_slice())?; return Ok(util::NALUPacket {packet_type: util::NALUPacketType::Video(util::VideoCodec::AV1), packet_data: data}); @@ -43,7 +42,6 @@ impl Encoder for AV1Encoder { } pub fn new_av1(metadata: Arc) -> Result> { - let f = File::create("dump.av1")?; let width = metadata.video.width.to_string(); let height = metadata.video.height.to_string(); let fps_num = ((metadata.video.framerate * 1000.0) as u32).to_string(); @@ -55,8 +53,9 @@ pub fn new_av1(metadata: Arc) -> Result, filename: &str) { + let mut f = File::create(filename).unwrap(); + loop { + let nalu = c.recv().unwrap(); + f.write_all(&nalu.packet_data); + } +}