From c501b76d2b12379da7b51b85f1024c6714e5d780 Mon Sep 17 00:00:00 2001 From: Juliusz Chroboczek Date: Thu, 6 Apr 2023 12:37:23 +0200 Subject: [PATCH] Rework selection of simulcast tracks. We used to hard-wire the rid identifiers. We now assume that the simulcast streams are ordered in decreasing order of quality. --- README.PROTOCOL | 8 ++++-- rtpconn/webclient.go | 68 +++++++++++++++++++------------------------- 2 files changed, 34 insertions(+), 42 deletions(-) diff --git a/README.PROTOCOL b/README.PROTOCOL index 747755b..fa806f6 100644 --- a/README.PROTOCOL +++ b/README.PROTOCOL @@ -232,9 +232,11 @@ a JSEP session description). Galène will interpret the `nack`, accordingly. The sender may either send a single stream per media section in the SDP, -or use rid-based simulcasting. In the latter case, it should send two -video streams, one with rid 'h' and high throughput, and one with rid 'l' -and throughput limited to roughly 100kbit/s. +or use rid-based simulcasting with the streams ordered in decreasing order +of throughput. In that case, it should send two video streams, the +first one with high throughput, and the second one with throughput limited +to roughly 100kbit/s. If more than two streams are sent, then only the +first and the last one will be considered. The receiver may either abort the stream immediately (see below), or send an answer. diff --git a/rtpconn/webclient.go b/rtpconn/webclient.go index 82cfebe..c85791a 100644 --- a/rtpconn/webclient.go +++ b/rtpconn/webclient.go @@ -743,21 +743,12 @@ func requestConns(target group.Client, g *group.Group, id string) { } } -func requestedTracks(c *webClient, override []string, up conn.Up, tracks []conn.UpTrack) ([]conn.UpTrack, bool) { - r := override - if r == nil { - var ok bool - r, ok = c.requested[up.Label()] - if !ok { - r, ok = c.requested[""] - } - if !ok || len(r) == 0 { - return nil, false - } +func requestedTracks(c *webClient, requested []string, tracks []conn.UpTrack) ([]conn.UpTrack, bool) { + if len(requested) == 0 { + return nil, false } - var audio, video, videoLow bool - for _, s := range r { + for _, s := range requested { switch s { case "audio": audio = true @@ -770,50 +761,42 @@ func requestedTracks(c *webClient, override []string, up conn.Up, tracks []conn. } } - find := func(kind webrtc.RTPCodecType, labels ...string) conn.UpTrack { - for _, l := range labels { - for _, t := range tracks { - if t.Kind() != kind { - continue - } - if t.Label() == l { - return t - } - } - } + find := func(kind webrtc.RTPCodecType, last bool) (conn.UpTrack, int) { + var track conn.UpTrack + count := 0 for _, t := range tracks { if t.Kind() != kind { continue } - return t + track = t + count++ + if !last { + break + } } - return nil + return track, count } var ts []conn.UpTrack limitSid := false if audio { - t := find(webrtc.RTPCodecTypeAudio) + t, _ := find(webrtc.RTPCodecTypeAudio, false) if t != nil { ts = append(ts, t) } } if video { - t := find( - webrtc.RTPCodecTypeVideo, "h", "m", "video", - ) + t, _ := find(webrtc.RTPCodecTypeVideo, false) if t != nil { ts = append(ts, t) } } else if videoLow { - t := find( - webrtc.RTPCodecTypeVideo, "l", "m", "video", - ) + t, count := find(webrtc.RTPCodecTypeVideo, true) if t != nil { ts = append(ts, t) - if t.Label() != "l" { - limitSid = true - } + } + if count < 2 { + limitSid = true } } @@ -1053,11 +1036,18 @@ func pushDownConn(c *webClient, id string, up conn.Up, tracks []conn.UpTrack, re } else { old = getDownConn(c, up.Id()) } - var override []string + var req []string if old != nil { - override = old.requested + req = old.requested } - requested, limitSid = requestedTracks(c, override, up, tracks) + if req == nil { + var ok bool + req, ok = c.requested[up.Label()] + if !ok { + req = c.requested[""] + } + } + requested, limitSid = requestedTracks(c, req, tracks) } if replace != "" {