diff --git a/interceptor.go b/interceptor.go index 5d7dea4c89c..0695538e7e5 100644 --- a/interceptor.go +++ b/interceptor.go @@ -222,6 +222,7 @@ func createStreamInfo( payloadType, payloadTypeRTX, payloadTypeFEC PayloadType, codec RTPCodecCapability, webrtcHeaderExtensions []RTPHeaderExtensionParameter, + codecs []RTPCodecParameters, ) *interceptor.StreamInfo { headerExtensions := make([]interceptor.RTPHeaderExtension, 0, len(webrtcHeaderExtensions)) for _, h := range webrtcHeaderExtensions { @@ -233,6 +234,11 @@ func createStreamInfo( feedbacks = append(feedbacks, interceptor.RTCPFeedback{Type: f.Type, Parameter: f.Parameter}) } + payloadToMimeType := make(map[uint8]string) + for _, c := range codecs { + payloadToMimeType[uint8(c.PayloadType)] = c.MimeType + } + return &interceptor.StreamInfo{ ID: id, Attributes: interceptor.Attributes{}, @@ -248,5 +254,6 @@ func createStreamInfo( Channels: codec.Channels, SDPFmtpLine: codec.SDPFmtpLine, RTCPFeedback: feedbacks, + PayloadToMimeType: payloadToMimeType, } } diff --git a/interceptor_test.go b/interceptor_test.go index 335ee0f368a..241135e3ae8 100644 --- a/interceptor_test.go +++ b/interceptor_test.go @@ -28,6 +28,7 @@ import ( // * Assert an extension can be set on an outbound packet // * Assert an extension can be read on an outbound packet // * Assert that attributes set by an interceptor are returned to the Reader. +// * Assert that StreamInfo.Codecs contain capabilities of all negotiated codecs for track's SSRC func TestPeerConnection_Interceptor(t *testing.T) { to := test.TimeOut(time.Second * 20) defer to.Stop() @@ -36,11 +37,35 @@ func TestPeerConnection_Interceptor(t *testing.T) { defer report() createPC := func() *PeerConnection { + videoRTCPFeedback := []RTCPFeedback{{"goog-remb", ""}, {"ccm", "fir"}, {"nack", ""}, {"nack", "pli"}} + videoCodecs := []RTPCodecParameters{ + { + RTPCodecCapability: RTPCodecCapability{MimeTypeVP8, 90000, 0, "", videoRTCPFeedback}, + PayloadType: 96, + }, + { + RTPCodecCapability: RTPCodecCapability{MimeTypeVP9, 90000, 0, "profile-id=0", videoRTCPFeedback}, + PayloadType: 98, + }, + } + + me := &MediaEngine{} + for _, videoCodec := range videoCodecs { + err := me.RegisterCodec(videoCodec, RTPCodecTypeVideo) + assert.NoError(t, err) + } + + payloadToMimeType := make(map[uint8]string) + for _, c := range videoCodecs { + payloadToMimeType[uint8(c.PayloadType)] = c.MimeType + } + ir := &interceptor.Registry{} ir.Add(&mock_interceptor.Factory{ NewInterceptorFn: func(_ string) (interceptor.Interceptor, error) { return &mock_interceptor.Interceptor{ - BindLocalStreamFn: func(_ *interceptor.StreamInfo, writer interceptor.RTPWriter) interceptor.RTPWriter { + BindLocalStreamFn: func(streamInfo *interceptor.StreamInfo, writer interceptor.RTPWriter) interceptor.RTPWriter { + assert.Equal(t, payloadToMimeType, streamInfo.PayloadToMimeType) return interceptor.RTPWriterFunc( func(header *rtp.Header, payload []byte, attributes interceptor.Attributes) (int, error) { // set extension on outgoing packet @@ -52,7 +77,8 @@ func TestPeerConnection_Interceptor(t *testing.T) { }, ) }, - BindRemoteStreamFn: func(_ *interceptor.StreamInfo, reader interceptor.RTPReader) interceptor.RTPReader { + BindRemoteStreamFn: func(streamInfo *interceptor.StreamInfo, reader interceptor.RTPReader) interceptor.RTPReader { + assert.Equal(t, payloadToMimeType, streamInfo.PayloadToMimeType) return interceptor.RTPReaderFunc(func(b []byte, a interceptor.Attributes) (int, interceptor.Attributes, error) { if a == nil { a = interceptor.Attributes{} @@ -67,7 +93,7 @@ func TestPeerConnection_Interceptor(t *testing.T) { }, }) - pc, err := NewAPI(WithInterceptorRegistry(ir)).NewPeerConnection(Configuration{}) + pc, err := NewAPI(WithInterceptorRegistry(ir), WithMediaEngine(me)).NewPeerConnection(Configuration{}) assert.NoError(t, err) return pc diff --git a/peerconnection.go b/peerconnection.go index 50b05cd058b..b3c1ee86e14 100644 --- a/peerconnection.go +++ b/peerconnection.go @@ -1778,6 +1778,7 @@ func (pc *PeerConnection) handleIncomingSSRC(rtpStream io.Reader, ssrc SSRC) err 0, 0, params.Codecs[0].RTPCodecCapability, params.HeaderExtensions, + params.Codecs, ) readStream, interceptor, rtcpReadStream, rtcpInterceptor, err := pc.dtlsTransport.streamsForSSRC(ssrc, *streamInfo) if err != nil { diff --git a/rtpreceiver.go b/rtpreceiver.go index 0e85b2d958c..6527ff2a441 100644 --- a/rtpreceiver.go +++ b/rtpreceiver.go @@ -224,6 +224,7 @@ func (r *RTPReceiver) startReceive(parameters RTPReceiveParameters) error { //no 0, 0, 0, 0, 0, codec, globalParams.HeaderExtensions, + globalParams.Codecs, ) var err error @@ -233,7 +234,7 @@ func (r *RTPReceiver) startReceive(parameters RTPReceiveParameters) error { //no } if rtxSsrc := parameters.Encodings[i].RTX.SSRC; rtxSsrc != 0 { - streamInfo := createStreamInfo("", rtxSsrc, 0, 0, 0, 0, 0, codec, globalParams.HeaderExtensions) + streamInfo := createStreamInfo("", rtxSsrc, 0, 0, 0, 0, 0, codec, globalParams.HeaderExtensions, globalParams.Codecs) rtpReadStream, rtpInterceptor, rtcpReadStream, rtcpInterceptor, err := r.transport.streamsForSSRC( rtxSsrc, *streamInfo, diff --git a/rtpsender.go b/rtpsender.go index dd4107ecbc0..e70d3cd9754 100644 --- a/rtpsender.go +++ b/rtpsender.go @@ -358,6 +358,7 @@ func (r *RTPSender) Send(parameters RTPSendParameters) error { findFECPayloadType(rtpParameters.Codecs), codec.RTPCodecCapability, parameters.HeaderExtensions, + parameters.Codecs, ) rtpInterceptor := r.api.interceptor.BindLocalStream(