Add SetFireOnTrackBeforeFirstRTP

This commit is contained in:
Eric Daniels
2024-10-15 12:04:40 -04:00
parent 8fbf8219dd
commit 76634b143a
3 changed files with 68 additions and 0 deletions

View File

@@ -1245,6 +1245,10 @@ func (pc *PeerConnection) startReceiver(incoming trackDetails, receiver *RTPRece
return
}
if pc.api.settingEngine.fireOnTrackBeforeFirstRTP {
pc.onTrack(t, receiver)
return
}
go func(track *TrackRemote) {
b := make([]byte, pc.api.settingEngine.getReceiveMTU())
n, _, err := track.peek(b)

View File

@@ -101,6 +101,7 @@ type SettingEngine struct {
srtpProtectionProfiles []dtls.SRTPProtectionProfile
receiveMTU uint
iceMaxBindingRequests *uint16
fireOnTrackBeforeFirstRTP bool
}
// getReceiveMTU returns the configured MTU. If SettingEngine's MTU is configured to 0 it returns the default
@@ -491,3 +492,12 @@ func (e *SettingEngine) SetSCTPRTOMax(rtoMax time.Duration) {
func (e *SettingEngine) SetICEBindingRequestHandler(bindingRequestHandler func(m *stun.Message, local, remote ice.Candidate, pair *ice.CandidatePair) bool) {
e.iceBindingRequestHandler = bindingRequestHandler
}
// SetFireOnTrackBeforeFirstRTP sets if firing the OnTrack event should happen
// before any RTP packets are received. Setting this to true will
// have the Track's Codec and PayloadTypes be initially set to their
// zero values in the OnTrack handler.
// Note: This does not yet affect simulcast tracks.
func (e *SettingEngine) SetFireOnTrackBeforeFirstRTP(fireOnTrackBeforeFirstRTP bool) {
e.fireOnTrackBeforeFirstRTP = fireOnTrackBeforeFirstRTP
}

View File

@@ -340,3 +340,57 @@ func TestSetHooks(t *testing.T) {
t.Errorf("Failed to set DTLS Certificate Request Hook")
}
}
func TestSetFireOnTrackBeforeFirstRTP(t *testing.T) {
lim := test.TimeOut(time.Second * 30)
defer lim.Stop()
report := test.CheckRoutines(t)
defer report()
s := SettingEngine{}
s.SetFireOnTrackBeforeFirstRTP(true)
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), WithSettingEngine(s)).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) {
_, _, err = track.Read(make([]byte, 1500))
assert.NoError(t, err)
assert.Equal(t, track.PayloadType(), PayloadType(100))
assert.Equal(t, track.Codec().RTPCodecCapability.MimeType, "video/VP8")
onTrackFiredFunc()
})
assert.NoError(t, signalPair(offerer, answerer))
sendVideoUntilDone(onTrackFired.Done(), t, []*TrackLocalStaticSample{track})
closePairNow(t, offerer, answerer)
}