Skip to content

Commit

Permalink
Answer to paused simucalst stream correctly
Browse files Browse the repository at this point in the history
Answer to paused simucalst stream correctly
  • Loading branch information
cnderrauber committed Dec 14, 2023
1 parent f369fda commit 462a717
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 17 deletions.
2 changes: 2 additions & 0 deletions constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const (

sdpAttributeRid = "rid"

sdpAttributeSimulcast = "simulcast"

rtpOutboundMTU = 1200

rtpPayloadTypeBitmask = 0x7F
Expand Down
38 changes: 32 additions & 6 deletions sdp.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,12 +232,30 @@ func trackDetailsToRTPReceiveParameters(t *trackDetails) RTPReceiveParameters {
return RTPReceiveParameters{Encodings: encodings}
}

func getRids(media *sdp.MediaDescription) map[string]string {
rids := map[string]string{}
func getRids(media *sdp.MediaDescription) map[string]*simulcastRid {
rids := map[string]*simulcastRid{}
var simulcastAttr string
for _, attr := range media.Attributes {
if attr.Key == sdpAttributeRid {
split := strings.Split(attr.Value, " ")
rids[split[0]] = attr.Value
rids[split[0]] = &simulcastRid{attrValue: attr.Value}
} else if attr.Key == sdpAttributeSimulcast {
simulcastAttr = attr.Value
}
}
// process paused stream like "a=simulcast:send 1;~2;~3"
if simulcastAttr != "" {
if space := strings.Index(simulcastAttr, " "); space > 0 {
simulcastAttr = simulcastAttr[space+1:]
}
ridStates := strings.Split(simulcastAttr, ";")
for _, ridState := range ridStates {
if ridState[:1] == "~" {
rid := ridState[1:]
if r, ok := rids[rid]; ok {
r.paused = true
}
}
}
}
return rids
Expand Down Expand Up @@ -379,7 +397,7 @@ func addSenderSDP(
sendRids = append(sendRids, encoding.RID)
}
// Simulcast
media.WithValueAttribute("simulcast", "send "+strings.Join(sendRids, ";"))
media.WithValueAttribute(sdpAttributeSimulcast, "send "+strings.Join(sendRids, ";"))
}

if !isPlanB {
Expand Down Expand Up @@ -475,10 +493,13 @@ func addTransceiverSDP(

for rid := range mediaSection.ridMap {
media.WithValueAttribute(sdpAttributeRid, rid+" recv")
if mediaSection.ridMap[rid].paused {
rid = "~" + rid
}
recvRids = append(recvRids, rid)
}
// Simulcast
media.WithValueAttribute("simulcast", "recv "+strings.Join(recvRids, ";"))
media.WithValueAttribute(sdpAttributeSimulcast, "recv "+strings.Join(recvRids, ";"))
}

addSenderSDP(mediaSection, isPlanB, media)
Expand All @@ -500,11 +521,16 @@ func addTransceiverSDP(
return true, nil
}

type simulcastRid struct {
attrValue string
paused bool
}

type mediaSection struct {
id string
transceivers []*RTPTransceiver
data bool
ridMap map[string]string
ridMap map[string]*simulcastRid
}

func bundleMatchFromRemote(matchBundleGroup *string) func(mid string) bool {
Expand Down
27 changes: 16 additions & 11 deletions sdp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,14 @@ func TestPopulateSDP(t *testing.T) {

tr := &RTPTransceiver{kind: RTPCodecTypeVideo, api: api, codecs: me.videoCodecs}
tr.setDirection(RTPTransceiverDirectionRecvonly)
ridMap := map[string]string{
"ridkey": "some",
ridMap := map[string]*simulcastRid{
"ridkey": {
attrValue: "some",
},
"ridPaused": {
attrValue: "some2",
paused: true,
},
}
mediaSections := []mediaSection{{id: "video", transceivers: []*RTPTransceiver{tr}, ridMap: ridMap}}

Expand All @@ -392,21 +398,20 @@ func TestPopulateSDP(t *testing.T) {
assert.Nil(t, err)

// Test contains rid map keys
var found bool
var ridFound int
for _, desc := range offerSdp.MediaDescriptions {
if desc.MediaName.Media != "video" {
continue
}
for _, a := range desc.Attributes {
if a.Key == sdpAttributeRid {
if strings.Contains(a.Value, "ridkey") {
found = true
break
}
}
ridInSDP := getRids(desc)
if ridKey, ok := ridInSDP["ridkey"]; ok && !ridKey.paused {
ridFound++
}
if ridPaused, ok := ridInSDP["ridPaused"]; ok && ridPaused.paused {
ridFound++
}
}
assert.Equal(t, true, found, "Rid key should be present")
assert.Equal(t, 2, ridFound, "All rid keys should be present")
})
t.Run("SetCodecPreferences", func(t *testing.T) {
se := SettingEngine{}
Expand Down

0 comments on commit 462a717

Please sign in to comment.