diff --git a/src/decode/cmds.rs b/src/decode/cmds.rs index 082013e..e851ce1 100644 --- a/src/decode/cmds.rs +++ b/src/decode/cmds.rs @@ -3,7 +3,16 @@ use std::error::Error; use crate::util; use crate::decode::codecs::Decoder; +use crate::decode::codecs; pub fn spawn(metadata: Arc) -> Result<(impl Decoder, impl Decoder), Box> { - todo!(); + let v = match metadata.video.codec { + Some(util::VideoCodec::H264) => codecs::video::new_h264(metadata.clone())?, + _ => {return Err(Box::new(util::DecoderError::CodecNotImplemented));} + }; + let a = match metadata.audio.codec { + Some(util::AudioCodec::AAC) => codecs::audio::new_aac(metadata)?, + _ => {return Err(Box::new(util::DecoderError::CodecNotImplemented));} + }; + return Ok((v, a)); } diff --git a/src/decode/codecs/audio.rs b/src/decode/codecs/audio.rs new file mode 100644 index 0000000..877cf23 --- /dev/null +++ b/src/decode/codecs/audio.rs @@ -0,0 +1,36 @@ +use std::error::Error; +use std::process::{ChildStdin, ChildStdout, Command, Stdio}; +use std::sync::Arc; +use std::io::{Read, Write}; + +use crate::decode::codecs::Decoder; +use crate::util; + +pub struct AACDecoder { + stdin: ChildStdin, + stdout: ChildStdout, + metadata: Arc, +} + +impl Decoder for AACDecoder { + fn write_nalu(&mut self, nalu: util::NALUPacket) -> Result<(), Box> { + self.stdin.write_all(nalu.packet_data.as_slice())?; + Ok(()) + } + fn read_raw(&mut self) -> Result> { + todo!(); + } +} + +pub fn new_aac(metadata: Arc) -> Result> { + let cmd = Command::new("tee").stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?; + let stdin = match cmd.stdin { + Some(x) => x, + None => {return Err(Box::new(util::DecoderError::InvalidPipeInit))} + }; + let stdout = match cmd.stdout { + Some(x) => x, + None => {return Err(Box::new(util::DecoderError::InvalidPipeInit))} + }; + return Ok(AACDecoder {stdin: stdin, stdout: stdout, metadata: metadata}) +} diff --git a/src/decode/codecs/mod.rs b/src/decode/codecs/mod.rs index 31f3302..8d28350 100644 --- a/src/decode/codecs/mod.rs +++ b/src/decode/codecs/mod.rs @@ -1,3 +1,6 @@ +pub mod video; +pub mod audio; + use std::sync::mpsc; use std::error::Error; diff --git a/src/decode/codecs/video.rs b/src/decode/codecs/video.rs new file mode 100644 index 0000000..b26c929 --- /dev/null +++ b/src/decode/codecs/video.rs @@ -0,0 +1,36 @@ +use std::error::Error; +use std::process::{ChildStdin, ChildStdout, Stdio, Command}; +use std::sync::Arc; +use std::io::{Read, Write}; + +use crate::decode::codecs::Decoder; +use crate::util; + +pub struct H264Decoder { + stdin: ChildStdin, + stdout: ChildStdout, + metadata: Arc, +} + +impl Decoder for H264Decoder { + fn write_nalu(&mut self, nalu: util::NALUPacket) -> Result<(), Box> { + self.stdin.write_all(nalu.packet_data.as_slice())?; + Ok(()) + } + fn read_raw(&mut self) -> Result> { + todo!(); + } +} + +pub fn new_h264(metadata: Arc) -> Result> { + let cmd = Command::new("tee").stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?; + let stdin = match cmd.stdin { + Some(x) => x, + None => {return Err(Box::new(util::DecoderError::InvalidPipeInit))} + }; + let stdout = match cmd.stdout { + Some(x) => x, + None => {return Err(Box::new(util::DecoderError::InvalidPipeInit))} + }; + return Ok(H264Decoder {stdin: stdin, stdout: stdout, metadata: metadata}); +} diff --git a/src/decode/mod.rs b/src/decode/mod.rs index acc0d44..1b92f8c 100644 --- a/src/decode/mod.rs +++ b/src/decode/mod.rs @@ -25,14 +25,6 @@ pub fn spawn( let (err_in, err_out) = mpsc::channel(); let (v_decoder, a_decoder) = cmds::spawn(metadata.clone())?; spawn_threads(v, raw_v_in, v_decoder, a, raw_a_in, a_decoder, err_in); - thread::spawn(move || { - &raw_v_in; - &raw_a_in; - &err_in; - &v; - &a; - thread::park(); - }); return Ok((raw_v_out, raw_a_out, err_out)); } diff --git a/src/util/mod.rs b/src/util/mod.rs index cb92b51..35133ba 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -128,6 +128,30 @@ impl fmt::Display for DemuxerError { } } +pub enum DecoderError { + CodecNotImplemented, + InvalidPipeInit, +} + +impl Error for DecoderError {} + +#[allow(unreachable_patterns)] +impl fmt::Debug for DecoderError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + DecoderError::CodecNotImplemented => write!(f, "Codec not recognized"), + DecoderError::InvalidPipeInit => write!(f, "Decoder has invalid piping"), + _ => write!(f, "Error not described yet") + } + } +} + +impl fmt::Display for DecoderError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(self, f) + } +} + // funcs pub fn thread_freeze(err_sender: mpsc::Sender>, err: Box) {