test nalu sending, av1 fixes and changes
This commit is contained in:
parent
0ecc9fe9d2
commit
08359cf7e2
5 changed files with 33 additions and 20 deletions
|
@ -6,7 +6,7 @@ use crate::util;
|
||||||
use crate::encode::codecs::Encoder;
|
use crate::encode::codecs::Encoder;
|
||||||
use crate::encode::codecs;
|
use crate::encode::codecs;
|
||||||
|
|
||||||
pub fn spawn(metadata: Arc<util::Metadata>, v_target: util::VideoCodec, a_target: util::AudioCodec) -> Result<(impl Encoder, impl Encoder), Box<dyn Error>> {
|
pub fn spawn(metadata: Arc<util::Metadata>, v_target: util::VideoCodec, a_target: util::AudioCodec) -> Result<(impl Encoder + Send, impl Encoder + Send), Box<dyn Error>> {
|
||||||
let v = match v_target {
|
let v = match v_target {
|
||||||
util::VideoCodec::AV1 => codecs::video::new_av1(metadata.clone())?,
|
util::VideoCodec::AV1 => codecs::video::new_av1(metadata.clone())?,
|
||||||
_ => return Err(Box::new(util::EncoderError::CodecNotSupported))
|
_ => return Err(Box::new(util::EncoderError::CodecNotSupported))
|
||||||
|
@ -18,9 +18,13 @@ pub fn spawn(metadata: Arc<util::Metadata>, v_target: util::VideoCodec, a_target
|
||||||
Ok((v, a))
|
Ok((v, a))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_encoder(mut encoder: impl Encoder, c_in: mpsc::Receiver<util::RawMedia>, c_out: mpsc::Sender<util::NALUPacket>, c_err: mpsc::Sender<Box<dyn Error + Send + Sync>>) {
|
pub fn handle_encoder(mut encoder: impl Encoder + Send + 'static, c_in: mpsc::Receiver<util::RawMedia>, c_out: mpsc::Sender<util::NALUPacket>, c_err: mpsc::Sender<Box<dyn Error + Send + Sync>>) {
|
||||||
let stdin = encoder.stdin();
|
let stdin = encoder.stdin();
|
||||||
|
let c_err2 = c_err.clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
codecs::read_raw_loop(stdin, c_in, c_err);
|
codecs::read_raw_loop(stdin, c_in, c_err);
|
||||||
});
|
});
|
||||||
|
thread::spawn(move || {
|
||||||
|
encoder.write_nalu_loop(c_out, c_err2);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,25 +32,29 @@ impl Encoder for OpusEncoder {
|
||||||
let num_segments = buff[buff.len() - 1] as usize;
|
let num_segments = buff[buff.len() - 1] as usize;
|
||||||
let mut segment_table_buff = vec![0u8; num_segments];
|
let mut segment_table_buff = vec![0u8; num_segments];
|
||||||
stdout.read_exact(&mut segment_table_buff)?;
|
stdout.read_exact(&mut segment_table_buff)?;
|
||||||
let mut data = vec![0u8; segment_table_buff.iter().sum::<u8>() 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)?;
|
stdout.read_exact(&mut data)?;
|
||||||
return Ok(util::NALUPacket {packet_type: util::NALUPacketType::Audio(util::AudioCodec::OPUS), packet_data: data});
|
return Ok(util::NALUPacket {packet_type: util::NALUPacketType::Audio(util::AudioCodec::OPUS), packet_data: data});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_opus(metadata: Arc<util::Metadata>) -> Result<OpusEncoder, Box<dyn Error>> {
|
pub fn new_opus(metadata: Arc<util::Metadata>) -> Result<OpusEncoder, Box<dyn Error>> {
|
||||||
let f = File::create("dump.opus")?;
|
|
||||||
let channels = metadata.audio.channels.to_string();
|
let channels = metadata.audio.channels.to_string();
|
||||||
let samplerate = metadata.audio.samplerate.to_string();
|
let samplerate = metadata.audio.samplerate.to_string();
|
||||||
let cmd = Command::new("opusenc")
|
let cmd = Command::new("opusenc")
|
||||||
.args([
|
.args([
|
||||||
|
"--quiet",
|
||||||
"--raw",
|
"--raw",
|
||||||
"--raw-bits", "16",
|
"--raw-bits", "16",
|
||||||
"--raw-rate", samplerate.as_str(),
|
"--raw-rate", samplerate.as_str(),
|
||||||
"--raw-chan", channels.as_str(),
|
"--raw-chan", channels.as_str(),
|
||||||
"--max-delay", "1",
|
"--max-delay", "1",
|
||||||
"-", "-"
|
"-", "-"
|
||||||
]).stdin(Stdio::piped()).stdout(f).spawn()?;
|
]).stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?;
|
||||||
return Ok(OpusEncoder {cmd: cmd});
|
return Ok(OpusEncoder {cmd: cmd});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,10 +39,6 @@ fn write_raw(cmd_in: &mut ChildStdin, media: util::RawMedia) -> Result<(), Box<d
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_nalu(cmd_out: &mut ChildStdout) -> Result<util::NALUPacket, Box<dyn Error>> {
|
|
||||||
todo!();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_raw_loop(mut cmd_in: ChildStdin, c_in: mpsc::Receiver<util::RawMedia>, c_err: mpsc::Sender<Box<dyn Error + Send + Sync>>) {
|
pub fn read_raw_loop(mut cmd_in: ChildStdin, c_in: mpsc::Receiver<util::RawMedia>, c_err: mpsc::Sender<Box<dyn Error + Send + Sync>>) {
|
||||||
loop {
|
loop {
|
||||||
let media = match c_in.recv() {
|
let media = match c_in.recv() {
|
||||||
|
@ -55,7 +51,3 @@ pub fn read_raw_loop(mut cmd_in: ChildStdin, c_in: mpsc::Receiver<util::RawMedia
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_nalu_loop(mut cmd_out: ChildStdout, c_out: mpsc::Sender<util::NALUPacket>, c_err: mpsc::Sender<Box<dyn Error + Send + Sync>>) {
|
|
||||||
todo!();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::process::{Child, Command, Stdio, ChildStdin};
|
use std::process::{Child, Command, Stdio, ChildStdin};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::fs::File;
|
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
@ -29,13 +28,13 @@ impl Encoder for AV1Encoder {
|
||||||
|
|
||||||
fn read_nalu(&mut self) -> Result<util::NALUPacket, Box<dyn Error + Send + Sync>> {
|
fn read_nalu(&mut self) -> Result<util::NALUPacket, Box<dyn Error + Send + Sync>> {
|
||||||
let mut stdout = self.cmd.stdout.as_mut().unwrap();
|
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) {
|
match stdout.read_exact(&mut buff) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(err) if err.kind() == io::ErrorKind::UnexpectedEof => return Err(Box::new(util::EncoderError::EOF)),
|
Err(err) if err.kind() == io::ErrorKind::UnexpectedEof => return Err(Box::new(util::EncoderError::EOF)),
|
||||||
Err(err) => return Err(Box::new(err))
|
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];
|
let mut data = vec![0u8; nalu_len];
|
||||||
stdout.read_exact(data.as_mut_slice())?;
|
stdout.read_exact(data.as_mut_slice())?;
|
||||||
return Ok(util::NALUPacket {packet_type: util::NALUPacketType::Video(util::VideoCodec::AV1), packet_data: data});
|
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<util::Metadata>) -> Result<AV1Encoder, Box<dyn Error>> {
|
pub fn new_av1(metadata: Arc<util::Metadata>) -> Result<AV1Encoder, Box<dyn Error>> {
|
||||||
let f = File::create("dump.av1")?;
|
|
||||||
let width = metadata.video.width.to_string();
|
let width = metadata.video.width.to_string();
|
||||||
let height = metadata.video.height.to_string();
|
let height = metadata.video.height.to_string();
|
||||||
let fps_num = ((metadata.video.framerate * 1000.0) as u32).to_string();
|
let fps_num = ((metadata.video.framerate * 1000.0) as u32).to_string();
|
||||||
|
@ -55,8 +53,9 @@ pub fn new_av1(metadata: Arc<util::Metadata>) -> Result<AV1Encoder, Box<dyn Erro
|
||||||
"-h", height.as_str(),
|
"-h", height.as_str(),
|
||||||
"--fps-num", fps_num.as_str(),
|
"--fps-num", fps_num.as_str(),
|
||||||
"--preset", "12",
|
"--preset", "12",
|
||||||
|
"--keyint", "30",
|
||||||
"-i", "-",
|
"-i", "-",
|
||||||
"-b", "-"
|
"-b", "-"
|
||||||
]).stdin(Stdio::piped()).stdout(f).spawn()?;
|
]).stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?;
|
||||||
return Ok(AV1Encoder {cmd: cmd});
|
return Ok(AV1Encoder {cmd: cmd});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use std::sync::{mpsc, Arc};
|
use std::sync::{mpsc, Arc};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
use crate::util;
|
use crate::util;
|
||||||
|
|
||||||
|
@ -15,11 +17,23 @@ pub fn spawn(
|
||||||
let (err_in, err_out) = mpsc::channel();
|
let (err_in, err_out) = mpsc::channel();
|
||||||
let metadata_handle = metadata.clone();
|
let metadata_handle = metadata.clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
&v;
|
write_to_file(v, "dump.av1");
|
||||||
&a;
|
});
|
||||||
|
thread::spawn(move || {
|
||||||
|
write_to_file(a, "dump.opus");
|
||||||
|
});
|
||||||
|
thread::spawn(move || {
|
||||||
&err_in;
|
&err_in;
|
||||||
&metadata_handle;
|
&metadata_handle;
|
||||||
thread::park();
|
thread::park();
|
||||||
});
|
});
|
||||||
return Ok(err_out);
|
return Ok(err_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn write_to_file(c: mpsc::Receiver<util::NALUPacket>, filename: &str) {
|
||||||
|
let mut f = File::create(filename).unwrap();
|
||||||
|
loop {
|
||||||
|
let nalu = c.recv().unwrap();
|
||||||
|
f.write_all(&nalu.packet_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue