blob: 71a3fb8fc33f5698c51dcef6eb172303b527fa17 [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"
Sebastian Jansson0b698262019-03-07 09:17:19 +010016#include "api/task_queue/global_task_queue_factory.h"
Niels Möller7d76a312018-10-26 12:57:07 +020017#include "api/test/loopback_media_transport.h"
18#include "api/test/mock_audio_mixer.h"
19#include "audio/audio_receive_stream.h"
20#include "audio/audio_send_stream.h"
Sebastian Jansson0b698262019-03-07 09:17:19 +010021#include "call/rtp_transport_controller_send.h"
Niels Möller7d76a312018-10-26 12:57:07 +020022#include "call/test/mock_bitrate_allocator.h"
23#include "logging/rtc_event_log/rtc_event_log.h"
24#include "modules/audio_device/include/test_audio_device.h"
25#include "modules/audio_mixer/audio_mixer_impl.h"
26#include "modules/audio_processing/include/mock_audio_processing.h"
27#include "modules/utility/include/process_thread.h"
28#include "rtc_base/task_queue.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 {
Sebastian Jansson0b698262019-03-07 09:17:19 +010037using testing::_;
38using testing::NiceMock;
39using testing::Return;
40
Niels Möller7d76a312018-10-26 12:57:07 +020041constexpr int kPayloadTypeOpus = 17;
42constexpr int kSamplingFrequency = 48000;
43constexpr int kNumChannels = 2;
44constexpr int kWantedSamples = 3000;
45constexpr int kTestTimeoutMs = 2 * rtc::kNumMillisecsPerSec;
46
47class TestRenderer : public TestAudioDeviceModule::Renderer {
48 public:
49 TestRenderer(int sampling_frequency, int num_channels, size_t wanted_samples)
50 : sampling_frequency_(sampling_frequency),
51 num_channels_(num_channels),
52 wanted_samples_(wanted_samples) {}
53 ~TestRenderer() override = default;
54
55 int SamplingFrequency() const override { return sampling_frequency_; }
56 int NumChannels() const override { return num_channels_; }
57
58 bool Render(rtc::ArrayView<const int16_t> data) override {
59 if (data.size() >= wanted_samples_) {
60 return false;
61 }
62 wanted_samples_ -= data.size();
63 return true;
64 }
65
66 private:
67 const int sampling_frequency_;
68 const int num_channels_;
69 size_t wanted_samples_;
70};
71
72} // namespace
73
74TEST(AudioWithMediaTransport, DeliversAudio) {
Bjorn Mellem273d0292018-11-01 16:42:44 -070075 std::unique_ptr<rtc::Thread> transport_thread = rtc::Thread::Create();
76 transport_thread->Start();
77 MediaTransportPair transport_pair(transport_thread.get());
Sebastian Jansson0b698262019-03-07 09:17:19 +010078 NiceMock<MockTransport> rtcp_send_transport;
79 NiceMock<MockTransport> send_transport;
Niels Möller7d76a312018-10-26 12:57:07 +020080 std::unique_ptr<RtcEventLog> null_event_log = RtcEventLog::CreateNull();
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 =
84 TestAudioDeviceModule::CreateTestAudioDeviceModule(
85 TestAudioDeviceModule::CreatePulsedNoiseCapturer(
86 /* max_amplitude= */ 10000, kSamplingFrequency, kNumChannels),
87 absl::make_unique<TestRenderer>(kSamplingFrequency, kNumChannels,
88 kWantedSamples));
89
90 AudioState::Config audio_config;
91 audio_config.audio_mixer = AudioMixerImpl::Create();
92 // TODO(nisse): Is a mock AudioProcessing enough?
93 audio_config.audio_processing =
94 new rtc::RefCountedObject<MockAudioProcessing>();
95 audio_config.audio_device_module = audio_device;
96 rtc::scoped_refptr<AudioState> audio_state = AudioState::Create(audio_config);
97
98 // TODO(nisse): Use some lossless codec?
99 const SdpAudioFormat audio_format("opus", kSamplingFrequency, kNumChannels);
100
101 // Setup receive stream;
102 webrtc::AudioReceiveStream::Config receive_config;
103 // TODO(nisse): Update AudioReceiveStream to not require rtcp_send_transport
104 // when a MediaTransport is provided.
105 receive_config.rtcp_send_transport = &rtcp_send_transport;
106 receive_config.media_transport = transport_pair.first();
107 receive_config.decoder_map.emplace(kPayloadTypeOpus, audio_format);
108 receive_config.decoder_factory =
109 CreateAudioDecoderFactory<AudioDecoderOpus>();
110
111 std::unique_ptr<ProcessThread> receive_process_thread =
112 ProcessThread::Create("audio recv thread");
113
114 webrtc::internal::AudioReceiveStream receive_stream(
Sebastian Jansson977b3352019-03-04 17:43:34 +0100115 Clock::GetRealTimeClock(),
Niels Möller7d76a312018-10-26 12:57:07 +0200116 /*rtp_stream_receiver_controller=*/nullptr,
117 /*packet_router=*/nullptr, receive_process_thread.get(), receive_config,
118 audio_state, null_event_log.get());
119
120 // TODO(nisse): Update AudioSendStream to not require send_transport when a
121 // MediaTransport is provided.
122 AudioSendStream::Config send_config(&send_transport, transport_pair.second());
123 send_config.send_codec_spec =
124 AudioSendStream::Config::SendCodecSpec(kPayloadTypeOpus, audio_format);
125 send_config.encoder_factory = CreateAudioEncoderFactory<AudioEncoderOpus>();
Niels Möller7d76a312018-10-26 12:57:07 +0200126 std::unique_ptr<ProcessThread> send_process_thread =
127 ProcessThread::Create("audio send thread");
Sebastian Jansson0b698262019-03-07 09:17:19 +0100128 RtpTransportControllerSend rtp_transport(
129 Clock::GetRealTimeClock(), null_event_log.get(), nullptr,
130 BitrateConstraints(), ProcessThread::Create("Pacer"),
131 &GlobalTaskQueueFactory());
Niels Möller7d76a312018-10-26 12:57:07 +0200132 webrtc::internal::AudioSendStream send_stream(
Sebastian Jansson0b698262019-03-07 09:17:19 +0100133 Clock::GetRealTimeClock(), send_config, audio_state,
134 send_process_thread.get(), &rtp_transport, &bitrate_allocator,
135 null_event_log.get(),
Sam Zackrissonff058162018-11-20 17:15:13 +0100136 /*rtcp_rtt_stats=*/nullptr, absl::optional<RtpState>());
Niels Möller7d76a312018-10-26 12:57:07 +0200137
138 audio_device->Init(); // Starts thread.
139 audio_device->RegisterAudioCallback(audio_state->audio_transport());
140
141 receive_stream.Start();
142 send_stream.Start();
143 audio_device->StartPlayout();
144 audio_device->StartRecording();
145
146 EXPECT_TRUE(audio_device->WaitForPlayoutEnd(kTestTimeoutMs));
147
148 audio_device->StopRecording();
149 audio_device->StopPlayout();
150 receive_stream.Stop();
151 send_stream.Stop();
152}
153
154} // namespace test
155} // namespace webrtc