clean break video code into new module
This commit is contained in:
parent
a6734667de
commit
fa929641e5
4 changed files with 26 additions and 17 deletions
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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"),
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -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
6
server/src/video/mod.rs
Normal 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::*;
|
Loading…
Reference in a new issue