video: Clean up the encoder thread a bit
This commit is contained in:
parent
ab9df17b6a
commit
f4ee32d3e4
2 changed files with 25 additions and 47 deletions
|
@ -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());
|
||||||
|
|
|
@ -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");
|
||||||
|
|
Loading…
Reference in a new issue