blob: 7794b435411bc048be321813a9d87e26f9389d37 [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"
Danil Chapovalov31660fd2019-03-22 12:59:48 +010016#include "api/task_queue/default_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"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "rtc_base/time_utils.h"
Niels Möller7d76a312018-10-26 12:57:07 +020029#include "test/gtest.h"
30#include "test/mock_transport.h"
31
32namespace webrtc {
33namespace test {
34
35namespace {
Mirko Bonadei6a489f22019-04-09 15:11:12 +020036using ::testing::NiceMock;
Sebastian Jansson0b698262019-03-07 09:17:19 +010037
Niels Möller7d76a312018-10-26 12:57:07 +020038constexpr int kPayloadTypeOpus = 17;
39constexpr int kSamplingFrequency = 48000;
40constexpr int kNumChannels = 2;
41constexpr int kWantedSamples = 3000;
42constexpr int kTestTimeoutMs = 2 * rtc::kNumMillisecsPerSec;
43
44class TestRenderer : public TestAudioDeviceModule::Renderer {
45 public:
46 TestRenderer(int sampling_frequency, int num_channels, size_t wanted_samples)
47 : sampling_frequency_(sampling_frequency),
48 num_channels_(num_channels),
49 wanted_samples_(wanted_samples) {}
50 ~TestRenderer() override = default;
51
52 int SamplingFrequency() const override { return sampling_frequency_; }
53 int NumChannels() const override { return num_channels_; }
54
55 bool Render(rtc::ArrayView<const int16_t> data) override {
56 if (data.size() >= wanted_samples_) {
57 return false;
58 }
59 wanted_samples_ -= data.size();
60 return true;
61 }
62
63 private:
64 const int sampling_frequency_;
65 const int num_channels_;
66 size_t wanted_samples_;
67};
68
69} // namespace
70
71TEST(AudioWithMediaTransport, DeliversAudio) {
Bjorn Mellem273d0292018-11-01 16:42:44 -070072 std::unique_ptr<rtc::Thread> transport_thread = rtc::Thread::Create();
73 transport_thread->Start();
74 MediaTransportPair transport_pair(transport_thread.get());
Sebastian Jansson0b698262019-03-07 09:17:19 +010075 NiceMock<MockTransport> rtcp_send_transport;
76 NiceMock<MockTransport> send_transport;
Niels Möller7d76a312018-10-26 12:57:07 +020077 std::unique_ptr<RtcEventLog> null_event_log = RtcEventLog::CreateNull();
Sebastian Jansson0b698262019-03-07 09:17:19 +010078 NiceMock<MockBitrateAllocator> bitrate_allocator;
Niels Möller7d76a312018-10-26 12:57:07 +020079
80 rtc::scoped_refptr<TestAudioDeviceModule> audio_device =
81 TestAudioDeviceModule::CreateTestAudioDeviceModule(
82 TestAudioDeviceModule::CreatePulsedNoiseCapturer(
83 /* max_amplitude= */ 10000, kSamplingFrequency, kNumChannels),
84 absl::make_unique<TestRenderer>(kSamplingFrequency, kNumChannels,
85 kWantedSamples));
86
87 AudioState::Config audio_config;
88 audio_config.audio_mixer = AudioMixerImpl::Create();
89 // TODO(nisse): Is a mock AudioProcessing enough?
90 audio_config.audio_processing =
91 new rtc::RefCountedObject<MockAudioProcessing>();
92 audio_config.audio_device_module = audio_device;
93 rtc::scoped_refptr<AudioState> audio_state = AudioState::Create(audio_config);
94
95 // TODO(nisse): Use some lossless codec?
96 const SdpAudioFormat audio_format("opus", kSamplingFrequency, kNumChannels);
97
98 // Setup receive stream;
99 webrtc::AudioReceiveStream::Config receive_config;
100 // TODO(nisse): Update AudioReceiveStream to not require rtcp_send_transport
101 // when a MediaTransport is provided.
102 receive_config.rtcp_send_transport = &rtcp_send_transport;
103 receive_config.media_transport = transport_pair.first();
104 receive_config.decoder_map.emplace(kPayloadTypeOpus, audio_format);
105 receive_config.decoder_factory =
106 CreateAudioDecoderFactory<AudioDecoderOpus>();
107
108 std::unique_ptr<ProcessThread> receive_process_thread =
109 ProcessThread::Create("audio recv thread");
110
111 webrtc::internal::AudioReceiveStream receive_stream(
Sebastian Jansson977b3352019-03-04 17:43:34 +0100112 Clock::GetRealTimeClock(),
Benjamin Wright17b050f2019-03-13 17:35:46 -0700113 /*receiver_controller=*/nullptr,
Niels Möller7d76a312018-10-26 12:57:07 +0200114 /*packet_router=*/nullptr, receive_process_thread.get(), receive_config,
115 audio_state, null_event_log.get());
116
117 // TODO(nisse): Update AudioSendStream to not require send_transport when a
118 // MediaTransport is provided.
119 AudioSendStream::Config send_config(&send_transport, transport_pair.second());
120 send_config.send_codec_spec =
121 AudioSendStream::Config::SendCodecSpec(kPayloadTypeOpus, audio_format);
122 send_config.encoder_factory = CreateAudioEncoderFactory<AudioEncoderOpus>();
Niels Möller7d76a312018-10-26 12:57:07 +0200123 std::unique_ptr<ProcessThread> send_process_thread =
124 ProcessThread::Create("audio send thread");
Danil Chapovalov31660fd2019-03-22 12:59:48 +0100125 std::unique_ptr<TaskQueueFactory> task_queue_factory =
126 CreateDefaultTaskQueueFactory();
Sebastian Jansson0b698262019-03-07 09:17:19 +0100127 RtpTransportControllerSend rtp_transport(
Ying Wang0810a7c2019-04-10 13:48:24 +0200128 Clock::GetRealTimeClock(), null_event_log.get(), nullptr, nullptr,
Sebastian Jansson0b698262019-03-07 09:17:19 +0100129 BitrateConstraints(), ProcessThread::Create("Pacer"),
Danil Chapovalov31660fd2019-03-22 12:59:48 +0100130 task_queue_factory.get());
Niels Möller7d76a312018-10-26 12:57:07 +0200131 webrtc::internal::AudioSendStream send_stream(
Sebastian Jansson0b698262019-03-07 09:17:19 +0100132 Clock::GetRealTimeClock(), send_config, audio_state,
Danil Chapovalov31660fd2019-03-22 12:59:48 +0100133 task_queue_factory.get(), send_process_thread.get(), &rtp_transport,
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100134 &bitrate_allocator, null_event_log.get(),
Sam Zackrissonff058162018-11-20 17:15:13 +0100135 /*rtcp_rtt_stats=*/nullptr, absl::optional<RtpState>());
Niels Möller7d76a312018-10-26 12:57:07 +0200136
137 audio_device->Init(); // Starts thread.
138 audio_device->RegisterAudioCallback(audio_state->audio_transport());
139
140 receive_stream.Start();
141 send_stream.Start();
142 audio_device->StartPlayout();
143 audio_device->StartRecording();
144
145 EXPECT_TRUE(audio_device->WaitForPlayoutEnd(kTestTimeoutMs));
146
147 audio_device->StopRecording();
148 audio_device->StopPlayout();
149 receive_stream.Stop();
150 send_stream.Stop();
151}
152
153} // namespace test
154} // namespace webrtc