mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-12 21:30:45 +01:00

Add base class NetworkPredictor and NetworkPredictorFactory in /api, make it possible to inject customized NetworkPredictor in PeerConnectionFactory level. The NetworkPredictor object will be pass down to GoogCCNetworkControl and DelayBasedBwe. Bug: webrtc:10492 Change-Id: Iceeadbe1c9388b11ce4ac01ee56554cb0bf64d04 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/130201 Commit-Queue: Ying Wang <yinwa@webrtc.org> Reviewed-by: Per Kjellander <perkj@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Reviewed-by: Sami Kalliomäki <sakal@webrtc.org> Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27543}
154 lines
5.9 KiB
C++
154 lines
5.9 KiB
C++
/*
|
|
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "absl/memory/memory.h"
|
|
#include "api/audio_codecs/audio_decoder_factory_template.h"
|
|
#include "api/audio_codecs/audio_encoder_factory_template.h"
|
|
#include "api/audio_codecs/opus/audio_decoder_opus.h"
|
|
#include "api/audio_codecs/opus/audio_encoder_opus.h"
|
|
#include "api/task_queue/default_task_queue_factory.h"
|
|
#include "api/test/loopback_media_transport.h"
|
|
#include "api/test/mock_audio_mixer.h"
|
|
#include "audio/audio_receive_stream.h"
|
|
#include "audio/audio_send_stream.h"
|
|
#include "call/rtp_transport_controller_send.h"
|
|
#include "call/test/mock_bitrate_allocator.h"
|
|
#include "logging/rtc_event_log/rtc_event_log.h"
|
|
#include "modules/audio_device/include/test_audio_device.h"
|
|
#include "modules/audio_mixer/audio_mixer_impl.h"
|
|
#include "modules/audio_processing/include/mock_audio_processing.h"
|
|
#include "modules/utility/include/process_thread.h"
|
|
#include "rtc_base/time_utils.h"
|
|
#include "test/gtest.h"
|
|
#include "test/mock_transport.h"
|
|
|
|
namespace webrtc {
|
|
namespace test {
|
|
|
|
namespace {
|
|
using ::testing::NiceMock;
|
|
|
|
constexpr int kPayloadTypeOpus = 17;
|
|
constexpr int kSamplingFrequency = 48000;
|
|
constexpr int kNumChannels = 2;
|
|
constexpr int kWantedSamples = 3000;
|
|
constexpr int kTestTimeoutMs = 2 * rtc::kNumMillisecsPerSec;
|
|
|
|
class TestRenderer : public TestAudioDeviceModule::Renderer {
|
|
public:
|
|
TestRenderer(int sampling_frequency, int num_channels, size_t wanted_samples)
|
|
: sampling_frequency_(sampling_frequency),
|
|
num_channels_(num_channels),
|
|
wanted_samples_(wanted_samples) {}
|
|
~TestRenderer() override = default;
|
|
|
|
int SamplingFrequency() const override { return sampling_frequency_; }
|
|
int NumChannels() const override { return num_channels_; }
|
|
|
|
bool Render(rtc::ArrayView<const int16_t> data) override {
|
|
if (data.size() >= wanted_samples_) {
|
|
return false;
|
|
}
|
|
wanted_samples_ -= data.size();
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
const int sampling_frequency_;
|
|
const int num_channels_;
|
|
size_t wanted_samples_;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
TEST(AudioWithMediaTransport, DeliversAudio) {
|
|
std::unique_ptr<rtc::Thread> transport_thread = rtc::Thread::Create();
|
|
transport_thread->Start();
|
|
MediaTransportPair transport_pair(transport_thread.get());
|
|
NiceMock<MockTransport> rtcp_send_transport;
|
|
NiceMock<MockTransport> send_transport;
|
|
std::unique_ptr<RtcEventLog> null_event_log = RtcEventLog::CreateNull();
|
|
NiceMock<MockBitrateAllocator> bitrate_allocator;
|
|
|
|
rtc::scoped_refptr<TestAudioDeviceModule> audio_device =
|
|
TestAudioDeviceModule::CreateTestAudioDeviceModule(
|
|
TestAudioDeviceModule::CreatePulsedNoiseCapturer(
|
|
/* max_amplitude= */ 10000, kSamplingFrequency, kNumChannels),
|
|
absl::make_unique<TestRenderer>(kSamplingFrequency, kNumChannels,
|
|
kWantedSamples));
|
|
|
|
AudioState::Config audio_config;
|
|
audio_config.audio_mixer = AudioMixerImpl::Create();
|
|
// TODO(nisse): Is a mock AudioProcessing enough?
|
|
audio_config.audio_processing =
|
|
new rtc::RefCountedObject<MockAudioProcessing>();
|
|
audio_config.audio_device_module = audio_device;
|
|
rtc::scoped_refptr<AudioState> audio_state = AudioState::Create(audio_config);
|
|
|
|
// TODO(nisse): Use some lossless codec?
|
|
const SdpAudioFormat audio_format("opus", kSamplingFrequency, kNumChannels);
|
|
|
|
// Setup receive stream;
|
|
webrtc::AudioReceiveStream::Config receive_config;
|
|
// TODO(nisse): Update AudioReceiveStream to not require rtcp_send_transport
|
|
// when a MediaTransport is provided.
|
|
receive_config.rtcp_send_transport = &rtcp_send_transport;
|
|
receive_config.media_transport = transport_pair.first();
|
|
receive_config.decoder_map.emplace(kPayloadTypeOpus, audio_format);
|
|
receive_config.decoder_factory =
|
|
CreateAudioDecoderFactory<AudioDecoderOpus>();
|
|
|
|
std::unique_ptr<ProcessThread> receive_process_thread =
|
|
ProcessThread::Create("audio recv thread");
|
|
|
|
webrtc::internal::AudioReceiveStream receive_stream(
|
|
Clock::GetRealTimeClock(),
|
|
/*receiver_controller=*/nullptr,
|
|
/*packet_router=*/nullptr, receive_process_thread.get(), receive_config,
|
|
audio_state, null_event_log.get());
|
|
|
|
// TODO(nisse): Update AudioSendStream to not require send_transport when a
|
|
// MediaTransport is provided.
|
|
AudioSendStream::Config send_config(&send_transport, transport_pair.second());
|
|
send_config.send_codec_spec =
|
|
AudioSendStream::Config::SendCodecSpec(kPayloadTypeOpus, audio_format);
|
|
send_config.encoder_factory = CreateAudioEncoderFactory<AudioEncoderOpus>();
|
|
std::unique_ptr<ProcessThread> send_process_thread =
|
|
ProcessThread::Create("audio send thread");
|
|
std::unique_ptr<TaskQueueFactory> task_queue_factory =
|
|
CreateDefaultTaskQueueFactory();
|
|
RtpTransportControllerSend rtp_transport(
|
|
Clock::GetRealTimeClock(), null_event_log.get(), nullptr, nullptr,
|
|
BitrateConstraints(), ProcessThread::Create("Pacer"),
|
|
task_queue_factory.get());
|
|
webrtc::internal::AudioSendStream send_stream(
|
|
Clock::GetRealTimeClock(), send_config, audio_state,
|
|
task_queue_factory.get(), send_process_thread.get(), &rtp_transport,
|
|
&bitrate_allocator, null_event_log.get(),
|
|
/*rtcp_rtt_stats=*/nullptr, absl::optional<RtpState>());
|
|
|
|
audio_device->Init(); // Starts thread.
|
|
audio_device->RegisterAudioCallback(audio_state->audio_transport());
|
|
|
|
receive_stream.Start();
|
|
send_stream.Start();
|
|
audio_device->StartPlayout();
|
|
audio_device->StartRecording();
|
|
|
|
EXPECT_TRUE(audio_device->WaitForPlayoutEnd(kTestTimeoutMs));
|
|
|
|
audio_device->StopRecording();
|
|
audio_device->StopPlayout();
|
|
receive_stream.Stop();
|
|
send_stream.Stop();
|
|
}
|
|
|
|
} // namespace test
|
|
} // namespace webrtc
|