diff --git a/mediaengine.go b/mediaengine.go index 920f5c2ec5c..152712f53ea 100644 --- a/mediaengine.go +++ b/mediaengine.go @@ -55,6 +55,8 @@ const ( MimeTypeFlexFEC = "video/flexfec" ) +var ErrCodecAlreadyRegistered = fmt.Errorf("codec already registered for same payload type") + type mediaEngineHeaderExtension struct { uri string isAudio, isVideo bool @@ -244,14 +246,14 @@ func (m *MediaEngine) RegisterDefaultCodecs() error { } // addCodec will append codec if it not exists. -func (m *MediaEngine) addCodec(codecs []RTPCodecParameters, codec RTPCodecParameters) []RTPCodecParameters { +func (m *MediaEngine) addCodec(codecs []RTPCodecParameters, codec RTPCodecParameters) ([]RTPCodecParameters, error) { for _, c := range codecs { - if c.MimeType == codec.MimeType && c.PayloadType == codec.PayloadType { - return codecs + if c.PayloadType == codec.PayloadType { + return codecs, ErrCodecAlreadyRegistered } } - return append(codecs, codec) + return append(codecs, codec), nil } // RegisterCodec adds codec to the MediaEngine @@ -261,17 +263,18 @@ func (m *MediaEngine) RegisterCodec(codec RTPCodecParameters, typ RTPCodecType) m.mu.Lock() defer m.mu.Unlock() + var err error codec.statsID = fmt.Sprintf("RTPCodec-%d", time.Now().UnixNano()) switch typ { case RTPCodecTypeAudio: - m.audioCodecs = m.addCodec(m.audioCodecs, codec) + m.audioCodecs, err = m.addCodec(m.audioCodecs, codec) case RTPCodecTypeVideo: - m.videoCodecs = m.addCodec(m.videoCodecs, codec) + m.videoCodecs, err = m.addCodec(m.videoCodecs, codec) default: return ErrUnknownType } - return nil + return err } // RegisterHeaderExtension adds a header extension to the MediaEngine @@ -573,9 +576,9 @@ func (m *MediaEngine) updateHeaderExtension(id int, extension string, typ RTPCod func (m *MediaEngine) pushCodecs(codecs []RTPCodecParameters, typ RTPCodecType) { for _, codec := range codecs { if typ == RTPCodecTypeAudio { - m.negotiatedAudioCodecs = m.addCodec(m.negotiatedAudioCodecs, codec) + m.negotiatedAudioCodecs, _ = m.addCodec(m.negotiatedAudioCodecs, codec) } else if typ == RTPCodecTypeVideo { - m.negotiatedVideoCodecs = m.addCodec(m.negotiatedVideoCodecs, codec) + m.negotiatedVideoCodecs, _ = m.addCodec(m.negotiatedVideoCodecs, codec) } } } diff --git a/mediaengine_test.go b/mediaengine_test.go index 7f0ae392781..4da7e01e96d 100644 --- a/mediaengine_test.go +++ b/mediaengine_test.go @@ -583,7 +583,26 @@ func TestMediaEngineDoubleRegister(t *testing.T) { PayloadType: 111, }, RTPCodecTypeAudio)) + assert.Error(t, ErrCodecAlreadyRegistered, mediaEngine.RegisterCodec( + RTPCodecParameters{ + RTPCodecCapability: RTPCodecCapability{MimeTypeOpus, 48000, 0, "", nil}, + PayloadType: 111, + }, RTPCodecTypeAudio)) + + assert.Equal(t, len(mediaEngine.audioCodecs), 1) +} + +// If a user attempts to register a codec with same payload but with different codec we should just discard duplicate calls. +func TestMediaEngineDoubleRegisterDifferentCodec(t *testing.T) { + mediaEngine := MediaEngine{} + assert.NoError(t, mediaEngine.RegisterCodec( + RTPCodecParameters{ + RTPCodecCapability: RTPCodecCapability{MimeTypeG722, 8000, 0, "", nil}, + PayloadType: 111, + }, RTPCodecTypeAudio)) + + assert.Error(t, ErrCodecAlreadyRegistered, mediaEngine.RegisterCodec( RTPCodecParameters{ RTPCodecCapability: RTPCodecCapability{MimeTypeOpus, 48000, 0, "", nil}, PayloadType: 111,