use paste::item;
use std::marker::PhantomData;
use obs_sys::{obs_output_info, OBS_OUTPUT_AUDIO, OBS_OUTPUT_VIDEO};
pub mod context;
mod ffi;
pub mod traits;
pub use context::*;
pub use traits::*;
pub struct OutputInfo {
info: Box<obs_output_info>,
}
impl OutputInfo {
pub unsafe fn into_raw(self) -> *mut obs_output_info {
Box::into_raw(self.info)
}
}
impl AsRef<obs_output_info> for OutputInfo {
fn as_ref(&self) -> &obs_output_info {
self.info.as_ref()
}
}
pub struct OutputInfoBuilder<D: Outputable> {
__data: PhantomData<D>,
info: obs_output_info,
}
impl<D: Outputable> OutputInfoBuilder<D> {
pub(crate) fn new() -> Self {
Self {
__data: PhantomData,
info: obs_output_info {
id: D::get_id().as_ptr(),
create: Some(ffi::create::<D>),
destroy: Some(ffi::destroy::<D>),
start: Some(ffi::start::<D>),
stop: Some(ffi::stop::<D>),
type_data: std::ptr::null_mut(),
..Default::default()
},
}
}
pub fn build(mut self) -> OutputInfo {
if self.info.raw_video.is_some() {
self.info.flags |= OBS_OUTPUT_VIDEO;
}
if self.info.raw_audio.is_some() || self.info.raw_audio2.is_some() {
self.info.flags |= OBS_OUTPUT_AUDIO;
}
OutputInfo {
info: Box::new(self.info),
}
}
}
macro_rules! impl_output_builder {
($($f:ident => $t:ident)*) => ($(
item! {
impl<D: Outputable + [<$t>]> OutputInfoBuilder<D> {
pub fn [<enable_$f>](mut self) -> Self {
self.info.[<$f>] = Some(ffi::[<$f>]::<D>);
self
}
}
}
)*)
}
impl_output_builder! {
get_name => GetNameOutput
raw_video => RawVideoOutput
raw_audio => RawAudioOutput
raw_audio2 => RawAudio2Output
encoded_packet => EncodedPacketOutput
update => UpdateOutput
get_defaults => GetDefaultsOutput
get_properties => GetPropertiesOutput
get_total_bytes => GetTotalBytesOutput
get_dropped_frames => GetDroppedFramesOutput
get_congestion => GetCongestionOutput
get_connect_time_ms => GetConnectTimeMsOutput
}