-
Notifications
You must be signed in to change notification settings - Fork 53
/
lib.rs
123 lines (110 loc) · 4.65 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
pub extern crate servo_media_audio as audio;
pub extern crate servo_media_player as player;
pub extern crate servo_media_streams as streams;
pub extern crate servo_media_traits as traits;
pub extern crate servo_media_webrtc as webrtc;
pub use traits::*;
use std::ops::Deref;
use std::sync::{Arc, Mutex, Once};
use audio::context::{AudioContext, AudioContextOptions};
use player::audio::AudioRenderer;
use player::context::PlayerGLContext;
use player::ipc_channel::ipc::IpcSender;
use player::video::VideoFrameRenderer;
use player::{Player, PlayerEvent, StreamType};
use streams::capture::MediaTrackConstraintSet;
use streams::device_monitor::MediaDeviceMonitor;
use streams::registry::MediaStreamId;
use streams::{MediaOutput, MediaSocket, MediaStreamType};
use webrtc::{WebRtcController, WebRtcSignaller};
pub struct ServoMedia(Box<dyn Backend>);
static INITIALIZER: Once = Once::new();
static mut INSTANCE: *mut Mutex<Option<Arc<ServoMedia>>> = std::ptr::null_mut();
pub trait BackendInit {
fn init() -> Box<dyn Backend>;
}
pub trait Backend: Send + Sync {
fn create_player(
&self,
id: &ClientContextId,
stream_type: StreamType,
sender: IpcSender<PlayerEvent>,
video_renderer: Option<Arc<Mutex<dyn VideoFrameRenderer>>>,
audio_renderer: Option<Arc<Mutex<dyn AudioRenderer>>>,
gl_context: Box<dyn PlayerGLContext>,
) -> Arc<Mutex<dyn Player>>;
fn create_audiostream(&self) -> MediaStreamId;
fn create_videostream(&self) -> MediaStreamId;
fn create_stream_output(&self) -> Box<dyn MediaOutput>;
fn create_stream_and_socket(
&self,
ty: MediaStreamType,
) -> (Box<dyn MediaSocket>, MediaStreamId);
fn create_audioinput_stream(&self, set: MediaTrackConstraintSet) -> Option<MediaStreamId>;
fn create_videoinput_stream(&self, set: MediaTrackConstraintSet) -> Option<MediaStreamId>;
fn create_audio_context(
&self,
id: &ClientContextId,
options: AudioContextOptions,
) -> Arc<Mutex<AudioContext>>;
fn create_webrtc(&self, signaller: Box<dyn WebRtcSignaller>) -> WebRtcController;
fn can_play_type(&self, media_type: &str) -> SupportsMediaType;
fn set_capture_mocking(&self, _mock: bool) {}
/// Allow muting/unmuting the media instances associated with the given client context identifier.
/// Backend implementations are responsible for keeping a match between client contexts
/// and the media instances created for these contexts.
/// The client context identifier is currently an abstraction of Servo's PipelineId.
fn mute(&self, _id: &ClientContextId, _val: bool) {}
/// Allow suspending the activity of all media instances associated with the given client
/// context identifier.
/// Note that suspending does not involve releasing any resources, so media playback can
/// be restarted.
/// Backend implementations are responsible for keeping a match between client contexts
/// and the media instances created for these contexts.
/// The client context identifier is currently an abstraction of Servo's PipelineId.
fn suspend(&self, _id: &ClientContextId) {}
/// Allow resuming the activity of all the media instances associated with the given client
/// context identifier.
/// Backend implementations are responsible for keeping a match between client contexts
/// and the media instances created for these contexts.
/// The client context identifier is currently an abstraction of Servo's PipelineId.
fn resume(&self, _id: &ClientContextId) {}
fn get_device_monitor(&self) -> Box<dyn MediaDeviceMonitor>;
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SupportsMediaType {
Maybe,
No,
Probably,
}
impl ServoMedia {
pub fn init<B: BackendInit>() {
INITIALIZER.call_once(|| unsafe {
let instance = Arc::new(ServoMedia(B::init()));
INSTANCE = Box::into_raw(Box::new(Mutex::new(Some(instance))));
})
}
pub fn init_with_backend(backend: Box<dyn Backend>) {
INITIALIZER.call_once(|| unsafe {
let instance = Arc::new(ServoMedia(backend));
INSTANCE = Box::into_raw(Box::new(Mutex::new(Some(instance))));
})
}
pub fn get() -> Result<Arc<ServoMedia>, ()> {
if INITIALIZER.is_completed() {
let instance = unsafe { &*INSTANCE }.lock().unwrap();
match *instance {
Some(ref instance) => Ok(instance.clone()),
None => Err(()),
}
} else {
Err(())
}
}
}
impl Deref for ServoMedia {
type Target = dyn Backend + 'static;
fn deref(&self) -> &(dyn Backend + 'static) {
&*self.0
}
}