Skip to content

Commit 7bfc4bf

Browse files
committed
Implement TestInterceptorNackReply
This is another end-to-end test for the NACK interceptor, it verifies that we actually get a reply to a NACK, both with and without a negotiated RTX track.
1 parent 8f77dc4 commit 7bfc4bf

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

interceptor_test.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,3 +435,138 @@ func testInterceptorNack(t *testing.T, requestNack bool) {
435435
}
436436
}
437437
}
438+
439+
// TestInterceptorNackReply is an end-to-end test for the NACK responder.
440+
// It tests that we do receive a resent packet to a NACK, both with and
441+
// without negotiating an RTX track.
442+
func TestInterceptorNackReply(t *testing.T) {
443+
to := test.TimeOut(time.Second * 20)
444+
defer to.Stop()
445+
446+
t.Run("RTX", func(t *testing.T) { testInterceptorNackReply(t, true) })
447+
t.Run("NoRTX", func(t *testing.T) { testInterceptorNackReply(t, false) })
448+
}
449+
450+
func testInterceptorNackReply(t *testing.T, negotiateRTX bool) {
451+
ir := interceptor.Registry{}
452+
m := MediaEngine{}
453+
feedback := []RTCPFeedback{{"nack", ""}}
454+
err := m.RegisterCodec(
455+
RTPCodecParameters{
456+
RTPCodecCapability: RTPCodecCapability{
457+
"video/VP8", 90000, 0,
458+
"",
459+
feedback,
460+
},
461+
PayloadType: 96,
462+
},
463+
RTPCodecTypeVideo,
464+
)
465+
assert.NoError(t, err)
466+
467+
if negotiateRTX {
468+
err = m.RegisterCodec(
469+
RTPCodecParameters{
470+
RTPCodecCapability: RTPCodecCapability{
471+
MimeTypeRTX, 90000, 0,
472+
"apt=96",
473+
feedback,
474+
},
475+
PayloadType: 97,
476+
},
477+
RTPCodecTypeVideo,
478+
)
479+
assert.NoError(t, err)
480+
}
481+
api := NewAPI(
482+
WithMediaEngine(&m),
483+
WithInterceptorRegistry(&ir),
484+
)
485+
486+
pc1, err := NewPeerConnection(Configuration{})
487+
assert.NoError(t, err)
488+
489+
track1, err := NewTrackLocalStaticRTP(
490+
RTPCodecCapability{MimeType: MimeTypeVP8},
491+
"video", "pion",
492+
)
493+
assert.NoError(t, err)
494+
sender, err := pc1.AddTrack(track1)
495+
assert.NoError(t, err)
496+
497+
pc2, err := api.NewPeerConnection(Configuration{})
498+
assert.NoError(t, err)
499+
500+
offer, err := pc1.CreateOffer(nil)
501+
assert.NoError(t, err)
502+
err = pc1.SetLocalDescription(offer)
503+
assert.NoError(t, err)
504+
<-GatheringCompletePromise(pc1)
505+
506+
err = pc2.SetRemoteDescription(*pc1.LocalDescription())
507+
assert.NoError(t, err)
508+
answer, err := pc2.CreateAnswer(nil)
509+
assert.NoError(t, err)
510+
err = pc2.SetLocalDescription(answer)
511+
assert.NoError(t, err)
512+
<-GatheringCompletePromise(pc2)
513+
514+
err = pc1.SetRemoteDescription(*pc2.LocalDescription())
515+
assert.NoError(t, err)
516+
517+
done := make(chan struct{})
518+
pc2.OnTrack(func(track2 *TrackRemote, _ *RTPReceiver) {
519+
defer close(done)
520+
p, _, err2 := track2.ReadRTP()
521+
assert.NoError(t, err2)
522+
time.Sleep(20 * time.Millisecond)
523+
err2 = pc2.WriteRTCP([]rtcp.Packet{
524+
&rtcp.TransportLayerNack{
525+
MediaSSRC: uint32(track2.SSRC()),
526+
Nacks: rtcp.NackPairsFromSequenceNumbers(
527+
[]uint16{p.SequenceNumber},
528+
),
529+
},
530+
})
531+
assert.NoError(t, err2)
532+
p2, _, err2 := track2.ReadRTP()
533+
assert.NoError(t, err2)
534+
assert.Equal(t, p.SequenceNumber, p2.SequenceNumber)
535+
assert.Equal(t, p.Timestamp, p2.Timestamp)
536+
assert.Equal(t, p.Payload, p2.Payload)
537+
})
538+
539+
rtcpDone := make(chan struct{})
540+
go func() {
541+
defer close(rtcpDone)
542+
buf := make([]byte, 1500)
543+
for {
544+
_, _, err2 := sender.Read(buf)
545+
// nolint
546+
if err2 == io.EOF {
547+
break
548+
}
549+
assert.NoError(t, err2)
550+
}
551+
}()
552+
553+
go func() {
554+
time.Sleep(20 * time.Millisecond)
555+
var p rtp.Packet
556+
p.Version = 2
557+
p.Marker = true
558+
p.PayloadType = 96
559+
p.SequenceNumber = 0
560+
p.Timestamp = 0
561+
p.Payload = []byte{42}
562+
err2 := track1.WriteRTP(&p)
563+
assert.NoError(t, err2)
564+
}()
565+
566+
<-done
567+
err = pc1.Close()
568+
assert.NoError(t, err)
569+
err = pc2.Close()
570+
assert.NoError(t, err)
571+
<-rtcpDone
572+
}

0 commit comments

Comments
 (0)