video: Clean up the encoder thread a bit

This commit is contained in:
Lily Tsuru 2024-12-04 23:19:29 -05:00
parent ab9df17b6a
commit f4ee32d3e4
2 changed files with 25 additions and 47 deletions

View file

@ -17,7 +17,7 @@ use super::h264_encoder::H264Encoder;
use super::{cuda_gl::safe::GraphicsResource, ffmpeg}; use super::{cuda_gl::safe::GraphicsResource, ffmpeg};
#[derive(Debug)] #[derive(Debug)]
pub enum EncodeThreadInput { pub enum EncoderCommand {
Init { size: crate::types::Size }, Init { size: crate::types::Size },
Shutdown, Shutdown,
@ -25,11 +25,6 @@ pub enum EncodeThreadInput {
SendFrame, SendFrame,
} }
#[derive(Clone)]
pub enum EncodeThreadOutput {
Frame { packet: ffmpeg::Packet },
}
struct EncoderStateHW { struct EncoderStateHW {
encoder: Option<H264Encoder>, encoder: Option<H264Encoder>,
frame: ffmpeg::frame::Video, frame: ffmpeg::frame::Video,
@ -147,7 +142,7 @@ extern \"C\" __global__ void flip_opengl(
fn encoder_thread_hwframe_main( fn encoder_thread_hwframe_main(
input_msg_notify: Arc<Condvar>, input_msg_notify: Arc<Condvar>,
input_msg: Arc<Mutex<EncodeThreadInput>>, input_msg: Arc<Mutex<EncoderCommand>>,
processed_notify: Arc<Condvar>, processed_notify: Arc<Condvar>,
processed: Arc<Mutex<bool>>, processed: Arc<Mutex<bool>>,
@ -205,18 +200,14 @@ fn encoder_thread_hwframe_main(
// allocated. // allocated.
let mut temp_buffer: CudaSlice<u32> = cuda_device.alloc_zeros::<u32>(48).expect("over"); let mut temp_buffer: CudaSlice<u32> = cuda_device.alloc_zeros::<u32>(48).expect("over");
let mut last_size: Option<crate::types::Size> = None;
loop { loop {
// wait for a message // wait for a message
{ {
let lk = input_msg.lock().expect("FUCK"); let lk = input_msg.lock().expect("FUCK");
let waited_lk = input_msg_notify.wait(lk).expect("you bone"); let waited_lk = input_msg_notify.wait(lk).expect("you bone");
//println!("got here with {:?}", &*waited_lk);
match &*waited_lk { match &*waited_lk {
EncodeThreadInput::Init { size } => { EncoderCommand::Init { size } => {
frame_number = 0; frame_number = 0;
force_keyframe = true; force_keyframe = true;
@ -230,42 +221,19 @@ fn encoder_thread_hwframe_main(
.expect("encoder init failed"); .expect("encoder init failed");
tracing::info!("Encoder initalized for {}x{}", size.width, size.height); tracing::info!("Encoder initalized for {}x{}", size.width, size.height);
/*
if last_size.is_some() {
let lss = last_size.as_ref().unwrap();
if size.width != lss.width && size.height != lss.height {
last_size = Some(size.clone());
}
} else {
// Allocate the flip buffer
temp_buffer = cuda_device
.alloc_zeros::<u32>((size.width * size.height) as usize)
.expect("oh youre fucked anyways");
encoder
.init(cuda_device, size.clone())
.expect("encoder init failed");
tracing::info!("Encoder initalized for {}x{}", size.width, size.height);
last_size = Some(size.clone());
}
*/
} }
// Simply shutdown. // Simply shutdown.
EncodeThreadInput::Shutdown => break, EncoderCommand::Shutdown => break,
EncodeThreadInput::ForceKeyframe => { EncoderCommand::ForceKeyframe => {
force_keyframe = true; force_keyframe = true;
} }
EncodeThreadInput::SendFrame => { EncoderCommand::SendFrame => {
// benchmarking // benchmarking
//use std::time::Instant; use std::time::Instant;
//let start = Instant::now(); let start = Instant::now();
// copy gl frame *ON THE GPU* to ffmpeg frame // copy gl frame *ON THE GPU* to ffmpeg frame
{ {
@ -376,7 +344,9 @@ fn encoder_thread_hwframe_main(
force_keyframe = false; force_keyframe = false;
} }
//tracing::info!("encoding frame {frame_number} took {:2?}", start.elapsed()); if frame_number % 64 == 0 {
tracing::info!("encoding frame {frame_number} took {:2?}", start.elapsed());
}
} }
} }
@ -406,7 +376,7 @@ pub struct EncoderThreadControl {
// input // input
/// NOTE: Only signal. Do not wait /// NOTE: Only signal. Do not wait
input_updated_cv: Arc<Condvar>, input_updated_cv: Arc<Condvar>,
input: Arc<Mutex<EncodeThreadInput>>, input: Arc<Mutex<EncoderCommand>>,
processed: Arc<Mutex<bool>>, processed: Arc<Mutex<bool>>,
processed_cv: Arc<Condvar>, processed_cv: Arc<Condvar>,
@ -417,7 +387,7 @@ pub struct EncoderThreadControl {
} }
impl EncoderThreadControl { impl EncoderThreadControl {
pub fn send_command(&self, cmd: EncodeThreadInput) { pub fn send_command(&self, cmd: EncoderCommand) {
{ {
let mut lk = self.input.lock().expect("failed to lock input"); let mut lk = self.input.lock().expect("failed to lock input");
//println!("Sent {:?}", cmd); //println!("Sent {:?}", cmd);
@ -427,18 +397,24 @@ impl EncoderThreadControl {
// Wait for the encoder thread to notify completion. // Wait for the encoder thread to notify completion.
{ {
let mut lklk = self.processed.lock().expect("failed to lock processed flag"); let mut lklk = self
.processed
.lock()
.expect("failed to lock processed flag");
*lklk = false; *lklk = false;
while *lklk == false { while *lklk == false {
lklk = self.processed_cv.wait(lklk).expect("failed to wait for encoder thread to signal completion"); lklk = self
.processed_cv
.wait(lklk)
.expect("failed to wait for encoder thread to signal completion");
} }
} }
} }
/// Shorthand to shutdown the encoder /// Shorthand to shutdown the encoder
pub fn shutdown(&self) { pub fn shutdown(&self) {
self.send_command(EncodeThreadInput::Shutdown); self.send_command(EncoderCommand::Shutdown);
} }
pub fn wait_for_packet(&self) -> MutexGuard<'_, ffmpeg::Packet> { pub fn wait_for_packet(&self) -> MutexGuard<'_, ffmpeg::Packet> {
@ -479,7 +455,7 @@ pub fn encoder_thread_spawn_hwframe(
let processed_cv = Arc::new(Condvar::new()); let processed_cv = Arc::new(Condvar::new());
let input_updated = Arc::new(Condvar::new()); let input_updated = Arc::new(Condvar::new());
let input = Arc::new(Mutex::new(EncodeThreadInput::ForceKeyframe)); // something dummy let input = Arc::new(Mutex::new(EncoderCommand::ForceKeyframe)); // something dummy
// packet // packet
let pkt_update_cv = Arc::new(Condvar::new()); let pkt_update_cv = Arc::new(Condvar::new());

View file

@ -217,6 +217,8 @@ impl H264Encoder {
dict.set("forced-idr", "1"); dict.set("forced-idr", "1");
dict.set("b_ref_mode", "2");
// damn you // damn you
dict.set("delay", "0"); dict.set("delay", "0");
dict.set("zerolatency", "1"); dict.set("zerolatency", "1");