Enable SSRC 0 in MediaChannel methods

Refactor voice engine and video engine to use default methods instead of
treating 0 as a special value.

Bug: webrtc:8694
Change-Id: I47c211c6e870cdec737d6b0d05df29a9b534a011
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/158600
Reviewed-by: Markus Handell <handellm@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Commit-Queue: Saurav Das <dinosaurav@chromium.org>
Cr-Commit-Position: refs/heads/master@{#30010}
This commit is contained in:
Saurav Das 2019-12-04 09:31:36 -08:00 committed by Commit Bot
parent 503d7237ce
commit 749f6604a1
13 changed files with 206 additions and 141 deletions

View File

@ -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<uint32_t, double>::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<webrtc::AudioSinkInterface> sink) {
sink_ = std::move(sink);
}
void FakeVoiceMediaChannel::SetDefaultRawAudioSink(
std::unique_ptr<webrtc::AudioSinkInterface> sink) {
sink_ = std::move(sink);
}
std::vector<webrtc::RtpSource> FakeVoiceMediaChannel::GetSources(
uint32_t ssrc) const {
return std::vector<webrtc::RtpSource>();
@ -308,14 +312,15 @@ bool FakeVideoMediaChannel::GetSendCodec(VideoCodec* send_codec) {
bool FakeVideoMediaChannel::SetSink(
uint32_t ssrc,
rtc::VideoSinkInterface<webrtc::VideoFrame>* 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<webrtc::VideoFrame>* sink) {}
bool FakeVideoMediaChannel::HasSink(uint32_t ssrc) const {
return sinks_.find(ssrc) != sinks_.end() && sinks_.at(ssrc) != nullptr;
}

View File

@ -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<VoiceMediaChannel> {
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<VoiceMediaChannel> {
void SetRawAudioSink(
uint32_t ssrc,
std::unique_ptr<webrtc::AudioSinkInterface> sink) override;
void SetDefaultRawAudioSink(
std::unique_ptr<webrtc::AudioSinkInterface> sink) override;
std::vector<webrtc::RtpSource> GetSources(uint32_t ssrc) const override;
@ -415,6 +422,8 @@ class FakeVideoMediaChannel : public RtpHelper<VideoMediaChannel> {
bool GetSendCodec(VideoCodec* send_codec) override;
bool SetSink(uint32_t ssrc,
rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) override;
void SetDefaultSink(
rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) override;
bool HasSink(uint32_t ssrc) const;
bool SetSend(bool send) override;

View File

@ -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<webrtc::AudioSinkInterface> sink) = 0;
virtual void SetDefaultRawAudioSink(
std::unique_ptr<webrtc::AudioSinkInterface> sink) = 0;
virtual std::vector<webrtc::RtpSource> 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<webrtc::VideoFrame>* 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<webrtc::VideoFrame>* sink) = 0;
// The sink is used for the 'default' stream.
virtual void SetDefaultSink(
rtc::VideoSinkInterface<webrtc::VideoFrame>* 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

View File

@ -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<uint32_t, WebRtcVideoReceiveStream*>::iterator it =
receive_streams_.find(ssrc);
@ -1375,6 +1379,13 @@ bool WebRtcVideoChannel::SetSink(
return true;
}
void WebRtcVideoChannel::SetDefaultSink(
rtc::VideoSinkInterface<webrtc::VideoFrame>* 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");

View File

@ -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<webrtc::VideoFrame>* sink) override;
void SetDefaultSink(
rtc::VideoSinkInterface<webrtc::VideoFrame>* 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<void(const webrtc::RecordableEncodedFrame&)> 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_);

View File

@ -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);

View File

@ -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<uint32_t> 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<webrtc::AudioSinkInterface> 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<webrtc::AudioSinkInterface> sink) {
RTC_DCHECK(worker_thread_checker_.IsCurrent());
RTC_LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::SetDefaultRawAudioSink:";
if (!unsignaled_recv_ssrcs_.empty()) {
std::unique_ptr<webrtc::AudioSinkInterface> proxy_sink(
sink ? new ProxySink(sink.get()) : nullptr);
SetRawAudioSink(unsignaled_recv_ssrcs_.back(), std::move(proxy_sink));
}
default_sink_ = std::move(sink);
}
std::vector<webrtc::RtpSource> WebRtcVoiceMediaChannel::GetSources(
uint32_t ssrc) const {
auto it = recv_streams_.find(ssrc);

View File

@ -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<webrtc::FrameEncryptorInterface>
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<int> 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<webrtc::AudioSinkInterface> 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<webrtc::AudioSinkInterface> sink) override;
std::vector<webrtc::RtpSource> GetSources(uint32_t ssrc) const override;

View File

@ -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<FakeAudioSink> 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<FakeAudioSink> 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());
}

View File

@ -76,8 +76,8 @@ bool AudioRtpReceiver::SetOutputVolume(double volume) {
RTC_DCHECK(media_channel_);
RTC_DCHECK(!stopped_);
return worker_thread_->Invoke<bool>(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<RtpParameters>(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<uint32_t> 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();
}

View File

@ -63,7 +63,7 @@ RemoteAudioSource::~RemoteAudioSource() {
}
void RemoteAudioSource::Start(cricket::VoiceMediaChannel* media_channel,
uint32_t ssrc) {
absl::optional<uint32_t> 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<void>(RTC_FROM_HERE, [&] {
media_channel->SetRawAudioSink(ssrc,
std::make_unique<AudioDataProxy>(this));
ssrc ? media_channel->SetRawAudioSink(
*ssrc, std::make_unique<AudioDataProxy>(this))
: media_channel->SetDefaultRawAudioSink(
std::make_unique<AudioDataProxy>(this));
});
}
void RemoteAudioSource::Stop(cricket::VoiceMediaChannel* media_channel,
uint32_t ssrc) {
absl::optional<uint32_t> ssrc) {
RTC_DCHECK_RUN_ON(main_thread_);
RTC_DCHECK(media_channel);
worker_thread_->Invoke<void>(
RTC_FROM_HERE, [&] { media_channel->SetRawAudioSink(ssrc, nullptr); });
worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
ssrc ? media_channel->SetRawAudioSink(*ssrc, nullptr)
: media_channel->SetDefaultRawAudioSink(nullptr);
});
}
MediaSourceInterface::SourceState RemoteAudioSource::state() const {

View File

@ -14,6 +14,7 @@
#include <list>
#include <string>
#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<AudioSourceInterface>,
// 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<uint32_t> ssrc);
void Stop(cricket::VoiceMediaChannel* media_channel,
absl::optional<uint32_t> ssrc);
// MediaSourceInterface implementation.
MediaSourceInterface::SourceState state() const override;

View File

@ -83,8 +83,8 @@ RtpParameters VideoRtpReceiver::GetParameters() const {
return RtpParameters();
}
return worker_thread_->Invoke<RtpParameters>(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<uint32_t> ssrc) {
}
void VideoRtpReceiver::SetSink(rtc::VideoSinkInterface<VideoFrame>* 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) {