diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp index 5b134a62ff8a3056e4208f996161311bd1f893d0..9225fcdd4879c51da6a7a5b692a2c862b3f3d207 100644 --- a/src/sip/sipcall.cpp +++ b/src/sip/sipcall.cpp @@ -2244,7 +2244,12 @@ SIPCall::isReinviteRequired(const std::vector<MediaAttribute>& mediaAttrList) auto streamIdx = findRtpStreamIndex(newAttr.label_); if (streamIdx == rtpStreams_.size()) { - // Always needs a reinvite when a new media is added. + // Always needs a re-invite when a new media is added. + return true; + } + + // Changing the source needs a re-invite + if (newAttr.sourceUri_ != rtpStreams_[streamIdx].mediaAttribute_->sourceUri_) { return true; } diff --git a/test/unitTest/media_negotiation/media_negotiation.cpp b/test/unitTest/media_negotiation/media_negotiation.cpp index 4dce34147199fb3fa72adf26ddb197c4f0f4aa96..ac470685b10ba5d25c4fe4e35e98cc86ce997390 100644 --- a/test/unitTest/media_negotiation/media_negotiation.cpp +++ b/test/unitTest/media_negotiation/media_negotiation.cpp @@ -113,12 +113,14 @@ private: void audio_and_video_then_mute_video(); void audio_only_then_add_video(); void audio_and_video_then_mute_audio(); + void audio_and_video_then_change_video_source(); void audio_only_then_add_video_but_peer_disabled_multistream(); CPPUNIT_TEST_SUITE(MediaNegotiationTest); CPPUNIT_TEST(audio_and_video_then_mute_video); CPPUNIT_TEST(audio_only_then_add_video); CPPUNIT_TEST(audio_and_video_then_mute_audio); + CPPUNIT_TEST(audio_and_video_then_change_video_source); CPPUNIT_TEST(audio_only_then_add_video_but_peer_disabled_multistream); CPPUNIT_TEST_SUITE_END(); @@ -842,6 +844,53 @@ MediaNegotiationTest::audio_and_video_then_mute_audio() JAMI_INFO("=== End test %s ===", __FUNCTION__); } +void +MediaNegotiationTest::audio_and_video_then_change_video_source() +{ + JAMI_INFO("=== Begin test %s ===", __FUNCTION__); + + configureScenario(aliceData_, bobData_); + + MediaAttribute defaultAudio(MediaType::MEDIA_AUDIO); + defaultAudio.label_ = "audio_0"; + defaultAudio.enabled_ = true; + + MediaAttribute defaultVideo(MediaType::MEDIA_VIDEO); + defaultVideo.label_ = "video_0"; + defaultVideo.enabled_ = true; + + { + MediaAttribute audio(defaultAudio); + MediaAttribute video(defaultVideo); + + TestScenario scenario; + // First offer/answer + scenario.offer_.emplace_back(audio); + scenario.offer_.emplace_back(video); + scenario.answer_.emplace_back(audio); + scenario.answer_.emplace_back(video); + + // Updated offer/answer + scenario.offerUpdate_.emplace_back(audio); + // Just change the media source to validate that a new + // media negotiation (re-invite) will be triggered. + video.sourceUri_ = "Fake source"; + scenario.offerUpdate_.emplace_back(video); + + scenario.answerUpdate_.emplace_back(audio); + scenario.answerUpdate_.emplace_back(video); + + scenario.expectMediaRenegotiation_ = true; + scenario.expectMediaChangeRequest_ = false; + + testWithScenario(aliceData_, bobData_, scenario); + } + + DRing::unregisterSignalHandlers(); + + JAMI_INFO("=== End test %s ===", __FUNCTION__); +} + void MediaNegotiationTest::audio_only_then_add_video_but_peer_disabled_multistream() {