David Woodhouse [Sat, 14 Apr 2018 22:07:36 +0000 (00:07 +0200)]
Basic implementation of outbound screen share
We're stilling Pidgin it's outbound video for now, so I've been testing
with videotestsrc. Need to teach Pidgin about a screen share media type
and do the "choose monitor / window" UI bits there where they belong.
David Woodhouse [Fri, 6 Apr 2018 09:42:36 +0000 (10:42 +0100)]
Switch to live mode for appsrc
The input data should be handled as a live stream. Maybe this will
help deal with the case where we get incoming silence on some calls when
Pidgin has been running for a while.
David Woodhouse [Thu, 5 Apr 2018 11:18:38 +0000 (12:18 +0100)]
Cancel conversation list update properly on connection close
There was race condition with close, and if an update was pending there
was a use-after-free of the connection object. Fix that the same way as
we do for the joinable meetings dialog.
David Woodhouse [Thu, 22 Mar 2018 23:57:21 +0000 (23:57 +0000)]
Handle transient buddies with NO_SAVE flag
We want libpurple to be able to create transient buddies which we can use
purely as a vehicle for conveying presence/name/photo information for an
IM window.
David Woodhouse [Fri, 16 Mar 2018 21:21:03 +0000 (21:21 +0000)]
Subscribe to presence channel only when availability first fetched
To avoid subscribing to presence of *all* members of chat rooms, only
subscribe once their availability is first requested. This should help
to avoid us getting kicked off when the rate limit kicks in.
David Woodhouse [Wed, 7 Mar 2018 20:32:03 +0000 (20:32 +0000)]
More audio cleanup
Fix up lifetime handling on the appsrc/appsink and uninstall the callbacks
when we're done.
Also fix up the timer handling for empty outbound packets. When the system
was slow we were sending 'muted' RT packets in between the audio frames,
so set the timers *only* when we're actually muted. If we fail to send
audio at other times, let it just do a red mic like it should.
David Woodhouse [Wed, 7 Mar 2018 16:33:38 +0000 (16:33 +0000)]
Slight cleanup for call media handling
The call is connecting before do_join_chat() is ever called, which means we
may miss some of the early state transitions. Try to cope with that.
We probably want to drive the call connection directly from chat code in
the end, but this will do for now.
Also decouple the media setup and connection; the call window in Pidgin
should now say 'Calling...' and then 'Call in progress' once it's connected.
Hopefully this helps to deal with some of the issues with slow call setup.
I *was* able to reproduce the ever-slower call connection but now I can't.
Not sure if that's just coincidence...
David Woodhouse [Wed, 7 Mar 2018 12:31:41 +0000 (12:31 +0000)]
Clean up fetch_presences() idle handling
Properly avoid re-running the function when it's already scheduled, and
ensure we cancel it when we need to too. Also ensure that disposed contacts
are removed from the 'contacts_needed' list.
Michael Gruenewald [Mon, 12 Feb 2018 15:05:31 +0000 (16:05 +0100)]
Only consider active members for mentions
Inactive members are effectively not part of the chat anymore and
shouldn't be considered for mentioning. This is especially helpful when
a member changed their profile (e.g., mail, domain, whatnot) but not
their display name.
Michael Gruenewald [Fri, 2 Feb 2018 14:39:56 +0000 (15:39 +0100)]
Prevent double-replacements in mentions
Outgoing mentions replace a name with a reference to the Chime user.
Sometimes you have two users with the same name in a chat room, or two
people where one name is a prefix of another one. This could end up with
something like `<@id1|<@id2|Last, First>>`, which is broken.
This change makes sure to only replace at word borders and not if a `|`
is in front. This isn't perfect, but better than before.
David Woodhouse [Thu, 22 Feb 2018 09:20:01 +0000 (09:20 +0000)]
Merge branch 'audio'.
I've been using it for every call I've made this week. There are still a
few things to be cleaned up, but I suppose I should concede it's time it
was merged into the master branch for others to test and heckle.
This ought to now work with the Ubuntu 16.04 packages of GStreamer,
FarStream, etc.
David Woodhouse [Thu, 22 Feb 2018 08:33:14 +0000 (08:33 +0000)]
Add Chime-specific RTP payload handling
RFC7587 defines the clock-rate for the OPUS payload format to be 48000.
This is painful since we're really quite like to be able to transpose
timestamps between the RTP and on-the-wire Chime protocol (which uses
16000) without conversion. It was OK having to multiply by three for the
appsrc, but dividing by three in the appsink would have overflow issues
and we'd have to reconstitute the high bits somehow.
By defining our own payload format we can work around that, and also
force it to encode only a single channel. That one might well be a bug
in the existing gstopuspay; if the output caps include 'stereo=0' it
*isn't* enforcing 'channels=1' on its input caps.
Both of the above could probably be fixed up in the OPUS payloaders
upstream, and once this code is public we can have a look at doing that.
For now though, having our own CHIME payload helps it work on Farstream
0.2.7 on Ubuntu 16.04, which can't cope with payloaders that have
multiple names (OPUS, X-GST-OPUS-DRAFT-SPITTKA-00). So it'll do for now
until we can get more traction on upstreaming the required fixes.
David Woodhouse [Wed, 21 Feb 2018 21:42:05 +0000 (21:42 +0000)]
Cope with RTP as application/x-srtp by depayloading for ourselves
Farstream's FsRtpConference always installs the srtpenc/srtpdec elements
even when there is no encryption. In that case they just pass packets
through unmodified. Unfortunately the caps are negotiated wrong — it's
still marked as application/x-srtp. This means that rtpopusdepay won't
accept it, for example.
David Woodhouse [Tue, 20 Feb 2018 21:33:38 +0000 (21:33 +0000)]
Create RTP directly for incoming audio
It doesn't look like GStreamer/Farstream can cope with Opus with an RTP
clock rate other than 48000, but for incoming we can cope by just
multiplying by three.
David Woodhouse [Fri, 2 Feb 2018 20:59:13 +0000 (20:59 +0000)]
Switch to using RTP for audio
We get a jitterbuffer for free this way, which makes it a lot more usable.
It also means I can drop a lot of the timestamp mangling crap and just
transpose the protocol's sample counts into RTP headers... I think. The
idea is to drop the 'opusrtppay' part and feed RTP directly into the
appsrc, and the converse for the sink.
It does require farstream 0.2.8 *and* to remove libgstsrtp.so for now.
David Woodhouse [Mon, 11 Dec 2017 15:42:28 +0000 (15:42 +0000)]
Let fs-app-transmitter launch a pipeline by its description
Instead of hard-coded audiotestsrc/filesink, let the pipeline descriptions
get passed in in the FsCandidate's 'host' and 'username' fields, much as
the FsShmTransmitter does for the filenames.
This might not last, as we can only reference named elements in a pipeline
description if they were created in that same pipeline, AFAICT. So my plan
of pre-creating the appsrc and then referencing it from the description
probably isn't going to work.
Which means we might end up with a dedicated FsChimeTransmitter after all,
but hey, at least I have a better understanding of how some of this stuff
fits together...
David Woodhouse [Sat, 9 Dec 2017 09:01:06 +0000 (09:01 +0000)]
Start cleaning up audio support, handle mute
There are locking issues here. The appsink_new_sample() function can get
invoked from another thread, which means it can race with the timer.
I think if the g_source_remove() in do_send_rt_packet() runs while a
timed_send_rt_packet() is waiting for the rt_lock, it can deadlock.
The simple fix is probably to shift all the actual packet processing into
a separate thread with a simple packet-sending loop which does both audio
and muted frames.
Or maybe we don't want a thread wakeup to add to the outbound packet
latency, and we'll allow appsink_new_sample() to send directly for itself
with some simple locking scheme between it and the thread.
The thread can then handle DTLS and auth and everything else sequentially,
which lets me do DTLS "natively" with GnuTLS and saves me from lamenting
the absence of GDtlsClientConnection too much.