Storing raw audio sink for default audio track.
BUG=webrtc:5250 Committed: https://crrev.com/e591f9377f33f3f725a30faecd1bef1a71fa6b99 Cr-Commit-Position: refs/heads/master@{#11230} Review URL: https://codereview.webrtc.org/1551813002 Cr-Commit-Position: refs/heads/master@{#11275}
This commit is contained in:
parent
1567d0bd98
commit
884f58523a
@ -2084,8 +2084,12 @@ TEST_F(PeerConnectionInterfaceTest, SdpWithoutMsidCreatesDefaultStream) {
|
||||
ASSERT_EQ(1u, observer_.remote_streams()->count());
|
||||
ASSERT_EQ(1u, remote_stream->GetAudioTracks().size());
|
||||
EXPECT_EQ("defaulta0", remote_stream->GetAudioTracks()[0]->id());
|
||||
EXPECT_EQ(MediaStreamTrackInterface::kLive,
|
||||
remote_stream->GetAudioTracks()[0]->state());
|
||||
ASSERT_EQ(1u, remote_stream->GetVideoTracks().size());
|
||||
EXPECT_EQ("defaultv0", remote_stream->GetVideoTracks()[0]->id());
|
||||
EXPECT_EQ(MediaStreamTrackInterface::kLive,
|
||||
remote_stream->GetVideoTracks()[0]->state());
|
||||
}
|
||||
|
||||
// This tests that a default MediaStream is created if a remote session
|
||||
|
||||
@ -89,6 +89,7 @@ class FakeAudioReceiveStream final : public webrtc::AudioReceiveStream {
|
||||
void SetStats(const webrtc::AudioReceiveStream::Stats& stats);
|
||||
int received_packets() const { return received_packets_; }
|
||||
void IncrementReceivedPackets();
|
||||
const webrtc::AudioSinkInterface* sink() const { return sink_.get(); }
|
||||
|
||||
private:
|
||||
// webrtc::ReceiveStream implementation.
|
||||
|
||||
@ -132,6 +132,16 @@ const int kMaxTelephoneEventCode = 255;
|
||||
const int kMinTelephoneEventDuration = 100;
|
||||
const int kMaxTelephoneEventDuration = 60000; // Actual limit is 2^16
|
||||
|
||||
class ProxySink : public webrtc::AudioSinkInterface {
|
||||
public:
|
||||
ProxySink(AudioSinkInterface* sink) : sink_(sink) { RTC_DCHECK(sink); }
|
||||
|
||||
void OnData(const Data& audio) override { sink_->OnData(audio); }
|
||||
|
||||
private:
|
||||
webrtc::AudioSinkInterface* sink_;
|
||||
};
|
||||
|
||||
bool ValidateStreamParams(const StreamParams& sp) {
|
||||
if (sp.ssrcs.empty()) {
|
||||
LOG(LS_ERROR) << "No SSRCs in stream parameters: " << sp.ToString();
|
||||
@ -2191,6 +2201,11 @@ void WebRtcVoiceMediaChannel::OnPacketReceived(
|
||||
}
|
||||
default_recv_ssrc_ = ssrc;
|
||||
SetOutputVolume(default_recv_ssrc_, default_recv_volume_);
|
||||
if (default_sink_) {
|
||||
rtc::scoped_ptr<webrtc::AudioSinkInterface> proxy_sink(
|
||||
new ProxySink(default_sink_.get()));
|
||||
SetRawAudioSink(default_recv_ssrc_, std::move(proxy_sink));
|
||||
}
|
||||
}
|
||||
|
||||
// Forward packet to Call. If the SSRC is unknown we'll return after this.
|
||||
@ -2419,7 +2434,17 @@ void WebRtcVoiceMediaChannel::SetRawAudioSink(
|
||||
uint32_t ssrc,
|
||||
rtc::scoped_ptr<webrtc::AudioSinkInterface> sink) {
|
||||
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
||||
LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::SetRawAudioSink";
|
||||
LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::SetRawAudioSink: ssrc:" << ssrc
|
||||
<< " " << (sink ? "(ptr)" : "NULL");
|
||||
if (ssrc == 0) {
|
||||
if (default_recv_ssrc_ != -1) {
|
||||
rtc::scoped_ptr<webrtc::AudioSinkInterface> proxy_sink(
|
||||
sink ? new ProxySink(sink.get()) : nullptr);
|
||||
SetRawAudioSink(default_recv_ssrc_, std::move(proxy_sink));
|
||||
}
|
||||
default_sink_ = std::move(sink);
|
||||
return;
|
||||
}
|
||||
const auto it = recv_streams_.find(ssrc);
|
||||
if (it == recv_streams_.end()) {
|
||||
LOG(LS_WARNING) << "SetRawAudioSink: no recv stream" << ssrc;
|
||||
|
||||
@ -272,6 +272,8 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel,
|
||||
int64_t default_recv_ssrc_ = -1;
|
||||
// Volume for unsignalled stream, which may be set before the stream exists.
|
||||
double default_recv_volume_ = 1.0;
|
||||
// Sink for unsignalled stream, which may be set before the stream exists.
|
||||
rtc::scoped_ptr<webrtc::AudioSinkInterface> default_sink_;
|
||||
// Default SSRC to use for RTCP receiver reports in case of no signaled
|
||||
// send streams. See: https://code.google.com/p/webrtc/issues/detail?id=4740
|
||||
// and https://code.google.com/p/chromium/issues/detail?id=547661
|
||||
|
||||
@ -72,6 +72,11 @@ class FakeVoEWrapper : public cricket::VoEWrapper {
|
||||
};
|
||||
} // namespace
|
||||
|
||||
class FakeAudioSink : public webrtc::AudioSinkInterface {
|
||||
public:
|
||||
void OnData(const Data& audio) override {}
|
||||
};
|
||||
|
||||
class WebRtcVoiceEngineTestFake : public testing::Test {
|
||||
public:
|
||||
WebRtcVoiceEngineTestFake()
|
||||
@ -125,6 +130,12 @@ class WebRtcVoiceEngineTestFake : public testing::Test {
|
||||
return *send_stream;
|
||||
}
|
||||
|
||||
const cricket::FakeAudioReceiveStream& GetRecvStream(uint32_t ssrc) {
|
||||
const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
|
||||
EXPECT_TRUE(recv_stream);
|
||||
return *recv_stream;
|
||||
}
|
||||
|
||||
const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
|
||||
const auto* send_stream = call_.GetAudioSendStream(ssrc);
|
||||
EXPECT_TRUE(send_stream);
|
||||
@ -3105,6 +3116,52 @@ TEST_F(WebRtcVoiceEngineTestFake, AssociateChannelResetUponDeleteChannnel) {
|
||||
EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), -1);
|
||||
}
|
||||
|
||||
TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSink) {
|
||||
EXPECT_TRUE(SetupEngine());
|
||||
rtc::scoped_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
|
||||
rtc::scoped_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
|
||||
|
||||
// Setting the sink before a recv stream exists should do nothing.
|
||||
channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_1));
|
||||
EXPECT_TRUE(
|
||||
channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc1)));
|
||||
EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
|
||||
|
||||
// Now try actually setting the sink.
|
||||
channel_->SetRawAudioSink(kSsrc1, std::move(fake_sink_2));
|
||||
EXPECT_NE(nullptr, GetRecvStream(kSsrc1).sink());
|
||||
|
||||
// Now try resetting it.
|
||||
channel_->SetRawAudioSink(kSsrc1, nullptr);
|
||||
EXPECT_EQ(nullptr, GetRecvStream(kSsrc1).sink());
|
||||
}
|
||||
|
||||
TEST_F(WebRtcVoiceEngineTestFake, SetRawAudioSinkDefaultRecvStream) {
|
||||
EXPECT_TRUE(SetupEngine());
|
||||
rtc::scoped_ptr<FakeAudioSink> fake_sink_1(new FakeAudioSink());
|
||||
rtc::scoped_ptr<FakeAudioSink> fake_sink_2(new FakeAudioSink());
|
||||
|
||||
// Should be able to set a default sink even when no stream exists.
|
||||
channel_->SetRawAudioSink(0, std::move(fake_sink_1));
|
||||
|
||||
// Create default channel and ensure it's assigned the default sink.
|
||||
DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
|
||||
EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
|
||||
|
||||
// Try resetting the default sink.
|
||||
channel_->SetRawAudioSink(0, nullptr);
|
||||
EXPECT_EQ(nullptr, GetRecvStream(0x01).sink());
|
||||
|
||||
// Try setting the default sink while the default stream exists.
|
||||
channel_->SetRawAudioSink(0, std::move(fake_sink_2));
|
||||
EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
|
||||
|
||||
// If we remove and add a default stream, it should get the same sink.
|
||||
EXPECT_TRUE(channel_->RemoveRecvStream(0x01));
|
||||
DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
|
||||
EXPECT_NE(nullptr, GetRecvStream(0x01).sink());
|
||||
}
|
||||
|
||||
// Tests that the library initializes and shuts down properly.
|
||||
TEST(WebRtcVoiceEngineTest, StartupShutdown) {
|
||||
cricket::WebRtcVoiceEngine engine;
|
||||
|
||||
@ -112,7 +112,7 @@ class AudioReceiveStream : public ReceiveStream {
|
||||
// Sets an audio sink that receives unmixed audio from the receive stream.
|
||||
// Ownership of the sink is passed to the stream and can be used by the
|
||||
// caller to do lifetime management (i.e. when the sink's dtor is called).
|
||||
// Only one sink can be set and passing a null sink, clears an existing one.
|
||||
// Only one sink can be set and passing a null sink clears an existing one.
|
||||
// NOTE: Audio must still somehow be pulled through AudioTransport for audio
|
||||
// to stream through this sink. In practice, this happens if mixed audio
|
||||
// is being pulled+rendered and/or if audio is being pulled for the purposes
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user