blob: cc360df49d9eeb52c38f5c885cdc43a21b102646 [file] [log] [blame]
Niels Möller7d76a312018-10-26 12:57:07 +02001/*
2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Steve Anton40d55332019-01-07 10:21:47 -080011#include "absl/memory/memory.h"
Niels Möller7d76a312018-10-26 12:57:07 +020012#include "api/audio_codecs/audio_decoder_factory_template.h"
13#include "api/audio_codecs/audio_encoder_factory_template.h"
14#include "api/audio_codecs/opus/audio_decoder_opus.h"
15#include "api/audio_codecs/opus/audio_encoder_opus.h"
Anton Sukhanov4f08faa2019-05-21 11:12:57 -070016#include "api/media_transport_config.h"
Danil Chapovalov83bbe912019-08-07 12:24:53 +020017#include "api/rtc_event_log/rtc_event_log.h"
Danil Chapovalov31660fd2019-03-22 12:59:48 +010018#include "api/task_queue/default_task_queue_factory.h"
Niels Möller7d76a312018-10-26 12:57:07 +020019#include "api/test/loopback_media_transport.h"
20#include "api/test/mock_audio_mixer.h"
21#include "audio/audio_receive_stream.h"
22#include "audio/audio_send_stream.h"
Sebastian Jansson0b698262019-03-07 09:17:19 +010023#include "call/rtp_transport_controller_send.h"
Niels Möller7d76a312018-10-26 12:57:07 +020024#include "call/test/mock_bitrate_allocator.h"
Niels Möller7d76a312018-10-26 12:57:07 +020025#include "modules/audio_device/include/test_audio_device.h"
26#include "modules/audio_mixer/audio_mixer_impl.h"
27#include "modules/audio_processing/include/mock_audio_processing.h"
28#include "modules/utility/include/process_thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "rtc_base/time_utils.h"
Niels Möller7d76a312018-10-26 12:57:07 +020030#include "test/gtest.h"
31#include "test/mock_transport.h"
32
33namespace webrtc {
34namespace test {
35
36namespace {
Mirko Bonadei6a489f22019-04-09 15:11:12 +020037using ::testing::NiceMock;
Sebastian Jansson0b698262019-03-07 09:17:19 +010038
Niels Möller7d76a312018-10-26 12:57:07 +020039constexpr int kPayloadTypeOpus = 17;
40constexpr int kSamplingFrequency = 48000;
41constexpr int kNumChannels = 2;
42constexpr int kWantedSamples = 3000;
43constexpr int kTestTimeoutMs = 2 * rtc::kNumMillisecsPerSec;
44
45class TestRenderer : public TestAudioDeviceModule::Renderer {
46 public:
47 TestRenderer(int sampling_frequency, int num_channels, size_t wanted_samples)
48 : sampling_frequency_(sampling_frequency),
49 num_channels_(num_channels),
50 wanted_samples_(wanted_samples) {}
51 ~TestRenderer() override = default;
52
53 int SamplingFrequency() const override { return sampling_frequency_; }
54 int NumChannels() const override { return num_channels_; }
55
56 bool Render(rtc::ArrayView<const int16_t> data) override {
57 if (data.size() >= wanted_samples_) {
58 return false;
59 }
60 wanted_samples_ -= data.size();
61 return true;
62 }
63
64 private:
65 const int sampling_frequency_;
66 const int num_channels_;
67 size_t wanted_samples_;
68};
69
70} // namespace
71
72TEST(AudioWithMediaTransport, DeliversAudio) {
Bjorn Mellem273d0292018-11-01 16:42:44 -070073 std::unique_ptr<rtc::Thread> transport_thread = rtc::Thread::Create();
74 transport_thread->Start();
Danil Chapovalov08fa9532019-06-12 11:49:17 +000075 std::unique_ptr<TaskQueueFactory> task_queue_factory =
76 CreateDefaultTaskQueueFactory();
Bjorn Mellem273d0292018-11-01 16:42:44 -070077 MediaTransportPair transport_pair(transport_thread.get());
Sebastian Jansson0b698262019-03-07 09:17:19 +010078 NiceMock<MockTransport> rtcp_send_transport;
79 NiceMock<MockTransport> send_transport;
Danil Chapovalovb32f2c72019-05-22 13:39:25 +020080 RtcEventLogNull null_event_log;
Sebastian Jansson0b698262019-03-07 09:17:19 +010081 NiceMock<MockBitrateAllocator> bitrate_allocator;
Niels Möller7d76a312018-10-26 12:57:07 +020082
83 rtc::scoped_refptr<TestAudioDeviceModule> audio_device =
Danil Chapovalov08fa9532019-06-12 11:49:17 +000084 TestAudioDeviceModule::Create(
85 task_queue_factory.get(),
Niels Möller7d76a312018-10-26 12:57:07 +020086 TestAudioDeviceModule::CreatePulsedNoiseCapturer(
87 /* max_amplitude= */ 10000, kSamplingFrequency, kNumChannels),
88 absl::make_unique<TestRenderer>(kSamplingFrequency, kNumChannels,
89 kWantedSamples));
90
91 AudioState::Config audio_config;
92 audio_config.audio_mixer = AudioMixerImpl::Create();
93 // TODO(nisse): Is a mock AudioProcessing enough?
94 audio_config.audio_processing =
95 new rtc::RefCountedObject<MockAudioProcessing>();
96 audio_config.audio_device_module = audio_device;
97 rtc::scoped_refptr<AudioState> audio_state = AudioState::Create(audio_config);
98
99 // TODO(nisse): Use some lossless codec?
100 const SdpAudioFormat audio_format("opus", kSamplingFrequency, kNumChannels);
101
102 // Setup receive stream;
103 webrtc::AudioReceiveStream::Config receive_config;
104 // TODO(nisse): Update AudioReceiveStream to not require rtcp_send_transport
105 // when a MediaTransport is provided.
106 receive_config.rtcp_send_transport = &rtcp_send_transport;
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700107 receive_config.media_transport_config.media_transport =
108 transport_pair.first();
Niels Möller7d76a312018-10-26 12:57:07 +0200109 receive_config.decoder_map.emplace(kPayloadTypeOpus, audio_format);
110 receive_config.decoder_factory =
111 CreateAudioDecoderFactory<AudioDecoderOpus>();
112
113 std::unique_ptr<ProcessThread> receive_process_thread =
114 ProcessThread::Create("audio recv thread");
115
116 webrtc::internal::AudioReceiveStream receive_stream(
Sebastian Jansson977b3352019-03-04 17:43:34 +0100117 Clock::GetRealTimeClock(),
Benjamin Wright17b050f2019-03-13 17:35:46 -0700118 /*receiver_controller=*/nullptr,
Niels Möller7d76a312018-10-26 12:57:07 +0200119 /*packet_router=*/nullptr, receive_process_thread.get(), receive_config,
Danil Chapovalovb32f2c72019-05-22 13:39:25 +0200120 audio_state, &null_event_log);
Niels Möller7d76a312018-10-26 12:57:07 +0200121
122 // TODO(nisse): Update AudioSendStream to not require send_transport when a
123 // MediaTransport is provided.
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700124 AudioSendStream::Config send_config(
125 &send_transport, webrtc::MediaTransportConfig(transport_pair.second()));
Niels Möller7d76a312018-10-26 12:57:07 +0200126 send_config.send_codec_spec =
127 AudioSendStream::Config::SendCodecSpec(kPayloadTypeOpus, audio_format);
128 send_config.encoder_factory = CreateAudioEncoderFactory<AudioEncoderOpus>();
Niels Möller7d76a312018-10-26 12:57:07 +0200129 std::unique_ptr<ProcessThread> send_process_thread =
130 ProcessThread::Create("audio send thread");
Sebastian Jansson0b698262019-03-07 09:17:19 +0100131 RtpTransportControllerSend rtp_transport(
Danil Chapovalovb32f2c72019-05-22 13:39:25 +0200132 Clock::GetRealTimeClock(), &null_event_log, nullptr, nullptr,
Sebastian Jansson0b698262019-03-07 09:17:19 +0100133 BitrateConstraints(), ProcessThread::Create("Pacer"),
Danil Chapovalov31660fd2019-03-22 12:59:48 +0100134 task_queue_factory.get());
Niels Möller7d76a312018-10-26 12:57:07 +0200135 webrtc::internal::AudioSendStream send_stream(
Sebastian Jansson0b698262019-03-07 09:17:19 +0100136 Clock::GetRealTimeClock(), send_config, audio_state,
Danil Chapovalov31660fd2019-03-22 12:59:48 +0100137 task_queue_factory.get(), send_process_thread.get(), &rtp_transport,
Danil Chapovalovb32f2c72019-05-22 13:39:25 +0200138 &bitrate_allocator, &null_event_log,
Sam Zackrissonff058162018-11-20 17:15:13 +0100139 /*rtcp_rtt_stats=*/nullptr, absl::optional<RtpState>());
Niels Möller7d76a312018-10-26 12:57:07 +0200140
141 audio_device->Init(); // Starts thread.
142 audio_device->RegisterAudioCallback(audio_state->audio_transport());
143
144 receive_stream.Start();
145 send_stream.Start();
146 audio_device->StartPlayout();
147 audio_device->StartRecording();
148
149 EXPECT_TRUE(audio_device->WaitForPlayoutEnd(kTestTimeoutMs));
150
151 audio_device->StopRecording();
152 audio_device->StopPlayout();
153 receive_stream.Stop();
154 send_stream.Stop();
155}
156
157} // namespace test
158} // namespace webrtc