Calls: Fix device selector for multi-party calls, allow picking device before call started
This commit is contained in:
parent
0f5f57888e
commit
369d0c79d7
|
@ -103,16 +103,17 @@ public abstract interface VideoCallPlugin : Object {
|
||||||
// Devices
|
// Devices
|
||||||
public signal void devices_changed(string media, bool incoming);
|
public signal void devices_changed(string media, bool incoming);
|
||||||
public abstract Gee.List<MediaDevice> get_devices(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 MediaDevice? get_preferred_device(string media, bool incoming);
|
||||||
public abstract void set_pause(Xmpp.Xep.JingleRtp.Stream stream, bool pause);
|
public abstract MediaDevice? get_device(Xmpp.Xep.JingleRtp.Stream? stream, bool incoming);
|
||||||
public abstract void set_device(Xmpp.Xep.JingleRtp.Stream stream, MediaDevice? device);
|
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 void dump_dot();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract interface VideoCallWidget : Object {
|
public abstract interface VideoCallWidget : Object {
|
||||||
public signal void resolution_changed(uint width, uint height);
|
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 display_device(MediaDevice device);
|
||||||
public abstract void detach();
|
public abstract void detach();
|
||||||
}
|
}
|
||||||
|
@ -120,7 +121,10 @@ public abstract interface VideoCallWidget : Object {
|
||||||
public abstract interface MediaDevice : Object {
|
public abstract interface MediaDevice : Object {
|
||||||
public abstract string id { owned get; }
|
public abstract string id { owned get; }
|
||||||
public abstract string display_name { 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 {
|
public abstract interface NotificationPopulator : Object {
|
||||||
|
|
|
@ -26,6 +26,10 @@ public class Dino.CallState : Object {
|
||||||
|
|
||||||
public HashMap<Jid, PeerState> peers = new HashMap<Jid, PeerState>(Jid.hash_func, Jid.equals_func);
|
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) {
|
public CallState(Call call, StreamInteractor stream_interactor) {
|
||||||
this.call = call;
|
this.call = call;
|
||||||
this.stream_interactor = stream_interactor;
|
this.stream_interactor = stream_interactor;
|
||||||
|
@ -80,6 +84,15 @@ public class Dino.CallState : Object {
|
||||||
peer_joined(peer.jid, peer);
|
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() {
|
public void accept() {
|
||||||
accepted = true;
|
accepted = true;
|
||||||
call.state = Call.State.ESTABLISHING;
|
call.state = Call.State.ESTABLISHING;
|
||||||
|
@ -206,30 +219,57 @@ public class Dino.CallState : Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Plugins.MediaDevice? get_microphone_device() {
|
public Plugins.MediaDevice? get_microphone_device() {
|
||||||
if (peers.is_empty) return null;
|
if (selected_microphone_device == null) {
|
||||||
|
if (!peers.is_empty) {
|
||||||
var audio_stream = peers.values.to_array()[0].get_audio_stream();
|
var audio_stream = peers.values.to_array()[0].get_audio_stream();
|
||||||
return call_plugin.get_device(audio_stream, false);
|
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() {
|
public Plugins.MediaDevice? get_speaker_device() {
|
||||||
if (peers.is_empty) return null;
|
if (selected_speaker_device == null) {
|
||||||
|
if (!peers.is_empty) {
|
||||||
var audio_stream = peers.values.to_array()[0].get_audio_stream();
|
var audio_stream = peers.values.to_array()[0].get_audio_stream();
|
||||||
return call_plugin.get_device(audio_stream, true);
|
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() {
|
public Plugins.MediaDevice? get_video_device() {
|
||||||
if (peers.is_empty) return null;
|
if (selected_video_device == null) {
|
||||||
|
if (!peers.is_empty) {
|
||||||
var video_stream = peers.values.to_array()[0].get_video_stream();
|
var video_stream = peers.values.to_array()[0].get_video_stream();
|
||||||
return call_plugin.get_device(video_stream, false);
|
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) {
|
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) {
|
foreach (PeerState peer_state in peers.values) {
|
||||||
call_plugin.set_device(peer_state.get_audio_stream(), device);
|
call_plugin.set_device(peer_state.get_audio_stream(), device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set_video_device(Plugins.MediaDevice? device) {
|
public void set_video_device(Plugins.MediaDevice? device) {
|
||||||
|
selected_video_device = device;
|
||||||
foreach (PeerState peer_state in peers.values) {
|
foreach (PeerState peer_state in peers.values) {
|
||||||
call_plugin.set_device(peer_state.get_video_stream(), device);
|
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("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);
|
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) => {
|
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);
|
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);
|
handle_peer_left(peer_state, we_terminated, reason_name, reason_text);
|
||||||
|
|
|
@ -37,10 +37,6 @@ public class Dino.Ui.AudioSettingsPopover : Gtk.Popover {
|
||||||
micro_frame.add(micro_list_box);
|
micro_frame.add(micro_list_box);
|
||||||
foreach (Plugins.MediaDevice device in devices) {
|
foreach (Plugins.MediaDevice device in devices) {
|
||||||
Label display_name_label = new Label(device.display_name) { xalign=0, visible=true };
|
Label display_name_label = new Label(device.display_name) { xalign=0, visible=true };
|
||||||
Label detail_name_label = new Label(device.detail_name) { xalign=0, visible=true };
|
|
||||||
detail_name_label.get_style_context().add_class("dim-label");
|
|
||||||
detail_name_label.attributes = new Pango.AttrList();
|
|
||||||
detail_name_label.attributes.insert(Pango.attr_scale_new(0.8));
|
|
||||||
Image image = new Image.from_icon_name("object-select-symbolic", IconSize.BUTTON) { visible=true };
|
Image image = new Image.from_icon_name("object-select-symbolic", IconSize.BUTTON) { visible=true };
|
||||||
if (current_microphone_device == null || current_microphone_device.id != device.id) {
|
if (current_microphone_device == null || current_microphone_device.id != device.id) {
|
||||||
image.opacity = 0;
|
image.opacity = 0;
|
||||||
|
@ -56,7 +52,13 @@ public class Dino.Ui.AudioSettingsPopover : Gtk.Popover {
|
||||||
device_box.add(image);
|
device_box.add(image);
|
||||||
Box label_box = new Box(Orientation.VERTICAL, 0) { visible = true };
|
Box label_box = new Box(Orientation.VERTICAL, 0) { visible = true };
|
||||||
label_box.add(display_name_label);
|
label_box.add(display_name_label);
|
||||||
|
if (device.detail_name != null) {
|
||||||
|
Label detail_name_label = new Label(device.detail_name) { xalign=0, visible=true };
|
||||||
|
detail_name_label.get_style_context().add_class("dim-label");
|
||||||
|
detail_name_label.attributes = new Pango.AttrList();
|
||||||
|
detail_name_label.attributes.insert(Pango.attr_scale_new(0.8));
|
||||||
label_box.add(detail_name_label);
|
label_box.add(detail_name_label);
|
||||||
|
}
|
||||||
device_box.add(label_box);
|
device_box.add(label_box);
|
||||||
ListBoxRow list_box_row = new ListBoxRow() { visible=true };
|
ListBoxRow list_box_row = new ListBoxRow() { visible=true };
|
||||||
list_box_row.add(device_box);
|
list_box_row.add(device_box);
|
||||||
|
@ -94,10 +96,6 @@ public class Dino.Ui.AudioSettingsPopover : Gtk.Popover {
|
||||||
speaker_frame.add(speaker_list_box);
|
speaker_frame.add(speaker_list_box);
|
||||||
foreach (Plugins.MediaDevice device in devices) {
|
foreach (Plugins.MediaDevice device in devices) {
|
||||||
Label display_name_label = new Label(device.display_name) { xalign=0, visible=true };
|
Label display_name_label = new Label(device.display_name) { xalign=0, visible=true };
|
||||||
Label detail_name_label = new Label(device.detail_name) { xalign=0, visible=true };
|
|
||||||
detail_name_label.get_style_context().add_class("dim-label");
|
|
||||||
detail_name_label.attributes = new Pango.AttrList();
|
|
||||||
detail_name_label.attributes.insert(Pango.attr_scale_new(0.8));
|
|
||||||
Image image = new Image.from_icon_name("object-select-symbolic", IconSize.BUTTON) { visible=true };
|
Image image = new Image.from_icon_name("object-select-symbolic", IconSize.BUTTON) { visible=true };
|
||||||
if (current_speaker_device == null || current_speaker_device.id != device.id) {
|
if (current_speaker_device == null || current_speaker_device.id != device.id) {
|
||||||
image.opacity = 0;
|
image.opacity = 0;
|
||||||
|
@ -113,7 +111,13 @@ public class Dino.Ui.AudioSettingsPopover : Gtk.Popover {
|
||||||
device_box.add(image);
|
device_box.add(image);
|
||||||
Box label_box = new Box(Orientation.VERTICAL, 0) { visible = true };
|
Box label_box = new Box(Orientation.VERTICAL, 0) { visible = true };
|
||||||
label_box.add(display_name_label);
|
label_box.add(display_name_label);
|
||||||
|
if (device.detail_name != null) {
|
||||||
|
Label detail_name_label = new Label(device.detail_name) { xalign=0, visible=true };
|
||||||
|
detail_name_label.get_style_context().add_class("dim-label");
|
||||||
|
detail_name_label.attributes = new Pango.AttrList();
|
||||||
|
detail_name_label.attributes.insert(Pango.attr_scale_new(0.8));
|
||||||
label_box.add(detail_name_label);
|
label_box.add(detail_name_label);
|
||||||
|
}
|
||||||
device_box.add(label_box);
|
device_box.add(label_box);
|
||||||
ListBoxRow list_box_row = new ListBoxRow() { visible=true };
|
ListBoxRow list_box_row = new ListBoxRow() { visible=true };
|
||||||
list_box_row.add(device_box);
|
list_box_row.add(device_box);
|
||||||
|
|
|
@ -115,6 +115,9 @@ public class Dino.Ui.CallWindowController : Object {
|
||||||
call_window.menu_dump_dot.connect(() => { call_plugin.dump_dot(); });
|
call_window.menu_dump_dot.connect(() => { call_plugin.dump_dot(); });
|
||||||
|
|
||||||
update_own_video();
|
update_own_video();
|
||||||
|
|
||||||
|
update_audio_device_choices();
|
||||||
|
update_video_device_choices();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void invite_button_clicked() {
|
private void invite_button_clicked() {
|
||||||
|
@ -135,13 +138,6 @@ public class Dino.Ui.CallWindowController : Object {
|
||||||
Jid peer_jid = peer_state.jid;
|
Jid peer_jid = peer_state.jid;
|
||||||
peer_states[peer_id] = peer_state;
|
peer_states[peer_id] = peer_state;
|
||||||
|
|
||||||
peer_state.stream_created.connect((media) => {
|
|
||||||
if (media == "audio") {
|
|
||||||
update_audio_device_choices();
|
|
||||||
} else if (media == "video") {
|
|
||||||
update_video_device_choices();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
peer_state.connection_ready.connect(() => {
|
peer_state.connection_ready.connect(() => {
|
||||||
call_window.set_status(peer_state.internal_id, "");
|
call_window.set_status(peer_state.internal_id, "");
|
||||||
if (participant_widgets.size == 1) {
|
if (participant_widgets.size == 1) {
|
||||||
|
@ -331,7 +327,7 @@ public class Dino.Ui.CallWindowController : Object {
|
||||||
} else {
|
} else {
|
||||||
Widget widget = (Widget) own_video;
|
Widget widget = (Widget) own_video;
|
||||||
call_window.set_own_video(widget);
|
call_window.set_own_video(widget);
|
||||||
own_video.display_device(devices.first());
|
own_video.display_device(call_state.get_video_device());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
own_video.detach();
|
own_video.detach();
|
||||||
|
|
|
@ -33,10 +33,6 @@ public class Dino.Ui.VideoSettingsPopover : Gtk.Popover {
|
||||||
frame.add(list_box);
|
frame.add(list_box);
|
||||||
foreach (Plugins.MediaDevice device in devices) {
|
foreach (Plugins.MediaDevice device in devices) {
|
||||||
Label display_name_label = new Label(device.display_name) { xalign=0, visible=true };
|
Label display_name_label = new Label(device.display_name) { xalign=0, visible=true };
|
||||||
Label detail_name_label = new Label(device.detail_name) { xalign=0, visible=true };
|
|
||||||
detail_name_label.get_style_context().add_class("dim-label");
|
|
||||||
detail_name_label.attributes = new Pango.AttrList();
|
|
||||||
detail_name_label.attributes.insert(Pango.attr_scale_new(0.8));
|
|
||||||
Image image = new Image.from_icon_name("object-select-symbolic", IconSize.BUTTON) { visible=true };
|
Image image = new Image.from_icon_name("object-select-symbolic", IconSize.BUTTON) { visible=true };
|
||||||
if (current_device == null || current_device.id != device.id) {
|
if (current_device == null || current_device.id != device.id) {
|
||||||
image.opacity = 0;
|
image.opacity = 0;
|
||||||
|
@ -52,7 +48,13 @@ public class Dino.Ui.VideoSettingsPopover : Gtk.Popover {
|
||||||
device_box.add(image);
|
device_box.add(image);
|
||||||
Box label_box = new Box(Orientation.VERTICAL, 0) { visible = true };
|
Box label_box = new Box(Orientation.VERTICAL, 0) { visible = true };
|
||||||
label_box.add(display_name_label);
|
label_box.add(display_name_label);
|
||||||
|
if (device.detail_name != null) {
|
||||||
|
Label detail_name_label = new Label(device.detail_name) { xalign=0, visible=true };
|
||||||
|
detail_name_label.get_style_context().add_class("dim-label");
|
||||||
|
detail_name_label.attributes = new Pango.AttrList();
|
||||||
|
detail_name_label.attributes.insert(Pango.attr_scale_new(0.8));
|
||||||
label_box.add(detail_name_label);
|
label_box.add(detail_name_label);
|
||||||
|
}
|
||||||
device_box.add(label_box);
|
device_box.add(label_box);
|
||||||
ListBoxRow list_box_row = new ListBoxRow() { visible=true };
|
ListBoxRow list_box_row = new ListBoxRow() { visible=true };
|
||||||
list_box_row.add(device_box);
|
list_box_row.add(device_box);
|
||||||
|
|
|
@ -18,12 +18,14 @@ public class Dino.Plugins.Rtp.Device : MediaDevice, Object {
|
||||||
|
|
||||||
public string id { owned get { return device_name; }}
|
public string id { owned get { return device_name; }}
|
||||||
public string display_name { owned get { return device_display_name; }}
|
public string display_name { owned get { return device_display_name; }}
|
||||||
public string detail_name { owned get {
|
public string? detail_name { owned get {
|
||||||
return device.properties.get_string("alsa.card_name") ?? device.properties.get_string("alsa.name") ?? device.properties.get_string("alsa.id") ?? device.properties.get_string("api.v4l2.cap.card") ?? id;
|
if (device.properties.has_field("alsa.card_name")) return device.properties.get_string("alsa.card_name");
|
||||||
|
if (device.properties.has_field("alsa.name")) return device.properties.get_string("alsa.name");
|
||||||
|
if (device.properties.has_field("alsa.id")) return device.properties.get_string("alsa.id");
|
||||||
|
if (device.properties.has_field("api.v4l2.cap.card")) return device.properties.get_string("api.v4l2.cap.card");
|
||||||
|
return null;
|
||||||
}}
|
}}
|
||||||
|
public string? media { owned get {
|
||||||
public Gst.Pipeline pipe { get { return plugin.pipe; }}
|
|
||||||
public string? media { get {
|
|
||||||
if (device.has_classes("Audio")) {
|
if (device.has_classes("Audio")) {
|
||||||
return "audio";
|
return "audio";
|
||||||
} else if (device.has_classes("Video")) {
|
} else if (device.has_classes("Video")) {
|
||||||
|
@ -32,6 +34,9 @@ public class Dino.Plugins.Rtp.Device : MediaDevice, Object {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
public bool incoming { get { return is_sink; } }
|
||||||
|
|
||||||
|
public Gst.Pipeline pipe { get { return plugin.pipe; }}
|
||||||
public bool is_source { get { return device.has_classes("Source"); }}
|
public bool is_source { get { return device.has_classes("Source"); }}
|
||||||
public bool is_sink { get { return device.has_classes("Sink"); }}
|
public bool is_sink { get { return device.has_classes("Sink"); }}
|
||||||
public bool is_monitor { get { return device.properties.get_string("device.class") == "monitor" || (protocol == DeviceProtocol.PIPEWIRE && device.has_classes("Stream")); } }
|
public bool is_monitor { get { return device.properties.get_string("device.class") == "monitor" || (protocol == DeviceProtocol.PIPEWIRE && device.has_classes("Stream")); } }
|
||||||
|
|
|
@ -388,7 +388,7 @@ public class Dino.Plugins.Rtp.Plugin : RootInterface, VideoCallPlugin, Object {
|
||||||
return fps;
|
return fps;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Device? get_preferred_device(string media, bool incoming) {
|
public MediaDevice? get_preferred_device(string media, bool incoming) {
|
||||||
Gee.List<Device> devices = new ArrayList<Device>();
|
Gee.List<Device> devices = new ArrayList<Device>();
|
||||||
foreach (MediaDevice media_device in get_devices(media, incoming)) {
|
foreach (MediaDevice media_device in get_devices(media, incoming)) {
|
||||||
if (media_device is Device) devices.add((Device)media_device);
|
if (media_device is Device) devices.add((Device)media_device);
|
||||||
|
@ -427,14 +427,11 @@ public class Dino.Plugins.Rtp.Plugin : RootInterface, VideoCallPlugin, Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MediaDevice? get_device(Xmpp.Xep.JingleRtp.Stream stream, bool incoming) {
|
public MediaDevice? get_device(Xmpp.Xep.JingleRtp.Stream? stream, bool incoming) {
|
||||||
Stream plugin_stream = stream as Stream;
|
Stream? plugin_stream = stream as Stream?;
|
||||||
if (plugin_stream == null) return null;
|
if (plugin_stream == null) return null;
|
||||||
if (incoming) {
|
MediaDevice? device = incoming ? plugin_stream.output_device : plugin_stream.input_device;
|
||||||
return plugin_stream.output_device ?? get_preferred_device(stream.media, incoming);
|
return device ?? get_preferred_device(stream.media, incoming);
|
||||||
} else {
|
|
||||||
return plugin_stream.input_device ?? get_preferred_device(stream.media, incoming);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dump_dot() {
|
public void dump_dot() {
|
||||||
|
@ -444,8 +441,8 @@ public class Dino.Plugins.Rtp.Plugin : RootInterface, VideoCallPlugin, Object {
|
||||||
print(@"Stored pipe details as $name\n");
|
print(@"Stored pipe details as $name\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set_pause(Xmpp.Xep.JingleRtp.Stream stream, bool pause) {
|
public void set_pause(Xmpp.Xep.JingleRtp.Stream? stream, bool pause) {
|
||||||
Stream plugin_stream = stream as Stream;
|
Stream? plugin_stream = stream as Stream?;
|
||||||
if (plugin_stream == null) return;
|
if (plugin_stream == null) return;
|
||||||
if (pause) {
|
if (pause) {
|
||||||
plugin_stream.pause();
|
plugin_stream.pause();
|
||||||
|
@ -454,9 +451,9 @@ public class Dino.Plugins.Rtp.Plugin : RootInterface, VideoCallPlugin, Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set_device(Xmpp.Xep.JingleRtp.Stream stream, MediaDevice? device) {
|
public void set_device(Xmpp.Xep.JingleRtp.Stream? stream, MediaDevice? device) {
|
||||||
Device real_device = device as Device;
|
Device? real_device = device as Device?;
|
||||||
Stream plugin_stream = stream as Stream;
|
Stream? plugin_stream = stream as Stream?;
|
||||||
if (real_device == null || plugin_stream == null) return;
|
if (real_device == null || plugin_stream == null) return;
|
||||||
if (real_device.is_source) {
|
if (real_device.is_source) {
|
||||||
plugin_stream.input_device = real_device;
|
plugin_stream.input_device = real_device;
|
||||||
|
|
|
@ -27,7 +27,7 @@ public class Dino.Plugins.Rtp.Stream : Xmpp.Xep.JingleRtp.Stream {
|
||||||
|
|
||||||
private Device _input_device;
|
private Device _input_device;
|
||||||
public Device input_device { get { return _input_device; } set {
|
public Device input_device { get { return _input_device; } set {
|
||||||
if (!paused) {
|
if (sending && !paused) {
|
||||||
var input = this.input;
|
var input = this.input;
|
||||||
set_input(value != null ? value.link_source(payload_type, our_ssrc, next_seqnum_offset, next_timestamp_offset) : null);
|
set_input(value != null ? value.link_source(payload_type, our_ssrc, next_seqnum_offset, next_timestamp_offset) : null);
|
||||||
if (this._input_device != null) this._input_device.unlink(input);
|
if (this._input_device != null) this._input_device.unlink(input);
|
||||||
|
@ -37,7 +37,7 @@ public class Dino.Plugins.Rtp.Stream : Xmpp.Xep.JingleRtp.Stream {
|
||||||
private Device _output_device;
|
private Device _output_device;
|
||||||
public Device output_device { get { return _output_device; } set {
|
public Device output_device { get { return _output_device; } set {
|
||||||
if (output != null) remove_output(output);
|
if (output != null) remove_output(output);
|
||||||
if (value != null) add_output(value.link_sink());
|
if (value != null && receiving) add_output(value.link_sink());
|
||||||
this._output_device = value;
|
this._output_device = value;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
@ -74,10 +74,10 @@ public class Dino.Plugins.Rtp.Stream : Xmpp.Xep.JingleRtp.Stream {
|
||||||
|
|
||||||
public void on_senders_changed() {
|
public void on_senders_changed() {
|
||||||
if (sending && input == null) {
|
if (sending && input == null) {
|
||||||
input_device = plugin.get_preferred_device(media, false);
|
input_device = input_device;
|
||||||
}
|
}
|
||||||
if (receiving && output == null) {
|
if (receiving && output == null) {
|
||||||
output_device = plugin.get_preferred_device(media, true);
|
output_device = output_device;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,11 +86,11 @@ public class Dino.Plugins.Rtp.Stream : Xmpp.Xep.JingleRtp.Stream {
|
||||||
|
|
||||||
// Create i/o if needed
|
// Create i/o if needed
|
||||||
|
|
||||||
if (input == null && input_device == null && sending) {
|
if (input == null && sending) {
|
||||||
input_device = plugin.get_preferred_device(media, false);
|
input_device = input_device;
|
||||||
}
|
}
|
||||||
if (output == null && output_device == null && receiving && media == "audio") {
|
if (output == null && receiving && media == "audio") {
|
||||||
output_device = plugin.get_preferred_device(media, true);
|
output_device = output_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create app elements
|
// Create app elements
|
||||||
|
|
|
@ -130,11 +130,11 @@ public class Dino.Plugins.Rtp.VideoWidget : Gtk.Bin, Dino.Plugins.VideoCallWidge
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void display_stream(Xmpp.Xep.JingleRtp.Stream stream, Xmpp.Jid jid) {
|
public void display_stream(Xmpp.Xep.JingleRtp.Stream? stream, Xmpp.Jid jid) {
|
||||||
if (sink == null) return;
|
if (sink == null) return;
|
||||||
detach();
|
detach();
|
||||||
if (stream.media != "video") return;
|
if (stream.media != "video") return;
|
||||||
connected_stream = stream as Stream;
|
connected_stream = stream as Stream?;
|
||||||
if (connected_stream == null) return;
|
if (connected_stream == null) return;
|
||||||
plugin.pause();
|
plugin.pause();
|
||||||
pipe.add(sink);
|
pipe.add(sink);
|
||||||
|
|
Loading…
Reference in a new issue