libobs_wrapper\encoders/
property_helper.rs1use std::{collections::HashMap, str::FromStr, sync::Arc};
2
3use duplicate::duplicate_item;
4
5use crate::{
6 context::ObsContext,
7 data::{
8 output::{ObsOutputRef, ObsOutputTrait},
9 properties::{
10 ObsProperty, ObsPropertyObject, ObsPropertyObjectPrivate, _ObsPropertiesDropGuard,
11 property_ptr_to_struct,
12 },
13 ObsData,
14 },
15 run_with_obs,
16 runtime::ObsRuntime,
17 unsafe_send::{Sendable, SmartPointerSendable},
18 utils::{ObjectInfo, ObsError, ObsString},
19};
20
21use super::{
22 audio::ObsAudioEncoder, video::ObsVideoEncoder, ObsAudioEncoderType, ObsVideoEncoderType,
23};
24
25#[duplicate_item(
26 StructName EncoderType;
27 [ObsAudioEncoderBuilder] [ObsAudioEncoderType];
28 [ObsVideoEncoderBuilder] [ObsVideoEncoderType]
29)]
30#[derive(Debug)]
31pub struct StructName {
32 encoder_id: EncoderType,
33 runtime: ObsRuntime,
34 _context: ObsContext,
36 settings: Option<ObsData>,
37 hotkey_data: Option<ObsData>,
38}
39
40#[duplicate_item(
41 StructName EncoderType;
42 [ObsAudioEncoderBuilder] [ObsAudioEncoderType];
43 [ObsVideoEncoderBuilder] [ObsVideoEncoderType]
44)]
45impl StructName {
46 pub fn new(context: ObsContext, encoder_id: &str) -> Self {
47 Self {
48 encoder_id: EncoderType::from_str(encoder_id).unwrap(),
49 runtime: context.runtime().clone(),
50 _context: context,
51 settings: None,
52 hotkey_data: None,
53 }
54 }
55
56 pub fn get_encoder_id(&self) -> &EncoderType {
57 &self.encoder_id
58 }
59
60 pub fn set_settings(&mut self, settings: ObsData) -> &mut Self {
61 self.settings = Some(settings);
62 self
63 }
64
65 pub fn set_hotkey_data(&mut self, hotkey_data: ObsData) -> &mut Self {
66 self.hotkey_data = Some(hotkey_data);
67 self
68 }
69
70 pub fn get_settings(&self) -> Option<&ObsData> {
71 self.settings.as_ref()
72 }
73
74 pub fn get_hotkey_data(&self) -> Option<&ObsData> {
75 self.hotkey_data.as_ref()
76 }
77
78 pub fn get_settings_mut(&mut self) -> Option<&mut ObsData> {
79 self.settings.as_mut()
80 }
81
82 pub fn get_hotkey_data_mut(&mut self) -> Option<&mut ObsData> {
83 self.hotkey_data.as_mut()
84 }
85}
86
87impl ObsAudioEncoderBuilder {
88 pub fn apply_to_context(
89 self,
90 output: &mut dyn ObsOutputTrait,
91 name: &str,
92 settings: Option<ObsData>,
93 hotkey_data: Option<ObsData>,
94 mixer_idx: usize,
95 ) -> Result<Arc<ObsAudioEncoder>, ObsError> {
96 let e_id: ObsString = self.encoder_id.into();
97 let info = ObjectInfo::new(e_id, ObsString::new(name), settings, hotkey_data);
98
99 output.create_and_set_audio_encoder(info, mixer_idx)
100 }
101}
102
103impl ObsVideoEncoderBuilder {
104 pub fn set_to_output(
105 self,
106 output: &mut ObsOutputRef,
107 name: &str,
108 ) -> Result<Arc<ObsVideoEncoder>, ObsError> {
109 let e_id: ObsString = self.encoder_id.into();
110 let info = ObjectInfo::new(e_id, ObsString::new(name), self.settings, self.hotkey_data);
111
112 output.create_and_set_video_encoder(info)
113 }
114}
115
116#[duplicate_item(
117 StructName;
118 [ObsAudioEncoderBuilder];
119 [ObsVideoEncoderBuilder]
120)]
121impl ObsPropertyObject for StructName {
122 fn get_properties(&self) -> Result<HashMap<String, ObsProperty>, ObsError> {
123 let properties_raw = self.get_properties_raw()?;
124 property_ptr_to_struct(properties_raw, self.runtime.clone())
125 }
126}
127
128#[duplicate_item(
129 StructName;
130 [ObsAudioEncoderBuilder];
131 [ObsVideoEncoderBuilder]
132)]
133impl ObsPropertyObjectPrivate for StructName {
134 fn get_properties_raw(
135 &self,
136 ) -> Result<SmartPointerSendable<*mut libobs::obs_properties_t>, ObsError> {
137 let encoder_name: ObsString = self.encoder_id.clone().into();
138
139 let property_ptr = run_with_obs!(self.runtime, (encoder_name), move || {
140 let encoder_name_ptr = encoder_name.as_ptr().0;
141
142 let property_ptr = unsafe {
143 libobs::obs_get_encoder_properties(encoder_name_ptr)
145 };
146
147 if property_ptr.is_null() {
148 Err(ObsError::NullPointer(None))
149 } else {
150 Ok(Sendable(property_ptr))
151 }
152 })??;
153
154 let drop_guard = Arc::new(_ObsPropertiesDropGuard::new(
155 property_ptr.clone(),
156 self.runtime.clone(),
157 ));
158
159 Ok(SmartPointerSendable::new(property_ptr.0, drop_guard))
160 }
161
162 fn get_properties_by_id_raw<T: Into<ObsString> + Sync + Send>(
163 id: T,
164 runtime: ObsRuntime,
165 ) -> Result<SmartPointerSendable<*mut libobs::obs_properties_t>, ObsError> {
166 let id: ObsString = id.into();
167 let ptr = run_with_obs!(runtime, (id), move || {
168 let id_ptr = id.as_ptr();
169
170 let property_ptr = unsafe {
171 libobs::obs_get_encoder_properties(id_ptr.0)
173 };
174
175 if property_ptr.is_null() {
176 Err(ObsError::NullPointer(None))
177 } else {
178 Ok(Sendable(property_ptr))
179 }
180 })??;
181
182 let drop_guard = Arc::new(_ObsPropertiesDropGuard::new(ptr.clone(), runtime.clone()));
183
184 Ok(SmartPointerSendable::new(ptr.0, drop_guard))
185 }
186}