From 3d7db263b902f319b5b0c828ccff59cd8664b937 Mon Sep 17 00:00:00 2001 From: mflodman Date: Fri, 29 Apr 2016 00:57:13 -0700 Subject: [PATCH] Switch voice transport to use Call and Stream instead of VoENetwork. VoENetwork is kept for now, but is not really used anylonger. webrtcvoiceengine is changed to have the same behavior for unsignaled ssrc as video has, which is reflected by disabling one test case and this will be discussed and followed up. BUG=webrtc:5079 TBR=tommi Review-Url: https://codereview.webrtc.org/1909333002 Cr-Commit-Position: refs/heads/master@{#12555} --- webrtc/audio/audio_receive_stream.cc | 11 +- webrtc/audio/audio_receive_stream_unittest.cc | 43 +++++- webrtc/audio/audio_send_stream.cc | 5 +- webrtc/audio/audio_send_stream_unittest.cc | 4 + webrtc/audio_receive_stream.h | 1 - webrtc/call/call.cc | 33 +++-- webrtc/call/call_perf_tests.cc | 106 ++++++-------- webrtc/media/engine/fakewebrtccall.cc | 19 ++- webrtc/media/engine/fakewebrtccall.h | 16 +-- webrtc/media/engine/fakewebrtcvoiceengine.h | 12 -- webrtc/media/engine/webrtcvoiceengine.cc | 127 ++++++----------- .../engine/webrtcvoiceengine_unittest.cc | 133 +++++++++++------- webrtc/test/call_test.cc | 25 ---- webrtc/test/call_test.h | 10 +- webrtc/test/mock_voe_channel_proxy.h | 6 + webrtc/voice_engine/channel.cc | 21 ++- webrtc/voice_engine/channel.h | 6 +- webrtc/voice_engine/channel_proxy.cc | 23 +++ webrtc/voice_engine/channel_proxy.h | 8 ++ webrtc/voice_engine/voe_network_impl.cc | 9 +- 20 files changed, 324 insertions(+), 294 deletions(-) diff --git a/webrtc/audio/audio_receive_stream.cc b/webrtc/audio/audio_receive_stream.cc index 9c25389471..449f2f492f 100644 --- a/webrtc/audio/audio_receive_stream.cc +++ b/webrtc/audio/audio_receive_stream.cc @@ -66,8 +66,6 @@ std::string AudioReceiveStream::Config::Rtp::ToString() const { std::string AudioReceiveStream::Config::ToString() const { std::stringstream ss; ss << "{rtp: " << rtp.ToString(); - ss << ", receive_transport: " - << (receive_transport ? "(Transport)" : "nullptr"); ss << ", rtcp_send_transport: " << (rtcp_send_transport ? "(Transport)" : "nullptr"); ss << ", voe_channel_id: " << voe_channel_id; @@ -95,6 +93,9 @@ AudioReceiveStream::AudioReceiveStream( VoiceEngineImpl* voe_impl = static_cast(voice_engine()); channel_proxy_ = voe_impl->GetChannelProxy(config_.voe_channel_id); channel_proxy_->SetLocalSSRC(config.rtp.local_ssrc); + + channel_proxy_->RegisterExternalTransport(config.rtcp_send_transport); + for (const auto& extension : config.rtp.extensions) { if (extension.name == RtpExtension::kAudioLevel) { channel_proxy_->SetReceiveAudioLevelIndicationStatus(true, extension.id); @@ -127,6 +128,7 @@ AudioReceiveStream::AudioReceiveStream( AudioReceiveStream::~AudioReceiveStream() { RTC_DCHECK(thread_checker_.CalledOnValidThread()); LOG(LS_INFO) << "~AudioReceiveStream: " << config_.ToString(); + channel_proxy_->DeRegisterExternalTransport(); channel_proxy_->ResetCongestionControlObjects(); if (remote_bitrate_estimator_) { remote_bitrate_estimator_->RemoveStream(config_.rtp.remote_ssrc); @@ -150,7 +152,7 @@ bool AudioReceiveStream::DeliverRtcp(const uint8_t* packet, size_t length) { // calls on the worker thread. We should move towards always using a network // thread. Then this check can be enabled. // RTC_DCHECK(!thread_checker_.CalledOnValidThread()); - return false; + return channel_proxy_->ReceivedRTCPPacket(packet, length); } bool AudioReceiveStream::DeliverRtp(const uint8_t* packet, @@ -177,7 +179,8 @@ bool AudioReceiveStream::DeliverRtp(const uint8_t* packet, remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, payload_size, header, false); } - return true; + + return channel_proxy_->ReceivedRTPPacket(packet, length, packet_time); } webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats() const { diff --git a/webrtc/audio/audio_receive_stream_unittest.cc b/webrtc/audio/audio_receive_stream_unittest.cc index 8703d6ed32..300ab20054 100644 --- a/webrtc/audio/audio_receive_stream_unittest.cc +++ b/webrtc/audio/audio_receive_stream_unittest.cc @@ -98,6 +98,10 @@ struct ConfigHelper { .WillOnce(Return(&packet_router_)); EXPECT_CALL(*channel_proxy_, ResetCongestionControlObjects()) .Times(1); + EXPECT_CALL(*channel_proxy_, RegisterExternalTransport(nullptr)) + .Times(1); + EXPECT_CALL(*channel_proxy_, DeRegisterExternalTransport()) + .Times(1); return channel_proxy_; })); stream_config_.voe_channel_id = kChannelId; @@ -120,6 +124,7 @@ struct ConfigHelper { AudioReceiveStream::Config& config() { return stream_config_; } rtc::scoped_refptr audio_state() { return audio_state_; } MockVoiceEngine& voice_engine() { return voice_engine_; } + MockVoEChannelProxy* channel_proxy() { return channel_proxy_; } void SetupMockForBweFeedback(bool send_side_bwe) { EXPECT_CALL(congestion_controller_, @@ -181,7 +186,7 @@ void BuildOneByteExtension(std::vector::iterator it, shifted_value); } -std::vector CreateRtpHeaderWithOneByteExtension( +const std::vector CreateRtpHeaderWithOneByteExtension( int extension_id, uint32_t extension_value, size_t value_length) { @@ -200,6 +205,18 @@ std::vector CreateRtpHeaderWithOneByteExtension( extension_value, value_length); return header; } + +const std::vector CreateRtcpSenderReport() { + std::vector packet; + const size_t kRtcpSrLength = 28; // In bytes. + packet.resize(kRtcpSrLength); + packet[0] = 0x80; // Version 2. + packet[1] = 0xc8; // PT = 200, SR. + // Length in number of 32-bit words - 1. + ByteWriter::WriteBigEndian(&packet[2], 6); + ByteWriter::WriteBigEndian(&packet[4], kLocalSsrc); + return packet; +} } // namespace TEST(AudioReceiveStreamTest, ConfigToString) { @@ -213,7 +230,7 @@ TEST(AudioReceiveStreamTest, ConfigToString) { "{rtp: {remote_ssrc: 1234, local_ssrc: 5678, extensions: [{name: " "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time, id: 2}], " "transport_cc: off}, " - "receive_transport: nullptr, rtcp_send_transport: nullptr, " + "rtcp_send_transport: nullptr, " "voe_channel_id: 2}", config.ToString()); } @@ -235,7 +252,7 @@ MATCHER_P(VerifyHeaderExtension, expected_extension, "") { expected_extension.transportSequenceNumber; } -TEST(AudioReceiveStreamTest, AudioPacketUpdatesBweFeedback) { +TEST(AudioReceiveStreamTest, ReceiveRtpPacket) { ConfigHelper helper; helper.config().rtp.transport_cc = true; helper.SetupMockForBweFeedback(true); @@ -254,10 +271,30 @@ TEST(AudioReceiveStreamTest, AudioPacketUpdatesBweFeedback) { rtp_packet.size() - kExpectedHeaderLength, VerifyHeaderExtension(expected_extension), false)) .Times(1); + EXPECT_CALL(*helper.channel_proxy(), + ReceivedRTPPacket(&rtp_packet[0], + rtp_packet.size(), + _)) + .WillOnce(Return(true)); EXPECT_TRUE( recv_stream.DeliverRtp(&rtp_packet[0], rtp_packet.size(), packet_time)); } +TEST(AudioReceiveStreamTest, ReceiveRtcpPacket) { + ConfigHelper helper; + helper.config().rtp.transport_cc = true; + helper.SetupMockForBweFeedback(true); + internal::AudioReceiveStream recv_stream( + helper.congestion_controller(), helper.config(), helper.audio_state()); + + std::vector rtcp_packet = CreateRtcpSenderReport(); + EXPECT_CALL(*helper.channel_proxy(), + ReceivedRTCPPacket(&rtcp_packet[0], rtcp_packet.size())) + .WillOnce(Return(true)); + EXPECT_TRUE(recv_stream.DeliverRtcp(&rtcp_packet[0], rtcp_packet.size())); +} + + TEST(AudioReceiveStreamTest, GetStats) { ConfigHelper helper; internal::AudioReceiveStream recv_stream( diff --git a/webrtc/audio/audio_send_stream.cc b/webrtc/audio/audio_send_stream.cc index 24afcbcf58..c5dfd77836 100644 --- a/webrtc/audio/audio_send_stream.cc +++ b/webrtc/audio/audio_send_stream.cc @@ -76,6 +76,8 @@ AudioSendStream::AudioSendStream( channel_proxy_->SetLocalSSRC(config.rtp.ssrc); channel_proxy_->SetRTCP_CNAME(config.rtp.c_name); + channel_proxy_->RegisterExternalTransport(config.send_transport); + for (const auto& extension : config.rtp.extensions) { if (extension.name == RtpExtension::kAbsSendTime) { channel_proxy_->SetSendAbsoluteSenderTimeStatus(true, extension.id); @@ -92,6 +94,7 @@ AudioSendStream::AudioSendStream( AudioSendStream::~AudioSendStream() { RTC_DCHECK(thread_checker_.CalledOnValidThread()); LOG(LS_INFO) << "~AudioSendStream: " << config_.ToString(); + channel_proxy_->DeRegisterExternalTransport(); channel_proxy_->ResetCongestionControlObjects(); } @@ -122,7 +125,7 @@ bool AudioSendStream::DeliverRtcp(const uint8_t* packet, size_t length) { // calls on the worker thread. We should move towards always using a network // thread. Then this check can be enabled. // RTC_DCHECK(!thread_checker_.CalledOnValidThread()); - return false; + return channel_proxy_->ReceivedRTCPPacket(packet, length); } bool AudioSendStream::SendTelephoneEvent(int payload_type, int event, diff --git a/webrtc/audio/audio_send_stream_unittest.cc b/webrtc/audio/audio_send_stream_unittest.cc index c04a3de77c..24efaada10 100644 --- a/webrtc/audio/audio_send_stream_unittest.cc +++ b/webrtc/audio/audio_send_stream_unittest.cc @@ -89,6 +89,10 @@ struct ConfigHelper { .Times(1); EXPECT_CALL(*channel_proxy_, ResetCongestionControlObjects()) .Times(1); + EXPECT_CALL(*channel_proxy_, RegisterExternalTransport(nullptr)) + .Times(1); + EXPECT_CALL(*channel_proxy_, DeRegisterExternalTransport()) + .Times(1); return channel_proxy_; })); stream_config_.voe_channel_id = kChannelId; diff --git a/webrtc/audio_receive_stream.h b/webrtc/audio_receive_stream.h index 5254c41780..97feccc938 100644 --- a/webrtc/audio_receive_stream.h +++ b/webrtc/audio_receive_stream.h @@ -83,7 +83,6 @@ class AudioReceiveStream : public ReceiveStream { std::vector extensions; } rtp; - Transport* receive_transport = nullptr; Transport* rtcp_send_transport = nullptr; // Underlying VoiceEngine handle, used to map AudioReceiveStream to lower- diff --git a/webrtc/call/call.cc b/webrtc/call/call.cc index 67abc5669d..23173decc6 100644 --- a/webrtc/call/call.cc +++ b/webrtc/call/call.cc @@ -750,8 +750,7 @@ PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type, const uint8_t* packet, size_t length) { TRACE_EVENT0("webrtc", "Call::DeliverRtcp"); - // TODO(pbos): Figure out what channel needs it actually. - // Do NOT broadcast! Also make sure it's a valid packet. + // TODO(pbos): Make sure it's a valid packet. // Return DELIVERY_UNKNOWN_SSRC if it can be determined that // there's no receiver of the packet. received_rtcp_bytes_ += length; @@ -759,25 +758,35 @@ PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type, if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) { ReadLockScoped read_lock(*receive_crit_); for (VideoReceiveStream* stream : video_receive_streams_) { - if (stream->DeliverRtcp(packet, length)) { + if (stream->DeliverRtcp(packet, length)) + rtcp_delivered = true; + } + } + if (media_type == MediaType::ANY || media_type == MediaType::AUDIO) { + ReadLockScoped read_lock(*receive_crit_); + for (auto& kv : audio_receive_ssrcs_) { + if (kv.second->DeliverRtcp(packet, length)) rtcp_delivered = true; - if (event_log_) - event_log_->LogRtcpPacket(kIncomingPacket, media_type, packet, - length); - } } } if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) { ReadLockScoped read_lock(*send_crit_); for (VideoSendStream* stream : video_send_streams_) { - if (stream->DeliverRtcp(packet, length)) { + if (stream->DeliverRtcp(packet, length)) rtcp_delivered = true; - if (event_log_) - event_log_->LogRtcpPacket(kIncomingPacket, media_type, packet, - length); - } } } + if (media_type == MediaType::ANY || media_type == MediaType::AUDIO) { + ReadLockScoped read_lock(*send_crit_); + for (auto& kv : audio_send_ssrcs_) { + if (kv.second->DeliverRtcp(packet, length)) + rtcp_delivered = true; + } + } + + if (event_log_ && rtcp_delivered) + event_log_->LogRtcpPacket(kIncomingPacket, media_type, packet, length); + return rtcp_delivered ? DELIVERY_OK : DELIVERY_PACKET_ERROR; } diff --git a/webrtc/call/call_perf_tests.cc b/webrtc/call/call_perf_tests.cc index 9aa50d0ad9..8412564ecf 100644 --- a/webrtc/call/call_perf_tests.cc +++ b/webrtc/call/call_perf_tests.cc @@ -17,6 +17,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/base/checks.h" +#include "webrtc/base/constructormagic.h" #include "webrtc/base/thread_annotations.h" #include "webrtc/call.h" #include "webrtc/call/transport_adapter.h" @@ -41,7 +42,6 @@ #include "webrtc/test/testsupport/perf_test.h" #include "webrtc/voice_engine/include/voe_base.h" #include "webrtc/voice_engine/include/voe_codec.h" -#include "webrtc/voice_engine/include/voe_network.h" #include "webrtc/voice_engine/include/voe_rtp_rtcp.h" #include "webrtc/voice_engine/include/voe_video_sync.h" @@ -149,39 +149,11 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec, const char* kSyncGroup = "av_sync"; const uint32_t kAudioSendSsrc = 1234; const uint32_t kAudioRecvSsrc = 5678; - class AudioPacketReceiver : public PacketReceiver { - public: - AudioPacketReceiver(int channel, VoENetwork* voe_network) - : channel_(channel), - voe_network_(voe_network), - parser_(RtpHeaderParser::Create()) {} - DeliveryStatus DeliverPacket(MediaType media_type, - const uint8_t* packet, - size_t length, - const PacketTime& packet_time) override { - EXPECT_TRUE(media_type == MediaType::ANY || - media_type == MediaType::AUDIO); - int ret; - if (parser_->IsRtcp(packet, length)) { - ret = voe_network_->ReceivedRTCPPacket(channel_, packet, length); - } else { - ret = voe_network_->ReceivedRTPPacket(channel_, packet, length, - PacketTime()); - } - return ret == 0 ? DELIVERY_OK : DELIVERY_PACKET_ERROR; - } - - private: - int channel_; - VoENetwork* voe_network_; - std::unique_ptr parser_; - }; test::ClearHistograms(); VoiceEngine* voice_engine = VoiceEngine::Create(); VoEBase* voe_base = VoEBase::GetInterface(voice_engine); VoECodec* voe_codec = VoECodec::GetInterface(voice_engine); - VoENetwork* voe_network = VoENetwork::GetInterface(voice_engine); const std::string audio_filename = test::ResourcePath("voice_engine/audio_long16", "pcm"); ASSERT_STRNE("", audio_filename.c_str()); @@ -201,44 +173,56 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec, receiver_config.audio_state = sender_config.audio_state; CreateCalls(sender_config, receiver_config); - AudioPacketReceiver voe_send_packet_receiver(send_channel_id, voe_network); - AudioPacketReceiver voe_recv_packet_receiver(recv_channel_id, voe_network); VideoRtcpAndSyncObserver observer(Clock::GetRealTimeClock()); - FakeNetworkPipe::Config net_config; - net_config.queue_delay_ms = 500; - net_config.loss_percent = 5; - test::PacketTransport audio_send_transport( - nullptr, &observer, test::PacketTransport::kSender, net_config); - audio_send_transport.SetReceiver(&voe_recv_packet_receiver); - test::PacketTransport audio_receive_transport( - nullptr, &observer, test::PacketTransport::kReceiver, net_config); - audio_receive_transport.SetReceiver(&voe_send_packet_receiver); + // Helper class to ensure we deliver correct media_type to the receiving call. + class MediaTypePacketReceiver : public PacketReceiver { + public: + MediaTypePacketReceiver(PacketReceiver* packet_receiver, + MediaType media_type) + : packet_receiver_(packet_receiver), media_type_(media_type) {} - internal::TransportAdapter send_transport_adapter(&audio_send_transport); - send_transport_adapter.Enable(); - EXPECT_EQ(0, voe_network->RegisterExternalTransport(send_channel_id, - send_transport_adapter)); + DeliveryStatus DeliverPacket(MediaType media_type, + const uint8_t* packet, + size_t length, + const PacketTime& packet_time) override { + return packet_receiver_->DeliverPacket(media_type_, packet, length, + packet_time); + } + private: + PacketReceiver* packet_receiver_; + const MediaType media_type_; - internal::TransportAdapter recv_transport_adapter(&audio_receive_transport); - recv_transport_adapter.Enable(); - EXPECT_EQ(0, voe_network->RegisterExternalTransport(recv_channel_id, - recv_transport_adapter)); + RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(MediaTypePacketReceiver); + }; - test::PacketTransport sync_send_transport(sender_call_.get(), &observer, - test::PacketTransport::kSender, - FakeNetworkPipe::Config()); - sync_send_transport.SetReceiver(receiver_call_->Receiver()); - test::PacketTransport sync_receive_transport(receiver_call_.get(), &observer, - test::PacketTransport::kReceiver, - FakeNetworkPipe::Config()); - sync_receive_transport.SetReceiver(sender_call_->Receiver()); + FakeNetworkPipe::Config audio_net_config; + audio_net_config.queue_delay_ms = 500; + audio_net_config.loss_percent = 5; + test::PacketTransport audio_send_transport(sender_call_.get(), &observer, + test::PacketTransport::kSender, + audio_net_config); + MediaTypePacketReceiver audio_receiver(receiver_call_->Receiver(), + MediaType::AUDIO); + audio_send_transport.SetReceiver(&audio_receiver); + + test::PacketTransport video_send_transport(sender_call_.get(), &observer, + test::PacketTransport::kSender, + FakeNetworkPipe::Config()); + MediaTypePacketReceiver video_receiver(receiver_call_->Receiver(), + MediaType::VIDEO); + video_send_transport.SetReceiver(&video_receiver); + + test::PacketTransport receive_transport( + receiver_call_.get(), &observer, test::PacketTransport::kReceiver, + FakeNetworkPipe::Config()); + receive_transport.SetReceiver(sender_call_->Receiver()); test::FakeDecoder fake_decoder; - CreateSendConfig(1, 0, &sync_send_transport); - CreateMatchingReceiveConfigs(&sync_receive_transport); + CreateSendConfig(1, 0, &video_send_transport); + CreateMatchingReceiveConfigs(&receive_transport); AudioSendStream::Config audio_send_config(&audio_send_transport); audio_send_config.voe_channel_id = send_channel_id; @@ -298,10 +282,9 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec, fake_audio_device.Stop(); Stop(); - sync_send_transport.StopSending(); - sync_receive_transport.StopSending(); + video_send_transport.StopSending(); audio_send_transport.StopSending(); - audio_receive_transport.StopSending(); + receive_transport.StopSending(); DestroyStreams(); @@ -312,7 +295,6 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec, voe_base->DeleteChannel(recv_channel_id); voe_base->Release(); voe_codec->Release(); - voe_network->Release(); DestroyCalls(); diff --git a/webrtc/media/engine/fakewebrtccall.cc b/webrtc/media/engine/fakewebrtccall.cc index 8eff0ebcf8..bc580e3ccc 100644 --- a/webrtc/media/engine/fakewebrtccall.cc +++ b/webrtc/media/engine/fakewebrtccall.cc @@ -67,8 +67,21 @@ void FakeAudioReceiveStream::SetStats( stats_ = stats; } -void FakeAudioReceiveStream::IncrementReceivedPackets() { - received_packets_++; +bool FakeAudioReceiveStream::VerifyLastPacket(const uint8_t* data, + size_t length) const { + return last_packet_ == rtc::Buffer(data, length); +} + +bool FakeAudioReceiveStream::DeliverRtp(const uint8_t* packet, + size_t length, + const webrtc::PacketTime& packet_time) { + ++received_packets_; + last_packet_.SetData(packet, length); + return true; +} + +bool FakeAudioReceiveStream::DeliverRtcp(const uint8_t* packet, size_t length) { + return true; } webrtc::AudioReceiveStream::Stats FakeAudioReceiveStream::GetStats() const { @@ -409,7 +422,7 @@ FakeCall::DeliveryStatus FakeCall::DeliverPacket( media_type == webrtc::MediaType::AUDIO) { for (auto receiver : audio_receive_streams_) { if (receiver->GetConfig().rtp.remote_ssrc == ssrc) { - receiver->IncrementReceivedPackets(); + receiver->DeliverRtp(packet, length, packet_time); return DELIVERY_OK; } } diff --git a/webrtc/media/engine/fakewebrtccall.h b/webrtc/media/engine/fakewebrtccall.h index ee3e449b19..63c3b41fd4 100644 --- a/webrtc/media/engine/fakewebrtccall.h +++ b/webrtc/media/engine/fakewebrtccall.h @@ -25,6 +25,7 @@ #include "webrtc/audio_receive_stream.h" #include "webrtc/audio_send_stream.h" +#include "webrtc/base/buffer.h" #include "webrtc/call.h" #include "webrtc/video_frame.h" #include "webrtc/video_receive_stream.h" @@ -74,22 +75,18 @@ class FakeAudioReceiveStream final : public webrtc::AudioReceiveStream { const webrtc::AudioReceiveStream::Config& GetConfig() const; void SetStats(const webrtc::AudioReceiveStream::Stats& stats); int received_packets() const { return received_packets_; } - void IncrementReceivedPackets(); + bool VerifyLastPacket(const uint8_t* data, size_t length) const; const webrtc::AudioSinkInterface* sink() const { return sink_.get(); } + bool DeliverRtp(const uint8_t* packet, + size_t length, + const webrtc::PacketTime& packet_time) override; + bool DeliverRtcp(const uint8_t* packet, size_t length) override; private: // webrtc::ReceiveStream implementation. void Start() override {} void Stop() override {} void SignalNetworkState(webrtc::NetworkState state) override {} - bool DeliverRtcp(const uint8_t* packet, size_t length) override { - return true; - } - bool DeliverRtp(const uint8_t* packet, - size_t length, - const webrtc::PacketTime& packet_time) override { - return true; - } // webrtc::AudioReceiveStream implementation. webrtc::AudioReceiveStream::Stats GetStats() const override; @@ -99,6 +96,7 @@ class FakeAudioReceiveStream final : public webrtc::AudioReceiveStream { webrtc::AudioReceiveStream::Stats stats_; int received_packets_; std::unique_ptr sink_; + rtc::Buffer last_packet_; }; class FakeVideoSendStream final : public webrtc::VideoSendStream, diff --git a/webrtc/media/engine/fakewebrtcvoiceengine.h b/webrtc/media/engine/fakewebrtcvoiceengine.h index 33629160bc..4aa6ea3d43 100644 --- a/webrtc/media/engine/fakewebrtcvoiceengine.h +++ b/webrtc/media/engine/fakewebrtcvoiceengine.h @@ -203,18 +203,6 @@ class FakeWebRtcVoiceEngine int GetSendREDPayloadType(int channel) { return channels_[channel]->red_type; } - bool CheckPacket(int channel, const void* data, size_t len) { - bool result = !CheckNoPacket(channel); - if (result) { - std::string packet = channels_[channel]->packets.front(); - result = (packet == std::string(static_cast(data), len)); - channels_[channel]->packets.pop_front(); - } - return result; - } - bool CheckNoPacket(int channel) { - return channels_[channel]->packets.empty(); - } void set_playout_fail_channel(int channel) { playout_fail_channel_ = channel; } diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc index 63241332a3..64f53b7eb1 100644 --- a/webrtc/media/engine/webrtcvoiceengine.cc +++ b/webrtc/media/engine/webrtcvoiceengine.cc @@ -1095,10 +1095,11 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream uint32_t ssrc, const std::string& c_name, const std::vector& extensions, - webrtc::Call* call) + webrtc::Call* call, + webrtc::Transport* send_transport) : voe_audio_transport_(voe_audio_transport), call_(call), - config_(nullptr), + config_(send_transport), rtp_parameters_(CreateRtpParametersWithOneEncoding()) { RTC_DCHECK_GE(ch, 0); // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: @@ -1926,18 +1927,11 @@ int WebRtcVoiceMediaChannel::CreateVoEChannel() { LOG_RTCERR0(CreateVoEChannel); return -1; } - if (engine()->voe()->network()->RegisterExternalTransport(id, *this) == -1) { - LOG_RTCERR2(RegisterExternalTransport, id, this); - engine()->voe()->base()->DeleteChannel(id); - return -1; - } + return id; } bool WebRtcVoiceMediaChannel::DeleteVoEChannel(int channel) { - if (engine()->voe()->network()->DeRegisterExternalTransport(channel) == -1) { - LOG_RTCERR1(DeRegisterExternalTransport, channel); - } if (engine()->voe()->base()->DeleteChannel(channel) == -1) { LOG_RTCERR1(DeleteChannel, channel); return false; @@ -1968,8 +1962,10 @@ bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { // delete the channel in case failure happens below. webrtc::AudioTransport* audio_transport = engine()->voe()->base()->audio_transport(); + WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( - channel, audio_transport, ssrc, sp.cname, send_rtp_extensions_, call_); + channel, audio_transport, ssrc, sp.cname, send_rtp_extensions_, call_, + this); send_streams_.insert(std::make_pair(ssrc, stream)); // Set the current codecs to be used for the new channel. We need to do this @@ -2266,54 +2262,52 @@ void WebRtcVoiceMediaChannel::OnPacketReceived( rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, + packet_time.not_before); + webrtc::PacketReceiver::DeliveryStatus delivery_result = + call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, + packet->cdata(), packet->size(), + webrtc_packet_time); + + if (delivery_result != webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC) { + return; + } + + // Create a default receive stream for this unsignalled and previously not + // received ssrc. If there already is a default receive stream, delete it. + // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5208 uint32_t ssrc = 0; if (!GetRtpSsrc(packet->cdata(), packet->size(), &ssrc)) { return; } - // If we don't have a default channel, and the SSRC is unknown, create a - // default channel. - if (default_recv_ssrc_ == -1 && GetReceiveChannelId(ssrc) == -1) { - StreamParams sp; - sp.ssrcs.push_back(ssrc); - LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; - if (!AddRecvStream(sp)) { - LOG(LS_WARNING) << "Could not create default receive stream."; - return; - } - default_recv_ssrc_ = ssrc; - SetOutputVolume(default_recv_ssrc_, default_recv_volume_); - if (default_sink_) { - std::unique_ptr proxy_sink( - new ProxySink(default_sink_.get())); - SetRawAudioSink(default_recv_ssrc_, std::move(proxy_sink)); - } + if (default_recv_ssrc_ != -1) { + LOG(LS_INFO) << "Removing default receive stream with ssrc " + << default_recv_ssrc_; + RTC_DCHECK_NE(ssrc, default_recv_ssrc_); + RemoveRecvStream(default_recv_ssrc_); + default_recv_ssrc_ = -1; } - // Forward packet to Call. If the SSRC is unknown we'll return after this. - const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, - packet_time.not_before); - webrtc::PacketReceiver::DeliveryStatus delivery_result = - call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, - packet->cdata(), packet->size(), webrtc_packet_time); - if (webrtc::PacketReceiver::DELIVERY_OK != delivery_result) { - // If the SSRC is unknown here, route it to the default channel, if we have - // one. See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5208 - if (default_recv_ssrc_ == -1) { - return; - } else { - ssrc = default_recv_ssrc_; - } + StreamParams sp; + sp.ssrcs.push_back(ssrc); + LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; + if (!AddRecvStream(sp)) { + LOG(LS_WARNING) << "Could not create default receive stream."; + return; } - - // Find the channel to send this packet to. It must exist since webrtc::Call - // was able to demux the packet. - int channel = GetReceiveChannelId(ssrc); - RTC_DCHECK(channel != -1); - - // Pass it off to the decoder. - engine()->voe()->network()->ReceivedRTPPacket( - channel, packet->cdata(), packet->size(), webrtc_packet_time); + default_recv_ssrc_ = ssrc; + SetOutputVolume(default_recv_ssrc_, default_recv_volume_); + if (default_sink_) { + std::unique_ptr proxy_sink( + new ProxySink(default_sink_.get())); + SetRawAudioSink(default_recv_ssrc_, std::move(proxy_sink)); + } + delivery_result = call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, + packet->cdata(), + packet->size(), + webrtc_packet_time); + RTC_DCHECK_NE(webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC, delivery_result); } void WebRtcVoiceMediaChannel::OnRtcpReceived( @@ -2325,37 +2319,6 @@ void WebRtcVoiceMediaChannel::OnRtcpReceived( packet_time.not_before); call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, packet->cdata(), packet->size(), webrtc_packet_time); - - // Sending channels need all RTCP packets with feedback information. - // Even sender reports can contain attached report blocks. - // Receiving channels need sender reports in order to create - // correct receiver reports. - int type = 0; - if (!GetRtcpType(packet->cdata(), packet->size(), &type)) { - LOG(LS_WARNING) << "Failed to parse type from received RTCP packet"; - return; - } - - // If it is a sender report, find the receive channel that is listening. - if (type == kRtcpTypeSR) { - uint32_t ssrc = 0; - if (!GetRtcpSsrc(packet->cdata(), packet->size(), &ssrc)) { - return; - } - int recv_channel_id = GetReceiveChannelId(ssrc); - if (recv_channel_id != -1) { - engine()->voe()->network()->ReceivedRTCPPacket( - recv_channel_id, packet->cdata(), packet->size()); - } - } - - // SR may continue RR and any RR entry may correspond to any one of the send - // channels. So all RTCP packets must be forwarded all send channels. VoE - // will filter out RR internally. - for (const auto& ch : send_streams_) { - engine()->voe()->network()->ReceivedRTCPPacket( - ch.second->channel(), packet->cdata(), packet->size()); - } } void WebRtcVoiceMediaChannel::OnNetworkRouteChanged( diff --git a/webrtc/media/engine/webrtcvoiceengine_unittest.cc b/webrtc/media/engine/webrtcvoiceengine_unittest.cc index 9f9ab47242..a0d7417870 100644 --- a/webrtc/media/engine/webrtcvoiceengine_unittest.cc +++ b/webrtc/media/engine/webrtcvoiceengine_unittest.cc @@ -2606,61 +2606,77 @@ TEST_F(WebRtcVoiceEngineTestFake, Recv) { EXPECT_TRUE(SetupChannel()); EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame)); - int channel_num = voe_.GetLastChannel(); - EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame, sizeof(kPcmuFrame))); + + EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame, + sizeof(kPcmuFrame))); } // Test that we can properly receive packets on multiple streams. TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) { EXPECT_TRUE(SetupChannel()); - EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); - int channel_num1 = voe_.GetLastChannel(); - EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2))); - int channel_num2 = voe_.GetLastChannel(); - EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3))); - int channel_num3 = voe_.GetLastChannel(); + const uint32_t ssrc1 = 1; + const uint32_t ssrc2 = 2; + const uint32_t ssrc3 = 3; + EXPECT_TRUE(channel_->AddRecvStream( + cricket::StreamParams::CreateLegacy(ssrc1))); + EXPECT_TRUE(channel_->AddRecvStream( + cricket::StreamParams::CreateLegacy(ssrc2))); + EXPECT_TRUE(channel_->AddRecvStream( + cricket::StreamParams::CreateLegacy(ssrc3))); // Create packets with the right SSRCs. - char packets[4][sizeof(kPcmuFrame)]; + unsigned char packets[4][sizeof(kPcmuFrame)]; for (size_t i = 0; i < arraysize(packets); ++i) { memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame)); rtc::SetBE32(packets[i] + 8, static_cast(i)); } - EXPECT_TRUE(voe_.CheckNoPacket(channel_num1)); - EXPECT_TRUE(voe_.CheckNoPacket(channel_num2)); - EXPECT_TRUE(voe_.CheckNoPacket(channel_num3)); + + const cricket::FakeAudioReceiveStream& s1 = GetRecvStream(ssrc1); + const cricket::FakeAudioReceiveStream& s2 = GetRecvStream(ssrc2); + const cricket::FakeAudioReceiveStream& s3 = GetRecvStream(ssrc3); + + EXPECT_EQ(s1.received_packets(), 0); + EXPECT_EQ(s2.received_packets(), 0); + EXPECT_EQ(s3.received_packets(), 0); DeliverPacket(packets[0], sizeof(packets[0])); - EXPECT_TRUE(voe_.CheckNoPacket(channel_num1)); - EXPECT_TRUE(voe_.CheckNoPacket(channel_num2)); - EXPECT_TRUE(voe_.CheckNoPacket(channel_num3)); + EXPECT_EQ(s1.received_packets(), 0); + EXPECT_EQ(s2.received_packets(), 0); + EXPECT_EQ(s3.received_packets(), 0); DeliverPacket(packets[1], sizeof(packets[1])); - EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1], sizeof(packets[1]))); - EXPECT_TRUE(voe_.CheckNoPacket(channel_num2)); - EXPECT_TRUE(voe_.CheckNoPacket(channel_num3)); + EXPECT_EQ(s1.received_packets(), 1); + EXPECT_TRUE(s1.VerifyLastPacket(packets[1], sizeof(packets[1]))); + EXPECT_EQ(s2.received_packets(), 0); + EXPECT_EQ(s3.received_packets(), 0); DeliverPacket(packets[2], sizeof(packets[2])); - EXPECT_TRUE(voe_.CheckNoPacket(channel_num1)); - EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2], sizeof(packets[2]))); - EXPECT_TRUE(voe_.CheckNoPacket(channel_num3)); + EXPECT_EQ(s1.received_packets(), 1); + EXPECT_EQ(s2.received_packets(), 1); + EXPECT_TRUE(s2.VerifyLastPacket(packets[2], sizeof(packets[2]))); + EXPECT_EQ(s3.received_packets(), 0); DeliverPacket(packets[3], sizeof(packets[3])); - EXPECT_TRUE(voe_.CheckNoPacket(channel_num1)); - EXPECT_TRUE(voe_.CheckNoPacket(channel_num2)); - EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3], sizeof(packets[3]))); + EXPECT_EQ(s1.received_packets(), 1); + EXPECT_EQ(s2.received_packets(), 1); + EXPECT_EQ(s3.received_packets(), 1); + EXPECT_TRUE(s3.VerifyLastPacket(packets[3], sizeof(packets[3]))); - EXPECT_TRUE(channel_->RemoveRecvStream(3)); - EXPECT_TRUE(channel_->RemoveRecvStream(2)); - EXPECT_TRUE(channel_->RemoveRecvStream(1)); + EXPECT_TRUE(channel_->RemoveRecvStream(ssrc3)); + EXPECT_TRUE(channel_->RemoveRecvStream(ssrc2)); + EXPECT_TRUE(channel_->RemoveRecvStream(ssrc1)); } // Test that receiving on an unsignalled stream works (default channel will be // created). TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalled) { EXPECT_TRUE(SetupChannel()); + EXPECT_EQ(0, call_.GetAudioReceiveStreams().size()); + DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame)); - int channel_num = voe_.GetLastChannel(); - EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame, sizeof(kPcmuFrame))); + + EXPECT_EQ(1, call_.GetAudioReceiveStreams().size()); + EXPECT_TRUE(GetRecvStream(1).VerifyLastPacket(kPcmuFrame, + sizeof(kPcmuFrame))); } // Test that receiving on an unsignalled stream works (default channel will be @@ -2668,48 +2684,61 @@ TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalled) { // regardless of their SSRCs. TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledWithSsrcSwitch) { EXPECT_TRUE(SetupChannel()); - char packet[sizeof(kPcmuFrame)]; + unsigned char packet[sizeof(kPcmuFrame)]; memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame)); - // Note that the first unknown SSRC cannot be 0, because we only support - // creating receive streams for SSRC!=0. - DeliverPacket(packet, sizeof(packet)); - int channel_num = voe_.GetLastChannel(); - EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet))); - // Once we have the default channel, SSRC==0 will be ok. - for (uint32_t ssrc = 0; ssrc < 10; ++ssrc) { + // Note that ssrc = 0 is not supported. + uint32_t ssrc = 1; + for (; ssrc < 10; ++ssrc) { rtc::SetBE32(&packet[8], ssrc); DeliverPacket(packet, sizeof(packet)); - EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet))); + + // Verify we only have one default stream. + EXPECT_EQ(1, call_.GetAudioReceiveStreams().size()); + EXPECT_EQ(1, GetRecvStream(ssrc).received_packets()); + EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet))); } + + // Sending the same ssrc again should not create a new stream. + --ssrc; + DeliverPacket(packet, sizeof(packet)); + EXPECT_EQ(1, call_.GetAudioReceiveStreams().size()); + EXPECT_EQ(2, GetRecvStream(ssrc).received_packets()); + EXPECT_TRUE(GetRecvStream(ssrc).VerifyLastPacket(packet, sizeof(packet))); } // Test that a default channel is created even after a signalled stream has been // added, and that this stream will get any packets for unknown SSRCs. TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledAfterSignalled) { EXPECT_TRUE(SetupChannel()); - char packet[sizeof(kPcmuFrame)]; + unsigned char packet[sizeof(kPcmuFrame)]; memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame)); // Add a known stream, send packet and verify we got it. - EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); - int signalled_channel_num = voe_.GetLastChannel(); + const uint32_t signaled_ssrc = 1; + rtc::SetBE32(&packet[8], signaled_ssrc); + EXPECT_TRUE(channel_->AddRecvStream( + cricket::StreamParams::CreateLegacy(signaled_ssrc))); DeliverPacket(packet, sizeof(packet)); - EXPECT_TRUE(voe_.CheckPacket(signalled_channel_num, packet, sizeof(packet))); + EXPECT_TRUE(GetRecvStream(signaled_ssrc).VerifyLastPacket( + packet, sizeof(packet))); // Note that the first unknown SSRC cannot be 0, because we only support // creating receive streams for SSRC!=0. - rtc::SetBE32(&packet[8], 7011); + const uint32_t unsignaled_ssrc = 7011; + rtc::SetBE32(&packet[8], unsignaled_ssrc); DeliverPacket(packet, sizeof(packet)); - int channel_num = voe_.GetLastChannel(); - EXPECT_NE(channel_num, signalled_channel_num); - EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet))); - // Once we have the default channel, SSRC==0 will be ok. - for (uint32_t ssrc = 0; ssrc < 20; ssrc += 2) { - rtc::SetBE32(&packet[8], ssrc); - DeliverPacket(packet, sizeof(packet)); - EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet))); - } + EXPECT_TRUE(GetRecvStream(unsignaled_ssrc).VerifyLastPacket( + packet, sizeof(packet))); + EXPECT_EQ(2, call_.GetAudioReceiveStreams().size()); + + DeliverPacket(packet, sizeof(packet)); + EXPECT_EQ(2, GetRecvStream(unsignaled_ssrc).received_packets()); + + rtc::SetBE32(&packet[8], signaled_ssrc); + DeliverPacket(packet, sizeof(packet)); + EXPECT_EQ(2, GetRecvStream(signaled_ssrc).received_packets()); + EXPECT_EQ(2, call_.GetAudioReceiveStreams().size()); } // Test that we properly handle failures to add a receive stream. diff --git a/webrtc/test/call_test.cc b/webrtc/test/call_test.cc index 1a20ff80da..768c007c3c 100644 --- a/webrtc/test/call_test.cc +++ b/webrtc/test/call_test.cc @@ -15,7 +15,6 @@ #include "webrtc/test/testsupport/fileutils.h" #include "webrtc/voice_engine/include/voe_base.h" #include "webrtc/voice_engine/include/voe_codec.h" -#include "webrtc/voice_engine/include/voe_network.h" namespace webrtc { namespace test { @@ -78,9 +77,6 @@ void CallTest::RunBaseTest(BaseTest* test) { if (test->ShouldCreateReceivers()) { CreateMatchingReceiveConfigs(receive_transport_.get()); } - if (num_audio_streams_ > 0) - SetupVoiceEngineTransports(send_transport_.get(), receive_transport_.get()); - if (num_video_streams_ > 0) { test->ModifyVideoConfigs(&video_send_config_, &video_receive_configs_, &video_encoder_config_); @@ -310,7 +306,6 @@ void CallTest::CreateVoiceEngines() { CreateFakeAudioDevices(); voe_send_.voice_engine = VoiceEngine::Create(); voe_send_.base = VoEBase::GetInterface(voe_send_.voice_engine); - voe_send_.network = VoENetwork::GetInterface(voe_send_.voice_engine); voe_send_.codec = VoECodec::GetInterface(voe_send_.voice_engine); EXPECT_EQ(0, voe_send_.base->Init(fake_send_audio_device_.get(), nullptr)); Config voe_config; @@ -320,35 +315,17 @@ void CallTest::CreateVoiceEngines() { voe_recv_.voice_engine = VoiceEngine::Create(); voe_recv_.base = VoEBase::GetInterface(voe_recv_.voice_engine); - voe_recv_.network = VoENetwork::GetInterface(voe_recv_.voice_engine); voe_recv_.codec = VoECodec::GetInterface(voe_recv_.voice_engine); EXPECT_EQ(0, voe_recv_.base->Init(fake_recv_audio_device_.get(), nullptr)); voe_recv_.channel_id = voe_recv_.base->CreateChannel(); EXPECT_GE(voe_recv_.channel_id, 0); } -void CallTest::SetupVoiceEngineTransports(PacketTransport* send_transport, - PacketTransport* recv_transport) { - voe_send_.transport_adapter.reset( - new internal::TransportAdapter(send_transport)); - voe_send_.transport_adapter->Enable(); - EXPECT_EQ(0, voe_send_.network->RegisterExternalTransport( - voe_send_.channel_id, *voe_send_.transport_adapter.get())); - - voe_recv_.transport_adapter.reset( - new internal::TransportAdapter(recv_transport)); - voe_recv_.transport_adapter->Enable(); - EXPECT_EQ(0, voe_recv_.network->RegisterExternalTransport( - voe_recv_.channel_id, *voe_recv_.transport_adapter.get())); -} - void CallTest::DestroyVoiceEngines() { voe_recv_.base->DeleteChannel(voe_recv_.channel_id); voe_recv_.channel_id = -1; voe_recv_.base->Release(); voe_recv_.base = nullptr; - voe_recv_.network->Release(); - voe_recv_.network = nullptr; voe_recv_.codec->Release(); voe_recv_.codec = nullptr; @@ -356,8 +333,6 @@ void CallTest::DestroyVoiceEngines() { voe_send_.channel_id = -1; voe_send_.base->Release(); voe_send_.base = nullptr; - voe_send_.network->Release(); - voe_send_.network = nullptr; voe_send_.codec->Release(); voe_send_.codec = nullptr; diff --git a/webrtc/test/call_test.h b/webrtc/test/call_test.h index 4d8e117956..41a6b5a6c2 100644 --- a/webrtc/test/call_test.h +++ b/webrtc/test/call_test.h @@ -14,7 +14,6 @@ #include #include "webrtc/call.h" -#include "webrtc/call/transport_adapter.h" #include "webrtc/test/fake_audio_device.h" #include "webrtc/test/fake_decoder.h" #include "webrtc/test/fake_encoder.h" @@ -25,7 +24,6 @@ namespace webrtc { class VoEBase; class VoECodec; -class VoENetwork; namespace test { @@ -113,22 +111,16 @@ class CallTest : public ::testing::Test { VoiceEngineState() : voice_engine(nullptr), base(nullptr), - network(nullptr), codec(nullptr), - channel_id(-1), - transport_adapter(nullptr) {} + channel_id(-1) {} VoiceEngine* voice_engine; VoEBase* base; - VoENetwork* network; VoECodec* codec; int channel_id; - rtc::scoped_ptr transport_adapter; }; void CreateVoiceEngines(); - void SetupVoiceEngineTransports(PacketTransport* send_transport, - PacketTransport* recv_transport); void DestroyVoiceEngines(); VoiceEngineState voe_send_; diff --git a/webrtc/test/mock_voe_channel_proxy.h b/webrtc/test/mock_voe_channel_proxy.h index c2211f8554..a27a739006 100644 --- a/webrtc/test/mock_voe_channel_proxy.h +++ b/webrtc/test/mock_voe_channel_proxy.h @@ -44,6 +44,12 @@ class MockVoEChannelProxy : public voe::ChannelProxy { MOCK_CONST_METHOD0(GetDelayEstimate, uint32_t()); MOCK_METHOD1(SetSendTelephoneEventPayloadType, bool(int payload_type)); MOCK_METHOD2(SendTelephoneEventOutband, bool(int event, int duration_ms)); + MOCK_METHOD1(RegisterExternalTransport, void(Transport* transport)); + MOCK_METHOD0(DeRegisterExternalTransport, void()); + MOCK_METHOD3(ReceivedRTPPacket, bool(const uint8_t* packet, + size_t length, + const PacketTime& packet_time)); + MOCK_METHOD2(ReceivedRTCPPacket, bool(const uint8_t* packet, size_t length)); }; } // namespace test } // namespace webrtc diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc index b9adde7e3e..a6c0c8d050 100644 --- a/webrtc/voice_engine/channel.cc +++ b/webrtc/voice_engine/channel.cc @@ -1449,12 +1449,11 @@ int Channel::SetOpusDtx(bool enable_dtx) { return 0; } -int32_t Channel::RegisterExternalTransport(Transport& transport) { +int32_t Channel::RegisterExternalTransport(Transport* transport) { WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), "Channel::RegisterExternalTransport()"); rtc::CritScope cs(&_callbackCritSect); - if (_externalTransport) { _engineStatisticsPtr->SetLastError( VE_INVALID_OPERATION, kTraceError, @@ -1462,7 +1461,7 @@ int32_t Channel::RegisterExternalTransport(Transport& transport) { return -1; } _externalTransport = true; - _transportPtr = &transport; + _transportPtr = transport; return 0; } @@ -1471,22 +1470,21 @@ int32_t Channel::DeRegisterExternalTransport() { "Channel::DeRegisterExternalTransport()"); rtc::CritScope cs(&_callbackCritSect); - - if (!_transportPtr) { + if (_transportPtr) { + WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), + "DeRegisterExternalTransport() all transport is disabled"); + } else { _engineStatisticsPtr->SetLastError( VE_INVALID_OPERATION, kTraceWarning, "DeRegisterExternalTransport() external transport already " "disabled"); - return 0; } _externalTransport = false; _transportPtr = NULL; - WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), - "DeRegisterExternalTransport() all transport is disabled"); return 0; } -int32_t Channel::ReceivedRTPPacket(const int8_t* data, +int32_t Channel::ReceivedRTPPacket(const uint8_t* received_packet, size_t length, const PacketTime& packet_time) { WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), @@ -1495,7 +1493,6 @@ int32_t Channel::ReceivedRTPPacket(const int8_t* data, // Store playout timestamp for the received RTP packet UpdatePlayoutTimestamp(false); - const uint8_t* received_packet = reinterpret_cast(data); RTPHeader header; if (!rtp_header_parser_->Parse(received_packet, length, &header)) { WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVoice, _channelId, @@ -1585,14 +1582,14 @@ bool Channel::IsPacketRetransmitted(const RTPHeader& header, return !in_order && statistician->IsRetransmitOfOldPacket(header, min_rtt); } -int32_t Channel::ReceivedRTCPPacket(const int8_t* data, size_t length) { +int32_t Channel::ReceivedRTCPPacket(const uint8_t* data, size_t length) { WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), "Channel::ReceivedRTCPPacket()"); // Store playout timestamp for the received RTCP packet UpdatePlayoutTimestamp(true); // Deliver RTCP packet to RTP/RTCP module for parsing - if (_rtpRtcpModule->IncomingRtcpPacket((const uint8_t*)data, length) == -1) { + if (_rtpRtcpModule->IncomingRtcpPacket(data, length) == -1) { _engineStatisticsPtr->SetLastError( VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning, "Channel::IncomingRTPPacket() RTCP packet is invalid"); diff --git a/webrtc/voice_engine/channel.h b/webrtc/voice_engine/channel.h index d22da74ae5..ac49e28752 100644 --- a/webrtc/voice_engine/channel.h +++ b/webrtc/voice_engine/channel.h @@ -218,12 +218,12 @@ class Channel int SetOpusDtx(bool enable_dtx); // VoENetwork - int32_t RegisterExternalTransport(Transport& transport); + int32_t RegisterExternalTransport(Transport* transport); int32_t DeRegisterExternalTransport(); - int32_t ReceivedRTPPacket(const int8_t* data, + int32_t ReceivedRTPPacket(const uint8_t* received_packet, size_t length, const PacketTime& packet_time); - int32_t ReceivedRTCPPacket(const int8_t* data, size_t length); + int32_t ReceivedRTCPPacket(const uint8_t* data, size_t length); // VoEFile int StartPlayingFileLocally(const char* fileName, diff --git a/webrtc/voice_engine/channel_proxy.cc b/webrtc/voice_engine/channel_proxy.cc index 10c8821202..4cc7f5cbbc 100644 --- a/webrtc/voice_engine/channel_proxy.cc +++ b/webrtc/voice_engine/channel_proxy.cc @@ -158,6 +158,29 @@ void ChannelProxy::SetSink(std::unique_ptr sink) { channel()->SetSink(std::move(sink)); } +void ChannelProxy::RegisterExternalTransport(Transport* transport) { + RTC_DCHECK(thread_checker_.CalledOnValidThread()); + int error = channel()->RegisterExternalTransport(transport); + RTC_DCHECK_EQ(0, error); +} + +void ChannelProxy::DeRegisterExternalTransport() { + RTC_DCHECK(thread_checker_.CalledOnValidThread()); + channel()->DeRegisterExternalTransport(); +} + +bool ChannelProxy::ReceivedRTPPacket(const uint8_t* packet, + size_t length, + const PacketTime& packet_time) { + // May be called on either worker thread or network thread. + return channel()->ReceivedRTPPacket(packet, length, packet_time) == 0; +} + +bool ChannelProxy::ReceivedRTCPPacket(const uint8_t* packet, size_t length) { + // May be called on either worker thread or network thread. + return channel()->ReceivedRTCPPacket(packet, length) == 0; +} + Channel* ChannelProxy::channel() const { RTC_DCHECK(channel_owner_.channel()); return channel_owner_.channel(); diff --git a/webrtc/voice_engine/channel_proxy.h b/webrtc/voice_engine/channel_proxy.h index f8f0659af8..df0c3f22ef 100644 --- a/webrtc/voice_engine/channel_proxy.h +++ b/webrtc/voice_engine/channel_proxy.h @@ -25,6 +25,7 @@ namespace webrtc { class AudioSinkInterface; class PacketRouter; class RtpPacketSender; +class Transport; class TransportFeedbackObserver; namespace voe { @@ -72,6 +73,13 @@ class ChannelProxy { virtual bool SendTelephoneEventOutband(int event, int duration_ms); virtual void SetSink(std::unique_ptr sink); + virtual void RegisterExternalTransport(Transport* transport); + virtual void DeRegisterExternalTransport(); + virtual bool ReceivedRTPPacket(const uint8_t* packet, + size_t length, + const PacketTime& packet_time); + virtual bool ReceivedRTCPPacket(const uint8_t* packet, size_t length); + private: Channel* channel() const; diff --git a/webrtc/voice_engine/voe_network_impl.cc b/webrtc/voice_engine/voe_network_impl.cc index 5562048295..6941629d79 100644 --- a/webrtc/voice_engine/voe_network_impl.cc +++ b/webrtc/voice_engine/voe_network_impl.cc @@ -43,7 +43,7 @@ int VoENetworkImpl::RegisterExternalTransport(int channel, LOG_F(LS_ERROR) << "Failed to locate channel: " << channel; return -1; } - return channelPtr->RegisterExternalTransport(transport); + return channelPtr->RegisterExternalTransport(&transport); } int VoENetworkImpl::DeRegisterExternalTransport(int channel) { @@ -84,8 +84,8 @@ int VoENetworkImpl::ReceivedRTPPacket(int channel, LOG_F(LS_ERROR) << "No external transport for channel: " << channel; return -1; } - return channelPtr->ReceivedRTPPacket((const int8_t*)data, length, - packet_time); + return channelPtr->ReceivedRTPPacket(static_cast(data), + length, packet_time); } int VoENetworkImpl::ReceivedRTCPPacket(int channel, @@ -107,7 +107,8 @@ int VoENetworkImpl::ReceivedRTCPPacket(int channel, LOG_F(LS_ERROR) << "No external transport for channel: " << channel; return -1; } - return channelPtr->ReceivedRTCPPacket((const int8_t*)data, length); + return channelPtr->ReceivedRTCPPacket(static_cast(data), + length); } } // namespace webrtc