waycap_rs/encoders/
dma_buf_encoder.rs

1use crate::{
2    encoders::video::{PipewireSPA, StartVideoEncoder},
3    types::{error::WaycapError, video_frame::RawVideoFrame},
4    waycap_egl::{EglContext, GpuVendor},
5    NvencEncoder, VaapiEncoder, VideoEncoder,
6};
7use crossbeam::channel::Receiver;
8
9use crate::types::error::Result;
10
11/// "Encoder" which provides the raw DMA-Buf pointers directly.
12///
13/// Allows for using the image directly on the GPU, which makes it far more performant when, for example, trying to display it to a user.
14/// The implementations of [`crate::NvencEncoder`] and [`crate::VaapiEncoder`] show how a [`RawVideoFrame`] can be used.
15#[derive(Default)]
16pub struct DmaBufEncoder {
17    receiver: Option<Receiver<RawVideoFrame>>,
18}
19
20impl StartVideoEncoder for DmaBufEncoder {
21    fn start_processing(
22        capture: &mut crate::Capture<Self>,
23        input: Receiver<RawVideoFrame>,
24    ) -> Result<()> {
25        capture
26            .video_encoder
27            .as_mut()
28            .expect("start_processing should be called after Capture.video_encoder is set")
29            .lock()
30            .unwrap()
31            .receiver = Some(input);
32        Ok(())
33    }
34}
35impl VideoEncoder for DmaBufEncoder {
36    type Output = RawVideoFrame;
37
38    fn reset(&mut self) -> crate::types::error::Result<()> {
39        Ok(())
40    }
41
42    fn output(&mut self) -> Option<Receiver<Self::Output>> {
43        self.receiver.clone()
44    }
45
46    fn drop_processor(&mut self) {}
47
48    fn drain(&mut self) -> crate::types::error::Result<()> {
49        Ok(())
50    }
51
52    fn get_encoder(&self) -> &Option<ffmpeg_next::codec::encoder::Video> {
53        &None
54    }
55}
56
57impl PipewireSPA for DmaBufEncoder {
58    fn get_spa_definition() -> Result<pipewire::spa::pod::Object> {
59        let dummy_context = EglContext::new(100, 100)?;
60        match dummy_context.get_gpu_vendor() {
61            GpuVendor::NVIDIA => NvencEncoder::get_spa_definition(),
62            GpuVendor::AMD | GpuVendor::INTEL => VaapiEncoder::get_spa_definition(),
63            GpuVendor::UNKNOWN => Err(WaycapError::Init(
64                "Unknown/Unimplemented GPU vendor".to_string(),
65            )),
66        }
67    }
68}