libobs_wrapper\encoders/
video.rs1use libobs::{obs_encoder, video_output};
2use std::{ptr, sync::Arc};
3
4use crate::{
5 data::ObsData,
6 impl_obs_drop, run_with_obs,
7 runtime::ObsRuntime,
8 unsafe_send::Sendable,
9 utils::{ObsError, ObsString, VideoEncoderInfo},
10};
11
12#[derive(Debug)]
13#[allow(dead_code)]
14pub struct ObsVideoEncoder {
15 pub(crate) encoder: Sendable<*mut obs_encoder>,
16 pub(crate) id: ObsString,
17 pub(crate) name: ObsString,
18 pub(crate) settings: Option<ObsData>,
19 pub(crate) hotkey_data: Option<ObsData>,
20 pub(crate) runtime: ObsRuntime,
21}
22
23impl ObsVideoEncoder {
24 pub fn new_from_info(
26 info: VideoEncoderInfo,
27 runtime: ObsRuntime,
28 ) -> Result<Arc<Self>, ObsError> {
29 let settings_ptr = match &info.settings {
30 Some(x) => x.as_ptr(),
31 None => Sendable(ptr::null_mut()),
32 };
33
34 let hotkey_data_ptr = match &info.hotkey_data {
35 Some(x) => x.as_ptr(),
36 None => Sendable(ptr::null_mut()),
37 };
38
39 let id_ptr = info.id.as_ptr();
40 let name_ptr = info.name.as_ptr();
41 let encoder = run_with_obs!(
42 runtime,
43 (id_ptr, name_ptr, hotkey_data_ptr, settings_ptr),
44 move || unsafe {
45 let ptr = libobs::obs_video_encoder_create(
46 id_ptr,
47 name_ptr,
48 settings_ptr,
49 hotkey_data_ptr,
50 );
51 Sendable(ptr)
52 }
53 )?;
54
55 if encoder.0.is_null() {
56 return Err(ObsError::NullPointer);
57 }
58
59 Ok(Arc::new(Self {
60 encoder,
61 id: info.id,
62 name: info.name,
63 settings: info.settings,
64 hotkey_data: info.hotkey_data,
65 runtime,
66 }))
67 }
68
69 pub fn as_ptr(&self) -> Sendable<*mut obs_encoder> {
70 self.encoder.clone()
71 }
72
73 pub fn set_video_context(
75 &mut self,
76 handler: Sendable<*mut video_output>,
77 ) -> Result<(), ObsError> {
78 let self_ptr = self.as_ptr();
79 run_with_obs!(self.runtime, (handler, self_ptr), move || unsafe {
80 libobs::obs_encoder_set_video(self_ptr, handler);
81 })
82 }
83
84 pub fn is_active(&self) -> Result<bool, ObsError> {
85 let encoder_ptr = self.as_ptr();
86
87 run_with_obs!(self.runtime, (encoder_ptr), move || unsafe {
88 libobs::obs_encoder_active(encoder_ptr)
89 })
90 }
91
92 pub fn update_settings(&mut self, settings: &ObsData) -> Result<(), ObsError> {
93 let encoder_ptr = self.as_ptr();
94 if self.is_active()? {
95 return Err(ObsError::EncoderActive);
96 }
97
98 let settings_ptr = settings.as_ptr();
99
100 run_with_obs!(self.runtime, (encoder_ptr, settings_ptr), move || unsafe {
101 libobs::obs_encoder_update(encoder_ptr, settings_ptr);
102 })
103 }
104}
105
106impl_obs_drop!(ObsVideoEncoder, (encoder), move || unsafe {
107 libobs::obs_encoder_release(encoder);
108});