Skip to content

Commit a57b0e6

Browse files
rayguo17jdm
andauthored
initial stub for ohos backend (#444)
* initial stub for ohos backend Signed-off-by: rayguo17 <rayguo17@gmail.com> * Update backends/ohos/lib.rs Co-authored-by: Josh Matthews <josh@joshmatthews.net> Signed-off-by: TIN TUN AUNG <62133983+rayguo17@users.noreply.github.com> --------- Signed-off-by: rayguo17 <rayguo17@gmail.com> Signed-off-by: TIN TUN AUNG <62133983+rayguo17@users.noreply.github.com> Co-authored-by: Josh Matthews <josh@joshmatthews.net>
1 parent 4f36494 commit a57b0e6

File tree

3 files changed

+327
-0
lines changed

3 files changed

+327
-0
lines changed

backends/ohos/Cargo.toml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[package]
2+
name = "servo-media-ohos"
3+
version = "0.0.1"
4+
authors = ["The Servo Project Developers"]
5+
edition = "2021"
6+
license = "MPL-2.0"
7+
8+
[lib]
9+
name = "servo_media_ohos"
10+
path = "lib.rs"
11+
12+
[dependencies]
13+
servo-media = { path = "../../servo-media" }
14+
servo-media-audio = { path = "../../audio" }
15+
servo-media-player = { path = "../../player" }
16+
servo-media-streams = { path = "../../streams" }
17+
servo-media-traits = { path = "../../traits" }
18+
servo-media-webrtc = { path = "../../webrtc" }
19+
log = "0.4"
20+
ohos-media-sys = { version = "0.0.4" ,features = ["api-13"] }

backends/ohos/lib.rs

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
use std::{
2+
collections::HashMap,
3+
sync::{
4+
atomic::AtomicUsize,
5+
mpsc::{self, Sender},
6+
Arc, Mutex, Weak,
7+
},
8+
thread,
9+
};
10+
11+
use log::warn;
12+
use mime::Mime;
13+
use servo_media::{
14+
Backend, BackendInit, BackendMsg, ClientContextId, MediaInstance, SupportsMediaType,
15+
};
16+
17+
use crate::{player::OhosAVPlayer, registry_scanner::OHOS_REGISTRY_SCANNER};
18+
mod player;
19+
mod registry_scanner;
20+
21+
pub struct OhosBackend {
22+
instances: Arc<Mutex<HashMap<ClientContextId, Vec<(usize, Weak<Mutex<dyn MediaInstance>>)>>>>,
23+
next_instance_id: AtomicUsize,
24+
backend_chan: Arc<Mutex<Sender<BackendMsg>>>,
25+
}
26+
27+
impl OhosBackend {
28+
fn media_instance_action(
29+
&self,
30+
id: &ClientContextId,
31+
cb: &dyn Fn(&dyn MediaInstance) -> Result<(), ()>,
32+
) {
33+
let mut instances = self.instances.lock().unwrap();
34+
match instances.get_mut(id) {
35+
Some(vec) => vec.retain(|(_, weak)| {
36+
if let Some(instance) = weak.upgrade() {
37+
if cb(&*(instance.lock().unwrap())).is_err() {
38+
warn!("Error executing media instance action");
39+
}
40+
true
41+
} else {
42+
false
43+
}
44+
}),
45+
None => {
46+
warn!("Trying to exec media action on an unknown client context");
47+
}
48+
}
49+
}
50+
}
51+
52+
impl BackendInit for OhosBackend {
53+
fn init() -> Box<dyn Backend> {
54+
let instances: Arc<
55+
Mutex<HashMap<ClientContextId, Vec<(usize, Weak<Mutex<dyn MediaInstance>>)>>>,
56+
> = Arc::new(Mutex::new(HashMap::new()));
57+
58+
let instances_ = instances.clone();
59+
let (backend_chan, recvr) = mpsc::channel();
60+
thread::Builder::new()
61+
.name("OhosBackend ShutdownThread".to_owned())
62+
.spawn(move || {
63+
match recvr.recv().unwrap() {
64+
BackendMsg::Shutdown(context_id, instance_id) => {
65+
let mut instances_ = instances_.lock().unwrap();
66+
if let Some(vec) = instances_.get_mut(&context_id) {
67+
vec.retain(|m| m.0 != instance_id);
68+
if vec.is_empty() {
69+
instances_.remove(&context_id);
70+
}
71+
}
72+
}
73+
};
74+
})
75+
.unwrap();
76+
return Box::new(OhosBackend {
77+
next_instance_id: AtomicUsize::new(0),
78+
instances,
79+
backend_chan: Arc::new(Mutex::new(backend_chan)),
80+
});
81+
}
82+
}
83+
84+
//https://developer.huawei.com/consumer/en/doc/harmonyos-guides/obtain-supported-codecs
85+
//https://developer.huawei.com/consumer/en/doc/harmonyos-guides/media-kit-intro-V5#supported-formats-and-protocols
86+
87+
impl Backend for OhosBackend {
88+
fn create_player(
89+
&self,
90+
id: &servo_media::ClientContextId,
91+
stream_type: servo_media_player::StreamType,
92+
sender: servo_media_player::ipc_channel::ipc::IpcSender<servo_media_player::PlayerEvent>,
93+
video_renderer: Option<
94+
std::sync::Arc<std::sync::Mutex<dyn servo_media_player::video::VideoFrameRenderer>>,
95+
>,
96+
audio_renderer: Option<
97+
std::sync::Arc<std::sync::Mutex<dyn servo_media_player::audio::AudioRenderer>>,
98+
>,
99+
gl_context: Box<dyn servo_media_player::context::PlayerGLContext>,
100+
) -> std::sync::Arc<std::sync::Mutex<dyn servo_media_player::Player>> {
101+
Arc::new(Mutex::new(OhosAVPlayer::new()))
102+
}
103+
104+
fn create_audiostream(&self) -> servo_media_streams::MediaStreamId {
105+
todo!()
106+
}
107+
108+
fn create_videostream(&self) -> servo_media_streams::MediaStreamId {
109+
todo!()
110+
}
111+
112+
fn create_stream_output(&self) -> Box<dyn servo_media_streams::MediaOutput> {
113+
todo!()
114+
}
115+
116+
fn create_stream_and_socket(
117+
&self,
118+
ty: servo_media_streams::MediaStreamType,
119+
) -> (
120+
Box<dyn servo_media_streams::MediaSocket>,
121+
servo_media_streams::MediaStreamId,
122+
) {
123+
todo!()
124+
}
125+
126+
fn create_audioinput_stream(
127+
&self,
128+
set: servo_media_streams::capture::MediaTrackConstraintSet,
129+
) -> Option<servo_media_streams::MediaStreamId> {
130+
todo!()
131+
}
132+
133+
fn create_videoinput_stream(
134+
&self,
135+
set: servo_media_streams::capture::MediaTrackConstraintSet,
136+
) -> Option<servo_media_streams::MediaStreamId> {
137+
todo!()
138+
}
139+
140+
fn create_audio_context(
141+
&self,
142+
id: &servo_media::ClientContextId,
143+
options: servo_media_audio::context::AudioContextOptions,
144+
) -> Result<
145+
std::sync::Arc<std::sync::Mutex<servo_media_audio::context::AudioContext>>,
146+
servo_media_audio::sink::AudioSinkError,
147+
> {
148+
todo!()
149+
}
150+
151+
fn create_webrtc(
152+
&self,
153+
signaller: Box<dyn servo_media_webrtc::WebRtcSignaller>,
154+
) -> servo_media_webrtc::WebRtcController {
155+
todo!()
156+
}
157+
158+
fn can_play_type(&self, media_type: &str) -> servo_media::SupportsMediaType {
159+
if let Ok(mime) = media_type.parse::<Mime>() {
160+
let mime_type = mime.type_().as_str().to_owned() + "/" + mime.subtype().as_str();
161+
let codecs = match mime.get_param("codecs") {
162+
Some(codecs) => codecs
163+
.as_str()
164+
.split(',')
165+
.map(|codec| codec.trim())
166+
.collect(),
167+
None => vec![],
168+
};
169+
if OHOS_REGISTRY_SCANNER.contains(mime_type.as_str()) {
170+
if codecs.is_empty() {
171+
return SupportsMediaType::Maybe;
172+
}
173+
}
174+
}
175+
SupportsMediaType::No
176+
}
177+
178+
fn get_device_monitor(
179+
&self,
180+
) -> Box<dyn servo_media_streams::device_monitor::MediaDeviceMonitor> {
181+
todo!()
182+
}
183+
184+
fn mute(&self, id: &ClientContextId, val: bool) {
185+
self.media_instance_action(
186+
id,
187+
&(move |instance: &dyn MediaInstance| instance.mute(val)),
188+
);
189+
}
190+
191+
fn resume(&self, id: &ClientContextId) {
192+
self.media_instance_action(id, &(move |instance: &dyn MediaInstance| instance.resume()));
193+
}
194+
195+
fn suspend(&self, id: &ClientContextId) {
196+
self.media_instance_action(
197+
id,
198+
&(move |instance: &dyn MediaInstance| instance.suspend()),
199+
);
200+
}
201+
}

backends/ohos/player.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
use servo_media::MediaInstance;
2+
use servo_media_player::Player;
3+
4+
pub struct OhosAVPlayer {}
5+
6+
impl OhosAVPlayer {
7+
pub fn new() -> OhosAVPlayer {
8+
OhosAVPlayer {}
9+
}
10+
}
11+
12+
impl MediaInstance for OhosAVPlayer {
13+
fn get_id(&self) -> usize {
14+
todo!()
15+
}
16+
17+
fn mute(&self, val: bool) -> Result<(), ()> {
18+
todo!()
19+
}
20+
21+
fn suspend(&self) -> Result<(), ()> {
22+
todo!()
23+
}
24+
25+
fn resume(&self) -> Result<(), ()> {
26+
todo!()
27+
}
28+
}
29+
30+
impl Player for OhosAVPlayer {
31+
fn play(&self) -> Result<(), servo_media_player::PlayerError> {
32+
todo!()
33+
}
34+
35+
fn pause(&self) -> Result<(), servo_media_player::PlayerError> {
36+
todo!()
37+
}
38+
39+
fn stop(&self) -> Result<(), servo_media_player::PlayerError> {
40+
todo!()
41+
}
42+
43+
fn seek(&self, time: f64) -> Result<(), servo_media_player::PlayerError> {
44+
todo!()
45+
}
46+
47+
fn seekable(&self) -> Result<Vec<std::ops::Range<f64>>, servo_media_player::PlayerError> {
48+
todo!()
49+
}
50+
51+
fn set_mute(&self, val: bool) -> Result<(), servo_media_player::PlayerError> {
52+
todo!()
53+
}
54+
55+
fn set_volume(&self, value: f64) -> Result<(), servo_media_player::PlayerError> {
56+
todo!()
57+
}
58+
59+
fn set_input_size(&self, size: u64) -> Result<(), servo_media_player::PlayerError> {
60+
todo!()
61+
}
62+
63+
fn set_rate(&self, rate: f64) -> Result<(), servo_media_player::PlayerError> {
64+
todo!()
65+
}
66+
67+
fn push_data(&self, data: Vec<u8>) -> Result<(), servo_media_player::PlayerError> {
68+
todo!()
69+
}
70+
71+
fn end_of_stream(&self) -> Result<(), servo_media_player::PlayerError> {
72+
todo!()
73+
}
74+
75+
fn buffered(&self) -> Result<Vec<std::ops::Range<f64>>, servo_media_player::PlayerError> {
76+
todo!()
77+
}
78+
79+
fn set_stream(
80+
&self,
81+
stream: &servo_media_streams::MediaStreamId,
82+
only_stream: bool,
83+
) -> Result<(), servo_media_player::PlayerError> {
84+
todo!()
85+
}
86+
87+
fn render_use_gl(&self) -> bool {
88+
todo!()
89+
}
90+
91+
fn set_audio_track(
92+
&self,
93+
stream_index: i32,
94+
enabled: bool,
95+
) -> Result<(), servo_media_player::PlayerError> {
96+
todo!()
97+
}
98+
99+
fn set_video_track(
100+
&self,
101+
stream_index: i32,
102+
enabled: bool,
103+
) -> Result<(), servo_media_player::PlayerError> {
104+
todo!()
105+
}
106+
}

0 commit comments

Comments
 (0)