From 1023bfdee547d49fe267d9d7f3b4ec5ec34dadda Mon Sep 17 00:00:00 2001 From: Muaz Ahmad Date: Thu, 12 Oct 2023 14:45:24 +0500 Subject: [PATCH] more boilerplate for encoder spawning --- src/demux/nalu_flv.rs | 4 ++-- src/encode/cmds.rs | 15 ++++++++++++--- src/encode/codecs/audio.rs | 17 +++++++++++++++++ src/encode/codecs/mod.rs | 3 +++ src/encode/codecs/video.rs | 16 ++++++++++++++++ src/encode/mod.rs | 7 +++---- src/util/mod.rs | 27 +++++++++++++++++++++++++++ 7 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 src/encode/codecs/audio.rs create mode 100644 src/encode/codecs/video.rs diff --git a/src/demux/nalu_flv.rs b/src/demux/nalu_flv.rs index 883bcf1..8a00c84 100644 --- a/src/demux/nalu_flv.rs +++ b/src/demux/nalu_flv.rs @@ -3,14 +3,14 @@ use crate::util; pub fn prepend_v(data: Vec, metadata: &util::Metadata) -> Vec { match metadata.video.codec { Some(util::VideoCodec::H264) => preprocess_h264(data), - None => panic!("not possible for codec to be None by this point") + _ => panic!("not possible for codec to be anything else by this point") } } pub fn prepend_a(data: Vec, metadata: &util::Metadata) -> Vec { match metadata.audio.codec { Some(util::AudioCodec::AAC) => preprocess_aac(data, metadata), - None => panic!("not possible for codec to be None by this point") + _ => panic!("not possible for codec to be anything else by this point") } } diff --git a/src/encode/cmds.rs b/src/encode/cmds.rs index 452b43f..af5d973 100644 --- a/src/encode/cmds.rs +++ b/src/encode/cmds.rs @@ -3,11 +3,20 @@ use std::sync::{Arc, mpsc}; use crate::util; use crate::encode::codecs::Encoder; +use crate::encode::codecs; -pub fn spawn(v_target: util::VideoCodec, a_target: util::AudioCodec) -> Result<(impl Encoder, impl Encoder), Box> { - todo!(); +pub fn spawn(metadata: Arc, v_target: util::VideoCodec, a_target: util::AudioCodec) -> Result<(impl Encoder, impl Encoder), Box> { + let v = match v_target { + util::VideoCodec::VP9 => codecs::video::new_vp9(metadata.clone())?, + _ => return Err(Box::new(util::EncoderError::CodecNotSupported)) + }; + let a = match a_target { + util::AudioCodec::OPUS => codecs::audio::new_opus(metadata)?, + _ => return Err(Box::new(util::EncoderError::CodecNotSupported)) + }; + Ok((v, a)) } -pub fn handle_encoder(encoder: impl Encoder, c_in: mpsc::Receiver, c_out: mpsc::Sender, metadata: Arc, c_err: mpsc::Sender>) { +pub fn handle_encoder(encoder: impl Encoder, c_in: mpsc::Receiver, c_out: mpsc::Sender, c_err: mpsc::Sender>) { todo!(); } diff --git a/src/encode/codecs/audio.rs b/src/encode/codecs/audio.rs new file mode 100644 index 0000000..5c2bcef --- /dev/null +++ b/src/encode/codecs/audio.rs @@ -0,0 +1,17 @@ +use std::error::Error; +use std::process::{Child, Command, Stdio, ChildStdin, ChildStdout}; +use std::sync::Arc; + +use crate::util; +use crate::encode::codecs::Encoder; + +pub struct OpusEncoder { + cmd: Child, +} + +impl Encoder for OpusEncoder {} + +pub fn new_opus(metadata: Arc) -> Result> { + todo!(); +} + diff --git a/src/encode/codecs/mod.rs b/src/encode/codecs/mod.rs index b9e0233..114a5f1 100644 --- a/src/encode/codecs/mod.rs +++ b/src/encode/codecs/mod.rs @@ -1,2 +1,5 @@ +pub mod video; +pub mod audio; + pub trait Encoder { } diff --git a/src/encode/codecs/video.rs b/src/encode/codecs/video.rs new file mode 100644 index 0000000..183efa6 --- /dev/null +++ b/src/encode/codecs/video.rs @@ -0,0 +1,16 @@ +use std::error::Error; +use std::process::{Child, Command, Stdio, ChildStdin, ChildStdout}; +use std::sync::Arc; + +use crate::util; +use crate::encode::codecs::Encoder; + +pub struct VP9Encoder { + cmd: Child, +} + +impl Encoder for VP9Encoder {} + +pub fn new_vp9(metadata: Arc) -> Result> { + todo!(); +} diff --git a/src/encode/mod.rs b/src/encode/mod.rs index 60c8435..d7eaee9 100644 --- a/src/encode/mod.rs +++ b/src/encode/mod.rs @@ -25,13 +25,12 @@ pub fn spawn( let (a_in, a_out) = mpsc::channel(); let (err_in_v, err_out) = mpsc::channel(); let err_in_a = err_in_v.clone(); - let (v_encoder, a_encoder) = cmds::spawn(v_target, a_target)?; - let metadata_cp = metadata.clone(); + let (v_encoder, a_encoder) = cmds::spawn(metadata, v_target, a_target)?; thread::spawn(move || { - cmds::handle_encoder(v_encoder, v, v_in, metadata_cp, err_in_v); + cmds::handle_encoder(v_encoder, v, v_in, err_in_v); }); thread::spawn(move || { - cmds::handle_encoder(a_encoder, a, a_in, metadata, err_in_a); + cmds::handle_encoder(a_encoder, a, a_in, err_in_a); }); return Ok((v_out, a_out, err_out)); } diff --git a/src/util/mod.rs b/src/util/mod.rs index 03d0711..d35a06c 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -159,6 +159,33 @@ impl fmt::Display for DecoderError { } } +pub enum EncoderError { + CodecNotSupported, + BrokenInPipe, + BrokenOutPipe, + EOF, +} + +impl Error for EncoderError {} + +#[allow(unreachable_patterns)] +impl fmt::Debug for EncoderError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + EncoderError::CodecNotSupported => write!(f, "Codec not recognized or not allowed for encoding"), + EncoderError::BrokenInPipe => write!(f, "Encoder has invalid piping, stdin closed"), + EncoderError::BrokenInPipe => write!(f, "Encoder has invalid piping, stdout closed"), + EncoderError::EOF => write!(f, "Encoder output closed, expected EOF"), + _ => write!(f, "Error not described yet") + } + } +} + +impl fmt::Display for EncoderError { + 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) {