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};
#[derive(Debug)]
pub enum EncodeThreadInput {
pub enum EncoderCommand {
Init { size: crate::types::Size },
Shutdown,
@ -25,11 +25,6 @@ pub enum EncodeThreadInput {
SendFrame,
}
#[derive(Clone)]
pub enum EncodeThreadOutput {
Frame { packet: ffmpeg::Packet },
}
struct EncoderStateHW {
encoder: Option<H264Encoder>,
frame: ffmpeg::frame::Video,
@ -147,7 +142,7 @@ extern \"C\" __global__ void flip_opengl(
fn encoder_thread_hwframe_main(
input_msg_notify: Arc<Condvar>,
input_msg: Arc<Mutex<EncodeThreadInput>>,
input_msg: Arc<Mutex<EncoderCommand>>,
processed_notify: Arc<Condvar>,
processed: Arc<Mutex<bool>>,
@ -205,18 +200,14 @@ fn encoder_thread_hwframe_main(
// allocated.
let mut temp_buffer: CudaSlice<u32> = cuda_device.alloc_zeros::<u32>(48).expect("over");
let mut last_size: Option<crate::types::Size> = None;
loop {
// wait for a message
{
let lk = input_msg.lock().expect("FUCK");
let waited_lk = input_msg_notify.wait(lk).expect("you bone");
//println!("got here with {:?}", &*waited_lk);
match &*waited_lk {
EncodeThreadInput::Init { size } => {
EncoderCommand::Init { size } => {
frame_number = 0;
force_keyframe = true;
@ -230,42 +221,19 @@ fn encoder_thread_hwframe_main(
.expect("encoder init failed");
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.
EncodeThreadInput::Shutdown => break,
EncoderCommand::Shutdown => break,
EncodeThreadInput::ForceKeyframe => {
EncoderCommand::ForceKeyframe => {
force_keyframe = true;
}
EncodeThreadInput::SendFrame => {
EncoderCommand::SendFrame => {
// benchmarking
//use std::time::Instant;
//let start = Instant::now();
use std::time::Instant;
let start = Instant::now();
// copy gl frame *ON THE GPU* to ffmpeg frame
{
@ -376,7 +344,9 @@ fn encoder_thread_hwframe_main(
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
/// NOTE: Only signal. Do not wait
input_updated_cv: Arc<Condvar>,
input: Arc<Mutex<EncodeThreadInput>>,
input: Arc<Mutex<EncoderCommand>>,
processed: Arc<Mutex<bool>>,
processed_cv: Arc<Condvar>,
@ -417,7 +387,7 @@ pub struct 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");
//println!("Sent {:?}", cmd);
@ -427,18 +397,24 @@ impl EncoderThreadControl {
// 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;
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
pub fn shutdown(&self) {
self.send_command(EncodeThreadInput::Shutdown);
self.send_command(EncoderCommand::Shutdown);
}
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 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
let pkt_update_cv = Arc::new(Condvar::new());

View file

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