Commit Graph

128 Commits

Author SHA1 Message Date
Sean DuBois
71b8a13dc9 Don't drop packets when probing Simulcast
Before any packets that we read during the probe would get lost

Co-authored-by: cptpcrd <31829097+cptpcrd@users.noreply.github.com>
2025-11-29 07:42:50 -05:00
Yutaka Takeda
5552def3bf Fix and improve a flaky test (#3275)
## Summary
Fixed inconsistent test duration and occational `panic timeout` in
Test_PeerConnection_RTX_E2E

```
panic: timeout

goroutine 4309 [running]:
github.com/pion/webrtc/v4.Test_PeerConnection_RTX_E2E.TimeOut.func5()
        /Users/ytakeda/go/pkg/mod/github.com/pion/transport/v3@v3.1.1/test/util.go:27 +0xb4
created by time.goFunc
        /Users/ytakeda/sdk/go1.25.4/src/time/sleep.go:215 +0x44
```


### Problem
The test was timing out intermittently (0.2s-18.6s variance) when run
with the race detector due to:

* Random 20% packet loss causing unpredictable RTX detection timing
* Missing goroutine cleanup causing hangs
* Race detector overhead amplifying timing issues

```
go test -v -race -run Test_PeerConnection_RTX_E2E -count 20

=== RUN   Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (7.46s)
=== RUN   Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (1.42s)
=== RUN   Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.72s)
=== RUN   Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (18.62s)
=== RUN   Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (1.22s)
 :
 ```


### Solution
1. Deterministic packet dropping - Changed from random 20% loss to dropping every 5th packet, ensuring predictable NACK/RTX triggering
2. Dynamic payload type detection - Uses negotiated payload type instead of hardcoded 96, making the test robust to codec configuration changes
3. Proper goroutine cleanup - Added context-based cleanup for RTCP reader and OnTrack callback
4. Fail-fast validation - Checks assertion return values and exits immediately on failure
5. Correct cleanup order - Closes peer connections before stopping the virtual network

### Result
* Consistent ~0.21s execution time (tested 50 runs with race detector)
* No more timeouts
* Still validates NACK/RTX behavior as intended by PR #2919

```
go test -v -race -run Test_PeerConnection_RTX_E2E -count 10
=== RUN   Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN   Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN   Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN   Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN   Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN   Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN   Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN   Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN   Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN   Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
PASS
ok      github.com/pion/webrtc/v4       3.373s
```
2025-11-22 14:38:53 -08:00
Kostya Vasilyev
e7e3b36fce Consider first packet when reading Simulcast IDs (#3144)
The code currently ignores the first packet when reading Simulcast IDs
from a new SSRC, and probes only subsequent packets. This commit makes
it so that we consider the first packet as well (which we already have
read). Helps if the publisher only sends Simulcast IDs on the first
packet.
2025-11-18 04:11:03 +02:00
Yutaka Takeda
17287fd0f0 Fix flaky test TestPeerConnection_Media_Sample 2025-11-17 01:54:55 -08:00
boks1971
c376d0edf9 Match codec order of remote peer
Done when creating a transceiver from remote description to respect
codec order preference of remote peer.

There was a recent change to include partial matches which overwrote
same codecs and also rtx was getting magled.

Change it by removing codecs from search space as matches are found so
that a codec match is applied only once.

Also, move RTX matching to separate block to ensure proper RTXes ar
matched.
2025-08-28 10:15:58 +05:30
boks1971
6424d85a10 Consider remote direction in add track
A follow on to https://github.com/pion/webrtc/pull/3200.
This removes the setting engine flag and uses knowledge
of remote direction to decide if a transceiver can be
re-used for sending.

Refactored the code a bit and moved the check into
RTPTransceiver.isSendAllowed.

Re-did the UT to check for re-use cases.
2025-08-25 10:15:56 -06:00
boks1971
2299a71701 Add opt control transceiver re-use in recvonly
SetDisableTransceiverReuseInRecvonly controls if a
transceiver is re-used when its current direction is `recvonly`.

This is useful for the following scenario
  - Remote side sends `offer` with `sendonly` media section.
  - Local side creates transceiver in `SetRemoteDescription`
    and sets direction to `recvonly.
  - Local side calls `AddTrack`.
  - As the current direction is `recvonly`, the transceiver added
    above will be re-used. That will set the direction to `sendrecv`
    and the generated `answer` will have `sendrecv` for that
    media section.
  - That answer becomes incompatible as the offerer is using
    `sendonly`.

Note that local transceiver will be in `recvonly` for both `sendrecv`
and `sendonly` directions in the media section. If the `offer` did use
`sendrecv`, it is possible to re-use that transceiver for sending.
So, disabling re-use will prohibit re-use in the `sendrecv` case also
and hence is slightly wasteful.
2025-08-24 21:38:59 +05:30
Xiaobo Liu
4f67c90d22 Replace custom atomicBool with sync/atomic.Bool
- Remove custom atomicBool implementation
- Replace all atomicBool usages with standard library sync/atomic.Bool

Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
2025-06-25 18:05:03 +08:00
Joe Turki
22dd7b733b Replace interface{} with any 2025-06-19 23:44:08 +03:00
sirzooro
7a46744651 Fixed flake in TestPeerConnection_Media_Sample 2025-06-09 19:55:56 +02:00
Joe Turki
740e5166c5 Update lint rules, force testify/assert for tests
Use testify's assert package instead of the standard library's testing
package.
2025-03-27 12:08:37 +02:00
Joe Turki
5ce8e05d22 Resolve undeclared SSRC using the payload type
Introduces a fallback mechanism to handle undeclared SSRCs from multiple
sections using the RTP stream's payload type. For legacy clients
without MID extension support, it documents the existing behavior for
handling undeclared SSRCs in single media sections.
2025-03-19 07:50:16 +02:00
Joe Turki
feeeebf251 Upgrade golangci-lint, more linters
Introduces new linters, upgrade golangci-lint to version (v1.63.4)
2025-01-18 07:16:06 -06:00
Juliusz Chroboczek
f2191fbfa7 Finish moving SDESRTPStreamIDURI (#3000)
Finish moving SDESRTPStreamIDURI from here to pion/sdp.
2025-01-13 09:25:13 -05:00
Nils Ohlmeier
2fd3640fa3 Only collect single fingerprints/ICE credentials
The way currently DTLS fingerprints and ICE credentials
are picked is causing interop issues as described in #2621

Peers which don't use Bundle can use different fingerprints
and credentials in each media section. Even though is
not (yet) supported by Pion, receiving an SDP offer from
such a peer is valid.

Additionally if Bundle is being used the group attribute
determines which media section is the master bundle section,
which establishes the transport. Currently Pion always
just uses the first credentials/fingerprint it can find
in the SDP, which results in not spec compliant behavior.

This PR attempts to fix the above issues and make
Pion more spec compliant and interoperable.

Fixes #2621
2024-11-13 23:44:00 -05:00
Sean DuBois
5637661fef Add E2E Test for RTX
Assert that generation of NACKs and sending of RTX operates as expected.
2024-10-05 01:05:12 -04:00
Sean DuBois
4541b73b1a Add Retransmission and FEC to TrackLocal
If the MediaEngine contains support for them a SSRC will be generated
appropriately

Co-authored-by: aggresss <aggresss@163.com>
Co-authored-by: Kevin Wang <kevmo314@gmail.com>

Resolves #1989
Resolves #1675
2024-10-03 20:44:49 -07:00
Juliusz Chroboczek
f29ef99b22 Avoid leaking tickers
In Go 1.22 and earlier, a ticker needs to be explicitly stopped
when it's no longer useful in order to avoid a resource leak.
In Go 1.23 and later, an orphaned ticker will eventually be
garbage collected, but it's still more thrifty to stop it early.
2024-08-01 14:35:24 -04:00
Sean DuBois
c85269bee3 Properly handle non-media probes
libwebrtc has started sending media probes on an unannounced SSRC(0).
Currently Pion will ignore this as the SSRC hasn't been declared
explicitly and no RID/MID RTP Headers.

This adds a special case to accept SSRC 0 and Read the RTP packets. This
allows the TWCC reports to properly be generated.
2024-07-20 22:16:22 -04:00
cnderrauber
287d10638d Match header extensions to remote media sections
Firefox would send updated header extension
in renegotiation, e.g. publish a track without
simucalst then renegotiate second track with
simucalst, the two media secontions will have
different rtp header extensions in offer. Need
to match remote header extentions for each
media sections to avoid second track publish
failed.
2024-07-18 12:30:19 +08:00
aler9
d56bead6a6 Fix race condition in test
In TestPeerConnection_Zero_PayloadType, WriteSample might be called
after closePairNow, resulting in failure. This patch fixes the issue.
2024-06-16 00:02:20 -04:00
knowmost
a97c420d0c Fix typos in multiple comments 2024-04-27 23:27:55 -04:00
cnderrauber
83cfeea397 Update RtxSSRC for simulcast track remote
Fix #2751, updates remote track's rtx ssrc for
simulcast track doesn't contain rtx ssrc in sdp
since readRTX relies on rtx ssrc to determine if
it has a rtx stream.
2024-04-25 09:54:36 -04:00
Michael Klingbeil
6deb47d3bf Properly update metadata when PayloadType is 0
In the case where a remote track is sending PCMU with payload type 0
checkAndUpdateTrack will fail to update the track codec and params
(because t.PayloadType() is already 0). Add an extra check to handle
this case.
2024-03-16 23:05:14 -04:00
Sean DuBois
fda6c4f836 Fix linter errors
golangci-lint upgrade to v1.56.2 added more checks

Relates to pion/.goassets#201
2024-03-16 21:09:38 -04:00
cnderrauber
dae5e8e1a0 Skip padding packet for simulcast probe
Skip padding packet for simulcast probe
Fix rtx attributes panic for nil map
2024-02-01 22:57:05 -08:00
Sean DuBois
c0437dc93d Add Simulcast RTCP Test
Resolves #1803
2023-09-15 00:41:01 -04:00
Sean DuBois
9052126590 Use Public API in Simulcast unit test
Developers read this, not as useful if we use private APIs
2023-09-14 16:56:38 -04:00
Mikhail
759fc73984 Respect SSRC Choice by User
Respect SSRC chosen via RTPTransceiverInit
2023-09-14 14:08:38 -04:00
Sean DuBois
b549c9580d Enable Simulcast RTP Headers by default
Relates to #2557
2023-09-13 12:38:26 -04:00
Sean DuBois
dc4b591c4d Start pion/webrtc/v4
60eea43 is a breaking change
2023-09-05 11:48:14 -04:00
Sean DuBois
60eea430ac Close PeerConnection on DTLS CloseNotify
Resolves #1767
Resolves pion/dtls#151
2023-09-05 04:52:17 -04:00
renovate[bot]
ea23dec2b9 Update module transport, srtp, ice and turn
ReplayDetector introduced a breaking change
2023-09-03 23:59:43 -04:00
Steffen Vogel
683fc837d0 Make repo REUSE compliant 2023-05-05 11:58:49 -04:00
streamer45
d08b3dc403 Handle Simulcast Offer with one Media Section
Everytime we receieve a new SSRC we probe it and try to determine the
proper way to handle it. In most cases a Track explicitly declares a
SSRC and a OnTrack is fired. In two cases we don't know the SSRC
ahead of time
* Undeclared SSRC in a single media section (pion/webrtc#880)
* Simulcast

The Undeclared SSRC processing code would run before Simulcast.
If a Simulcast Offer/Answer only contained one Media Section we
would never fire the OnTrack. We would assume it was a failed
Undeclared SSRC processing. This commit fixes the behavior.
2023-04-23 00:04:54 -04:00
Pion
308f8616a3 Update CI configs to v0.10.6
Update lint scripts and CI configs.
2023-04-08 14:24:19 -04:00
Steffen Vogel
eafdc7742a Use new pion/transport Net interface
This change adapts pion/ice to use a new interface for most network
related operations. The interface was formerly a simple struct vnet.Net
which was originally intended to facilicate testing. By replacing it
with an interface we have greater flexibility and allow users to hook
into the networking stack by providing their own implementation of
the interface.
2023-02-09 09:39:33 +01:00
boks1971
37e16a3b15 Bolting on send side simulcast
Introduces AddEncoding method in RTP sender to add simulcast encodings.

Added UTs for AddEncoding.
Also modified the Simulcast send test to use the new API.
2022-02-24 23:55:17 -08:00
Sean DuBois
664f6df0d3 Add test for 65b517
Assert that Simulcast probe thread doesn't close the Tracks that have
been emitted to the user.
2022-02-01 19:03:00 -05:00
Sean DuBois
157220e800 Run gofmt to add new build constraints
Also remove some 1.13 specific WASM code
2022-01-17 22:36:01 -05:00
cnderrauber
635bfd9cad Set prefer codec created by remote sdp
If a transceiver is created by remote sdp, then set
prefer codec same as offer peer.
For pion's codec match, it will use exact match
first, and then partial match. If patial match
only, the partial match codecs will become
negotiated codes. So it will be set prefer codec
when only exist partial match. And has same payload.

Add test cast for this.

refer to https://www.w3.org/TR/webrtc/#bib-rfc8829
2021-11-12 14:05:33 +08:00
boks1971
ef285fbe09 Use RIDs for SSRC resolution
Problem:
--------
Firefox (testing with Firefox 93) sends an `offer`
with simulcast track which includes both RIDs and SSRCs.

When track details are gathered, RIDs are fetched
using `getRids` which returns a map. A `range` is
done on the returned map and RIDs are appended to
the `rids` array in `trackDetails`.

And then SSRCs are read from SDP and set into the
`ssrcs` array of `trackDetails`.

As map range order is not guaranteed, some times
the RID index and SSRC index in their respective arrays
do not match.

Due to the mismatch, services like ion-sfu which rely
on RID to find the correct spatial layer get confused
and end up forwarding the wrong layer.

Solution(s):
------------
There are three possible solutions I could think of

1. The simplest is to not populate SSRCs in `trackDetails`
if RIDs are available. Let `handleIncomingSSRC` do the
SSRC resolution based on RID.

According to RFC 8853 (https://www.ietf.org/rfc/rfc8853.pdf),
the binding to SSRC should happen using RID.

This is the change I have made in this PR. See testing
below for browsers tested.

2. Look for `simulcast` attribute in SDP and take
the RID ordering from that line in `getRids` if that
attribute is available. If not fall back to `rid` attribute.

Also, change `getRids` to return an array.

But, I cannot find an RFC which defines behaviour when
both RID and SSRC are used in `offer`. The question is,
"Will the `ssrc` attribute ordering match the `rid`
ordering?". If that is not guaranteed, this will run
into trouble.

This should be easy to do though if we want to go down this
route.

3. The hardest option is to change the receiver SSRC based
on RID. But, that makes it too complicated (for example
if we have to change SSRC binding of a receiver based on
received RID, there will be two receivers with the same SSRC
binding unless there is some way to swap bindings of receivers)

Testing:
--------
Tested on Firefox, Firefox 78.15.0esr, Chrome, Ssafari and
ensured that Simulcast sender and receiver are in sync for
rid/ssrc/spatial layer resolution.
2021-10-29 19:42:56 -04:00
Sean DuBois
67a9913f00 Reduce PeerConnection_Media_Disconnected runtime
Set custom ICE timing via SettingEngine
2021-09-15 15:29:20 -04:00
Sean DuBois
11b8873da2 Handle Simulcast RepairStream
Read + Discard packets from the Simulcast repair stream. When a
Simulcast stream is enabled the remote will send packets via the repair
stream for probing. We can't ignore these packets anymore because it
will cause gaps in the feedback reports

Resolves #1957
2021-09-15 15:08:22 -04:00
Dean Sheather
f8ecedc524 Fix double loop in data channel ID generation
(*SCTPTransport).generateAndSetDataChannelID performed a double loop to
find the next available data channel ID. This changes that behavior to
generate a lookup map with the taken IDs first, so generating a data
channel ID takes much less time.

Before, it would take more than 1000ms to generate the next data channel
ID once you had roughly 50k of them. Now it only takes 4ms at that same
point.

Fixes #1945
2021-09-07 20:45:30 -04:00
Sean DuBois
a630d62dd4 Move Simulcast SDP Modification into helper
Will be used by Simulcast renegotation tests as well

Relates to #1345
2021-08-29 20:54:44 -04:00
Sean DuBois
ec3d65ea35 Improve SSRC Based Simulcast test
Relates to #1345
2021-08-29 13:26:23 -04:00
Sean DuBois
d570b78ae1 Implement SSRC Based Simulcast
Resolves #1345
2021-08-28 11:00:44 -04:00
Sean DuBois
e3ced781d0 Add E2E RID Simulcast test
Relates to #1345
2021-08-26 16:52:14 -04:00
Sean DuBois
8cbcb571c2 Use constants for MimeType
Replace VP8/H264/Opus string usage
2021-08-25 21:41:49 -04:00