Skip to content
This repository has been archived by the owner on Mar 16, 2022. It is now read-only.

Commit

Permalink
Implement answering to RIDs
Browse files Browse the repository at this point in the history
When responding to a remote description
with RIDs we now properly respond
  • Loading branch information
jbrady42 authored and Sean-Der committed Jul 10, 2020
1 parent 1b14767 commit 5895668
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 6 deletions.
2 changes: 1 addition & 1 deletion peerconnection.go
Original file line number Diff line number Diff line change
Expand Up @@ -1866,7 +1866,7 @@ func (pc *PeerConnection) generateMatchedSDP(useIdentity bool, includeUnmatched
t.Sender().setNegotiated()
}
mediaTransceivers := []*RTPTransceiver{t}
mediaSections = append(mediaSections, mediaSection{id: midValue, transceivers: mediaTransceivers})
mediaSections = append(mediaSections, mediaSection{id: midValue, transceivers: mediaTransceivers, ridMap: getRids(media)})
}
}

Expand Down
29 changes: 26 additions & 3 deletions sdp.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,31 @@ func trackDetailsFromSDP(log logging.LeveledLogger, s *sdp.SessionDescription) m

// Plan B might send multiple a=ssrc lines under a single m= section. This is also why a single trackDetails{}
// is not defined at the top of the loop over s.MediaDescriptions.
incomingTracks[uint32(ssrc)] = trackDetails{midValue, codecType, trackLabel, trackID, uint32(ssrc)}
incomingTracks[uint32(ssrc)] = trackDetails{
mid: midValue,
kind: codecType,
label: trackLabel,
id: trackID,
ssrc: uint32(ssrc),
}
}
}
}

return incomingTracks
}

func getRids(media *sdp.MediaDescription) map[string]string {
rids := map[string]string{}
for _, attr := range media.Attributes {
if attr.Key == "rid" {
split := strings.Split(attr.Value, " ")
rids[split[0]] = attr.Value
}
}
return rids
}

func addCandidatesToMediaDescriptions(candidates []ICECandidate, m *sdp.MediaDescription, iceGatheringState ICEGatheringState) {
appendCandidateIfNew := func(c sdp.ICECandidate, attributes []sdp.Attribute) {
marshaled := c.Marshal()
Expand Down Expand Up @@ -210,7 +227,8 @@ func populateLocalCandidates(sessionDescription *SessionDescription, i *ICEGathe
}
}

func addTransceiverSDP(d *sdp.SessionDescription, isPlanB bool, dtlsFingerprints []DTLSFingerprint, mediaEngine *MediaEngine, midValue string, iceParams ICEParameters, candidates []ICECandidate, dtlsRole sdp.ConnectionRole, iceGatheringState ICEGatheringState, extMaps map[SDPSectionType][]sdp.ExtMap, transceivers ...*RTPTransceiver) (bool, error) {
func addTransceiverSDP(d *sdp.SessionDescription, isPlanB bool, dtlsFingerprints []DTLSFingerprint, mediaEngine *MediaEngine, midValue string, iceParams ICEParameters, candidates []ICECandidate, dtlsRole sdp.ConnectionRole, iceGatheringState ICEGatheringState, extMaps map[SDPSectionType][]sdp.ExtMap, mediaSection mediaSection) (bool, error) {
transceivers := mediaSection.transceivers
if len(transceivers) < 1 {
return false, fmt.Errorf("addTransceiverSDP() called with 0 transceivers")
}
Expand Down Expand Up @@ -251,6 +269,10 @@ func addTransceiverSDP(d *sdp.SessionDescription, isPlanB bool, dtlsFingerprints
}
}

for rid := range mediaSection.ridMap {
media.WithValueAttribute("rid", rid+" recv")
}

for _, mt := range transceivers {
if mt.Sender() != nil && mt.Sender().track != nil {
track := mt.Sender().track
Expand Down Expand Up @@ -278,6 +300,7 @@ type mediaSection struct {
id string
transceivers []*RTPTransceiver
data bool
ridMap map[string]string
}

// populateSDP serializes a PeerConnections state into an SDP
Expand Down Expand Up @@ -307,7 +330,7 @@ func populateSDP(d *sdp.SessionDescription, isPlanB bool, dtlsFingerprints []DTL
if m.data {
addDataMediaSection(d, mediaDtlsFingerprints, m.id, iceParams, candidates, connectionRole, iceGatheringState)
} else {
shouldAddID, err = addTransceiverSDP(d, isPlanB, mediaDtlsFingerprints, mediaEngine, m.id, iceParams, candidates, connectionRole, iceGatheringState, extMaps, m.transceivers...)
shouldAddID, err = addTransceiverSDP(d, isPlanB, mediaDtlsFingerprints, mediaEngine, m.id, iceParams, candidates, connectionRole, iceGatheringState, extMaps, m)
if err != nil {
return nil, err
}
Expand Down
69 changes: 67 additions & 2 deletions sdp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,15 @@ func TestTrackDetailsFromSDP(t *testing.T) {
{Key: "ssrc", Value: "5000"},
},
},
{
MediaName: sdp.MediaName{
Media: "video",
},
Attributes: []sdp.Attribute{
{Key: "sendonly"},
{Key: "rid", Value: "f send pt=97;max-width=1280;max-height=720"},
},
},
},
}

Expand Down Expand Up @@ -257,7 +266,6 @@ func TestTrackDetailsFromSDP(t *testing.T) {
},
},
}

assert.Equal(t, 0, len(trackDetailsFromSDP(nil, s)))
})
}
Expand Down Expand Up @@ -356,7 +364,7 @@ func TestMediaDescriptionFingerprints(t *testing.T) {
}

func TestPopulateSDP(t *testing.T) {
t.Run("Offer", func(t *testing.T) {
t.Run("Extensions", func(t *testing.T) {
transportCCURL, _ := url.Parse(sdp.TransportCCURI)
absSendURL, _ := url.Parse(sdp.ABSSendTimeURI)

Expand Down Expand Up @@ -416,6 +424,42 @@ func TestPopulateSDP(t *testing.T) {
// Test video does not contain global
assert.Equal(t, false, foundGlobal, "Global extension should not be present in video section")
})

t.Run("Rid", func(t *testing.T) {
tr := &RTPTransceiver{kind: RTPCodecTypeVideo}
tr.setDirection(RTPTransceiverDirectionRecvonly)
ridMap := map[string]string{
"ridkey": "some",
}
mediaSections := []mediaSection{{id: "video", transceivers: []*RTPTransceiver{tr}, ridMap: ridMap}}

se := SettingEngine{}

m := MediaEngine{}
m.RegisterDefaultCodecs()

d := &sdp.SessionDescription{}

offerSdp, err := populateSDP(d, false, []DTLSFingerprint{}, se.sdpMediaLevelFingerprints, se.candidates.ICELite, &m, connectionRoleFromDtlsRole(defaultDtlsRoleOffer), []ICECandidate{}, ICEParameters{}, mediaSections, ICEGatheringStateComplete, se.getSDPExtensions())
assert.Nil(t, err)

// Test contains rid map keys
var found bool
for _, desc := range offerSdp.MediaDescriptions {
if desc.MediaName.Media != mediaNameVideo {
continue
}
for _, a := range desc.Attributes {
if a.Key == "rid" {
if strings.Contains(a.Value, "ridkey") {
found = true
break
}
}
}
}
assert.Equal(t, true, found, "Rid key should be present")
})
}

func TestMatchedAnswerExt(t *testing.T) {
Expand Down Expand Up @@ -466,3 +510,24 @@ func TestMatchedAnswerExt(t *testing.T) {
t.Fatal("No video ext maps found")
}
}

func TestGetRIDs(t *testing.T) {
m := []*sdp.MediaDescription{
{
MediaName: sdp.MediaName{
Media: "video",
},
Attributes: []sdp.Attribute{
{Key: "sendonly"},
{Key: "rid", Value: "f send pt=97;max-width=1280;max-height=720"},
},
},
}

rids := getRids(m[0])

assert.NotEmpty(t, rids, "Rid mapping should be present")
if _, ok := rids["f"]; !ok {
assert.Fail(t, "rid values should contain 'f'")
}
}

0 comments on commit 5895668

Please sign in to comment.