Skip to content

Commit 2407bf2

Browse files
committed
Refine rtx support
Always handle header extensions from packet read from interceptor, let interceptor has consistent chance to process headers Fix rtx is not negotiated when there is multiple codecs has same mime but different profile (H264) Fix rtx stream info missed when SSRC group attr shows after base track's ssrc attr.
1 parent 0f7dd0f commit 2407bf2

File tree

4 files changed

+79
-11
lines changed

4 files changed

+79
-11
lines changed

mediaengine.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,11 @@ func (m *MediaEngine) matchRemoteCodec(remoteCodec RTPCodecParameters, typ RTPCo
414414
}
415415

416416
aptMatch := codecMatchNone
417+
var aptCodec RTPCodecParameters
417418
for _, codec := range exactMatches {
418419
if codec.PayloadType == PayloadType(payloadType) {
419420
aptMatch = codecMatchExact
421+
aptCodec = codec
420422
break
421423
}
422424
}
@@ -425,6 +427,7 @@ func (m *MediaEngine) matchRemoteCodec(remoteCodec RTPCodecParameters, typ RTPCo
425427
for _, codec := range partialMatches {
426428
if codec.PayloadType == PayloadType(payloadType) {
427429
aptMatch = codecMatchPartial
430+
aptCodec = codec
428431
break
429432
}
430433
}
@@ -434,8 +437,14 @@ func (m *MediaEngine) matchRemoteCodec(remoteCodec RTPCodecParameters, typ RTPCo
434437
return codecMatchNone, nil // not an error, we just ignore this codec we don't support
435438
}
436439

440+
// replace the apt value with the original codec's payload type
441+
toMatchCodec := remoteCodec
442+
if aptMatched, mt := codecParametersFuzzySearch(aptCodec, codecs); mt == aptMatch {
443+
toMatchCodec.SDPFmtpLine = strings.Replace(toMatchCodec.SDPFmtpLine, fmt.Sprintf("apt=%d", payloadType), fmt.Sprintf("apt=%d", aptMatched.PayloadType), 1)
444+
}
445+
437446
// if apt's media codec is partial match, then apt codec must be partial match too
438-
_, matchType := codecParametersFuzzySearch(remoteCodec, codecs)
447+
_, matchType := codecParametersFuzzySearch(toMatchCodec, codecs)
439448
if matchType == codecMatchExact && aptMatch == codecMatchPartial {
440449
matchType = codecMatchPartial
441450
}

mediaengine_test.go

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,18 @@ a=rtpmap:96 VP8/90000
308308
o=- 4596489990601351948 2 IN IP4 127.0.0.1
309309
s=-
310310
t=0 0
311-
m=video 60323 UDP/TLS/RTP/SAVPF 94 96 97
311+
m=video 60323 UDP/TLS/RTP/SAVPF 94 95 106 107 108 109 96 97
312312
a=rtpmap:94 VP8/90000
313+
a=rtpmap:95 rtx/90000
314+
a=fmtp:95 apt=94
315+
a=rtpmap:106 H264/90000
316+
a=fmtp:106 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
317+
a=rtpmap:107 rtx/90000
318+
a=fmtp:107 apt=106
319+
a=rtpmap:108 H264/90000
320+
a=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f
321+
a=rtpmap:109 rtx/90000
322+
a=fmtp:109 apt=108
313323
a=rtpmap:96 VP9/90000
314324
a=fmtp:96 profile-id=2
315325
a=rtpmap:97 rtx/90000
@@ -318,22 +328,64 @@ a=fmtp:97 apt=96
318328
m := MediaEngine{}
319329
assert.NoError(t, m.RegisterCodec(RTPCodecParameters{
320330
RTPCodecCapability: RTPCodecCapability{MimeTypeVP8, 90000, 0, "", nil},
321-
PayloadType: 94,
322-
}, RTPCodecTypeVideo))
323-
assert.NoError(t, m.RegisterCodec(RTPCodecParameters{
324-
RTPCodecCapability: RTPCodecCapability{MimeTypeVP9, 90000, 0, "profile-id=2", nil},
325331
PayloadType: 96,
326332
}, RTPCodecTypeVideo))
327333
assert.NoError(t, m.RegisterCodec(RTPCodecParameters{
328334
RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=96", nil},
329335
PayloadType: 97,
330336
}, RTPCodecTypeVideo))
337+
assert.NoError(t, m.RegisterCodec(RTPCodecParameters{
338+
RTPCodecCapability: RTPCodecCapability{MimeTypeH264, 90000, 0, "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f", nil},
339+
PayloadType: 102,
340+
}, RTPCodecTypeVideo))
341+
assert.NoError(t, m.RegisterCodec(RTPCodecParameters{
342+
RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=102", nil},
343+
PayloadType: 103,
344+
}, RTPCodecTypeVideo))
345+
assert.NoError(t, m.RegisterCodec(RTPCodecParameters{
346+
RTPCodecCapability: RTPCodecCapability{MimeTypeH264, 90000, 0, "level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f", nil},
347+
PayloadType: 104,
348+
}, RTPCodecTypeVideo))
349+
assert.NoError(t, m.RegisterCodec(RTPCodecParameters{
350+
RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=104", nil},
351+
PayloadType: 105,
352+
}, RTPCodecTypeVideo))
353+
assert.NoError(t, m.RegisterCodec(RTPCodecParameters{
354+
RTPCodecCapability: RTPCodecCapability{MimeTypeVP9, 90000, 0, "profile-id=2", nil},
355+
PayloadType: 98,
356+
}, RTPCodecTypeVideo))
357+
assert.NoError(t, m.RegisterCodec(RTPCodecParameters{
358+
RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=98", nil},
359+
PayloadType: 99,
360+
}, RTPCodecTypeVideo))
331361
assert.NoError(t, m.updateFromRemoteDescription(mustParse(profileLevels)))
332362

333363
assert.True(t, m.negotiatedVideo)
334364

335-
_, _, err := m.getCodecByPayload(97)
365+
vp9Codec, _, err := m.getCodecByPayload(96)
366+
assert.NoError(t, err)
367+
assert.Equal(t, vp9Codec.MimeType, MimeTypeVP9)
368+
vp9RTX, _, err := m.getCodecByPayload(97)
369+
assert.NoError(t, err)
370+
assert.Equal(t, vp9RTX.MimeType, "video/rtx")
371+
372+
h264P1Codec, _, err := m.getCodecByPayload(106)
373+
assert.NoError(t, err)
374+
assert.Equal(t, h264P1Codec.MimeType, MimeTypeH264)
375+
assert.Equal(t, h264P1Codec.SDPFmtpLine, "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f")
376+
h264P1RTX, _, err := m.getCodecByPayload(107)
377+
assert.NoError(t, err)
378+
assert.Equal(t, h264P1RTX.MimeType, "video/rtx")
379+
assert.Equal(t, h264P1RTX.SDPFmtpLine, "apt=106")
380+
381+
h264P0Codec, _, err := m.getCodecByPayload(108)
382+
assert.NoError(t, err)
383+
assert.Equal(t, h264P0Codec.MimeType, MimeTypeH264)
384+
assert.Equal(t, h264P0Codec.SDPFmtpLine, "level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f")
385+
h264P0RTX, _, err := m.getCodecByPayload(109)
336386
assert.NoError(t, err)
387+
assert.Equal(t, h264P0RTX.MimeType, "video/rtx")
388+
assert.Equal(t, h264P0RTX.SDPFmtpLine, "apt=108")
337389
})
338390

339391
t.Run("Matches when rtx apt for partial match codec", func(t *testing.T) {

peerconnection.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,12 +1587,11 @@ func (pc *PeerConnection) handleIncomingSSRC(rtpStream io.Reader, ssrc SSRC) err
15871587
return err
15881588
}
15891589

1590-
var mid, rid, rsid string
1591-
payloadType, paddingOnly, err := handleUnknownRTPPacket(b[:i], uint8(midExtensionID), uint8(streamIDExtensionID), uint8(repairStreamIDExtensionID), &mid, &rid, &rsid)
1592-
if err != nil {
1593-
return err
1590+
if i < 4 {
1591+
return errRTPTooShort
15941592
}
15951593

1594+
payloadType := PayloadType(b[1] & 0x7f)
15961595
params, err := pc.api.mediaEngine.getRTPParametersByPayloadType(payloadType)
15971596
if err != nil {
15981597
return err
@@ -1604,6 +1603,8 @@ func (pc *PeerConnection) handleIncomingSSRC(rtpStream io.Reader, ssrc SSRC) err
16041603
return err
16051604
}
16061605

1606+
var mid, rid, rsid string
1607+
var paddingOnly bool
16071608
for readCount := 0; readCount <= simulcastProbeCount; readCount++ {
16081609
if mid == "" || (rid == "" && rsid == "") {
16091610
// skip padding only packets for probing

sdp.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ func trackDetailsFromSDP(log logging.LeveledLogger, s *sdp.SessionDescription) (
128128
}
129129
rtxRepairFlows[rtxRepairFlow] = baseSsrc
130130
tracksInMediaSection = filterTrackWithSSRC(tracksInMediaSection, SSRC(rtxRepairFlow)) // Remove if rtx was added as track before
131+
for i := range tracksInMediaSection {
132+
if tracksInMediaSection[i].ssrcs[0] == SSRC(baseSsrc) {
133+
repairSsrc := SSRC(rtxRepairFlow)
134+
tracksInMediaSection[i].repairSsrc = &repairSsrc
135+
}
136+
}
131137
}
132138
}
133139

0 commit comments

Comments
 (0)