Add padding support to TrackLocalStaticSample

To add padding-only samples call GeneratePadding
This commit is contained in:
Alex Pokotilo 2024-04-10 14:32:42 +06:00 committed by Sean DuBois
parent b2af663a46
commit e60bf03293
2 changed files with 86 additions and 0 deletions

View File

@ -304,3 +304,28 @@ func (s *TrackLocalStaticSample) WriteSample(sample media.Sample) error {
return util.FlattenErrs(writeErrs)
}
// GeneratePadding writes padding-only samples to the TrackLocalStaticSample
// If one PeerConnection fails the packets will still be sent to
// all PeerConnections. The error message will contain the ID of the failed
// PeerConnections so you can remove them
func (s *TrackLocalStaticSample) GeneratePadding(samples uint32) error {
s.rtpTrack.mu.RLock()
p := s.packetizer
s.rtpTrack.mu.RUnlock()
if p == nil {
return nil
}
packets := p.GeneratePadding(samples)
writeErrs := []error{}
for _, p := range packets {
if err := s.rtpTrack.WriteRTP(p); err != nil {
writeErrs = append(writeErrs, err)
}
}
return util.FlattenErrs(writeErrs)
}

View File

@ -252,3 +252,64 @@ func BenchmarkTrackLocalWrite(b *testing.B) {
assert.NoError(b, err)
}
}
func Test_TrackLocalStatic_Padding(t *testing.T) {
mediaEngineOne := &MediaEngine{}
assert.NoError(t, mediaEngineOne.RegisterCodec(RTPCodecParameters{
RTPCodecCapability: RTPCodecCapability{MimeType: "video/VP8", ClockRate: 90000, Channels: 0, SDPFmtpLine: "", RTCPFeedback: nil},
PayloadType: 100,
}, RTPCodecTypeVideo))
mediaEngineTwo := &MediaEngine{}
assert.NoError(t, mediaEngineTwo.RegisterCodec(RTPCodecParameters{
RTPCodecCapability: RTPCodecCapability{MimeType: "video/VP8", ClockRate: 90000, Channels: 0, SDPFmtpLine: "", RTCPFeedback: nil},
PayloadType: 200,
}, RTPCodecTypeVideo))
offerer, err := NewAPI(WithMediaEngine(mediaEngineOne)).NewPeerConnection(Configuration{})
assert.NoError(t, err)
answerer, err := NewAPI(WithMediaEngine(mediaEngineTwo)).NewPeerConnection(Configuration{})
assert.NoError(t, err)
track, err := NewTrackLocalStaticSample(RTPCodecCapability{MimeType: MimeTypeVP8}, "video", "pion")
assert.NoError(t, err)
_, err = offerer.AddTransceiverFromKind(RTPCodecTypeVideo)
assert.NoError(t, err)
_, err = answerer.AddTrack(track)
assert.NoError(t, err)
onTrackFired, onTrackFiredFunc := context.WithCancel(context.Background())
offerer.OnTrack(func(track *TrackRemote, _ *RTPReceiver) {
assert.Equal(t, track.PayloadType(), PayloadType(100))
assert.Equal(t, track.Codec().RTPCodecCapability.MimeType, "video/VP8")
for i := 0; i < 20; i++ {
// Padding payload
p, _, e := track.ReadRTP()
assert.NoError(t, e)
assert.True(t, p.Padding)
assert.Equal(t, p.PaddingSize, byte(255))
}
onTrackFiredFunc()
})
assert.NoError(t, signalPair(offerer, answerer))
exit := false
for !exit {
select {
case <-time.After(1 * time.Millisecond):
assert.NoError(t, track.GeneratePadding(1))
case <-onTrackFired.Done():
exit = true
}
}
closePairNow(t, offerer, answerer)
}