blob: ba24e46c1b5e5465dcba81e794de3a5e87c9e9ba [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"
16#include "api/test/loopback_media_transport.h"
17#include "api/test/mock_audio_mixer.h"
18#include "audio/audio_receive_stream.h"
19#include "audio/audio_send_stream.h"
20#include "call/test/mock_bitrate_allocator.h"
21#include "logging/rtc_event_log/rtc_event_log.h"
22#include "modules/audio_device/include/test_audio_device.h"
23#include "modules/audio_mixer/audio_mixer_impl.h"
24#include "modules/audio_processing/include/mock_audio_processing.h"
25#include "modules/utility/include/process_thread.h"
26#include "rtc_base/task_queue.h"
27#include "rtc_base/timeutils.h"
28#include "test/gtest.h"
29#include "test/mock_transport.h"
30
31namespace webrtc {
32namespace test {
33
34namespace {
35constexpr int kPayloadTypeOpus = 17;
36constexpr int kSamplingFrequency = 48000;
37constexpr int kNumChannels = 2;
38constexpr int kWantedSamples = 3000;
39constexpr int kTestTimeoutMs = 2 * rtc::kNumMillisecsPerSec;
40
41class TestRenderer : public TestAudioDeviceModule::Renderer {
42 public:
43 TestRenderer(int sampling_frequency, int num_channels, size_t wanted_samples)
44 : sampling_frequency_(sampling_frequency),
45 num_channels_(num_channels),
46 wanted_samples_(wanted_samples) {}
47 ~TestRenderer() override = default;
48
49 int SamplingFrequency() const override { return sampling_frequency_; }
50 int NumChannels() const override { return num_channels_; }
51
52 bool Render(rtc::ArrayView<const int16_t> data) override {
53 if (data.size() >= wanted_samples_) {
54 return false;
55 }
56 wanted_samples_ -= data.size();
57 return true;
58 }
59
60 private:
61 const int sampling_frequency_;
62 const int num_channels_;
63 size_t wanted_samples_;
64};
65
66} // namespace
67
68TEST(AudioWithMediaTransport, DeliversAudio) {
Bjorn Mellem273d0292018-11-01 16:42:44 -070069 std::unique_ptr<rtc::Thread> transport_thread = rtc::Thread::Create();
70 transport_thread->Start();
71 MediaTransportPair transport_pair(transport_thread.get());
Niels Möller7d76a312018-10-26 12:57:07 +020072 MockTransport rtcp_send_transport;
73 MockTransport send_transport;
74 std::unique_ptr<RtcEventLog> null_event_log = RtcEventLog::CreateNull();
75 MockBitrateAllocator bitrate_allocator;
76
77 rtc::scoped_refptr<TestAudioDeviceModule> audio_device =
78 TestAudioDeviceModule::CreateTestAudioDeviceModule(
79 TestAudioDeviceModule::CreatePulsedNoiseCapturer(
80 /* max_amplitude= */ 10000, kSamplingFrequency, kNumChannels),
81 absl::make_unique<TestRenderer>(kSamplingFrequency, kNumChannels,
82 kWantedSamples));
83
84 AudioState::Config audio_config;
85 audio_config.audio_mixer = AudioMixerImpl::Create();
86 // TODO(nisse): Is a mock AudioProcessing enough?
87 audio_config.audio_processing =
88 new rtc::RefCountedObject<MockAudioProcessing>();
89 audio_config.audio_device_module = audio_device;
90 rtc::scoped_refptr<AudioState> audio_state = AudioState::Create(audio_config);
91
92 // TODO(nisse): Use some lossless codec?
93 const SdpAudioFormat audio_format("opus", kSamplingFrequency, kNumChannels);
94
95 // Setup receive stream;
96 webrtc::AudioReceiveStream::Config receive_config;
97 // TODO(nisse): Update AudioReceiveStream to not require rtcp_send_transport
98 // when a MediaTransport is provided.
99 receive_config.rtcp_send_transport = &rtcp_send_transport;
100 receive_config.media_transport = transport_pair.first();
101 receive_config.decoder_map.emplace(kPayloadTypeOpus, audio_format);
102 receive_config.decoder_factory =
103 CreateAudioDecoderFactory<AudioDecoderOpus>();
104
105 std::unique_ptr<ProcessThread> receive_process_thread =
106 ProcessThread::Create("audio recv thread");
107
108 webrtc::internal::AudioReceiveStream receive_stream(
109 /*rtp_stream_receiver_controller=*/nullptr,
110 /*packet_router=*/nullptr, receive_process_thread.get(), receive_config,
111 audio_state, null_event_log.get());
112
113 // TODO(nisse): Update AudioSendStream to not require send_transport when a
114 // MediaTransport is provided.
115 AudioSendStream::Config send_config(&send_transport, transport_pair.second());
116 send_config.send_codec_spec =
117 AudioSendStream::Config::SendCodecSpec(kPayloadTypeOpus, audio_format);
118 send_config.encoder_factory = CreateAudioEncoderFactory<AudioEncoderOpus>();
119 rtc::TaskQueue send_tq("audio send queue");
120 std::unique_ptr<ProcessThread> send_process_thread =
121 ProcessThread::Create("audio send thread");
Niels Möller7d76a312018-10-26 12:57:07 +0200122 webrtc::internal::AudioSendStream send_stream(
123 send_config, audio_state, &send_tq, send_process_thread.get(),
124 /*transport=*/nullptr, &bitrate_allocator, null_event_log.get(),
Sam Zackrissonff058162018-11-20 17:15:13 +0100125 /*rtcp_rtt_stats=*/nullptr, absl::optional<RtpState>());
Niels Möller7d76a312018-10-26 12:57:07 +0200126
127 audio_device->Init(); // Starts thread.
128 audio_device->RegisterAudioCallback(audio_state->audio_transport());
129
130 receive_stream.Start();
131 send_stream.Start();
132 audio_device->StartPlayout();
133 audio_device->StartRecording();
134
135 EXPECT_TRUE(audio_device->WaitForPlayoutEnd(kTestTimeoutMs));
136
137 audio_device->StopRecording();
138 audio_device->StopPlayout();
139 receive_stream.Stop();
140 send_stream.Stop();
141}
142
143} // namespace test
144} // namespace webrtc