1use std::collections::HashMap;
6use std::sync::atomic::{AtomicUsize, Ordering};
7use std::sync::mpsc::{self, Sender};
8use std::sync::{Arc, Mutex, Weak};
9use std::thread;
10
11use log::{debug, warn};
12use mime::Mime;
13use servo_media::player::StreamType;
14use servo_media::{
15 Backend, BackendInit, BackendMsg, ClientContextId, MediaInstance, MediaInstanceError,
16 SupportsMediaType,
17};
18
19use crate::player::OhosAvPlayer;
20use crate::registry_scanner::OHOS_REGISTRY_SCANNER;
21mod ohos_media;
22mod player;
23mod registry_scanner;
24
25type MediaInstanceMap = HashMap<ClientContextId, Vec<(usize, Weak<Mutex<dyn MediaInstance>>)>>;
26
27pub struct OhosBackend {
28 instances: Arc<Mutex<MediaInstanceMap>>,
29 next_instance_id: AtomicUsize,
30 backend_chan: Arc<Mutex<Sender<BackendMsg>>>,
31}
32
33impl OhosBackend {
34 fn media_instance_action(
35 &self,
36 id: &ClientContextId,
37 cb: &dyn Fn(&dyn MediaInstance) -> Result<(), MediaInstanceError>,
38 ) {
39 let mut instances = self.instances.lock().unwrap();
40 match instances.get_mut(id) {
41 Some(vec) => vec.retain(|(_, weak)| {
42 if let Some(instance) = weak.upgrade() {
43 if cb(&*(instance.lock().unwrap())).is_err() {
44 warn!("Error executing media instance action");
45 }
46 true
47 } else {
48 false
49 }
50 }),
51 None => {
52 warn!("Trying to exec media action on an unknown client context");
53 },
54 }
55 }
56}
57
58impl BackendInit for OhosBackend {
59 fn init() -> Box<dyn Backend> {
60 let instances: Arc<Mutex<MediaInstanceMap>> = Arc::new(Mutex::new(HashMap::new()));
61
62 let instances_ = instances.clone();
63 let (backend_chan, recvr) = mpsc::channel();
64 thread::Builder::new()
65 .name("OhosBackend ShutdownThread".to_owned())
66 .spawn(move || {
67 match recvr.recv().unwrap() {
68 BackendMsg::Shutdown {
69 context,
70 id,
71 tx_ack,
72 } => {
73 let mut map = instances_.lock().unwrap();
74 if let Some(vec) = map.get_mut(&context) {
75 vec.retain(|m| m.0 != id);
76 if vec.is_empty() {
77 map.remove(&context);
78 }
79 }
80 let _ = tx_ack.send(());
81 },
82 };
83 })
84 .unwrap();
85 Box::new(OhosBackend {
86 next_instance_id: AtomicUsize::new(0),
87 instances,
88 backend_chan: Arc::new(Mutex::new(backend_chan)),
89 })
90 }
91}
92
93impl Backend for OhosBackend {
97 fn create_player(
98 &self,
99 context_id: &servo_media::ClientContextId,
100 stream_type: servo_media_player::StreamType,
101 sender: servo_media_player::ipc_channel::ipc::IpcSender<servo_media_player::PlayerEvent>,
102 video_renderer: Option<
103 std::sync::Arc<std::sync::Mutex<dyn servo_media_player::video::VideoFrameRenderer>>,
104 >,
105 audio_renderer: Option<
106 std::sync::Arc<std::sync::Mutex<dyn servo_media_player::audio::AudioRenderer>>,
107 >,
108 _gl_context: Box<dyn servo_media_player::context::PlayerGLContext>,
109 ) -> std::sync::Arc<std::sync::Mutex<dyn servo_media_player::Player>> {
110 match stream_type {
112 StreamType::Stream => {
113 todo!("Stream Type currently not supported!")
114 },
115 StreamType::Seekable => (),
116 }
117
118 if let Some(_audio_renderer) = audio_renderer {
119 warn!("Audio Rendering Currently Not Supported!");
120 }
121
122 let player_id = self.next_instance_id.fetch_add(1, Ordering::Relaxed);
123 debug!("Creating Player in OhosBackend");
124 let mut player = OhosAvPlayer::new(
125 player_id,
126 *context_id,
127 sender,
128 video_renderer,
129 self.backend_chan.clone(),
130 );
131
132 player.setup_info_event();
133 player.setup_data_source();
134 Arc::new(Mutex::new(player))
135 }
136
137 fn create_audiostream(&self) -> servo_media_streams::MediaStreamId {
138 todo!()
139 }
140
141 fn create_videostream(&self) -> servo_media_streams::MediaStreamId {
142 todo!()
143 }
144
145 fn create_stream_output(&self) -> Box<dyn servo_media_streams::MediaOutput> {
146 todo!()
147 }
148
149 fn create_stream_and_socket(
150 &self,
151 _ty: servo_media_streams::MediaStreamType,
152 ) -> (
153 Box<dyn servo_media_streams::MediaSocket>,
154 servo_media_streams::MediaStreamId,
155 ) {
156 todo!()
157 }
158
159 fn create_audioinput_stream(
160 &self,
161 _set: servo_media_streams::capture::MediaTrackConstraintSet,
162 ) -> Option<servo_media_streams::MediaStreamId> {
163 todo!()
164 }
165
166 fn create_videoinput_stream(
167 &self,
168 _set: servo_media_streams::capture::MediaTrackConstraintSet,
169 ) -> Option<servo_media_streams::MediaStreamId> {
170 todo!()
171 }
172
173 fn create_audio_context(
174 &self,
175 _id: &servo_media::ClientContextId,
176 _options: servo_media_audio::context::AudioContextOptions,
177 ) -> Result<
178 std::sync::Arc<std::sync::Mutex<servo_media_audio::context::AudioContext>>,
179 servo_media_audio::sink::AudioSinkError,
180 > {
181 todo!()
182 }
183
184 fn create_webrtc(
185 &self,
186 _signaller: Box<dyn servo_media_webrtc::WebRtcSignaller>,
187 ) -> servo_media_webrtc::WebRtcController {
188 todo!()
189 }
190
191 fn can_play_type(&self, media_type: &str) -> servo_media::SupportsMediaType {
192 if let Ok(mime) = media_type.parse::<Mime>() {
193 let mime_type = mime.type_().as_str().to_owned() + "/" + mime.subtype().as_str();
194 let codecs = match mime.get_param("codecs") {
195 Some(codecs) => codecs
196 .as_str()
197 .split(',')
198 .map(|codec| codec.trim())
199 .collect(),
200 None => vec![],
201 };
202
203 if OHOS_REGISTRY_SCANNER.are_mime_and_codecs_supported(&mime_type, &codecs) {
204 if codecs.is_empty() {
205 return SupportsMediaType::Maybe;
206 }
207 return SupportsMediaType::Probably;
208 }
209 }
210 SupportsMediaType::No
211 }
212
213 fn get_device_monitor(
214 &self,
215 ) -> Box<dyn servo_media_streams::device_monitor::MediaDeviceMonitor> {
216 todo!()
217 }
218
219 fn mute(&self, id: &ClientContextId, val: bool) {
220 self.media_instance_action(
221 id,
222 &(move |instance: &dyn MediaInstance| instance.mute(val)),
223 );
224 }
225
226 fn resume(&self, id: &ClientContextId) {
227 self.media_instance_action(id, &(move |instance: &dyn MediaInstance| instance.resume()));
228 }
229
230 fn suspend(&self, id: &ClientContextId) {
231 self.media_instance_action(
232 id,
233 &(move |instance: &dyn MediaInstance| instance.suspend()),
234 );
235 }
236}