clean break video code into new module

This commit is contained in:
Lily Tsuru 2024-09-09 22:02:57 -04:00
parent a6734667de
commit fa929641e5
4 changed files with 26 additions and 17 deletions

View file

@ -1,9 +1,11 @@
mod encoder_thread; mod video;
mod ffmpeg;
mod surface; mod surface;
mod types; mod types;
mod vnc_engine; mod vnc_engine;
use video::encoder_thread;
use video::ffmpeg;
use std::{ use std::{
sync::{Arc, Mutex}, sync::{Arc, Mutex},
time::Duration, time::Duration,
@ -62,8 +64,8 @@ async fn main() -> anyhow::Result<()> {
let (engine_input_tx, engine_input_rx) = mpsc::channel(16); let (engine_input_tx, engine_input_rx) = mpsc::channel(16);
// H.264 encoder related // H.264 encoder related
let frame: Arc<Mutex<Option<ffmpeg_the_third::frame::Video>>> = Arc::new(Mutex::new(None)); let frame: Arc<Mutex<Option<ffmpeg::frame::Video>>> = Arc::new(Mutex::new(None));
let (mut encoder_rx, encoder_tx) = encoder_thread::encoder_thread_spawn(&frame); let (mut encoder_rx, encoder_tx) = video::encoder_thread_spawn(&frame);
let state = Arc::new(AppState::new(engine_input_tx, encoder_tx)); let state = Arc::new(AppState::new(engine_input_tx, encoder_tx));

View file

@ -4,6 +4,9 @@ use std::{
}; };
use tokio::sync::mpsc::{self, error::TryRecvError}; use tokio::sync::mpsc::{self, error::TryRecvError};
use super::ffmpeg;
use super::h264_encoder_sw::H264EncoderSW;
pub enum EncodeThreadInput { pub enum EncodeThreadInput {
Init { size: crate::types::Size }, Init { size: crate::types::Size },
ForceKeyframe, ForceKeyframe,
@ -12,20 +15,18 @@ pub enum EncodeThreadInput {
#[derive(Clone)] #[derive(Clone)]
pub enum EncodeThreadOutput { pub enum EncodeThreadOutput {
Frame { packet: ffmpeg_the_third::Packet }, Frame { packet: ffmpeg::Packet },
} }
#[inline] #[inline]
fn set_frame_flags(frame: &mut ffmpeg_the_third::Frame, force_keyframe: bool) { fn set_frame_flags(frame: &mut ffmpeg_the_third::Frame, force_keyframe: bool) {
unsafe { unsafe {
if force_keyframe { if force_keyframe {
(*frame.as_mut_ptr()).pict_type = (*frame.as_mut_ptr()).pict_type = ffmpeg::sys::AVPictureType::AV_PICTURE_TYPE_I;
ffmpeg_the_third::sys::AVPictureType::AV_PICTURE_TYPE_I;
(*frame.as_mut_ptr()).flags = ffmpeg_the_third::sys::AV_FRAME_FLAG_KEY; (*frame.as_mut_ptr()).flags = ffmpeg_the_third::sys::AV_FRAME_FLAG_KEY;
(*frame.as_mut_ptr()).key_frame = 1; (*frame.as_mut_ptr()).key_frame = 1;
} else { } else {
(*frame.as_mut_ptr()).pict_type = (*frame.as_mut_ptr()).pict_type = ffmpeg::sys::AVPictureType::AV_PICTURE_TYPE_NONE;
ffmpeg_the_third::sys::AVPictureType::AV_PICTURE_TYPE_NONE;
(*frame.as_mut_ptr()).flags = 0i32; (*frame.as_mut_ptr()).flags = 0i32;
(*frame.as_mut_ptr()).key_frame = 0; (*frame.as_mut_ptr()).key_frame = 0;
} }
@ -35,11 +36,11 @@ fn set_frame_flags(frame: &mut ffmpeg_the_third::Frame, force_keyframe: bool) {
fn encoder_thread_main( fn encoder_thread_main(
mut rx: mpsc::Receiver<EncodeThreadInput>, mut rx: mpsc::Receiver<EncodeThreadInput>,
tx: mpsc::Sender<EncodeThreadOutput>, tx: mpsc::Sender<EncodeThreadOutput>,
frame: &Arc<Mutex<Option<ffmpeg_the_third::frame::Video>>>, frame: &Arc<Mutex<Option<ffmpeg::frame::Video>>>,
) { ) {
let mut packet = ffmpeg_the_third::Packet::empty(); let mut packet = ffmpeg::Packet::empty();
let mut encoder: Option<crate::ffmpeg::H264Encoder> = None; let mut encoder: Option<H264EncoderSW> = None;
let mut sws = None; let mut sws = None;
let mut yuv_frame = None; let mut yuv_frame = None;
@ -73,7 +74,7 @@ fn encoder_thread_main(
); );
encoder = Some( encoder = Some(
crate::ffmpeg::H264Encoder::new(size, 60, 3 * (1000 * 1000)) H264EncoderSW::new(size, 60, 3 * (1000 * 1000))
.expect("Failed to create encoder"), .expect("Failed to create encoder"),
); );
} }

View file

@ -1,6 +1,6 @@
use super::ffmpeg;
use anyhow::Context; use anyhow::Context;
use ffmpeg::error::EAGAIN; use ffmpeg::error::EAGAIN;
use ffmpeg_the_third as ffmpeg;
use ffmpeg::codec as lavc; // lavc use ffmpeg::codec as lavc; // lavc
@ -19,12 +19,12 @@ pub fn create_context_from_codec(codec: ffmpeg::Codec) -> Result<lavc::Context,
} }
} }
/// A simple H.264 encoder. /// A simple software H.264 encoder.
pub struct H264Encoder { pub struct H264EncoderSW {
encoder: ffmpeg::encoder::video::Encoder, encoder: ffmpeg::encoder::video::Encoder,
} }
impl H264Encoder { impl H264EncoderSW {
pub fn new(size: Size, max_framerate: u32, bitrate: usize) -> anyhow::Result<Self> { pub fn new(size: Size, max_framerate: u32, bitrate: usize) -> anyhow::Result<Self> {
let encoder = ffmpeg::encoder::find(lavc::Id::H264).expect("could not find libx264"); let encoder = ffmpeg::encoder::find(lavc::Id::H264).expect("could not find libx264");

6
server/src/video/mod.rs Normal file
View file

@ -0,0 +1,6 @@
pub mod h264_encoder_sw;
pub mod encoder_thread;
pub use ffmpeg_the_third as ffmpeg;
pub use encoder_thread::*;