aboutsummaryrefslogtreecommitdiff
path: root/libdino/src
diff options
context:
space:
mode:
authorMarvin W <git@larma.de>2022-02-12 14:35:44 +0100
committerMarvin W <git@larma.de>2022-02-12 14:36:26 +0100
commit369d0c79d7272b4059c39ecedb10a62121bfbe56 (patch)
tree6ae87a1fd71b68dd8eff163c2b01dc5903f58ee0 /libdino/src
parent0f5f57888e2e237549b1bc7002770ec102ff0e6b (diff)
downloaddino-369d0c79d7272b4059c39ecedb10a62121bfbe56.tar.gz
dino-369d0c79d7272b4059c39ecedb10a62121bfbe56.zip
Calls: Fix device selector for multi-party calls, allow picking device before call started
Diffstat (limited to 'libdino/src')
-rw-r--r--libdino/src/plugin/interfaces.vala14
-rw-r--r--libdino/src/service/call_state.vala59
2 files changed, 59 insertions, 14 deletions
diff --git a/libdino/src/plugin/interfaces.vala b/libdino/src/plugin/interfaces.vala
index b6955a6b..c7c2c375 100644
--- a/libdino/src/plugin/interfaces.vala
+++ b/libdino/src/plugin/interfaces.vala
@@ -103,16 +103,17 @@ public abstract interface VideoCallPlugin : Object {
// Devices
public signal void devices_changed(string media, bool incoming);
public abstract Gee.List<MediaDevice> get_devices(string media, bool incoming);
- public abstract MediaDevice? get_device(Xmpp.Xep.JingleRtp.Stream stream, bool incoming);
- public abstract void set_pause(Xmpp.Xep.JingleRtp.Stream stream, bool pause);
- public abstract void set_device(Xmpp.Xep.JingleRtp.Stream stream, MediaDevice? device);
+ public abstract MediaDevice? get_preferred_device(string media, bool incoming);
+ public abstract MediaDevice? get_device(Xmpp.Xep.JingleRtp.Stream? stream, bool incoming);
+ public abstract void set_pause(Xmpp.Xep.JingleRtp.Stream? stream, bool pause);
+ public abstract void set_device(Xmpp.Xep.JingleRtp.Stream? stream, MediaDevice? device);
public abstract void dump_dot();
}
public abstract interface VideoCallWidget : Object {
public signal void resolution_changed(uint width, uint height);
- public abstract void display_stream(Xmpp.Xep.JingleRtp.Stream stream, Jid jid);
+ public abstract void display_stream(Xmpp.Xep.JingleRtp.Stream? stream, Jid jid);
public abstract void display_device(MediaDevice device);
public abstract void detach();
}
@@ -120,7 +121,10 @@ public abstract interface VideoCallWidget : Object {
public abstract interface MediaDevice : Object {
public abstract string id { owned get; }
public abstract string display_name { owned get; }
- public abstract string detail_name { owned get; }
+ public abstract string? detail_name { owned get; }
+
+ public abstract string? media { owned get; }
+ public abstract bool incoming { get; }
}
public abstract interface NotificationPopulator : Object {
diff --git a/libdino/src/service/call_state.vala b/libdino/src/service/call_state.vala
index c403fc6a..c1f0522d 100644
--- a/libdino/src/service/call_state.vala
+++ b/libdino/src/service/call_state.vala
@@ -26,6 +26,10 @@ public class Dino.CallState : Object {
public HashMap<Jid, PeerState> peers = new HashMap<Jid, PeerState>(Jid.hash_func, Jid.equals_func);
+ private Plugins.MediaDevice selected_microphone_device;
+ private Plugins.MediaDevice selected_speaker_device;
+ private Plugins.MediaDevice selected_video_device;
+
public CallState(Call call, StreamInteractor stream_interactor) {
this.call = call;
this.stream_interactor = stream_interactor;
@@ -80,6 +84,15 @@ public class Dino.CallState : Object {
peer_joined(peer.jid, peer);
}
+ internal void on_peer_stream_created(PeerState peer, string media) {
+ if (media == "audio") {
+ call_plugin.set_device(peer.get_audio_stream(), get_microphone_device());
+ call_plugin.set_device(peer.get_audio_stream(), get_speaker_device());
+ } else if (media == "video") {
+ call_plugin.set_device(peer.get_video_stream(), get_video_device());
+ }
+ }
+
public void accept() {
accepted = true;
call.state = Call.State.ESTABLISHING;
@@ -206,30 +219,57 @@ public class Dino.CallState : Object {
}
public Plugins.MediaDevice? get_microphone_device() {
- if (peers.is_empty) return null;
- var audio_stream = peers.values.to_array()[0].get_audio_stream();
- return call_plugin.get_device(audio_stream, false);
+ if (selected_microphone_device == null) {
+ if (!peers.is_empty) {
+ var audio_stream = peers.values.to_array()[0].get_audio_stream();
+ selected_microphone_device = call_plugin.get_device(audio_stream, false);
+ }
+ if (selected_microphone_device == null) {
+ selected_microphone_device = call_plugin.get_preferred_device("audio", false);
+ }
+ }
+ return selected_microphone_device;
}
public Plugins.MediaDevice? get_speaker_device() {
- if (peers.is_empty) return null;
- var audio_stream = peers.values.to_array()[0].get_audio_stream();
- return call_plugin.get_device(audio_stream, true);
+ if (selected_speaker_device == null) {
+ if (!peers.is_empty) {
+ var audio_stream = peers.values.to_array()[0].get_audio_stream();
+ selected_speaker_device = call_plugin.get_device(audio_stream, true);
+ }
+ if (selected_speaker_device == null) {
+ selected_speaker_device = call_plugin.get_preferred_device("audio", true);
+ }
+ }
+ return selected_speaker_device;
}
public Plugins.MediaDevice? get_video_device() {
- if (peers.is_empty) return null;
- var video_stream = peers.values.to_array()[0].get_video_stream();
- return call_plugin.get_device(video_stream, false);
+ if (selected_video_device == null) {
+ if (!peers.is_empty) {
+ var video_stream = peers.values.to_array()[0].get_video_stream();
+ selected_video_device = call_plugin.get_device(video_stream, false);
+ }
+ if (selected_video_device == null) {
+ selected_video_device = call_plugin.get_preferred_device("video", false);
+ }
+ }
+ return selected_video_device;
}
public void set_audio_device(Plugins.MediaDevice? device) {
+ if (device.incoming) {
+ selected_speaker_device = device;
+ } else {
+ selected_microphone_device = device;
+ }
foreach (PeerState peer_state in peers.values) {
call_plugin.set_device(peer_state.get_audio_stream(), device);
}
}
public void set_video_device(Plugins.MediaDevice? device) {
+ selected_video_device = device;
foreach (PeerState peer_state in peers.values) {
call_plugin.set_device(peer_state.get_video_stream(), device);
}
@@ -270,6 +310,7 @@ public class Dino.CallState : Object {
this.bind_property("we-should-send-video", peer_state, "we-should-send-video", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
this.bind_property("group-call", peer_state, "group-call", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
+ peer_state.stream_created.connect((peer, media) => { on_peer_stream_created(peer, media); });
peer_state.session_terminated.connect((we_terminated, reason_name, reason_text) => {
debug("[%s] Peer left %s: %s %s (%i peers remaining)", call.account.bare_jid.to_string(), reason_text ?? "", reason_name ?? "", peer_state.jid.to_string(), peers.size);
handle_peer_left(peer_state, we_terminated, reason_name, reason_text);