As per discussion in the bug, remove the drop state from transportreceivebin.
Dropping data is necessary, but for bundled config, needs to happen
further downstream after mixed flows have been separated.
Also support switching back to BLOCK from PASS state.
https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/1206
Instead of synchronising at the ICE transport, do clock sync for the
RTP stream at the DTLS transport via the dtlssrtpenc rtp-sync
property. This avoids delaying RTCP while waiting until it is time
to output an RTP packet when rtcp-mux is enabled.
https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/1212
Add latency configuration logic to transportsendbin to
isolate it from the overall pipeline latency. That means that
it configures minimum latency internally based on the
latency query, and sends a latency event upstream that
matches.
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/1209
When emitting ICE candidates, also merge them to the local and
pending description so they show up in the SDP if those are
retrieved from the current-local-description and
pending-local-description properties.
https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/676
Otherwise it can happen that e.g. the stream-start event is tried to be
sent as part of pushing the first buffer. Downstream might not be in
PAUSED/PLAYING yet, so the event is rejected with GST_FLOW_FLUSHING and
because it's an event would not cause the blocking pad probe to trigger
first. This would then return GST_FLOW_FLUSHING for the buffer and shut
down all of upstream.
To solve this we return GST_PAD_PROBE_DROP for all events. In case of
sticky events they would be resent again later once we unblocked after
blocking on the buffer and everything works fine.
Don't handle events specifically in sink pad blocking pad probes as here
downstream is not linked yet and we are actually waiting for the
following CAPS event before unblocking can happen.
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/1172
Without this it might happen that received data from the DTLS transport
is already passed to sctpdec before its state was set to PLAYING. This
would cause the data to be dropped, GST_FLOW_FLUSHING to be returned and
the whole DTLS transport to shut down.
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/1172
among other things.
Using a GCond can easily lead to deadlocks and only duplicates the
waiting code from gstpad.c in the best case.
In this case it actually could lead to a deadlock if both RTP and RTCP
were waiting. Only one of them would be woken up because g_cond_signal()
was used instead of g_cond_broadcast().
The receive bin should block buffers from reaching dtlsdec before
the dtls connection has started.
While there was code to block its sinkpads until receive_state
was different from BLOCK, nothing was ever setting it to BLOCK
in the first place. This commit corrects this by setting the
initial state to BLOCK, directly in the constructor.
In addition, now that blocking is effective, we want to only
block buffers and buffer lists, as that's what might trigger
errors, we want to still let events and queries go through,
not doing so causes immediate deadlocks when linking the
bin.
We need the streams' pt maps updated before requesting pads
on rtpbin, because this is what will trigger the requesting
of FEC encoders, and our handler for this request looks for
the payload types in the relevant stream's pt map.
Fixes#1187
Otherwise we would start sending data to the DTLS connection before, and
the DTLS elements consider this an error.
Also RFC 8261 mentions:
o A DTLS connection MUST be established before an SCTP association can
be set up.
For us it can happen that the DTLS transports are still in the process
of connecting while the ICE transport is already completed. This
situation is not specified in the spec but conceptually that means it is
still in the process of connecting.
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/758
We don't have any mid before parsing the SDP, which happens after we
handled the SDP answer and that usually happens long after ICE candidate
gathering is finished.
Without this all transceivers are considered inactive and as such ICE
gathering is for active transceiver was considered complete from the
very beginning.
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/1126
We don't support stopping RTP receivers currently so let's not consider
them all stopped all the time. This fixes some of the ICE/DTLS state
change handling and specifically fixes the ICE gathering state.
Previously the ICE gathering state was immediately going from NEW to
COMPLETE because it considered all transceivers stopped and as such all
activate transceivers were finished gathering ICE candidates.
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/1126
By passing NULL to `g_signal_new` instead of a marshaller, GLib will
actually internally optimize the signal (if the marshaller is available
in GLib itself) by also setting the valist marshaller. This makes the
signal emission a bit more performant than the regular marshalling,
which still needs to box into `GValue` and call libffi in case of a
generic marshaller.
Note that for custom marshallers, one would use
`g_signal_set_va_marshaller()` with the valist marshaller instead.
Internal sources seem to be rtp streams we are sending whereas
non-internal sources are the rtp streams we are receiving. Redo the
statistics with that in mind.
The function _get_stats_from_ice_transport returns a string which must be
freed by the caller. However, _get_stats_from_dtls_transport was ignoring
the return value from this function, resulting in a leak.
Ran this with valgrind. Before this fix there was a leak of 40 bytes each
time this was called. After there was no leak.
When negotiating a data channel, Chrome as recent as 75 still uses SDP
based on version 05 of the SCTP SDP draft, for example:
m=application 9 DTLS/SCTP 5000
a=sctpmap:5000 webrtc-datachannel 1024
Implement support for parsing SCTP port out of SDP message with sctpmap
attribute. Fixes data channel negotiation with Chrome browser.
There's no reason for it to inherit from GstObject apart from
locking, which is easily replaced, and inheriting from
GInitiallyUnowned made introspection awkward and needlessly
complicated.
Regression introduced by b4bdcf15b7
This commit prevents the handshake from reaching dtlsdec when
the receive state of the receive bin is set to DROP (for example
when transceivers are sendonly).
This preserves the intent of the commit, by blocking the bin
at its sinks until the receive state is no longer BLOCK, but
makes sure the handshake still goes through, by only dropping
data at the src pads, as was the case before.
1. The spec indicates that the notification should occur near the end of
'setting the description' processing
2. The current location with the drop of the lock could cause the 'check
if negotiation is needed' logic to execute and become confused about
the state of the webrtcbin's current local descriptions.
In the bad case, the following assertions could be hit:
g_assert (trans->mline < gst_sdp_message_medias_len (webrtc->current_local_description->sdp));
g_assert (trans->mline < gst_sdp_message_medias_len (webrtc->current_remote_description->sdp));
Moving the signalling state change later in the set description task
means that checking for a renegotiation will early abort as the
signalling state is not STABLE before the session description and
transceivers have been updated.
If both data channels become ready simultaneously, then the two integer
read-add-update cycles can execute concurrently and only ever increment
once instead of the required twice. Use an atomic add instead.
It is very possible for badly behaving signalling or peers to send
us ICE candidates before we receive an SDP. While we had consideration
for that on the first set SDP, subsequent SDP's could result in
misconfigured ICE transports. Expand the previous code to also take
into account reconfigurations.
Limitations:
- No transport changes at all (ICE, DTLS)
- Codec changes are untested and probably don't work
- Stream removal doesn't remove transports (i.e. non-bundled transports
will stay around until webrtcbin is shutdown)
- Unified Plan SDP only. No Plan-B support.
Some GIR annotations were incorrect or even missing. The former isn't
good for bindings, while the latter is especially annoying for signal
handlers, as that means your arguments will get the wrong names in the
rendered documentation.
Since the addition of BUNDLE support, the pads and the transceivers
share a single transport stream. When getting stats from the stream,
filter by the ssrc of the current pad to avoid merging the stats for
different pads.
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/889
If bundle was used in combination with rtx, only the bundled transport
stream would have correctly configured rtx parameters.
Iterate over the payloads upfront in the bundled case to ensure the
correct payload mapping is set for the RTX elements.
This is the equivalent of iceTransportPolicy in the RTCConfiguration
dictionary.
Only two values are implemented:
* all: default behaviour
* relay: only gather relay candidates
The third member of the iceTransportPolicy enum, "public", is
obsolete.
Currently master code of gst1-plugins-bad use plain-string host name while passing it to
libnice agent: nice_agent_set_relay_info() in gstwebrtcice.c while adding turn_server(_add_turn_server).
It is observered that if we don't convert the host parameter by using gst_uri_get_host, it fails in libnice agent(0.1.14-1).
Code does, actually, set the host correctly but while passing params to nice_agent_set_relay_info, it uses incorrect one.
https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/823
With prenegotiated channels, the data-channel protocol is not used and
instead the channel's negotiation is intended to be performed out of band in
some application-specific manner.
Comes with test!
This means that we will reject all operations before we've transitioned
into READY.
This also fixes the tests using the default GMainContext in the NULL
state instead of the webrtcbin internal GMainContext and thread. Also
removes a potential ordering race where on the element transitioning to
READY, an operations could have been queued on two different threads and
removing a guarentee on operation ordering.
It might be possible that if we set webrtcbin to the NULL state some
tasks (idle sources) are still executed and they might even freeze. The freeze
is caused because the webrtcbin tasks don't hold a reference to webrtcbin and
if it's last unref inside the idle source itself this will not allow the main
loop to finish because the main loop is waiting on the idle source to finish.
We now start and stop webrtcbin thread when changing states. This will allow
the idle sources to finish properly.
https://bugzilla.gnome.org/show_bug.cgi?id=797251
It is possible and often desirable to pass multiple ICE relays
to libnice agents, the "turn-server" property, while convenient
to use from the command line, does not allow that.
This adds a new action signal, "add-turn-server" to address that.
https://bugzilla.gnome.org/show_bug.cgi?id=797012
Refactor transportsendbin, and change the way
pads are blocked on dtlssrtpenc so that they
don't interfere with state changes.
As well as being easier to read, this fixes
spurious failures shutting down webrtcbin
if DTLS negotiation hasn't completed yet.
Move the errant piece of dtlssrtpenc state change
management from dtlstransport in the Webrtc libs,
into the transportsendbin that does the rest of
the element management so it's all in one place.
When negotiation is triggered by receiving caps on our sink pad
probes, we could encounter a race condition where need-negotiation
is emitted and the application requires the creation of an offer
before the current caps were actually updated.
This led to retrieving incomplete caps when creating the offer,
using find_codec_preferences -> pad_get_current_caps.
Instead, as we save the caps in the probe callback anyway, it is better
and thread safe to use these if they were set.
https://bugzilla.gnome.org/show_bug.cgi?id=796801