waycap_rs/encoders/
video.rs

1use std::any::Any;
2use std::ffi::CString;
3use std::ptr::null_mut;
4
5use crate::types::error::{Result, WaycapError};
6use crate::types::video_frame::RawVideoFrame;
7use crate::types::{config::QualityPreset, video_frame::EncodedVideoFrame};
8use ffmpeg_next::{self as ffmpeg};
9use ffmpeg::ffi::{av_hwdevice_ctx_create, av_hwframe_ctx_alloc, AVBufferRef};
10use ringbuf::HeapCons;
11
12pub const GOP_SIZE: u32 = 30;
13
14pub trait VideoEncoder: Send {
15    fn new(width: u32, height: u32, quality: QualityPreset) -> Result<Self>
16    where
17        Self: Sized;
18    fn process(&mut self, frame: &RawVideoFrame) -> Result<()>;
19    fn drain(&mut self) -> Result<()>;
20    fn reset(&mut self) -> Result<()>;
21    fn drop_encoder(&mut self);
22    fn get_encoder(&self) -> &Option<ffmpeg::codec::encoder::Video>;
23    fn take_encoded_recv(&mut self) -> Option<HeapCons<EncodedVideoFrame>>;
24
25    fn as_any(&self) -> &dyn Any;
26}
27
28pub fn create_hw_frame_ctx(device: *mut AVBufferRef) -> Result<*mut AVBufferRef> {
29    unsafe {
30        let frame = av_hwframe_ctx_alloc(device);
31
32        if frame.is_null() {
33            return Err(WaycapError::Init(
34                "Could not create hw frame context".to_string(),
35            ));
36        }
37
38        Ok(frame)
39    }
40}
41
42pub fn create_hw_device(device_type: ffmpeg_next::ffi::AVHWDeviceType) -> Result<*mut AVBufferRef> {
43    unsafe {
44        let mut device: *mut AVBufferRef = null_mut();
45        let device_path = CString::new("/dev/dri/renderD128").unwrap();
46        let ret = av_hwdevice_ctx_create(
47            &mut device,
48            device_type,
49            device_path.as_ptr(),
50            null_mut(),
51            0,
52        );
53        if ret < 0 {
54            return Err(WaycapError::Init(format!(
55                "Failed to create hardware device: Error code {}",
56                ret
57            )));
58        }
59
60        Ok(device)
61    }
62}