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