waycap_rs/encoders/
video.rs1use 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}