libobs_wrapper\encoders/
video.rs

1use libobs::{
2    obs_encoder, obs_encoder_release, obs_encoder_set_video, obs_video_encoder_create, video_output,
3};
4use std::ptr;
5
6use crate::{
7    data::ObsData,
8    impl_obs_drop, run_with_obs,
9    runtime::ObsRuntime,
10    unsafe_send::Sendable,
11    utils::{ObsError, ObsString},
12};
13
14#[derive(Debug)]
15#[allow(dead_code)]
16pub struct ObsVideoEncoder {
17    pub(crate) encoder: Sendable<*mut obs_encoder>,
18    pub(crate) id: ObsString,
19    pub(crate) name: ObsString,
20    pub(crate) settings: Option<ObsData>,
21    pub(crate) hotkey_data: Option<ObsData>,
22    pub(crate) runtime: ObsRuntime,
23}
24
25impl ObsVideoEncoder {
26    #[cfg_attr(feature="blocking", remove_async_await::remove_async_await)]
27    pub async fn new<T: Into<ObsString> + Sync + Send, K: Into<ObsString> + Sync + Send>(
28        id: T,
29        name: K,
30        settings: Option<ObsData>,
31        hotkey_data: Option<ObsData>,
32        runtime: ObsRuntime,
33    ) -> Result<Self, ObsError> {
34        let id = id.into();
35        let name = name.into();
36
37        let settings_ptr = match &settings {
38            Some(x) => x.as_ptr(),
39            None => Sendable(ptr::null_mut()),
40        };
41
42        let hotkey_data_ptr = match &hotkey_data {
43            Some(x) => x.as_ptr(),
44            None => Sendable(ptr::null_mut()),
45        };
46
47        let id_ptr = id.as_ptr();
48        let name_ptr = name.as_ptr();
49        let encoder = run_with_obs!(
50            runtime,
51            (id_ptr, name_ptr, hotkey_data_ptr, settings_ptr),
52            move || unsafe {
53                let ptr = obs_video_encoder_create(id_ptr, name_ptr, settings_ptr, hotkey_data_ptr);
54                Sendable(ptr)
55            }
56        ).await?;
57
58        if encoder.0 == ptr::null_mut() {
59            return Err(ObsError::NullPointer);
60        }
61
62        Ok(Self {
63            encoder,
64            id,
65            name,
66            settings,
67            hotkey_data,
68            runtime,
69        })
70    }
71
72    pub fn as_ptr(&self) -> Sendable<*mut obs_encoder> {
73        self.encoder.clone()
74    }
75
76    /// This is only needed once for global video context
77    #[cfg_attr(feature="blocking", remove_async_await::remove_async_await)]
78    pub async fn set_video_context(&mut self, handler: Sendable<*mut video_output>) -> Result<(), ObsError> {
79        let self_ptr = self.as_ptr();
80        run_with_obs!(self.runtime, (handler, self_ptr), move || unsafe {
81            Sendable(obs_encoder_set_video(self_ptr, handler));
82        }).await
83    }
84}
85
86impl_obs_drop!(ObsVideoEncoder, (encoder), move || unsafe {
87    obs_encoder_release(encoder);
88});