diff --git a/media/base/fake_media_engine.cc b/media/base/fake_media_engine.cc index d1302342f3..c31ef97786 100644 --- a/media/base/fake_media_engine.cc +++ b/media/base/fake_media_engine.cc @@ -147,18 +147,18 @@ bool FakeVoiceMediaChannel::InsertDtmf(uint32_t ssrc, return true; } bool FakeVoiceMediaChannel::SetOutputVolume(uint32_t ssrc, double volume) { - if (0 == ssrc) { - std::map::iterator it; - for (it = output_scalings_.begin(); it != output_scalings_.end(); ++it) { - it->second = volume; - } - return true; - } else if (output_scalings_.find(ssrc) != output_scalings_.end()) { + if (output_scalings_.find(ssrc) != output_scalings_.end()) { output_scalings_[ssrc] = volume; return true; } return false; } +bool FakeVoiceMediaChannel::SetDefaultOutputVolume(double volume) { + for (auto& entry : output_scalings_) { + entry.second = volume; + } + return true; +} bool FakeVoiceMediaChannel::GetOutputVolume(uint32_t ssrc, double* volume) { if (output_scalings_.find(ssrc) == output_scalings_.end()) return false; @@ -190,6 +190,10 @@ void FakeVoiceMediaChannel::SetRawAudioSink( std::unique_ptr sink) { sink_ = std::move(sink); } +void FakeVoiceMediaChannel::SetDefaultRawAudioSink( + std::unique_ptr sink) { + sink_ = std::move(sink); +} std::vector FakeVoiceMediaChannel::GetSources( uint32_t ssrc) const { return std::vector(); @@ -308,14 +312,15 @@ bool FakeVideoMediaChannel::GetSendCodec(VideoCodec* send_codec) { bool FakeVideoMediaChannel::SetSink( uint32_t ssrc, rtc::VideoSinkInterface* sink) { - if (ssrc != 0 && sinks_.find(ssrc) == sinks_.end()) { + auto it = sinks_.find(ssrc); + if (it == sinks_.end()) { return false; } - if (ssrc != 0) { - sinks_[ssrc] = sink; - } + it->second = sink; return true; } +void FakeVideoMediaChannel::SetDefaultSink( + rtc::VideoSinkInterface* sink) {} bool FakeVideoMediaChannel::HasSink(uint32_t ssrc) const { return sinks_.find(ssrc) != sinks_.end() && sinks_.at(ssrc) != nullptr; } diff --git a/media/base/fake_media_engine.h b/media/base/fake_media_engine.h index aa713d04f0..3df8f85965 100644 --- a/media/base/fake_media_engine.h +++ b/media/base/fake_media_engine.h @@ -168,6 +168,9 @@ class RtpHelper : public Base { } return webrtc::RtpParameters(); } + virtual webrtc::RtpParameters GetDefaultRtpReceiveParameters() const { + return webrtc::RtpParameters(); + } bool IsStreamMuted(uint32_t ssrc) const { bool ret = muted_streams_.find(ssrc) != muted_streams_.end(); @@ -338,6 +341,8 @@ class FakeVoiceMediaChannel : public RtpHelper { bool InsertDtmf(uint32_t ssrc, int event_code, int duration) override; bool SetOutputVolume(uint32_t ssrc, double volume) override; + bool SetDefaultOutputVolume(double volume) override; + bool GetOutputVolume(uint32_t ssrc, double* volume); bool SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, int delay_ms) override; @@ -349,6 +354,8 @@ class FakeVoiceMediaChannel : public RtpHelper { void SetRawAudioSink( uint32_t ssrc, std::unique_ptr sink) override; + void SetDefaultRawAudioSink( + std::unique_ptr sink) override; std::vector GetSources(uint32_t ssrc) const override; @@ -415,6 +422,8 @@ class FakeVideoMediaChannel : public RtpHelper { bool GetSendCodec(VideoCodec* send_codec) override; bool SetSink(uint32_t ssrc, rtc::VideoSinkInterface* sink) override; + void SetDefaultSink( + rtc::VideoSinkInterface* sink) override; bool HasSink(uint32_t ssrc) const; bool SetSend(bool send) override; diff --git a/media/base/media_channel.h b/media/base/media_channel.h index be4730e6b3..90c33bd7a6 100644 --- a/media/base/media_channel.h +++ b/media/base/media_channel.h @@ -802,12 +802,11 @@ class VoiceMediaChannel : public MediaChannel, public Delayable { virtual bool SetSendParameters(const AudioSendParameters& params) = 0; virtual bool SetRecvParameters(const AudioRecvParameters& params) = 0; // Get the receive parameters for the incoming stream identified by |ssrc|. - // If |ssrc| is 0, retrieve the receive parameters for the default receive - // stream, which is used when SSRCs are not signaled. Note that calling with - // an |ssrc| of 0 will return encoding parameters with an unset |ssrc| - // member. virtual webrtc::RtpParameters GetRtpReceiveParameters( uint32_t ssrc) const = 0; + // Retrieve the receive parameters for the default receive + // stream, which is used when SSRCs are not signaled. + virtual webrtc::RtpParameters GetDefaultRtpReceiveParameters() const = 0; // Starts or stops playout of received audio. virtual void SetPlayout(bool playout) = 0; // Starts or stops sending (and potentially capture) of local audio. @@ -819,6 +818,8 @@ class VoiceMediaChannel : public MediaChannel, public Delayable { AudioSource* source) = 0; // Set speaker output volume of the specified ssrc. virtual bool SetOutputVolume(uint32_t ssrc, double volume) = 0; + // Set speaker output volume for future unsignaled streams. + virtual bool SetDefaultOutputVolume(double volume) = 0; // Returns if the telephone-event has been negotiated. virtual bool CanInsertDtmf() = 0; // Send a DTMF |event|. The DTMF out-of-band signal will be used. @@ -832,6 +833,8 @@ class VoiceMediaChannel : public MediaChannel, public Delayable { virtual void SetRawAudioSink( uint32_t ssrc, std::unique_ptr sink) = 0; + virtual void SetDefaultRawAudioSink( + std::unique_ptr sink) = 0; virtual std::vector GetSources(uint32_t ssrc) const = 0; }; @@ -868,12 +871,11 @@ class VideoMediaChannel : public MediaChannel, public Delayable { virtual bool SetSendParameters(const VideoSendParameters& params) = 0; virtual bool SetRecvParameters(const VideoRecvParameters& params) = 0; // Get the receive parameters for the incoming stream identified by |ssrc|. - // If |ssrc| is 0, retrieve the receive parameters for the default receive - // stream, which is used when SSRCs are not signaled. Note that calling with - // an |ssrc| of 0 will return encoding parameters with an unset |ssrc| - // member. virtual webrtc::RtpParameters GetRtpReceiveParameters( uint32_t ssrc) const = 0; + // Retrieve the receive parameters for the default receive + // stream, which is used when SSRCs are not signaled. + virtual webrtc::RtpParameters GetDefaultRtpReceiveParameters() const = 0; // Gets the currently set codecs/payload types to be used for outgoing media. virtual bool GetSendCodec(VideoCodec* send_codec) = 0; // Starts or stops transmission (and potentially capture) of local video. @@ -885,9 +887,11 @@ class VideoMediaChannel : public MediaChannel, public Delayable { const VideoOptions* options, rtc::VideoSourceInterface* source) = 0; // Sets the sink object to be used for the specified stream. - // If SSRC is 0, the sink is used for the 'default' stream. virtual bool SetSink(uint32_t ssrc, rtc::VideoSinkInterface* sink) = 0; + // The sink is used for the 'default' stream. + virtual void SetDefaultSink( + rtc::VideoSinkInterface* sink) = 0; // This fills the "bitrate parts" (rtx, video bitrate) of the // BandwidthEstimationInfo, since that part that isn't possible to get // through webrtc::Call::GetStats, as they are statistics of the send diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index 7f241c86aa..a5afcb3fe6 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -923,26 +923,34 @@ webrtc::RtpParameters WebRtcVideoChannel::GetRtpReceiveParameters( uint32_t ssrc) const { RTC_DCHECK_RUN_ON(&thread_checker_); webrtc::RtpParameters rtp_params; - // SSRC of 0 represents an unsignaled receive stream. - if (ssrc == 0) { - if (!default_unsignalled_ssrc_handler_.GetDefaultSink()) { - RTC_LOG(LS_WARNING) - << "Attempting to get RTP parameters for the default, " - "unsignaled video receive stream, but not yet " - "configured to receive such a stream."; - return rtp_params; - } - rtp_params.encodings.emplace_back(); - } else { - auto it = receive_streams_.find(ssrc); - if (it == receive_streams_.end()) { - RTC_LOG(LS_WARNING) - << "Attempting to get RTP receive parameters for stream " - << "with SSRC " << ssrc << " which doesn't exist."; - return webrtc::RtpParameters(); - } - rtp_params = it->second->GetRtpParameters(); + auto it = receive_streams_.find(ssrc); + if (it == receive_streams_.end()) { + RTC_LOG(LS_WARNING) + << "Attempting to get RTP receive parameters for stream " + << "with SSRC " << ssrc << " which doesn't exist."; + return webrtc::RtpParameters(); } + rtp_params = it->second->GetRtpParameters(); + + // Add codecs, which any stream is prepared to receive. + for (const VideoCodec& codec : recv_params_.codecs) { + rtp_params.codecs.push_back(codec.ToCodecParameters()); + } + + return rtp_params; +} + +webrtc::RtpParameters WebRtcVideoChannel::GetDefaultRtpReceiveParameters() + const { + RTC_DCHECK_RUN_ON(&thread_checker_); + webrtc::RtpParameters rtp_params; + if (!default_unsignalled_ssrc_handler_.GetDefaultSink()) { + RTC_LOG(LS_WARNING) << "Attempting to get RTP parameters for the default, " + "unsignaled video receive stream, but not yet " + "configured to receive such a stream."; + return rtp_params; + } + rtp_params.encodings.emplace_back(); // Add codecs, which any stream is prepared to receive. for (const VideoCodec& codec : recv_params_.codecs) { @@ -1360,10 +1368,6 @@ bool WebRtcVideoChannel::SetSink( RTC_DCHECK_RUN_ON(&thread_checker_); RTC_LOG(LS_INFO) << "SetSink: ssrc:" << ssrc << " " << (sink ? "(ptr)" : "nullptr"); - if (ssrc == 0) { - default_unsignalled_ssrc_handler_.SetDefaultSink(this, sink); - return true; - } std::map::iterator it = receive_streams_.find(ssrc); @@ -1375,6 +1379,13 @@ bool WebRtcVideoChannel::SetSink( return true; } +void WebRtcVideoChannel::SetDefaultSink( + rtc::VideoSinkInterface* sink) { + RTC_DCHECK_RUN_ON(&thread_checker_); + RTC_LOG(LS_INFO) << "SetDefaultSink: " << (sink ? "(ptr)" : "nullptr"); + default_unsignalled_ssrc_handler_.SetDefaultSink(this, sink); +} + bool WebRtcVideoChannel::GetStats(VideoMediaInfo* info) { RTC_DCHECK_RUN_ON(&thread_checker_); TRACE_EVENT0("webrtc", "WebRtcVideoChannel::GetStats"); diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h index 4b423243ac..3a0a156e2a 100644 --- a/media/engine/webrtc_video_engine.h +++ b/media/engine/webrtc_video_engine.h @@ -129,6 +129,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, uint32_t ssrc, const webrtc::RtpParameters& parameters) override; webrtc::RtpParameters GetRtpReceiveParameters(uint32_t ssrc) const override; + webrtc::RtpParameters GetDefaultRtpReceiveParameters() const override; bool GetSendCodec(VideoCodec* send_codec) override; bool SetSend(bool send) override; bool SetVideoSend( @@ -143,6 +144,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, void ResetUnsignaledRecvStream() override; bool SetSink(uint32_t ssrc, rtc::VideoSinkInterface* sink) override; + void SetDefaultSink( + rtc::VideoSinkInterface* sink) override; void FillBitrateInfo(BandwidthEstimationInfo* bwe_info) override; bool GetStats(VideoMediaInfo* info) override; @@ -210,6 +213,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, void RequestEncoderFallback() override; void RequestEncoderSwitch( const EncoderSwitchRequestCallback::Config& conf) override; + void SetRecordableEncodedFrameCallback( uint32_t ssrc, std::function callback) @@ -220,8 +224,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, private: class WebRtcVideoReceiveStream; - // Finds VideoReceiveStream corresponding to ssrc. Aware of unsignalled - // ssrc handling. + // Finds VideoReceiveStream corresponding to ssrc. Aware of unsignalled ssrc + // handling. WebRtcVideoReceiveStream* FindReceiveStream(uint32_t ssrc) RTC_EXCLUSIVE_LOCKS_REQUIRED(thread_checker_); diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc index b7f9266411..0270355455 100644 --- a/media/engine/webrtc_video_engine_unittest.cc +++ b/media/engine/webrtc_video_engine_unittest.cc @@ -79,7 +79,6 @@ static const int kDefaultQpMax = 56; static const uint8_t kRedRtxPayloadType = 125; static const uint32_t kTimeout = 5000U; -static const uint32_t kDefaultReceiveSsrc = 0; static const uint32_t kSsrc = 1234u; static const uint32_t kSsrcs4[] = {1, 2, 3, 4}; static const int kVideoWidth = 640; @@ -91,7 +90,6 @@ static const uint32_t kSsrcs3[] = {1, 2, 3}; static const uint32_t kRtxSsrcs1[] = {4}; static const uint32_t kFlexfecSsrc = 5; static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE; -static const uint32_t kDefaultRecvSsrc = 0; constexpr uint32_t kRtpHeaderSize = 12; @@ -1579,7 +1577,7 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { void SendAndReceive(const cricket::VideoCodec& codec) { EXPECT_TRUE(SetOneCodec(codec)); EXPECT_TRUE(SetSend(true)); - EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_)); + channel_->SetDefaultSink(&renderer_); EXPECT_EQ(0, renderer_.num_rendered_frames()); SendFrame(); EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout); @@ -1592,7 +1590,7 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { int fps) { EXPECT_TRUE(SetOneCodec(codec)); EXPECT_TRUE(SetSend(true)); - EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_)); + channel_->SetDefaultSink(&renderer_); EXPECT_EQ(0, renderer_.num_rendered_frames()); for (int i = 0; i < duration_sec; ++i) { for (int frame = 1; frame <= fps; ++frame) { @@ -1984,12 +1982,12 @@ TEST_F(WebRtcVideoChannelBaseTest, SetSink) { rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1)); rtc::SetBE32(packet1.data() + 8, kSsrc); - channel_->SetSink(kDefaultReceiveSsrc, NULL); + channel_->SetDefaultSink(NULL); EXPECT_TRUE(SetDefaultCodec()); EXPECT_TRUE(SetSend(true)); EXPECT_EQ(0, renderer_.num_rendered_frames()); channel_->OnPacketReceived(packet1, /* packet_time_us */ -1); - EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_)); + channel_->SetDefaultSink(&renderer_); SendFrame(); EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout); } @@ -1998,7 +1996,7 @@ TEST_F(WebRtcVideoChannelBaseTest, SetSink) { TEST_F(WebRtcVideoChannelBaseTest, AddRemoveSendStreams) { EXPECT_TRUE(SetOneCodec(DefaultCodec())); EXPECT_TRUE(SetSend(true)); - EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_)); + channel_->SetDefaultSink(&renderer_); SendFrame(); EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout); EXPECT_GT(NumRtpPackets(), 0); @@ -2073,7 +2071,7 @@ TEST_F(WebRtcVideoChannelBaseTest, DISABLED_AddRemoveCapturer) { const int time_between_send_ms = VideoFormat::FpsToInterval(kFramerate); EXPECT_TRUE(SetOneCodec(codec)); EXPECT_TRUE(SetSend(true)); - EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_)); + channel_->SetDefaultSink(&renderer_); EXPECT_EQ(0, renderer_.num_rendered_frames()); SendFrame(); EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout); @@ -2133,7 +2131,7 @@ TEST_F(WebRtcVideoChannelBaseTest, DISABLED_AddRemoveCapturer) { TEST_F(WebRtcVideoChannelBaseTest, RemoveCapturerWithoutAdd) { EXPECT_TRUE(SetOneCodec(DefaultCodec())); EXPECT_TRUE(SetSend(true)); - EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_)); + channel_->SetDefaultSink(&renderer_); EXPECT_EQ(0, renderer_.num_rendered_frames()); SendFrame(); EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout); @@ -5781,7 +5779,7 @@ TEST_F(WebRtcVideoChannelTest, ReceiveDifferentUnsignaledSsrc) { // No receive streams yet. ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size()); cricket::FakeVideoRenderer renderer; - EXPECT_TRUE(channel_->SetSink(kDefaultRecvSsrc, &renderer)); + channel_->SetDefaultSink(&renderer); // Receive VP8 packet on first SSRC. uint8_t data[kMinRtpPacketLen]; @@ -7478,10 +7476,12 @@ TEST_F(WebRtcVideoChannelTest, SetAndGetRtpReceiveParameters) { EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(last_ssrc_)); } -// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs -// aren't signaled. It should always return an empty "RtpEncodingParameters", -// even after a packet is received and the unsignaled SSRC is known. -TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersWithUnsignaledSsrc) { +// Test that GetDefaultRtpReceiveParameters returns parameters correctly when +// SSRCs aren't signaled. It should always return an empty +// "RtpEncodingParameters", even after a packet is received and the unsignaled +// SSRC is known. +TEST_F(WebRtcVideoChannelTest, + GetDefaultRtpReceiveParametersWithUnsignaledSsrc) { // Call necessary methods to configure receiving a default stream as // soon as it arrives. cricket::VideoRecvParameters parameters; @@ -7491,16 +7491,16 @@ TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersWithUnsignaledSsrc) { // Call GetRtpReceiveParameters before configured to receive an unsignaled // stream. Should return nothing. - EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0)); + EXPECT_EQ(webrtc::RtpParameters(), + channel_->GetDefaultRtpReceiveParameters()); // Set a sink for an unsignaled stream. cricket::FakeVideoRenderer renderer; - // Value of "0" means "unsignaled stream". - EXPECT_TRUE(channel_->SetSink(0, &renderer)); + channel_->SetDefaultSink(&renderer); - // Call GetRtpReceiveParameters before the SSRC is known. Value of "0" - // in this method means "unsignaled stream". - webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0); + // Call GetDefaultRtpReceiveParameters before the SSRC is known. + webrtc::RtpParameters rtp_parameters = + channel_->GetDefaultRtpReceiveParameters(); ASSERT_EQ(1u, rtp_parameters.encodings.size()); EXPECT_FALSE(rtp_parameters.encodings[0].ssrc); @@ -7515,7 +7515,7 @@ TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersWithUnsignaledSsrc) { channel_->OnPacketReceived(packet, /* packet_time_us */ -1); // The |ssrc| member should still be unset. - rtp_parameters = channel_->GetRtpReceiveParameters(0); + rtp_parameters = channel_->GetDefaultRtpReceiveParameters(); ASSERT_EQ(1u, rtp_parameters.encodings.size()); EXPECT_FALSE(rtp_parameters.encodings[0].ssrc); } @@ -7780,7 +7780,7 @@ TEST_F(WebRtcVideoChannelSimulcastTest, SimulcastScreenshareWithoutConference) { TEST_F(WebRtcVideoChannelBaseTest, GetSources) { EXPECT_THAT(channel_->GetSources(kSsrc), IsEmpty()); - EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_)); + channel_->SetDefaultSink(&renderer_); EXPECT_TRUE(SetDefaultCodec()); EXPECT_TRUE(SetSend(true)); EXPECT_EQ(renderer_.num_rendered_frames(), 0); diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc index cfbd774279..97e12ba9c8 100644 --- a/media/engine/webrtc_voice_engine.cc +++ b/media/engine/webrtc_voice_engine.cc @@ -1423,26 +1423,32 @@ webrtc::RtpParameters WebRtcVoiceMediaChannel::GetRtpReceiveParameters( uint32_t ssrc) const { RTC_DCHECK(worker_thread_checker_.IsCurrent()); webrtc::RtpParameters rtp_params; - // SSRC of 0 represents the default receive stream. - if (ssrc == 0) { - if (!default_sink_) { - RTC_LOG(LS_WARNING) - << "Attempting to get RTP parameters for the default, " - "unsignaled audio receive stream, but not yet " - "configured to receive such a stream."; - return rtp_params; - } - rtp_params.encodings.emplace_back(); - } else { - auto it = recv_streams_.find(ssrc); - if (it == recv_streams_.end()) { - RTC_LOG(LS_WARNING) - << "Attempting to get RTP receive parameters for stream " - << "with ssrc " << ssrc << " which doesn't exist."; - return webrtc::RtpParameters(); - } - rtp_params = it->second->GetRtpParameters(); + auto it = recv_streams_.find(ssrc); + if (it == recv_streams_.end()) { + RTC_LOG(LS_WARNING) + << "Attempting to get RTP receive parameters for stream " + << "with ssrc " << ssrc << " which doesn't exist."; + return webrtc::RtpParameters(); } + rtp_params = it->second->GetRtpParameters(); + + for (const AudioCodec& codec : recv_codecs_) { + rtp_params.codecs.push_back(codec.ToCodecParameters()); + } + return rtp_params; +} + +webrtc::RtpParameters WebRtcVoiceMediaChannel::GetDefaultRtpReceiveParameters() + const { + RTC_DCHECK(worker_thread_checker_.IsCurrent()); + webrtc::RtpParameters rtp_params; + if (!default_sink_) { + RTC_LOG(LS_WARNING) << "Attempting to get RTP parameters for the default, " + "unsignaled audio receive stream, but not yet " + "configured to receive such a stream."; + return rtp_params; + } + rtp_params.encodings.emplace_back(); for (const AudioCodec& codec : recv_codecs_) { rtp_params.codecs.push_back(codec.ToCodecParameters()); @@ -1910,20 +1916,28 @@ bool WebRtcVoiceMediaChannel::SetLocalSource(uint32_t ssrc, bool WebRtcVoiceMediaChannel::SetOutputVolume(uint32_t ssrc, double volume) { RTC_DCHECK(worker_thread_checker_.IsCurrent()); - std::vector ssrcs(1, ssrc); - // SSRC of 0 represents the default receive stream. - if (ssrc == 0) { - default_recv_volume_ = volume; - ssrcs = unsignaled_recv_ssrcs_; + const auto it = recv_streams_.find(ssrc); + if (it == recv_streams_.end()) { + RTC_LOG(LS_WARNING) << "SetOutputVolume: no recv stream " << ssrc; + return false; } - for (uint32_t ssrc : ssrcs) { + it->second->SetOutputVolume(volume); + RTC_LOG(LS_INFO) << "SetOutputVolume() to " << volume + << " for recv stream with ssrc " << ssrc; + return true; +} + +bool WebRtcVoiceMediaChannel::SetDefaultOutputVolume(double volume) { + RTC_DCHECK(worker_thread_checker_.IsCurrent()); + default_recv_volume_ = volume; + for (uint32_t ssrc : unsignaled_recv_ssrcs_) { const auto it = recv_streams_.find(ssrc); if (it == recv_streams_.end()) { - RTC_LOG(LS_WARNING) << "SetOutputVolume: no recv stream " << ssrc; + RTC_LOG(LS_WARNING) << "SetDefaultOutputVolume: no recv stream " << ssrc; return false; } it->second->SetOutputVolume(volume); - RTC_LOG(LS_INFO) << "SetOutputVolume() to " << volume + RTC_LOG(LS_INFO) << "SetDefaultOutputVolume() to " << volume << " for recv stream with ssrc " << ssrc; } return true; @@ -2267,15 +2281,6 @@ void WebRtcVoiceMediaChannel::SetRawAudioSink( RTC_DCHECK(worker_thread_checker_.IsCurrent()); RTC_LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::SetRawAudioSink: ssrc:" << ssrc << " " << (sink ? "(ptr)" : "NULL"); - if (ssrc == 0) { - if (!unsignaled_recv_ssrcs_.empty()) { - std::unique_ptr proxy_sink( - sink ? new ProxySink(sink.get()) : nullptr); - SetRawAudioSink(unsignaled_recv_ssrcs_.back(), std::move(proxy_sink)); - } - default_sink_ = std::move(sink); - return; - } const auto it = recv_streams_.find(ssrc); if (it == recv_streams_.end()) { RTC_LOG(LS_WARNING) << "SetRawAudioSink: no recv stream " << ssrc; @@ -2284,6 +2289,18 @@ void WebRtcVoiceMediaChannel::SetRawAudioSink( it->second->SetRawAudioSink(std::move(sink)); } +void WebRtcVoiceMediaChannel::SetDefaultRawAudioSink( + std::unique_ptr sink) { + RTC_DCHECK(worker_thread_checker_.IsCurrent()); + RTC_LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::SetDefaultRawAudioSink:"; + if (!unsignaled_recv_ssrcs_.empty()) { + std::unique_ptr proxy_sink( + sink ? new ProxySink(sink.get()) : nullptr); + SetRawAudioSink(unsignaled_recv_ssrcs_.back(), std::move(proxy_sink)); + } + default_sink_ = std::move(sink); +} + std::vector WebRtcVoiceMediaChannel::GetSources( uint32_t ssrc) const { auto it = recv_streams_.find(ssrc); diff --git a/media/engine/webrtc_voice_engine.h b/media/engine/webrtc_voice_engine.h index 3c46980483..7ff8690b2d 100644 --- a/media/engine/webrtc_voice_engine.h +++ b/media/engine/webrtc_voice_engine.h @@ -151,6 +151,7 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, uint32_t ssrc, const webrtc::RtpParameters& parameters) override; webrtc::RtpParameters GetRtpReceiveParameters(uint32_t ssrc) const override; + webrtc::RtpParameters GetDefaultRtpReceiveParameters() const override; void SetPlayout(bool playout) override; void SetSend(bool send) override; @@ -178,8 +179,9 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, rtc::scoped_refptr frame_encryptor) override; - // SSRC=0 will apply the new volume to current and future unsignaled streams. bool SetOutputVolume(uint32_t ssrc, double volume) override; + // Applies the new volume to current and future unsignaled streams. + bool SetDefaultOutputVolume(double volume) override; bool SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, int delay_ms) override; absl::optional GetBaseMinimumPlayoutDelayMs( @@ -195,11 +197,14 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, void OnReadyToSend(bool ready) override; bool GetStats(VoiceMediaInfo* info) override; - // SSRC=0 will set the audio sink on the latest unsignaled stream, future or - // current. Only one stream at a time will use the sink. + // Set the audio sink for an existing stream. void SetRawAudioSink( uint32_t ssrc, std::unique_ptr sink) override; + // Will set the audio sink on the latest unsignaled stream, future or + // current. Only one stream at a time will use the sink. + void SetDefaultRawAudioSink( + std::unique_ptr sink) override; std::vector GetSources(uint32_t ssrc) const override; diff --git a/media/engine/webrtc_voice_engine_unittest.cc b/media/engine/webrtc_voice_engine_unittest.cc index d509831fec..d34383c0a2 100644 --- a/media/engine/webrtc_voice_engine_unittest.cc +++ b/media/engine/webrtc_voice_engine_unittest.cc @@ -1392,18 +1392,18 @@ TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) { parameters.codecs.push_back(kPcmuCodec); EXPECT_TRUE(channel_->SetRecvParameters(parameters)); - // Call GetRtpReceiveParameters before configured to receive an unsignaled - // stream. Should return nothing. - EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0)); + // Call GetDefaultRtpReceiveParameters before configured to receive an + // unsignaled stream. Should return nothing. + EXPECT_EQ(webrtc::RtpParameters(), + channel_->GetDefaultRtpReceiveParameters()); // Set a sink for an unsignaled stream. std::unique_ptr fake_sink(new FakeAudioSink()); - // Value of "0" means "unsignaled stream". - channel_->SetRawAudioSink(0, std::move(fake_sink)); + channel_->SetDefaultRawAudioSink(std::move(fake_sink)); - // Call GetRtpReceiveParameters before the SSRC is known. Value of "0" - // in this method means "unsignaled stream". - webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0); + // Call GetDefaultRtpReceiveParameters before the SSRC is known. + webrtc::RtpParameters rtp_parameters = + channel_->GetDefaultRtpReceiveParameters(); ASSERT_EQ(1u, rtp_parameters.encodings.size()); EXPECT_FALSE(rtp_parameters.encodings[0].ssrc); @@ -1411,7 +1411,7 @@ TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersWithUnsignaledSsrc) { DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame)); // The |ssrc| member should still be unset. - rtp_parameters = channel_->GetRtpReceiveParameters(0); + rtp_parameters = channel_->GetDefaultRtpReceiveParameters(); ASSERT_EQ(1u, rtp_parameters.encodings.size()); EXPECT_FALSE(rtp_parameters.encodings[0].ssrc); } @@ -3104,7 +3104,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) { // Should remember the volume "2" which will be set on new unsignaled streams, // and also set the gain to 2 on existing unsignaled streams. - EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 2)); + EXPECT_TRUE(channel_->SetDefaultOutputVolume(2)); EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrc1).gain()); // Spawn an unsignaled stream by sending a packet - gain should be 2. @@ -3114,8 +3114,8 @@ TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeUnsignaledRecvStream) { DeliverPacket(pcmuFrame2, sizeof(pcmuFrame2)); EXPECT_DOUBLE_EQ(2, GetRecvStream(kSsrcX).gain()); - // Setting gain with SSRC=0 should affect all unsignaled streams. - EXPECT_TRUE(channel_->SetOutputVolume(kSsrc0, 3)); + // Setting gain for all unsignaled streams. + EXPECT_TRUE(channel_->SetDefaultOutputVolume(3)); if (kMaxUnsignaledRecvStreams > 1) { EXPECT_DOUBLE_EQ(3, GetRecvStream(kSsrc1).gain()); } @@ -3341,7 +3341,7 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) { std::unique_ptr fake_sink_4(new FakeAudioSink()); // Should be able to set a default sink even when no stream exists. - channel_->SetRawAudioSink(0, std::move(fake_sink_1)); + channel_->SetDefaultRawAudioSink(std::move(fake_sink_1)); // Spawn an unsignaled stream by sending a packet - it should be assigned the // default sink. @@ -3349,11 +3349,11 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) { EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink()); // Try resetting the default sink. - channel_->SetRawAudioSink(kSsrc0, nullptr); + channel_->SetDefaultRawAudioSink(nullptr); EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink()); // Try setting the default sink while the default stream exists. - channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_2)); + channel_->SetDefaultRawAudioSink(std::move(fake_sink_2)); EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink()); // If we remove and add a default stream, it should get the same sink. @@ -3373,14 +3373,14 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkUnsignaledRecvStream) { EXPECT_NE(nullptr, GetRecvStream(kSsrcX).sink()); // Reset the default sink - the second unsignaled stream should lose it. - channel_->SetRawAudioSink(kSsrc0, nullptr); + channel_->SetDefaultRawAudioSink(nullptr); if (kMaxUnsignaledRecvStreams > 1) { EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink()); } EXPECT_EQ(nullptr, GetRecvStream(kSsrcX).sink()); // Try setting the default sink while two streams exists. - channel_->SetRawAudioSink(kSsrc0, std::move(fake_sink_3)); + channel_->SetDefaultRawAudioSink(std::move(fake_sink_3)); if (kMaxUnsignaledRecvStreams > 1) { EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink()); } diff --git a/pc/audio_rtp_receiver.cc b/pc/audio_rtp_receiver.cc index 6c0445adce..e83e558c7b 100644 --- a/pc/audio_rtp_receiver.cc +++ b/pc/audio_rtp_receiver.cc @@ -76,8 +76,8 @@ bool AudioRtpReceiver::SetOutputVolume(double volume) { RTC_DCHECK(media_channel_); RTC_DCHECK(!stopped_); return worker_thread_->Invoke(RTC_FROM_HERE, [&] { - // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC value. - return media_channel_->SetOutputVolume(ssrc_.value_or(0), volume); + return ssrc_ ? media_channel_->SetOutputVolume(*ssrc_, volume) + : media_channel_->SetDefaultOutputVolume(volume); }); } @@ -112,8 +112,8 @@ RtpParameters AudioRtpReceiver::GetParameters() const { return RtpParameters(); } return worker_thread_->Invoke(RTC_FROM_HERE, [&] { - // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC value. - return media_channel_->GetRtpReceiveParameters(ssrc_.value_or(0)); + return ssrc_ ? media_channel_->GetRtpReceiveParameters(*ssrc_) + : media_channel_->GetDefaultRtpReceiveParameters(); }); } @@ -153,12 +153,12 @@ void AudioRtpReceiver::RestartMediaChannel(absl::optional ssrc) { } if (!stopped_) { - source_->Stop(media_channel_, ssrc_.value_or(0)); + source_->Stop(media_channel_, ssrc_); delay_->OnStop(); } ssrc_ = ssrc; stopped_ = false; - source_->Start(media_channel_, ssrc.value_or(0)); + source_->Start(media_channel_, ssrc); delay_->OnStart(media_channel_, ssrc.value_or(0)); Reconfigure(); } diff --git a/pc/remote_audio_source.cc b/pc/remote_audio_source.cc index d9752f3052..05d0899f2a 100644 --- a/pc/remote_audio_source.cc +++ b/pc/remote_audio_source.cc @@ -63,7 +63,7 @@ RemoteAudioSource::~RemoteAudioSource() { } void RemoteAudioSource::Start(cricket::VoiceMediaChannel* media_channel, - uint32_t ssrc) { + absl::optional ssrc) { RTC_DCHECK_RUN_ON(main_thread_); RTC_DCHECK(media_channel); @@ -71,18 +71,22 @@ void RemoteAudioSource::Start(cricket::VoiceMediaChannel* media_channel, // notified when a channel goes out of scope (signaled when "AudioDataProxy" // is destroyed). worker_thread_->Invoke(RTC_FROM_HERE, [&] { - media_channel->SetRawAudioSink(ssrc, - std::make_unique(this)); + ssrc ? media_channel->SetRawAudioSink( + *ssrc, std::make_unique(this)) + : media_channel->SetDefaultRawAudioSink( + std::make_unique(this)); }); } void RemoteAudioSource::Stop(cricket::VoiceMediaChannel* media_channel, - uint32_t ssrc) { + absl::optional ssrc) { RTC_DCHECK_RUN_ON(main_thread_); RTC_DCHECK(media_channel); - worker_thread_->Invoke( - RTC_FROM_HERE, [&] { media_channel->SetRawAudioSink(ssrc, nullptr); }); + worker_thread_->Invoke(RTC_FROM_HERE, [&] { + ssrc ? media_channel->SetRawAudioSink(*ssrc, nullptr) + : media_channel->SetDefaultRawAudioSink(nullptr); + }); } MediaSourceInterface::SourceState RemoteAudioSource::state() const { diff --git a/pc/remote_audio_source.h b/pc/remote_audio_source.h index 399e7e3a44..15dc75b511 100644 --- a/pc/remote_audio_source.h +++ b/pc/remote_audio_source.h @@ -14,6 +14,7 @@ #include #include +#include "absl/types/optional.h" #include "api/call/audio_sink.h" #include "api/notifier.h" #include "pc/channel.h" @@ -37,8 +38,10 @@ class RemoteAudioSource : public Notifier, // Register and unregister remote audio source with the underlying media // engine. - void Start(cricket::VoiceMediaChannel* media_channel, uint32_t ssrc); - void Stop(cricket::VoiceMediaChannel* media_channel, uint32_t ssrc); + void Start(cricket::VoiceMediaChannel* media_channel, + absl::optional ssrc); + void Stop(cricket::VoiceMediaChannel* media_channel, + absl::optional ssrc); // MediaSourceInterface implementation. MediaSourceInterface::SourceState state() const override; diff --git a/pc/video_rtp_receiver.cc b/pc/video_rtp_receiver.cc index d50407d333..24cc4eafb8 100644 --- a/pc/video_rtp_receiver.cc +++ b/pc/video_rtp_receiver.cc @@ -83,8 +83,8 @@ RtpParameters VideoRtpReceiver::GetParameters() const { return RtpParameters(); } return worker_thread_->Invoke(RTC_FROM_HERE, [&] { - // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC - return media_channel_->GetRtpReceiveParameters(ssrc_.value_or(0)); + return ssrc_ ? media_channel_->GetRtpReceiveParameters(*ssrc_) + : media_channel_->GetDefaultRtpReceiveParameters(); }); } @@ -155,8 +155,11 @@ void VideoRtpReceiver::RestartMediaChannel(absl::optional ssrc) { } void VideoRtpReceiver::SetSink(rtc::VideoSinkInterface* sink) { - // TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC - media_channel_->SetSink(ssrc_.value_or(0), sink); + if (ssrc_) { + media_channel_->SetSink(*ssrc_, sink); + return; + } + media_channel_->SetDefaultSink(sink); } void VideoRtpReceiver::SetupMediaChannel(uint32_t ssrc) {