Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webrtc: speed up gathering of incoming tracks #3441

Merged
merged 1 commit into from
Jun 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 40 additions & 6 deletions internal/protocols/webrtc/peer_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

"github.com/pion/ice/v2"
"github.com/pion/interceptor"
"github.com/pion/sdp/v3"
"github.com/pion/webrtc/v3"

"github.com/bluenviron/mediamtx/internal/conf"
Expand All @@ -29,6 +30,37 @@
return false
}

// TracksAreValid checks whether tracks in the SDP are valid
func TracksAreValid(medias []*sdp.MediaDescription) error {
videoTrack := false
audioTrack := false

for _, media := range medias {
switch media.MediaName.Media {
case "video":
if videoTrack {
return fmt.Errorf("only a single video and a single audio track are supported")
}
videoTrack = true

Check warning on line 44 in internal/protocols/webrtc/peer_connection.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/webrtc/peer_connection.go#L34-L44

Added lines #L34 - L44 were not covered by tests

case "audio":
if audioTrack {
return fmt.Errorf("only a single video and a single audio track are supported")
}
audioTrack = true

Check warning on line 50 in internal/protocols/webrtc/peer_connection.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/webrtc/peer_connection.go#L46-L50

Added lines #L46 - L50 were not covered by tests

default:
return fmt.Errorf("unsupported media '%s'", media.MediaName.Media)

Check warning on line 53 in internal/protocols/webrtc/peer_connection.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/webrtc/peer_connection.go#L52-L53

Added lines #L52 - L53 were not covered by tests
}
}

if !videoTrack && !audioTrack {
return fmt.Errorf("no valid tracks count")
}

Check warning on line 59 in internal/protocols/webrtc/peer_connection.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/webrtc/peer_connection.go#L57-L59

Added lines #L57 - L59 were not covered by tests

return nil

Check warning on line 61 in internal/protocols/webrtc/peer_connection.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/webrtc/peer_connection.go#L61

Added line #L61 was not covered by tests
}

type trackRecvPair struct {
track *webrtc.TrackRemote
receiver *webrtc.RTPReceiver
Expand Down Expand Up @@ -334,10 +366,12 @@
}

// GatherIncomingTracks gathers incoming tracks.
func (co *PeerConnection) GatherIncomingTracks(
ctx context.Context,
maxCount int,
) ([]*IncomingTrack, error) {
func (co *PeerConnection) GatherIncomingTracks(ctx context.Context) ([]*IncomingTrack, error) {
var sdp sdp.SessionDescription
sdp.Unmarshal([]byte(co.wr.RemoteDescription().SDP)) //nolint:errcheck

maxTrackCount := len(sdp.MediaDescriptions)

var tracks []*IncomingTrack

t := time.NewTimer(time.Duration(co.TrackGatherTimeout))
Expand All @@ -346,7 +380,7 @@
for {
select {
case <-t.C:
if maxCount == 0 && len(tracks) != 0 {
if len(tracks) != 0 {

Check warning on line 383 in internal/protocols/webrtc/peer_connection.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/webrtc/peer_connection.go#L383

Added line #L383 was not covered by tests
return tracks, nil
}
return nil, fmt.Errorf("deadline exceeded while waiting tracks")
Expand All @@ -358,7 +392,7 @@
}
tracks = append(tracks, track)

if len(tracks) == maxCount || len(tracks) >= 2 {
if len(tracks) >= maxTrackCount {
return tracks, nil
}

Expand Down
2 changes: 1 addition & 1 deletion internal/protocols/webrtc/peer_connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ func TestPeerConnectionPublishRead(t *testing.T) {
})
require.NoError(t, err)

inc, err := pc2.GatherIncomingTracks(context.Background(), 1)
inc, err := pc2.GatherIncomingTracks(context.Background())
require.NoError(t, err)

require.Equal(t, ca.out, inc[0].Format())
Expand Down
37 changes: 0 additions & 37 deletions internal/protocols/webrtc/track_count.go

This file was deleted.

5 changes: 2 additions & 3 deletions internal/protocols/webrtc/whip_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,7 @@
return nil, err
}

// check that there are at most two tracks
_, err = TrackCount(sdp.MediaDescriptions)
err = TracksAreValid(sdp.MediaDescriptions)

Check warning on line 172 in internal/protocols/webrtc/whip_client.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/webrtc/whip_client.go#L172

Added line #L172 was not covered by tests
if err != nil {
c.deleteSession(context.Background()) //nolint:errcheck
c.pc.Close()
Expand Down Expand Up @@ -210,7 +209,7 @@
}
}

tracks, err := c.pc.GatherIncomingTracks(ctx, 0)
tracks, err := c.pc.GatherIncomingTracks(ctx)

Check warning on line 212 in internal/protocols/webrtc/whip_client.go

View check run for this annotation

Codecov / codecov/patch

internal/protocols/webrtc/whip_client.go#L212

Added line #L212 was not covered by tests
if err != nil {
c.deleteSession(context.Background()) //nolint:errcheck
c.pc.Close()
Expand Down
4 changes: 2 additions & 2 deletions internal/servers/webrtc/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ func (s *session) runPublish() (int, error) {
return http.StatusBadRequest, err
}

trackCount, err := webrtc.TrackCount(sdp.MediaDescriptions)
err = webrtc.TracksAreValid(sdp.MediaDescriptions)
if err != nil {
// RFC draft-ietf-wish-whip
// if the number of audio and or video
Expand Down Expand Up @@ -489,7 +489,7 @@ func (s *session) runPublish() (int, error) {
s.pc = pc
s.mutex.Unlock()

tracks, err := pc.GatherIncomingTracks(s.ctx, trackCount)
tracks, err := pc.GatherIncomingTracks(s.ctx)
if err != nil {
return 0, err
}
Expand Down
Loading