Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
5
TMessagesProj/jni/voip/webrtc/pc/test/DEPS
Normal file
5
TMessagesProj/jni/voip/webrtc/pc/test/DEPS
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
include_rules = [
|
||||
# Allow include of sdk/android to allow accessing the JVM and Env in tests.
|
||||
"+sdk/android",
|
||||
"+modules/utility/include/jvm_android.h",
|
||||
]
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2015 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 "pc/test/android_test_initializer.h"
|
||||
|
||||
#include <jni.h>
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "modules/utility/include/jvm_android.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "sdk/android/src/jni/jvm.h"
|
||||
// TODO(phoglund): This include is to a target we can't really depend on.
|
||||
// We need to either break it out into a smaller target or find some way to
|
||||
// not use it.
|
||||
#include "rtc_base/ssl_adapter.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
static pthread_once_t g_initialize_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
// There can only be one JNI_OnLoad in each binary. So since this is a GTEST
|
||||
// C++ runner binary, we want to initialize the same global objects we normally
|
||||
// do if this had been a Java binary.
|
||||
void EnsureInitializedOnce() {
|
||||
RTC_CHECK(::webrtc::jni::GetJVM() != nullptr);
|
||||
JNIEnv* jni = ::webrtc::jni::AttachCurrentThreadIfNeeded();
|
||||
JavaVM* jvm = NULL;
|
||||
RTC_CHECK_EQ(0, jni->GetJavaVM(&jvm));
|
||||
|
||||
RTC_CHECK(rtc::InitializeSSL()) << "Failed to InitializeSSL()";
|
||||
|
||||
JVM::Initialize(jvm);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void InitializeAndroidObjects() {
|
||||
RTC_CHECK_EQ(0, pthread_once(&g_initialize_once, &EnsureInitializedOnce));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_ANDROID_TEST_INITIALIZER_H_
|
||||
#define PC_TEST_ANDROID_TEST_INITIALIZER_H_
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
void InitializeAndroidObjects();
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_ANDROID_TEST_INITIALIZER_H_
|
||||
63
TMessagesProj/jni/voip/webrtc/pc/test/enable_fake_media.cc
Normal file
63
TMessagesProj/jni/voip/webrtc/pc/test/enable_fake_media.cc
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright 2023 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 "pc/test/enable_fake_media.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/base/nullability.h"
|
||||
#include "api/environment/environment.h"
|
||||
#include "api/peer_connection_interface.h"
|
||||
#include "call/call.h"
|
||||
#include "call/call_config.h"
|
||||
#include "media/base/fake_media_engine.h"
|
||||
#include "pc/media_factory.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
using ::cricket::FakeMediaEngine;
|
||||
using ::cricket::MediaEngineInterface;
|
||||
|
||||
void EnableFakeMedia(
|
||||
PeerConnectionFactoryDependencies& deps,
|
||||
absl::Nonnull<std::unique_ptr<FakeMediaEngine>> fake_media_engine) {
|
||||
class FakeMediaFactory : public MediaFactory {
|
||||
public:
|
||||
explicit FakeMediaFactory(
|
||||
absl::Nonnull<std::unique_ptr<FakeMediaEngine>> fake)
|
||||
: fake_(std::move(fake)) {}
|
||||
|
||||
std::unique_ptr<Call> CreateCall(const CallConfig& config) override {
|
||||
return Call::Create(config);
|
||||
}
|
||||
|
||||
std::unique_ptr<MediaEngineInterface> CreateMediaEngine(
|
||||
const Environment& /*env*/,
|
||||
PeerConnectionFactoryDependencies& /*dependencies*/) {
|
||||
RTC_CHECK(fake_ != nullptr)
|
||||
<< "CreateMediaEngine can be called at most once.";
|
||||
return std::move(fake_);
|
||||
}
|
||||
|
||||
private:
|
||||
absl::Nullable<std::unique_ptr<FakeMediaEngine>> fake_;
|
||||
};
|
||||
|
||||
deps.media_factory =
|
||||
std::make_unique<FakeMediaFactory>(std::move(fake_media_engine));
|
||||
}
|
||||
|
||||
void EnableFakeMedia(PeerConnectionFactoryDependencies& deps) {
|
||||
EnableFakeMedia(deps, std::make_unique<cricket::FakeMediaEngine>());
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
38
TMessagesProj/jni/voip/webrtc/pc/test/enable_fake_media.h
Normal file
38
TMessagesProj/jni/voip/webrtc/pc/test/enable_fake_media.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2023 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.
|
||||
*/
|
||||
|
||||
// Enables fake media support for PeerConnnectionFactory created from `deps` for
|
||||
// testing purposes. Such fake media support ignores media dependencies in the
|
||||
// `PeerConnectionFactoryDependencies`. Allows to test PeerConnection and
|
||||
// PeerConnectionFactory in the presence of the media, but doesn't test media
|
||||
// support itself.
|
||||
|
||||
#ifndef PC_TEST_ENABLE_FAKE_MEDIA_H_
|
||||
#define PC_TEST_ENABLE_FAKE_MEDIA_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "absl/base/nullability.h"
|
||||
#include "api/peer_connection_interface.h"
|
||||
#include "media/base/fake_media_engine.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Enables media support backed by the 'fake_media_engine'.
|
||||
void EnableFakeMedia(
|
||||
PeerConnectionFactoryDependencies& deps,
|
||||
absl::Nonnull<std::unique_ptr<cricket::FakeMediaEngine>> fake_media_engine);
|
||||
|
||||
// Enables media support backed by unspecified lightweight fake implementation.
|
||||
void EnableFakeMedia(PeerConnectionFactoryDependencies& deps);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_ENABLE_FAKE_MEDIA_H_
|
||||
|
|
@ -0,0 +1,519 @@
|
|||
/*
|
||||
* Copyright 2012 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 "pc/test/fake_audio_capture_module.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "api/make_ref_counted.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/thread.h"
|
||||
#include "rtc_base/time_utils.h"
|
||||
|
||||
using ::webrtc::TimeDelta;
|
||||
|
||||
// Audio sample value that is high enough that it doesn't occur naturally when
|
||||
// frames are being faked. E.g. NetEq will not generate this large sample value
|
||||
// unless it has received an audio frame containing a sample of this value.
|
||||
// Even simpler buffers would likely just contain audio sample values of 0.
|
||||
static const int kHighSampleValue = 10000;
|
||||
|
||||
// Constants here are derived by running VoE using a real ADM.
|
||||
// The constants correspond to 10ms of mono audio at 44kHz.
|
||||
static const int kTimePerFrameMs = 10;
|
||||
static const uint8_t kNumberOfChannels = 1;
|
||||
static const int kSamplesPerSecond = 44000;
|
||||
static const int kTotalDelayMs = 0;
|
||||
static const int kClockDriftMs = 0;
|
||||
static const uint32_t kMaxVolume = 14392;
|
||||
|
||||
FakeAudioCaptureModule::FakeAudioCaptureModule()
|
||||
: audio_callback_(nullptr),
|
||||
recording_(false),
|
||||
playing_(false),
|
||||
play_is_initialized_(false),
|
||||
rec_is_initialized_(false),
|
||||
current_mic_level_(kMaxVolume),
|
||||
started_(false),
|
||||
next_frame_time_(0),
|
||||
frames_received_(0) {}
|
||||
|
||||
FakeAudioCaptureModule::~FakeAudioCaptureModule() {
|
||||
if (process_thread_) {
|
||||
process_thread_->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<FakeAudioCaptureModule> FakeAudioCaptureModule::Create() {
|
||||
auto capture_module = rtc::make_ref_counted<FakeAudioCaptureModule>();
|
||||
if (!capture_module->Initialize()) {
|
||||
return nullptr;
|
||||
}
|
||||
return capture_module;
|
||||
}
|
||||
|
||||
int FakeAudioCaptureModule::frames_received() const {
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
return frames_received_;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::ActiveAudioLayer(
|
||||
AudioLayer* /*audio_layer*/) const {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::RegisterAudioCallback(
|
||||
webrtc::AudioTransport* audio_callback) {
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
audio_callback_ = audio_callback;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::Init() {
|
||||
// Initialize is called by the factory method. Safe to ignore this Init call.
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::Terminate() {
|
||||
// Clean up in the destructor. No action here, just success.
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FakeAudioCaptureModule::Initialized() const {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int16_t FakeAudioCaptureModule::PlayoutDevices() {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int16_t FakeAudioCaptureModule::RecordingDevices() {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::PlayoutDeviceName(
|
||||
uint16_t /*index*/,
|
||||
char /*name*/[webrtc::kAdmMaxDeviceNameSize],
|
||||
char /*guid*/[webrtc::kAdmMaxGuidSize]) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::RecordingDeviceName(
|
||||
uint16_t /*index*/,
|
||||
char /*name*/[webrtc::kAdmMaxDeviceNameSize],
|
||||
char /*guid*/[webrtc::kAdmMaxGuidSize]) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::SetPlayoutDevice(uint16_t /*index*/) {
|
||||
// No playout device, just playing from file. Return success.
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::SetPlayoutDevice(WindowsDeviceType /*device*/) {
|
||||
if (play_is_initialized_) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::SetRecordingDevice(uint16_t /*index*/) {
|
||||
// No recording device, just dropping audio. Return success.
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::SetRecordingDevice(
|
||||
WindowsDeviceType /*device*/) {
|
||||
if (rec_is_initialized_) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::PlayoutIsAvailable(bool* /*available*/) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::InitPlayout() {
|
||||
play_is_initialized_ = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FakeAudioCaptureModule::PlayoutIsInitialized() const {
|
||||
return play_is_initialized_;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::RecordingIsAvailable(bool* /*available*/) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::InitRecording() {
|
||||
rec_is_initialized_ = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FakeAudioCaptureModule::RecordingIsInitialized() const {
|
||||
return rec_is_initialized_;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::StartPlayout() {
|
||||
if (!play_is_initialized_) {
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
playing_ = true;
|
||||
}
|
||||
bool start = true;
|
||||
UpdateProcessing(start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::StopPlayout() {
|
||||
bool start = false;
|
||||
{
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
playing_ = false;
|
||||
start = ShouldStartProcessing();
|
||||
}
|
||||
UpdateProcessing(start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FakeAudioCaptureModule::Playing() const {
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
return playing_;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::StartRecording() {
|
||||
if (!rec_is_initialized_) {
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
recording_ = true;
|
||||
}
|
||||
bool start = true;
|
||||
UpdateProcessing(start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::StopRecording() {
|
||||
bool start = false;
|
||||
{
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
recording_ = false;
|
||||
start = ShouldStartProcessing();
|
||||
}
|
||||
UpdateProcessing(start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FakeAudioCaptureModule::Recording() const {
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
return recording_;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::InitSpeaker() {
|
||||
// No speaker, just playing from file. Return success.
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FakeAudioCaptureModule::SpeakerIsInitialized() const {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::InitMicrophone() {
|
||||
// No microphone, just playing from file. Return success.
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FakeAudioCaptureModule::MicrophoneIsInitialized() const {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::SpeakerVolumeIsAvailable(bool* /*available*/) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::SetSpeakerVolume(uint32_t /*volume*/) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::SpeakerVolume(uint32_t* /*volume*/) const {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::MaxSpeakerVolume(
|
||||
uint32_t* /*max_volume*/) const {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::MinSpeakerVolume(
|
||||
uint32_t* /*min_volume*/) const {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::MicrophoneVolumeIsAvailable(
|
||||
bool* /*available*/) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::SetMicrophoneVolume(uint32_t volume) {
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
current_mic_level_ = volume;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::MicrophoneVolume(uint32_t* volume) const {
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
*volume = current_mic_level_;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::MaxMicrophoneVolume(
|
||||
uint32_t* max_volume) const {
|
||||
*max_volume = kMaxVolume;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::MinMicrophoneVolume(
|
||||
uint32_t* /*min_volume*/) const {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::SpeakerMuteIsAvailable(bool* /*available*/) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::SetSpeakerMute(bool /*enable*/) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::SpeakerMute(bool* /*enabled*/) const {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::MicrophoneMuteIsAvailable(bool* /*available*/) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::SetMicrophoneMute(bool /*enable*/) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::MicrophoneMute(bool* /*enabled*/) const {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::StereoPlayoutIsAvailable(
|
||||
bool* available) const {
|
||||
// No recording device, just dropping audio. Stereo can be dropped just
|
||||
// as easily as mono.
|
||||
*available = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::SetStereoPlayout(bool /*enable*/) {
|
||||
// No recording device, just dropping audio. Stereo can be dropped just
|
||||
// as easily as mono.
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::StereoPlayout(bool* /*enabled*/) const {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::StereoRecordingIsAvailable(
|
||||
bool* available) const {
|
||||
// Keep thing simple. No stereo recording.
|
||||
*available = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::SetStereoRecording(bool enable) {
|
||||
if (!enable) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::StereoRecording(bool* /*enabled*/) const {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t FakeAudioCaptureModule::PlayoutDelay(uint16_t* delay_ms) const {
|
||||
// No delay since audio frames are dropped.
|
||||
*delay_ms = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FakeAudioCaptureModule::Initialize() {
|
||||
// Set the send buffer samples high enough that it would not occur on the
|
||||
// remote side unless a packet containing a sample of that magnitude has been
|
||||
// sent to it. Note that the audio processing pipeline will likely distort the
|
||||
// original signal.
|
||||
SetSendBuffer(kHighSampleValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
void FakeAudioCaptureModule::SetSendBuffer(int value) {
|
||||
Sample* buffer_ptr = reinterpret_cast<Sample*>(send_buffer_);
|
||||
const size_t buffer_size_in_samples =
|
||||
sizeof(send_buffer_) / kNumberBytesPerSample;
|
||||
for (size_t i = 0; i < buffer_size_in_samples; ++i) {
|
||||
buffer_ptr[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void FakeAudioCaptureModule::ResetRecBuffer() {
|
||||
memset(rec_buffer_, 0, sizeof(rec_buffer_));
|
||||
}
|
||||
|
||||
bool FakeAudioCaptureModule::CheckRecBuffer(int value) {
|
||||
const Sample* buffer_ptr = reinterpret_cast<const Sample*>(rec_buffer_);
|
||||
const size_t buffer_size_in_samples =
|
||||
sizeof(rec_buffer_) / kNumberBytesPerSample;
|
||||
for (size_t i = 0; i < buffer_size_in_samples; ++i) {
|
||||
if (buffer_ptr[i] >= value)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FakeAudioCaptureModule::ShouldStartProcessing() {
|
||||
return recording_ || playing_;
|
||||
}
|
||||
|
||||
void FakeAudioCaptureModule::UpdateProcessing(bool start) {
|
||||
if (start) {
|
||||
if (!process_thread_) {
|
||||
process_thread_ = rtc::Thread::Create();
|
||||
process_thread_->Start();
|
||||
}
|
||||
process_thread_->PostTask([this] { StartProcessP(); });
|
||||
} else {
|
||||
if (process_thread_) {
|
||||
process_thread_->Stop();
|
||||
process_thread_.reset(nullptr);
|
||||
process_thread_checker_.Detach();
|
||||
}
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
started_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void FakeAudioCaptureModule::StartProcessP() {
|
||||
RTC_DCHECK_RUN_ON(&process_thread_checker_);
|
||||
{
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
if (started_) {
|
||||
// Already started.
|
||||
return;
|
||||
}
|
||||
}
|
||||
ProcessFrameP();
|
||||
}
|
||||
|
||||
void FakeAudioCaptureModule::ProcessFrameP() {
|
||||
RTC_DCHECK_RUN_ON(&process_thread_checker_);
|
||||
{
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
if (!started_) {
|
||||
next_frame_time_ = rtc::TimeMillis();
|
||||
started_ = true;
|
||||
}
|
||||
|
||||
// Receive and send frames every kTimePerFrameMs.
|
||||
if (playing_) {
|
||||
ReceiveFrameP();
|
||||
}
|
||||
if (recording_) {
|
||||
SendFrameP();
|
||||
}
|
||||
}
|
||||
|
||||
next_frame_time_ += kTimePerFrameMs;
|
||||
const int64_t current_time = rtc::TimeMillis();
|
||||
const int64_t wait_time =
|
||||
(next_frame_time_ > current_time) ? next_frame_time_ - current_time : 0;
|
||||
process_thread_->PostDelayedTask([this] { ProcessFrameP(); },
|
||||
TimeDelta::Millis(wait_time));
|
||||
}
|
||||
|
||||
void FakeAudioCaptureModule::ReceiveFrameP() {
|
||||
RTC_DCHECK_RUN_ON(&process_thread_checker_);
|
||||
if (!audio_callback_) {
|
||||
return;
|
||||
}
|
||||
ResetRecBuffer();
|
||||
size_t nSamplesOut = 0;
|
||||
int64_t elapsed_time_ms = 0;
|
||||
int64_t ntp_time_ms = 0;
|
||||
if (audio_callback_->NeedMorePlayData(kNumberSamples, kNumberBytesPerSample,
|
||||
kNumberOfChannels, kSamplesPerSecond,
|
||||
rec_buffer_, nSamplesOut,
|
||||
&elapsed_time_ms, &ntp_time_ms) != 0) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
}
|
||||
RTC_CHECK(nSamplesOut == kNumberSamples);
|
||||
|
||||
// The SetBuffer() function ensures that after decoding, the audio buffer
|
||||
// should contain samples of similar magnitude (there is likely to be some
|
||||
// distortion due to the audio pipeline). If one sample is detected to
|
||||
// have the same or greater magnitude somewhere in the frame, an actual frame
|
||||
// has been received from the remote side (i.e. faked frames are not being
|
||||
// pulled).
|
||||
if (CheckRecBuffer(kHighSampleValue)) {
|
||||
++frames_received_;
|
||||
}
|
||||
}
|
||||
|
||||
void FakeAudioCaptureModule::SendFrameP() {
|
||||
RTC_DCHECK_RUN_ON(&process_thread_checker_);
|
||||
if (!audio_callback_) {
|
||||
return;
|
||||
}
|
||||
bool key_pressed = false;
|
||||
uint32_t current_mic_level = current_mic_level_;
|
||||
if (audio_callback_->RecordedDataIsAvailable(
|
||||
send_buffer_, kNumberSamples, kNumberBytesPerSample,
|
||||
kNumberOfChannels, kSamplesPerSecond, kTotalDelayMs, kClockDriftMs,
|
||||
current_mic_level, key_pressed, current_mic_level) != 0) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
}
|
||||
current_mic_level_ = current_mic_level;
|
||||
}
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* Copyright 2012 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.
|
||||
*/
|
||||
|
||||
// This class implements an AudioCaptureModule that can be used to detect if
|
||||
// audio is being received properly if it is fed by another AudioCaptureModule
|
||||
// in some arbitrary audio pipeline where they are connected. It does not play
|
||||
// out or record any audio so it does not need access to any hardware and can
|
||||
// therefore be used in the gtest testing framework.
|
||||
|
||||
// Note P postfix of a function indicates that it should only be called by the
|
||||
// processing thread.
|
||||
|
||||
#ifndef PC_TEST_FAKE_AUDIO_CAPTURE_MODULE_H_
|
||||
#define PC_TEST_FAKE_AUDIO_CAPTURE_MODULE_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "api/scoped_refptr.h"
|
||||
#include "api/sequence_checker.h"
|
||||
#include "modules/audio_device/include/audio_device.h"
|
||||
#include "modules/audio_device/include/audio_device_defines.h"
|
||||
#include "rtc_base/synchronization/mutex.h"
|
||||
#include "rtc_base/thread_annotations.h"
|
||||
|
||||
namespace rtc {
|
||||
class Thread;
|
||||
} // namespace rtc
|
||||
|
||||
class FakeAudioCaptureModule : public webrtc::AudioDeviceModule {
|
||||
public:
|
||||
typedef uint16_t Sample;
|
||||
|
||||
// The value for the following constants have been derived by running VoE
|
||||
// using a real ADM. The constants correspond to 10ms of mono audio at 44kHz.
|
||||
static const size_t kNumberSamples = 440;
|
||||
static const size_t kNumberBytesPerSample = sizeof(Sample);
|
||||
|
||||
// Creates a FakeAudioCaptureModule or returns NULL on failure.
|
||||
static rtc::scoped_refptr<FakeAudioCaptureModule> Create();
|
||||
|
||||
// Returns the number of frames that have been successfully pulled by the
|
||||
// instance. Note that correctly detecting success can only be done if the
|
||||
// pulled frame was generated/pushed from a FakeAudioCaptureModule.
|
||||
int frames_received() const RTC_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
int32_t ActiveAudioLayer(AudioLayer* audio_layer) const override;
|
||||
|
||||
// Note: Calling this method from a callback may result in deadlock.
|
||||
int32_t RegisterAudioCallback(webrtc::AudioTransport* audio_callback) override
|
||||
RTC_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
int32_t Init() override;
|
||||
int32_t Terminate() override;
|
||||
bool Initialized() const override;
|
||||
|
||||
int16_t PlayoutDevices() override;
|
||||
int16_t RecordingDevices() override;
|
||||
int32_t PlayoutDeviceName(uint16_t index,
|
||||
char name[webrtc::kAdmMaxDeviceNameSize],
|
||||
char guid[webrtc::kAdmMaxGuidSize]) override;
|
||||
int32_t RecordingDeviceName(uint16_t index,
|
||||
char name[webrtc::kAdmMaxDeviceNameSize],
|
||||
char guid[webrtc::kAdmMaxGuidSize]) override;
|
||||
|
||||
int32_t SetPlayoutDevice(uint16_t index) override;
|
||||
int32_t SetPlayoutDevice(WindowsDeviceType device) override;
|
||||
int32_t SetRecordingDevice(uint16_t index) override;
|
||||
int32_t SetRecordingDevice(WindowsDeviceType device) override;
|
||||
|
||||
int32_t PlayoutIsAvailable(bool* available) override;
|
||||
int32_t InitPlayout() override;
|
||||
bool PlayoutIsInitialized() const override;
|
||||
int32_t RecordingIsAvailable(bool* available) override;
|
||||
int32_t InitRecording() override;
|
||||
bool RecordingIsInitialized() const override;
|
||||
|
||||
int32_t StartPlayout() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
int32_t StopPlayout() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
bool Playing() const RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
int32_t StartRecording() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
int32_t StopRecording() RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
bool Recording() const RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
|
||||
int32_t InitSpeaker() override;
|
||||
bool SpeakerIsInitialized() const override;
|
||||
int32_t InitMicrophone() override;
|
||||
bool MicrophoneIsInitialized() const override;
|
||||
|
||||
int32_t SpeakerVolumeIsAvailable(bool* available) override;
|
||||
int32_t SetSpeakerVolume(uint32_t volume) override;
|
||||
int32_t SpeakerVolume(uint32_t* volume) const override;
|
||||
int32_t MaxSpeakerVolume(uint32_t* max_volume) const override;
|
||||
int32_t MinSpeakerVolume(uint32_t* min_volume) const override;
|
||||
|
||||
int32_t MicrophoneVolumeIsAvailable(bool* available) override;
|
||||
int32_t SetMicrophoneVolume(uint32_t volume)
|
||||
RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
int32_t MicrophoneVolume(uint32_t* volume) const
|
||||
RTC_LOCKS_EXCLUDED(mutex_) override;
|
||||
int32_t MaxMicrophoneVolume(uint32_t* max_volume) const override;
|
||||
|
||||
int32_t MinMicrophoneVolume(uint32_t* min_volume) const override;
|
||||
|
||||
int32_t SpeakerMuteIsAvailable(bool* available) override;
|
||||
int32_t SetSpeakerMute(bool enable) override;
|
||||
int32_t SpeakerMute(bool* enabled) const override;
|
||||
|
||||
int32_t MicrophoneMuteIsAvailable(bool* available) override;
|
||||
int32_t SetMicrophoneMute(bool enable) override;
|
||||
int32_t MicrophoneMute(bool* enabled) const override;
|
||||
|
||||
int32_t StereoPlayoutIsAvailable(bool* available) const override;
|
||||
int32_t SetStereoPlayout(bool enable) override;
|
||||
int32_t StereoPlayout(bool* enabled) const override;
|
||||
int32_t StereoRecordingIsAvailable(bool* available) const override;
|
||||
int32_t SetStereoRecording(bool enable) override;
|
||||
int32_t StereoRecording(bool* enabled) const override;
|
||||
|
||||
int32_t PlayoutDelay(uint16_t* delay_ms) const override;
|
||||
|
||||
bool BuiltInAECIsAvailable() const override { return false; }
|
||||
int32_t EnableBuiltInAEC(bool enable) override { return -1; }
|
||||
bool BuiltInAGCIsAvailable() const override { return false; }
|
||||
int32_t EnableBuiltInAGC(bool enable) override { return -1; }
|
||||
bool BuiltInNSIsAvailable() const override { return false; }
|
||||
int32_t EnableBuiltInNS(bool enable) override { return -1; }
|
||||
|
||||
int32_t GetPlayoutUnderrunCount() const override { return -1; }
|
||||
|
||||
absl::optional<webrtc::AudioDeviceModule::Stats> GetStats() const override {
|
||||
return webrtc::AudioDeviceModule::Stats();
|
||||
}
|
||||
#if defined(WEBRTC_IOS)
|
||||
int GetPlayoutAudioParameters(
|
||||
webrtc::AudioParameters* params) const override {
|
||||
return -1;
|
||||
}
|
||||
int GetRecordAudioParameters(webrtc::AudioParameters* params) const override {
|
||||
return -1;
|
||||
}
|
||||
#endif // WEBRTC_IOS
|
||||
|
||||
// End of functions inherited from webrtc::AudioDeviceModule.
|
||||
|
||||
protected:
|
||||
// The constructor is protected because the class needs to be created as a
|
||||
// reference counted object (for memory managment reasons). It could be
|
||||
// exposed in which case the burden of proper instantiation would be put on
|
||||
// the creator of a FakeAudioCaptureModule instance. To create an instance of
|
||||
// this class use the Create(..) API.
|
||||
FakeAudioCaptureModule();
|
||||
// The destructor is protected because it is reference counted and should not
|
||||
// be deleted directly.
|
||||
virtual ~FakeAudioCaptureModule();
|
||||
|
||||
private:
|
||||
// Initializes the state of the FakeAudioCaptureModule. This API is called on
|
||||
// creation by the Create() API.
|
||||
bool Initialize();
|
||||
// SetBuffer() sets all samples in send_buffer_ to `value`.
|
||||
void SetSendBuffer(int value);
|
||||
// Resets rec_buffer_. I.e., sets all rec_buffer_ samples to 0.
|
||||
void ResetRecBuffer();
|
||||
// Returns true if rec_buffer_ contains one or more sample greater than or
|
||||
// equal to `value`.
|
||||
bool CheckRecBuffer(int value);
|
||||
|
||||
// Returns true/false depending on if recording or playback has been
|
||||
// enabled/started.
|
||||
bool ShouldStartProcessing() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
// Starts or stops the pushing and pulling of audio frames.
|
||||
void UpdateProcessing(bool start) RTC_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Starts the periodic calling of ProcessFrame() in a thread safe way.
|
||||
void StartProcessP();
|
||||
// Periodcally called function that ensures that frames are pulled and pushed
|
||||
// periodically if enabled/started.
|
||||
void ProcessFrameP() RTC_LOCKS_EXCLUDED(mutex_);
|
||||
// Pulls frames from the registered webrtc::AudioTransport.
|
||||
void ReceiveFrameP() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
// Pushes frames to the registered webrtc::AudioTransport.
|
||||
void SendFrameP() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
// Callback for playout and recording.
|
||||
webrtc::AudioTransport* audio_callback_ RTC_GUARDED_BY(mutex_);
|
||||
|
||||
bool recording_ RTC_GUARDED_BY(
|
||||
mutex_); // True when audio is being pushed from the instance.
|
||||
bool playing_ RTC_GUARDED_BY(
|
||||
mutex_); // True when audio is being pulled by the instance.
|
||||
|
||||
bool play_is_initialized_; // True when the instance is ready to pull audio.
|
||||
bool rec_is_initialized_; // True when the instance is ready to push audio.
|
||||
|
||||
// Input to and output from RecordedDataIsAvailable(..) makes it possible to
|
||||
// modify the current mic level. The implementation does not care about the
|
||||
// mic level so it just feeds back what it receives.
|
||||
uint32_t current_mic_level_ RTC_GUARDED_BY(mutex_);
|
||||
|
||||
// next_frame_time_ is updated in a non-drifting manner to indicate the next
|
||||
// wall clock time the next frame should be generated and received. started_
|
||||
// ensures that next_frame_time_ can be initialized properly on first call.
|
||||
bool started_ RTC_GUARDED_BY(mutex_);
|
||||
int64_t next_frame_time_ RTC_GUARDED_BY(process_thread_checker_);
|
||||
|
||||
std::unique_ptr<rtc::Thread> process_thread_;
|
||||
|
||||
// Buffer for storing samples received from the webrtc::AudioTransport.
|
||||
char rec_buffer_[kNumberSamples * kNumberBytesPerSample];
|
||||
// Buffer for samples to send to the webrtc::AudioTransport.
|
||||
char send_buffer_[kNumberSamples * kNumberBytesPerSample];
|
||||
|
||||
// Counter of frames received that have samples of high enough amplitude to
|
||||
// indicate that the frames are not faked somewhere in the audio pipeline
|
||||
// (e.g. by a jitter buffer).
|
||||
int frames_received_;
|
||||
|
||||
// Protects variables that are accessed from process_thread_ and
|
||||
// the main thread.
|
||||
mutable webrtc::Mutex mutex_;
|
||||
webrtc::SequenceChecker process_thread_checker_{
|
||||
webrtc::SequenceChecker::kDetached};
|
||||
};
|
||||
|
||||
#endif // PC_TEST_FAKE_AUDIO_CAPTURE_MODULE_H_
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* Copyright 2012 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 "pc/test/fake_audio_capture_module.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "api/scoped_refptr.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "rtc_base/synchronization/mutex.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
class FakeAdmTest : public ::testing::Test, public webrtc::AudioTransport {
|
||||
protected:
|
||||
static const int kMsInSecond = 1000;
|
||||
|
||||
FakeAdmTest()
|
||||
: push_iterations_(0), pull_iterations_(0), rec_buffer_bytes_(0) {
|
||||
memset(rec_buffer_, 0, sizeof(rec_buffer_));
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
|
||||
EXPECT_TRUE(fake_audio_capture_module_.get() != NULL);
|
||||
}
|
||||
|
||||
// Callbacks inherited from webrtc::AudioTransport.
|
||||
// ADM is pushing data.
|
||||
int32_t RecordedDataIsAvailable(const void* audioSamples,
|
||||
const size_t nSamples,
|
||||
const size_t nBytesPerSample,
|
||||
const size_t nChannels,
|
||||
const uint32_t samplesPerSec,
|
||||
const uint32_t totalDelayMS,
|
||||
const int32_t clockDrift,
|
||||
const uint32_t currentMicLevel,
|
||||
const bool keyPressed,
|
||||
uint32_t& newMicLevel) override {
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
rec_buffer_bytes_ = nSamples * nBytesPerSample;
|
||||
if ((rec_buffer_bytes_ == 0) ||
|
||||
(rec_buffer_bytes_ >
|
||||
FakeAudioCaptureModule::kNumberSamples *
|
||||
FakeAudioCaptureModule::kNumberBytesPerSample)) {
|
||||
ADD_FAILURE();
|
||||
return -1;
|
||||
}
|
||||
memcpy(rec_buffer_, audioSamples, rec_buffer_bytes_);
|
||||
++push_iterations_;
|
||||
newMicLevel = currentMicLevel;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PullRenderData(int bits_per_sample,
|
||||
int sample_rate,
|
||||
size_t number_of_channels,
|
||||
size_t number_of_frames,
|
||||
void* audio_data,
|
||||
int64_t* elapsed_time_ms,
|
||||
int64_t* ntp_time_ms) override {}
|
||||
|
||||
// ADM is pulling data.
|
||||
int32_t NeedMorePlayData(const size_t nSamples,
|
||||
const size_t nBytesPerSample,
|
||||
const size_t nChannels,
|
||||
const uint32_t samplesPerSec,
|
||||
void* audioSamples,
|
||||
size_t& nSamplesOut,
|
||||
int64_t* elapsed_time_ms,
|
||||
int64_t* ntp_time_ms) override {
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
++pull_iterations_;
|
||||
const size_t audio_buffer_size = nSamples * nBytesPerSample;
|
||||
const size_t bytes_out =
|
||||
RecordedDataReceived()
|
||||
? CopyFromRecBuffer(audioSamples, audio_buffer_size)
|
||||
: GenerateZeroBuffer(audioSamples, audio_buffer_size);
|
||||
nSamplesOut = bytes_out / nBytesPerSample;
|
||||
*elapsed_time_ms = 0;
|
||||
*ntp_time_ms = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int push_iterations() const {
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
return push_iterations_;
|
||||
}
|
||||
int pull_iterations() const {
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
return pull_iterations_;
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
|
||||
|
||||
private:
|
||||
bool RecordedDataReceived() const { return rec_buffer_bytes_ != 0; }
|
||||
size_t GenerateZeroBuffer(void* audio_buffer, size_t audio_buffer_size) {
|
||||
memset(audio_buffer, 0, audio_buffer_size);
|
||||
return audio_buffer_size;
|
||||
}
|
||||
size_t CopyFromRecBuffer(void* audio_buffer, size_t audio_buffer_size) {
|
||||
EXPECT_EQ(audio_buffer_size, rec_buffer_bytes_);
|
||||
const size_t min_buffer_size =
|
||||
std::min(audio_buffer_size, rec_buffer_bytes_);
|
||||
memcpy(audio_buffer, rec_buffer_, min_buffer_size);
|
||||
return min_buffer_size;
|
||||
}
|
||||
|
||||
rtc::AutoThread main_thread_;
|
||||
|
||||
mutable webrtc::Mutex mutex_;
|
||||
|
||||
int push_iterations_;
|
||||
int pull_iterations_;
|
||||
|
||||
char rec_buffer_[FakeAudioCaptureModule::kNumberSamples *
|
||||
FakeAudioCaptureModule::kNumberBytesPerSample];
|
||||
size_t rec_buffer_bytes_;
|
||||
};
|
||||
|
||||
TEST_F(FakeAdmTest, PlayoutTest) {
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->RegisterAudioCallback(this));
|
||||
|
||||
bool stereo_available = false;
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->StereoPlayoutIsAvailable(
|
||||
&stereo_available));
|
||||
EXPECT_TRUE(stereo_available);
|
||||
|
||||
EXPECT_NE(0, fake_audio_capture_module_->StartPlayout());
|
||||
EXPECT_FALSE(fake_audio_capture_module_->PlayoutIsInitialized());
|
||||
EXPECT_FALSE(fake_audio_capture_module_->Playing());
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->StopPlayout());
|
||||
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->InitPlayout());
|
||||
EXPECT_TRUE(fake_audio_capture_module_->PlayoutIsInitialized());
|
||||
EXPECT_FALSE(fake_audio_capture_module_->Playing());
|
||||
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->StartPlayout());
|
||||
EXPECT_TRUE(fake_audio_capture_module_->Playing());
|
||||
|
||||
uint16_t delay_ms = 10;
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->PlayoutDelay(&delay_ms));
|
||||
EXPECT_EQ(0, delay_ms);
|
||||
|
||||
EXPECT_TRUE_WAIT(pull_iterations() > 0, kMsInSecond);
|
||||
EXPECT_GE(0, push_iterations());
|
||||
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->StopPlayout());
|
||||
EXPECT_FALSE(fake_audio_capture_module_->Playing());
|
||||
}
|
||||
|
||||
TEST_F(FakeAdmTest, RecordTest) {
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->RegisterAudioCallback(this));
|
||||
|
||||
bool stereo_available = false;
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->StereoRecordingIsAvailable(
|
||||
&stereo_available));
|
||||
EXPECT_FALSE(stereo_available);
|
||||
|
||||
EXPECT_NE(0, fake_audio_capture_module_->StartRecording());
|
||||
EXPECT_FALSE(fake_audio_capture_module_->Recording());
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->StopRecording());
|
||||
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->InitRecording());
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->StartRecording());
|
||||
EXPECT_TRUE(fake_audio_capture_module_->Recording());
|
||||
|
||||
EXPECT_TRUE_WAIT(push_iterations() > 0, kMsInSecond);
|
||||
EXPECT_GE(0, pull_iterations());
|
||||
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->StopRecording());
|
||||
EXPECT_FALSE(fake_audio_capture_module_->Recording());
|
||||
}
|
||||
|
||||
TEST_F(FakeAdmTest, DuplexTest) {
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->RegisterAudioCallback(this));
|
||||
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->InitPlayout());
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->StartPlayout());
|
||||
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->InitRecording());
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->StartRecording());
|
||||
|
||||
EXPECT_TRUE_WAIT(push_iterations() > 0, kMsInSecond);
|
||||
EXPECT_TRUE_WAIT(pull_iterations() > 0, kMsInSecond);
|
||||
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->StopPlayout());
|
||||
EXPECT_EQ(0, fake_audio_capture_module_->StopRecording());
|
||||
}
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
* Copyright 2013 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_FAKE_DATA_CHANNEL_CONTROLLER_H_
|
||||
#define PC_TEST_FAKE_DATA_CHANNEL_CONTROLLER_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "pc/sctp_data_channel.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/weak_ptr.h"
|
||||
|
||||
class FakeDataChannelController
|
||||
: public webrtc::SctpDataChannelControllerInterface {
|
||||
public:
|
||||
explicit FakeDataChannelController(rtc::Thread* network_thread)
|
||||
: signaling_thread_(rtc::Thread::Current()),
|
||||
network_thread_(network_thread),
|
||||
send_blocked_(false),
|
||||
transport_available_(false),
|
||||
ready_to_send_(false),
|
||||
transport_error_(false) {}
|
||||
|
||||
~FakeDataChannelController() override {
|
||||
network_thread_->BlockingCall([&] {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
weak_factory_.InvalidateWeakPtrs();
|
||||
});
|
||||
}
|
||||
|
||||
rtc::WeakPtr<FakeDataChannelController> weak_ptr() {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
return weak_factory_.GetWeakPtr();
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<webrtc::SctpDataChannel> CreateDataChannel(
|
||||
absl::string_view label,
|
||||
webrtc::InternalDataChannelInit init) {
|
||||
rtc::scoped_refptr<webrtc::SctpDataChannel> channel =
|
||||
network_thread_->BlockingCall([&]() {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
rtc::WeakPtr<FakeDataChannelController> my_weak_ptr = weak_ptr();
|
||||
// Explicitly associate the weak ptr instance with the current thread
|
||||
// to catch early any inappropriate referencing of it on the network
|
||||
// thread.
|
||||
RTC_CHECK(my_weak_ptr);
|
||||
|
||||
rtc::scoped_refptr<webrtc::SctpDataChannel> channel =
|
||||
webrtc::SctpDataChannel::Create(
|
||||
std::move(my_weak_ptr), std::string(label),
|
||||
transport_available_, init, signaling_thread_,
|
||||
network_thread_);
|
||||
if (transport_available_ && channel->sid_n().HasValue()) {
|
||||
AddSctpDataStream(channel->sid_n());
|
||||
}
|
||||
if (ready_to_send_) {
|
||||
network_thread_->PostTask([channel = channel] {
|
||||
if (channel->state() !=
|
||||
webrtc::DataChannelInterface::DataState::kClosed) {
|
||||
channel->OnTransportReady();
|
||||
}
|
||||
});
|
||||
}
|
||||
connected_channels_.insert(channel.get());
|
||||
return channel;
|
||||
});
|
||||
return channel;
|
||||
}
|
||||
|
||||
webrtc::RTCError SendData(webrtc::StreamId sid,
|
||||
const webrtc::SendDataParams& params,
|
||||
const rtc::CopyOnWriteBuffer& payload) override {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
RTC_CHECK(ready_to_send_);
|
||||
RTC_CHECK(transport_available_);
|
||||
if (send_blocked_) {
|
||||
return webrtc::RTCError(webrtc::RTCErrorType::RESOURCE_EXHAUSTED);
|
||||
}
|
||||
|
||||
if (transport_error_) {
|
||||
return webrtc::RTCError(webrtc::RTCErrorType::INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
last_sid_ = sid;
|
||||
last_send_data_params_ = params;
|
||||
return webrtc::RTCError::OK();
|
||||
}
|
||||
|
||||
void AddSctpDataStream(webrtc::StreamId sid) override {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
RTC_CHECK(sid.HasValue());
|
||||
if (!transport_available_) {
|
||||
return;
|
||||
}
|
||||
known_stream_ids_.insert(sid);
|
||||
}
|
||||
|
||||
void RemoveSctpDataStream(webrtc::StreamId sid) override {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
RTC_CHECK(sid.HasValue());
|
||||
known_stream_ids_.erase(sid);
|
||||
// Unlike the real SCTP transport, act like the closing procedure finished
|
||||
// instantly.
|
||||
auto it = absl::c_find_if(connected_channels_,
|
||||
[&](const auto* c) { return c->sid_n() == sid; });
|
||||
// This path mimics the DCC's OnChannelClosed handler since the FDCC
|
||||
// (this class) doesn't have a transport that would do that.
|
||||
if (it != connected_channels_.end())
|
||||
(*it)->OnClosingProcedureComplete();
|
||||
}
|
||||
|
||||
void OnChannelStateChanged(
|
||||
webrtc::SctpDataChannel* data_channel,
|
||||
webrtc::DataChannelInterface::DataState state) override {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
if (state == webrtc::DataChannelInterface::DataState::kOpen) {
|
||||
++channels_opened_;
|
||||
} else if (state == webrtc::DataChannelInterface::DataState::kClosed) {
|
||||
++channels_closed_;
|
||||
connected_channels_.erase(data_channel);
|
||||
}
|
||||
}
|
||||
|
||||
// Set true to emulate the SCTP stream being blocked by congestion control.
|
||||
void set_send_blocked(bool blocked) {
|
||||
network_thread_->BlockingCall([&]() {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
send_blocked_ = blocked;
|
||||
if (!blocked) {
|
||||
RTC_CHECK(transport_available_);
|
||||
// Make a copy since `connected_channels_` may change while
|
||||
// OnTransportReady is called.
|
||||
auto copy = connected_channels_;
|
||||
for (webrtc::SctpDataChannel* ch : copy) {
|
||||
ch->OnTransportReady();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Set true to emulate the transport channel creation, e.g. after
|
||||
// setLocalDescription/setRemoteDescription called with data content.
|
||||
void set_transport_available(bool available) {
|
||||
network_thread_->BlockingCall([&]() {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
transport_available_ = available;
|
||||
});
|
||||
}
|
||||
|
||||
// Set true to emulate the transport OnTransportReady signal when the
|
||||
// transport becomes writable for the first time.
|
||||
void set_ready_to_send(bool ready) {
|
||||
network_thread_->BlockingCall([&]() {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
RTC_CHECK(transport_available_);
|
||||
ready_to_send_ = ready;
|
||||
if (ready) {
|
||||
std::set<webrtc::SctpDataChannel*>::iterator it;
|
||||
for (it = connected_channels_.begin(); it != connected_channels_.end();
|
||||
++it) {
|
||||
(*it)->OnTransportReady();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void set_transport_error() {
|
||||
network_thread_->BlockingCall([&]() {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
transport_error_ = true;
|
||||
});
|
||||
}
|
||||
|
||||
int last_sid() const {
|
||||
return network_thread_->BlockingCall([&]() {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
return last_sid_.stream_id_int();
|
||||
});
|
||||
}
|
||||
|
||||
webrtc::SendDataParams last_send_data_params() const {
|
||||
return network_thread_->BlockingCall([&]() {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
return last_send_data_params_;
|
||||
});
|
||||
}
|
||||
|
||||
bool IsConnected(webrtc::SctpDataChannel* data_channel) const {
|
||||
return network_thread_->BlockingCall([&]() {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
return connected_channels_.find(data_channel) !=
|
||||
connected_channels_.end();
|
||||
});
|
||||
}
|
||||
|
||||
bool IsStreamAdded(webrtc::StreamId id) const {
|
||||
return network_thread_->BlockingCall([&]() {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
return known_stream_ids_.find(id) != known_stream_ids_.end();
|
||||
});
|
||||
}
|
||||
|
||||
int channels_opened() const {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
return channels_opened_;
|
||||
}
|
||||
int channels_closed() const {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
return channels_closed_;
|
||||
}
|
||||
|
||||
private:
|
||||
rtc::Thread* const signaling_thread_;
|
||||
rtc::Thread* const network_thread_;
|
||||
webrtc::StreamId last_sid_ RTC_GUARDED_BY(network_thread_);
|
||||
webrtc::SendDataParams last_send_data_params_ RTC_GUARDED_BY(network_thread_);
|
||||
bool send_blocked_ RTC_GUARDED_BY(network_thread_);
|
||||
bool transport_available_ RTC_GUARDED_BY(network_thread_);
|
||||
bool ready_to_send_ RTC_GUARDED_BY(network_thread_);
|
||||
bool transport_error_ RTC_GUARDED_BY(network_thread_);
|
||||
int channels_closed_ RTC_GUARDED_BY(network_thread_) = 0;
|
||||
int channels_opened_ RTC_GUARDED_BY(network_thread_) = 0;
|
||||
std::set<webrtc::SctpDataChannel*> connected_channels_
|
||||
RTC_GUARDED_BY(network_thread_);
|
||||
std::set<webrtc::StreamId> known_stream_ids_ RTC_GUARDED_BY(network_thread_);
|
||||
rtc::WeakPtrFactory<FakeDataChannelController> weak_factory_
|
||||
RTC_GUARDED_BY(network_thread_){this};
|
||||
};
|
||||
#endif // PC_TEST_FAKE_DATA_CHANNEL_CONTROLLER_H_
|
||||
|
|
@ -0,0 +1,374 @@
|
|||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_FAKE_PEER_CONNECTION_BASE_H_
|
||||
#define PC_TEST_FAKE_PEER_CONNECTION_BASE_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/field_trials_view.h"
|
||||
#include "api/sctp_transport_interface.h"
|
||||
#include "pc/peer_connection_internal.h"
|
||||
#include "test/scoped_key_value_config.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Customized PeerConnection fakes can be created by subclassing
|
||||
// FakePeerConnectionBase then overriding the interesting methods. This class
|
||||
// takes care of providing default implementations for all the pure virtual
|
||||
// functions specified in the interfaces.
|
||||
class FakePeerConnectionBase : public PeerConnectionInternal {
|
||||
public:
|
||||
// PeerConnectionInterface implementation.
|
||||
|
||||
rtc::scoped_refptr<StreamCollectionInterface> local_streams() override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<StreamCollectionInterface> remote_streams() override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool AddStream(MediaStreamInterface* stream) override { return false; }
|
||||
|
||||
void RemoveStream(MediaStreamInterface* stream) override {}
|
||||
|
||||
RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> AddTrack(
|
||||
rtc::scoped_refptr<MediaStreamTrackInterface> track,
|
||||
const std::vector<std::string>& stream_ids) override {
|
||||
return RTCError(RTCErrorType::UNSUPPORTED_OPERATION, "Not implemented");
|
||||
}
|
||||
|
||||
RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> AddTrack(
|
||||
rtc::scoped_refptr<MediaStreamTrackInterface> track,
|
||||
const std::vector<std::string>& stream_ids,
|
||||
const std::vector<RtpEncodingParameters>& init_send_encodings) override {
|
||||
return RTCError(RTCErrorType::UNSUPPORTED_OPERATION, "Not implemented");
|
||||
}
|
||||
|
||||
RTCError RemoveTrackOrError(
|
||||
rtc::scoped_refptr<RtpSenderInterface> sender) override {
|
||||
return RTCError(RTCErrorType::UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> AddTransceiver(
|
||||
rtc::scoped_refptr<MediaStreamTrackInterface> track) override {
|
||||
return RTCError(RTCErrorType::UNSUPPORTED_OPERATION, "Not implemented");
|
||||
}
|
||||
|
||||
RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> AddTransceiver(
|
||||
rtc::scoped_refptr<MediaStreamTrackInterface> track,
|
||||
const RtpTransceiverInit& init) override {
|
||||
return RTCError(RTCErrorType::UNSUPPORTED_OPERATION, "Not implemented");
|
||||
}
|
||||
|
||||
RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> AddTransceiver(
|
||||
cricket::MediaType media_type) override {
|
||||
return RTCError(RTCErrorType::UNSUPPORTED_OPERATION, "Not implemented");
|
||||
}
|
||||
|
||||
RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> AddTransceiver(
|
||||
cricket::MediaType media_type,
|
||||
const RtpTransceiverInit& init) override {
|
||||
return RTCError(RTCErrorType::UNSUPPORTED_OPERATION, "Not implemented");
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<RtpSenderInterface> CreateSender(
|
||||
const std::string& kind,
|
||||
const std::string& stream_id) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<rtc::scoped_refptr<RtpSenderInterface>> GetSenders()
|
||||
const override {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceivers()
|
||||
const override {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> GetTransceivers()
|
||||
const override {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool GetStats(StatsObserver* observer,
|
||||
MediaStreamTrackInterface* track,
|
||||
StatsOutputLevel level) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
void GetStats(RTCStatsCollectorCallback* callback) override {}
|
||||
void GetStats(
|
||||
rtc::scoped_refptr<RtpSenderInterface> selector,
|
||||
rtc::scoped_refptr<RTCStatsCollectorCallback> callback) override {}
|
||||
void GetStats(
|
||||
rtc::scoped_refptr<RtpReceiverInterface> selector,
|
||||
rtc::scoped_refptr<RTCStatsCollectorCallback> callback) override {}
|
||||
|
||||
void ClearStatsCache() override {}
|
||||
|
||||
rtc::scoped_refptr<SctpTransportInterface> GetSctpTransport() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RTCErrorOr<rtc::scoped_refptr<DataChannelInterface>> CreateDataChannelOrError(
|
||||
const std::string& label,
|
||||
const DataChannelInit* config) override {
|
||||
return RTCError(RTCErrorType::UNSUPPORTED_OPERATION,
|
||||
"Fake function called");
|
||||
}
|
||||
|
||||
const SessionDescriptionInterface* local_description() const override {
|
||||
return nullptr;
|
||||
}
|
||||
const SessionDescriptionInterface* remote_description() const override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const SessionDescriptionInterface* current_local_description()
|
||||
const override {
|
||||
return nullptr;
|
||||
}
|
||||
const SessionDescriptionInterface* current_remote_description()
|
||||
const override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const SessionDescriptionInterface* pending_local_description()
|
||||
const override {
|
||||
return nullptr;
|
||||
}
|
||||
const SessionDescriptionInterface* pending_remote_description()
|
||||
const override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RestartIce() override {}
|
||||
|
||||
void CreateOffer(CreateSessionDescriptionObserver* observer,
|
||||
const RTCOfferAnswerOptions& options) override {}
|
||||
|
||||
void CreateAnswer(CreateSessionDescriptionObserver* observer,
|
||||
const RTCOfferAnswerOptions& options) override {}
|
||||
|
||||
void SetLocalDescription(SetSessionDescriptionObserver* observer,
|
||||
SessionDescriptionInterface* desc) override {}
|
||||
|
||||
void SetRemoteDescription(SetSessionDescriptionObserver* observer,
|
||||
SessionDescriptionInterface* desc) override {}
|
||||
|
||||
void SetRemoteDescription(
|
||||
std::unique_ptr<SessionDescriptionInterface> desc,
|
||||
rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer)
|
||||
override {}
|
||||
|
||||
RTCConfiguration GetConfiguration() override { return RTCConfiguration(); }
|
||||
|
||||
RTCError SetConfiguration(
|
||||
const PeerConnectionInterface::RTCConfiguration& config) override {
|
||||
return RTCError();
|
||||
}
|
||||
|
||||
bool AddIceCandidate(const IceCandidateInterface* candidate) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RemoveIceCandidates(
|
||||
const std::vector<cricket::Candidate>& candidates) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
RTCError SetBitrate(const BitrateSettings& bitrate) override {
|
||||
return RTCError(RTCErrorType::UNSUPPORTED_OPERATION, "Not implemented");
|
||||
}
|
||||
|
||||
void ReconfigureBandwidthEstimation(
|
||||
const BandwidthEstimationSettings& settings) override {}
|
||||
|
||||
void SetAudioPlayout(bool playout) override {}
|
||||
|
||||
void SetAudioRecording(bool recording) override {}
|
||||
|
||||
rtc::scoped_refptr<DtlsTransportInterface> LookupDtlsTransportByMid(
|
||||
const std::string& mid) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SignalingState signaling_state() override { return SignalingState::kStable; }
|
||||
|
||||
IceConnectionState ice_connection_state() override {
|
||||
return IceConnectionState::kIceConnectionNew;
|
||||
}
|
||||
|
||||
IceConnectionState standardized_ice_connection_state() override {
|
||||
return IceConnectionState::kIceConnectionNew;
|
||||
}
|
||||
|
||||
PeerConnectionState peer_connection_state() override {
|
||||
return PeerConnectionState::kNew;
|
||||
}
|
||||
|
||||
IceGatheringState ice_gathering_state() override {
|
||||
return IceGatheringState::kIceGatheringNew;
|
||||
}
|
||||
|
||||
absl::optional<bool> can_trickle_ice_candidates() { return absl::nullopt; }
|
||||
|
||||
bool StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,
|
||||
int64_t output_period_ms) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
void StopRtcEventLog() override {}
|
||||
|
||||
void Close() override {}
|
||||
|
||||
// PeerConnectionInternal implementation.
|
||||
|
||||
rtc::Thread* network_thread() const override { return nullptr; }
|
||||
rtc::Thread* worker_thread() const override { return nullptr; }
|
||||
rtc::Thread* signaling_thread() const override { return nullptr; }
|
||||
|
||||
std::string session_id() const override { return ""; }
|
||||
|
||||
bool initial_offerer() const override { return false; }
|
||||
|
||||
std::vector<
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
|
||||
GetTransceiversInternal() const override {
|
||||
return {};
|
||||
}
|
||||
|
||||
absl::optional<std::string> sctp_transport_name() const override {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
absl::optional<std::string> sctp_mid() const override {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
std::map<std::string, cricket::TransportStats> GetTransportStatsByNames(
|
||||
const std::set<std::string>& transport_names) override {
|
||||
return {};
|
||||
}
|
||||
|
||||
Call::Stats GetCallStats() override { return Call::Stats(); }
|
||||
|
||||
absl::optional<AudioDeviceModule::Stats> GetAudioDeviceStats() override {
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
bool GetLocalCertificate(
|
||||
const std::string& transport_name,
|
||||
rtc::scoped_refptr<rtc::RTCCertificate>* certificate) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain(
|
||||
const std::string& transport_name) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool IceRestartPending(const std::string& content_name) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NeedsIceRestart(const std::string& content_name) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetSslRole(const std::string& content_name,
|
||||
rtc::SSLRole* role) override {
|
||||
return false;
|
||||
}
|
||||
const PeerConnectionInterface::RTCConfiguration* configuration()
|
||||
const override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ReportSdpBundleUsage(
|
||||
const SessionDescriptionInterface& remote_description) override {}
|
||||
|
||||
PeerConnectionMessageHandler* message_handler() override { return nullptr; }
|
||||
RtpTransmissionManager* rtp_manager() override { return nullptr; }
|
||||
const RtpTransmissionManager* rtp_manager() const override { return nullptr; }
|
||||
bool dtls_enabled() const override { return false; }
|
||||
const PeerConnectionFactoryInterface::Options* options() const override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CryptoOptions GetCryptoOptions() override { return CryptoOptions(); }
|
||||
JsepTransportController* transport_controller_s() override { return nullptr; }
|
||||
JsepTransportController* transport_controller_n() override { return nullptr; }
|
||||
DataChannelController* data_channel_controller() override { return nullptr; }
|
||||
cricket::PortAllocator* port_allocator() override { return nullptr; }
|
||||
LegacyStatsCollector* legacy_stats() override { return nullptr; }
|
||||
PeerConnectionObserver* Observer() const override { return nullptr; }
|
||||
absl::optional<rtc::SSLRole> GetSctpSslRole_n() override {
|
||||
return absl::nullopt;
|
||||
}
|
||||
PeerConnectionInterface::IceConnectionState ice_connection_state_internal()
|
||||
override {
|
||||
return PeerConnectionInterface::IceConnectionState::kIceConnectionNew;
|
||||
}
|
||||
void SetIceConnectionState(
|
||||
PeerConnectionInterface::IceConnectionState new_state) override {}
|
||||
void NoteUsageEvent(UsageEvent event) override {}
|
||||
bool IsClosed() const override { return false; }
|
||||
bool IsUnifiedPlan() const override { return true; }
|
||||
bool ValidateBundleSettings(
|
||||
const cricket::SessionDescription* desc,
|
||||
const std::map<std::string, const cricket::ContentGroup*>&
|
||||
bundle_groups_by_mid) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> AddTransceiver(
|
||||
cricket::MediaType media_type,
|
||||
rtc::scoped_refptr<MediaStreamTrackInterface> track,
|
||||
const RtpTransceiverInit& init,
|
||||
bool fire_callback = true) override {
|
||||
return RTCError(RTCErrorType::INTERNAL_ERROR, "");
|
||||
}
|
||||
void StartSctpTransport(int local_port,
|
||||
int remote_port,
|
||||
int max_message_size) override {}
|
||||
|
||||
void AddRemoteCandidate(const std::string& mid,
|
||||
const cricket::Candidate& candidate) override {}
|
||||
|
||||
Call* call_ptr() override { return nullptr; }
|
||||
bool SrtpRequired() const override { return false; }
|
||||
bool CreateDataChannelTransport(absl::string_view mid) override {
|
||||
return false;
|
||||
}
|
||||
void DestroyDataChannelTransport(RTCError error) override {}
|
||||
|
||||
const FieldTrialsView& trials() const override { return field_trials_; }
|
||||
|
||||
protected:
|
||||
test::ScopedKeyValueConfig field_trials_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_FAKE_PEER_CONNECTION_BASE_H_
|
||||
|
|
@ -0,0 +1,570 @@
|
|||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_FAKE_PEER_CONNECTION_FOR_STATS_H_
|
||||
#define PC_TEST_FAKE_PEER_CONNECTION_FOR_STATS_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "api/environment/environment_factory.h"
|
||||
#include "media/base/media_channel.h"
|
||||
#include "pc/channel.h"
|
||||
#include "pc/stream_collection.h"
|
||||
#include "pc/test/enable_fake_media.h"
|
||||
#include "pc/test/fake_data_channel_controller.h"
|
||||
#include "pc/test/fake_peer_connection_base.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Fake VoiceMediaChannel where the result of GetStats can be configured.
|
||||
class FakeVoiceMediaSendChannelForStats
|
||||
: public cricket::FakeVoiceMediaSendChannel {
|
||||
public:
|
||||
explicit FakeVoiceMediaSendChannelForStats(TaskQueueBase* network_thread)
|
||||
: cricket::FakeVoiceMediaSendChannel(cricket::AudioOptions(),
|
||||
network_thread) {}
|
||||
|
||||
void SetStats(const cricket::VoiceMediaInfo& voice_info) {
|
||||
send_stats_ = cricket::VoiceMediaSendInfo();
|
||||
send_stats_->senders = voice_info.senders;
|
||||
send_stats_->send_codecs = voice_info.send_codecs;
|
||||
}
|
||||
|
||||
// VoiceMediaChannel overrides.
|
||||
bool GetStats(cricket::VoiceMediaSendInfo* info) override {
|
||||
if (send_stats_) {
|
||||
*info = *send_stats_;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
absl::optional<cricket::VoiceMediaSendInfo> send_stats_;
|
||||
};
|
||||
|
||||
class FakeVoiceMediaReceiveChannelForStats
|
||||
: public cricket::FakeVoiceMediaReceiveChannel {
|
||||
public:
|
||||
explicit FakeVoiceMediaReceiveChannelForStats(TaskQueueBase* network_thread)
|
||||
: cricket::FakeVoiceMediaReceiveChannel(cricket::AudioOptions(),
|
||||
network_thread) {}
|
||||
|
||||
void SetStats(const cricket::VoiceMediaInfo& voice_info) {
|
||||
receive_stats_ = cricket::VoiceMediaReceiveInfo();
|
||||
receive_stats_->receivers = voice_info.receivers;
|
||||
receive_stats_->receive_codecs = voice_info.receive_codecs;
|
||||
receive_stats_->device_underrun_count = voice_info.device_underrun_count;
|
||||
}
|
||||
|
||||
// VoiceMediaChannel overrides.
|
||||
bool GetStats(cricket::VoiceMediaReceiveInfo* info,
|
||||
bool get_and_clear_legacy_stats) override {
|
||||
if (receive_stats_) {
|
||||
*info = *receive_stats_;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
absl::optional<cricket::VoiceMediaReceiveInfo> receive_stats_;
|
||||
};
|
||||
|
||||
// Fake VideoMediaChannel where the result of GetStats can be configured.
|
||||
class FakeVideoMediaSendChannelForStats
|
||||
: public cricket::FakeVideoMediaSendChannel {
|
||||
public:
|
||||
explicit FakeVideoMediaSendChannelForStats(TaskQueueBase* network_thread)
|
||||
: cricket::FakeVideoMediaSendChannel(cricket::VideoOptions(),
|
||||
network_thread) {}
|
||||
|
||||
void SetStats(const cricket::VideoMediaInfo& video_info) {
|
||||
send_stats_ = cricket::VideoMediaSendInfo();
|
||||
send_stats_->senders = video_info.senders;
|
||||
send_stats_->aggregated_senders = video_info.aggregated_senders;
|
||||
send_stats_->send_codecs = video_info.send_codecs;
|
||||
}
|
||||
|
||||
// VideoMediaChannel overrides.
|
||||
bool GetStats(cricket::VideoMediaSendInfo* info) override {
|
||||
if (send_stats_) {
|
||||
*info = *send_stats_;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
absl::optional<cricket::VideoMediaSendInfo> send_stats_;
|
||||
};
|
||||
|
||||
class FakeVideoMediaReceiveChannelForStats
|
||||
: public cricket::FakeVideoMediaReceiveChannel {
|
||||
public:
|
||||
explicit FakeVideoMediaReceiveChannelForStats(TaskQueueBase* network_thread)
|
||||
: cricket::FakeVideoMediaReceiveChannel(cricket::VideoOptions(),
|
||||
network_thread) {}
|
||||
|
||||
void SetStats(const cricket::VideoMediaInfo& video_info) {
|
||||
receive_stats_ = cricket::VideoMediaReceiveInfo();
|
||||
receive_stats_->receivers = video_info.receivers;
|
||||
receive_stats_->receive_codecs = video_info.receive_codecs;
|
||||
}
|
||||
|
||||
// VideoMediaChannel overrides.
|
||||
bool GetStats(cricket::VideoMediaReceiveInfo* info) override {
|
||||
if (receive_stats_) {
|
||||
*info = *receive_stats_;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
absl::optional<cricket::VideoMediaReceiveInfo> receive_stats_;
|
||||
};
|
||||
|
||||
constexpr bool kDefaultRtcpMuxRequired = true;
|
||||
constexpr bool kDefaultSrtpRequired = true;
|
||||
|
||||
class VoiceChannelForTesting : public cricket::VoiceChannel {
|
||||
public:
|
||||
VoiceChannelForTesting(
|
||||
rtc::Thread* worker_thread,
|
||||
rtc::Thread* network_thread,
|
||||
rtc::Thread* signaling_thread,
|
||||
std::unique_ptr<cricket::VoiceMediaSendChannelInterface> send_channel,
|
||||
std::unique_ptr<cricket::VoiceMediaReceiveChannelInterface>
|
||||
receive_channel,
|
||||
const std::string& content_name,
|
||||
bool srtp_required,
|
||||
CryptoOptions crypto_options,
|
||||
rtc::UniqueRandomIdGenerator* ssrc_generator,
|
||||
std::string transport_name)
|
||||
: VoiceChannel(worker_thread,
|
||||
network_thread,
|
||||
signaling_thread,
|
||||
std::move(send_channel),
|
||||
std::move(receive_channel),
|
||||
content_name,
|
||||
srtp_required,
|
||||
std::move(crypto_options),
|
||||
ssrc_generator),
|
||||
test_transport_name_(std::move(transport_name)) {}
|
||||
|
||||
private:
|
||||
absl::string_view transport_name() const override {
|
||||
return test_transport_name_;
|
||||
}
|
||||
|
||||
const std::string test_transport_name_;
|
||||
};
|
||||
|
||||
class VideoChannelForTesting : public cricket::VideoChannel {
|
||||
public:
|
||||
VideoChannelForTesting(
|
||||
rtc::Thread* worker_thread,
|
||||
rtc::Thread* network_thread,
|
||||
rtc::Thread* signaling_thread,
|
||||
std::unique_ptr<cricket::VideoMediaSendChannelInterface> send_channel,
|
||||
std::unique_ptr<cricket::VideoMediaReceiveChannelInterface>
|
||||
receive_channel,
|
||||
const std::string& content_name,
|
||||
bool srtp_required,
|
||||
CryptoOptions crypto_options,
|
||||
rtc::UniqueRandomIdGenerator* ssrc_generator,
|
||||
std::string transport_name)
|
||||
: VideoChannel(worker_thread,
|
||||
network_thread,
|
||||
signaling_thread,
|
||||
std::move(send_channel),
|
||||
std::move(receive_channel),
|
||||
content_name,
|
||||
srtp_required,
|
||||
std::move(crypto_options),
|
||||
ssrc_generator),
|
||||
test_transport_name_(std::move(transport_name)) {}
|
||||
|
||||
private:
|
||||
absl::string_view transport_name() const override {
|
||||
return test_transport_name_;
|
||||
}
|
||||
|
||||
const std::string test_transport_name_;
|
||||
};
|
||||
|
||||
// This class is intended to be fed into the StatsCollector and
|
||||
// RTCStatsCollector so that the stats functionality can be unit tested.
|
||||
// Individual tests can configure this fake as needed to simulate scenarios
|
||||
// under which to test the stats collectors.
|
||||
class FakePeerConnectionForStats : public FakePeerConnectionBase {
|
||||
public:
|
||||
// TODO(steveanton): Add support for specifying separate threads to test
|
||||
// multi-threading correctness.
|
||||
FakePeerConnectionForStats()
|
||||
: network_thread_(rtc::Thread::Current()),
|
||||
worker_thread_(rtc::Thread::Current()),
|
||||
signaling_thread_(rtc::Thread::Current()),
|
||||
// TODO(hta): remove separate thread variables and use context.
|
||||
dependencies_(MakeDependencies()),
|
||||
context_(
|
||||
ConnectionContext::Create(CreateEnvironment(), &dependencies_)),
|
||||
local_streams_(StreamCollection::Create()),
|
||||
remote_streams_(StreamCollection::Create()),
|
||||
data_channel_controller_(network_thread_) {}
|
||||
|
||||
~FakePeerConnectionForStats() {
|
||||
for (auto transceiver : transceivers_) {
|
||||
transceiver->internal()->ClearChannel();
|
||||
}
|
||||
}
|
||||
|
||||
static PeerConnectionFactoryDependencies MakeDependencies() {
|
||||
PeerConnectionFactoryDependencies dependencies;
|
||||
dependencies.network_thread = rtc::Thread::Current();
|
||||
dependencies.worker_thread = rtc::Thread::Current();
|
||||
dependencies.signaling_thread = rtc::Thread::Current();
|
||||
EnableFakeMedia(dependencies);
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<StreamCollection> mutable_local_streams() {
|
||||
return local_streams_;
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<StreamCollection> mutable_remote_streams() {
|
||||
return remote_streams_;
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<RtpSenderInterface> AddSender(
|
||||
rtc::scoped_refptr<RtpSenderInternal> sender) {
|
||||
// TODO(steveanton): Switch tests to use RtpTransceivers directly.
|
||||
auto sender_proxy = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
|
||||
signaling_thread_, sender);
|
||||
GetOrCreateFirstTransceiverOfType(sender->media_type())
|
||||
->internal()
|
||||
->AddSender(sender_proxy);
|
||||
return sender_proxy;
|
||||
}
|
||||
|
||||
void RemoveSender(rtc::scoped_refptr<RtpSenderInterface> sender) {
|
||||
GetOrCreateFirstTransceiverOfType(sender->media_type())
|
||||
->internal()
|
||||
->RemoveSender(sender.get());
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<RtpReceiverInterface> AddReceiver(
|
||||
rtc::scoped_refptr<RtpReceiverInternal> receiver) {
|
||||
// TODO(steveanton): Switch tests to use RtpTransceivers directly.
|
||||
auto receiver_proxy =
|
||||
RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
|
||||
signaling_thread_, worker_thread_, receiver);
|
||||
GetOrCreateFirstTransceiverOfType(receiver->media_type())
|
||||
->internal()
|
||||
->AddReceiver(receiver_proxy);
|
||||
return receiver_proxy;
|
||||
}
|
||||
|
||||
void RemoveReceiver(rtc::scoped_refptr<RtpReceiverInterface> receiver) {
|
||||
GetOrCreateFirstTransceiverOfType(receiver->media_type())
|
||||
->internal()
|
||||
->RemoveReceiver(receiver.get());
|
||||
}
|
||||
|
||||
std::pair<FakeVoiceMediaSendChannelForStats*,
|
||||
FakeVoiceMediaReceiveChannelForStats*>
|
||||
AddVoiceChannel(
|
||||
const std::string& mid,
|
||||
const std::string& transport_name,
|
||||
cricket::VoiceMediaInfo initial_stats = cricket::VoiceMediaInfo()) {
|
||||
auto voice_media_send_channel =
|
||||
std::make_unique<FakeVoiceMediaSendChannelForStats>(network_thread_);
|
||||
auto voice_media_receive_channel =
|
||||
std::make_unique<FakeVoiceMediaReceiveChannelForStats>(network_thread_);
|
||||
auto* voice_media_send_channel_ptr = voice_media_send_channel.get();
|
||||
auto* voice_media_receive_channel_ptr = voice_media_receive_channel.get();
|
||||
auto voice_channel = std::make_unique<VoiceChannelForTesting>(
|
||||
worker_thread_, network_thread_, signaling_thread_,
|
||||
std::move(voice_media_send_channel),
|
||||
std::move(voice_media_receive_channel), mid, kDefaultSrtpRequired,
|
||||
CryptoOptions(), context_->ssrc_generator(), transport_name);
|
||||
auto transceiver =
|
||||
GetOrCreateFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
|
||||
->internal();
|
||||
if (transceiver->channel()) {
|
||||
// This transceiver already has a channel, create a new one.
|
||||
transceiver =
|
||||
CreateTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)->internal();
|
||||
}
|
||||
RTC_DCHECK(!transceiver->channel());
|
||||
transceiver->SetChannel(std::move(voice_channel),
|
||||
[](const std::string&) { return nullptr; });
|
||||
voice_media_send_channel_ptr->SetStats(initial_stats);
|
||||
voice_media_receive_channel_ptr->SetStats(initial_stats);
|
||||
return std::make_pair(voice_media_send_channel_ptr,
|
||||
voice_media_receive_channel_ptr);
|
||||
}
|
||||
|
||||
std::pair<FakeVideoMediaSendChannelForStats*,
|
||||
FakeVideoMediaReceiveChannelForStats*>
|
||||
AddVideoChannel(
|
||||
const std::string& mid,
|
||||
const std::string& transport_name,
|
||||
cricket::VideoMediaInfo initial_stats = cricket::VideoMediaInfo()) {
|
||||
auto video_media_send_channel =
|
||||
std::make_unique<FakeVideoMediaSendChannelForStats>(network_thread_);
|
||||
auto video_media_receive_channel =
|
||||
std::make_unique<FakeVideoMediaReceiveChannelForStats>(network_thread_);
|
||||
auto video_media_send_channel_ptr = video_media_send_channel.get();
|
||||
auto video_media_receive_channel_ptr = video_media_receive_channel.get();
|
||||
auto video_channel = std::make_unique<VideoChannelForTesting>(
|
||||
worker_thread_, network_thread_, signaling_thread_,
|
||||
std::move(video_media_send_channel),
|
||||
std::move(video_media_receive_channel), mid, kDefaultSrtpRequired,
|
||||
CryptoOptions(), context_->ssrc_generator(), transport_name);
|
||||
auto transceiver =
|
||||
GetOrCreateFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
|
||||
->internal();
|
||||
if (transceiver->channel()) {
|
||||
// This transceiver already has a channel, create a new one.
|
||||
transceiver =
|
||||
CreateTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)->internal();
|
||||
}
|
||||
RTC_DCHECK(!transceiver->channel());
|
||||
transceiver->SetChannel(std::move(video_channel),
|
||||
[](const std::string&) { return nullptr; });
|
||||
video_media_send_channel_ptr->SetStats(initial_stats);
|
||||
video_media_receive_channel_ptr->SetStats(initial_stats);
|
||||
return std::make_pair(video_media_send_channel_ptr,
|
||||
video_media_receive_channel_ptr);
|
||||
}
|
||||
|
||||
void AddSctpDataChannel(const std::string& label) {
|
||||
AddSctpDataChannel(label, InternalDataChannelInit());
|
||||
}
|
||||
|
||||
void AddSctpDataChannel(const std::string& label,
|
||||
const InternalDataChannelInit& init) {
|
||||
// TODO(bugs.webrtc.org/11547): Supply a separate network thread.
|
||||
AddSctpDataChannel(SctpDataChannel::Create(
|
||||
data_channel_controller_.weak_ptr(), label, false, init,
|
||||
rtc::Thread::Current(), rtc::Thread::Current()));
|
||||
}
|
||||
|
||||
void AddSctpDataChannel(rtc::scoped_refptr<SctpDataChannel> data_channel) {
|
||||
sctp_data_channels_.push_back(data_channel);
|
||||
}
|
||||
|
||||
void SetTransportStats(const std::string& transport_name,
|
||||
const cricket::TransportChannelStats& channel_stats) {
|
||||
SetTransportStats(
|
||||
transport_name,
|
||||
std::vector<cricket::TransportChannelStats>{channel_stats});
|
||||
}
|
||||
|
||||
void SetTransportStats(
|
||||
const std::string& transport_name,
|
||||
const std::vector<cricket::TransportChannelStats>& channel_stats_list) {
|
||||
cricket::TransportStats transport_stats;
|
||||
transport_stats.transport_name = transport_name;
|
||||
transport_stats.channel_stats = channel_stats_list;
|
||||
transport_stats_by_name_[transport_name] = transport_stats;
|
||||
}
|
||||
|
||||
void SetCallStats(const Call::Stats& call_stats) { call_stats_ = call_stats; }
|
||||
|
||||
void SetAudioDeviceStats(
|
||||
absl::optional<AudioDeviceModule::Stats> audio_device_stats) {
|
||||
audio_device_stats_ = audio_device_stats;
|
||||
}
|
||||
|
||||
void SetLocalCertificate(
|
||||
const std::string& transport_name,
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> certificate) {
|
||||
local_certificates_by_transport_[transport_name] = certificate;
|
||||
}
|
||||
|
||||
void SetRemoteCertChain(const std::string& transport_name,
|
||||
std::unique_ptr<rtc::SSLCertChain> chain) {
|
||||
remote_cert_chains_by_transport_[transport_name] = std::move(chain);
|
||||
}
|
||||
|
||||
// PeerConnectionInterface overrides.
|
||||
|
||||
rtc::scoped_refptr<StreamCollectionInterface> local_streams() override {
|
||||
return local_streams_;
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<StreamCollectionInterface> remote_streams() override {
|
||||
return remote_streams_;
|
||||
}
|
||||
|
||||
std::vector<rtc::scoped_refptr<RtpSenderInterface>> GetSenders()
|
||||
const override {
|
||||
std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders;
|
||||
for (auto transceiver : transceivers_) {
|
||||
for (auto sender : transceiver->internal()->senders()) {
|
||||
senders.push_back(sender);
|
||||
}
|
||||
}
|
||||
return senders;
|
||||
}
|
||||
|
||||
std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceivers()
|
||||
const override {
|
||||
std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
|
||||
for (auto transceiver : transceivers_) {
|
||||
for (auto receiver : transceiver->internal()->receivers()) {
|
||||
receivers.push_back(receiver);
|
||||
}
|
||||
}
|
||||
return receivers;
|
||||
}
|
||||
|
||||
// PeerConnectionInternal overrides.
|
||||
|
||||
rtc::Thread* network_thread() const override { return network_thread_; }
|
||||
|
||||
rtc::Thread* worker_thread() const override { return worker_thread_; }
|
||||
|
||||
rtc::Thread* signaling_thread() const override { return signaling_thread_; }
|
||||
|
||||
std::vector<
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
|
||||
GetTransceiversInternal() const override {
|
||||
return transceivers_;
|
||||
}
|
||||
|
||||
std::vector<DataChannelStats> GetDataChannelStats() const override {
|
||||
RTC_DCHECK_RUN_ON(signaling_thread());
|
||||
std::vector<DataChannelStats> stats;
|
||||
for (const auto& channel : sctp_data_channels_)
|
||||
stats.push_back(channel->GetStats());
|
||||
return stats;
|
||||
}
|
||||
|
||||
cricket::CandidateStatsList GetPooledCandidateStats() const override {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::map<std::string, cricket::TransportStats> GetTransportStatsByNames(
|
||||
const std::set<std::string>& transport_names) override {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
std::map<std::string, cricket::TransportStats> transport_stats_by_name;
|
||||
for (const std::string& transport_name : transport_names) {
|
||||
transport_stats_by_name[transport_name] =
|
||||
GetTransportStatsByName(transport_name);
|
||||
}
|
||||
return transport_stats_by_name;
|
||||
}
|
||||
|
||||
Call::Stats GetCallStats() override { return call_stats_; }
|
||||
|
||||
absl::optional<AudioDeviceModule::Stats> GetAudioDeviceStats() override {
|
||||
return audio_device_stats_;
|
||||
}
|
||||
|
||||
bool GetLocalCertificate(
|
||||
const std::string& transport_name,
|
||||
rtc::scoped_refptr<rtc::RTCCertificate>* certificate) override {
|
||||
auto it = local_certificates_by_transport_.find(transport_name);
|
||||
if (it != local_certificates_by_transport_.end()) {
|
||||
*certificate = it->second;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain(
|
||||
const std::string& transport_name) override {
|
||||
auto it = remote_cert_chains_by_transport_.find(transport_name);
|
||||
if (it != remote_cert_chains_by_transport_.end()) {
|
||||
return it->second->Clone();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
cricket::TransportStats GetTransportStatsByName(
|
||||
const std::string& transport_name) {
|
||||
auto it = transport_stats_by_name_.find(transport_name);
|
||||
if (it != transport_stats_by_name_.end()) {
|
||||
// If specific transport stats have been specified, return those.
|
||||
return it->second;
|
||||
}
|
||||
// Otherwise, generate some dummy stats.
|
||||
cricket::TransportChannelStats channel_stats;
|
||||
channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
|
||||
cricket::TransportStats transport_stats;
|
||||
transport_stats.transport_name = transport_name;
|
||||
transport_stats.channel_stats.push_back(channel_stats);
|
||||
return transport_stats;
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
|
||||
GetOrCreateFirstTransceiverOfType(cricket::MediaType media_type) {
|
||||
for (auto transceiver : transceivers_) {
|
||||
if (transceiver->internal()->media_type() == media_type) {
|
||||
return transceiver;
|
||||
}
|
||||
}
|
||||
return CreateTransceiverOfType(media_type);
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
|
||||
CreateTransceiverOfType(cricket::MediaType media_type) {
|
||||
auto transceiver = RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
|
||||
signaling_thread_,
|
||||
rtc::make_ref_counted<RtpTransceiver>(media_type, context_.get()));
|
||||
transceivers_.push_back(transceiver);
|
||||
return transceiver;
|
||||
}
|
||||
|
||||
rtc::Thread* const network_thread_;
|
||||
rtc::Thread* const worker_thread_;
|
||||
rtc::Thread* const signaling_thread_;
|
||||
|
||||
PeerConnectionFactoryDependencies dependencies_;
|
||||
rtc::scoped_refptr<ConnectionContext> context_;
|
||||
|
||||
rtc::scoped_refptr<StreamCollection> local_streams_;
|
||||
rtc::scoped_refptr<StreamCollection> remote_streams_;
|
||||
|
||||
std::vector<
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
|
||||
transceivers_;
|
||||
|
||||
FakeDataChannelController data_channel_controller_;
|
||||
|
||||
std::vector<rtc::scoped_refptr<SctpDataChannel>> sctp_data_channels_;
|
||||
|
||||
std::map<std::string, cricket::TransportStats> transport_stats_by_name_;
|
||||
|
||||
Call::Stats call_stats_;
|
||||
|
||||
absl::optional<AudioDeviceModule::Stats> audio_device_stats_;
|
||||
|
||||
std::map<std::string, rtc::scoped_refptr<rtc::RTCCertificate>>
|
||||
local_certificates_by_transport_;
|
||||
std::map<std::string, std::unique_ptr<rtc::SSLCertChain>>
|
||||
remote_cert_chains_by_transport_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_FAKE_PEER_CONNECTION_FOR_STATS_H_
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_FAKE_PERIODIC_VIDEO_SOURCE_H_
|
||||
#define PC_TEST_FAKE_PERIODIC_VIDEO_SOURCE_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "api/video/video_source_interface.h"
|
||||
#include "media/base/fake_frame_source.h"
|
||||
#include "media/base/video_broadcaster.h"
|
||||
#include "rtc_base/synchronization/mutex.h"
|
||||
#include "rtc_base/task_queue_for_test.h"
|
||||
#include "rtc_base/task_utils/repeating_task.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class FakePeriodicVideoSource final
|
||||
: public rtc::VideoSourceInterface<VideoFrame> {
|
||||
public:
|
||||
static constexpr int kDefaultFrameIntervalMs = 33;
|
||||
static constexpr int kDefaultWidth = 640;
|
||||
static constexpr int kDefaultHeight = 480;
|
||||
|
||||
struct Config {
|
||||
int width = kDefaultWidth;
|
||||
int height = kDefaultHeight;
|
||||
int frame_interval_ms = kDefaultFrameIntervalMs;
|
||||
VideoRotation rotation = kVideoRotation_0;
|
||||
int64_t timestamp_offset_ms = 0;
|
||||
};
|
||||
|
||||
FakePeriodicVideoSource() : FakePeriodicVideoSource(Config()) {}
|
||||
explicit FakePeriodicVideoSource(Config config)
|
||||
: frame_source_(
|
||||
config.width,
|
||||
config.height,
|
||||
config.frame_interval_ms * rtc::kNumMicrosecsPerMillisec,
|
||||
config.timestamp_offset_ms * rtc::kNumMicrosecsPerMillisec),
|
||||
task_queue_(std::make_unique<TaskQueueForTest>(
|
||||
"FakePeriodicVideoTrackSource")) {
|
||||
frame_source_.SetRotation(config.rotation);
|
||||
|
||||
TimeDelta frame_interval = TimeDelta::Millis(config.frame_interval_ms);
|
||||
repeating_task_handle_ =
|
||||
RepeatingTaskHandle::Start(task_queue_->Get(), [this, frame_interval] {
|
||||
if (broadcaster_.wants().rotation_applied) {
|
||||
broadcaster_.OnFrame(frame_source_.GetFrameRotationApplied());
|
||||
} else {
|
||||
broadcaster_.OnFrame(frame_source_.GetFrame());
|
||||
}
|
||||
return frame_interval;
|
||||
});
|
||||
}
|
||||
|
||||
rtc::VideoSinkWants wants() const {
|
||||
MutexLock lock(&mutex_);
|
||||
return wants_;
|
||||
}
|
||||
|
||||
void RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) override {
|
||||
RTC_DCHECK(thread_checker_.IsCurrent());
|
||||
broadcaster_.RemoveSink(sink);
|
||||
}
|
||||
|
||||
void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
|
||||
const rtc::VideoSinkWants& wants) override {
|
||||
RTC_DCHECK(thread_checker_.IsCurrent());
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
wants_ = wants;
|
||||
}
|
||||
broadcaster_.AddOrUpdateSink(sink, wants);
|
||||
}
|
||||
|
||||
void Stop() {
|
||||
RTC_DCHECK(task_queue_);
|
||||
task_queue_->SendTask([&]() { repeating_task_handle_.Stop(); });
|
||||
task_queue_.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
SequenceChecker thread_checker_{SequenceChecker::kDetached};
|
||||
|
||||
rtc::VideoBroadcaster broadcaster_;
|
||||
cricket::FakeFrameSource frame_source_;
|
||||
mutable Mutex mutex_;
|
||||
rtc::VideoSinkWants wants_ RTC_GUARDED_BY(&mutex_);
|
||||
|
||||
std::unique_ptr<TaskQueueForTest> task_queue_;
|
||||
RepeatingTaskHandle repeating_task_handle_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_FAKE_PERIODIC_VIDEO_SOURCE_H_
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_FAKE_PERIODIC_VIDEO_TRACK_SOURCE_H_
|
||||
#define PC_TEST_FAKE_PERIODIC_VIDEO_TRACK_SOURCE_H_
|
||||
|
||||
#include "pc/test/fake_periodic_video_source.h"
|
||||
#include "pc/video_track_source.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// A VideoTrackSource generating frames with configured size and frame interval.
|
||||
class FakePeriodicVideoTrackSource : public VideoTrackSource {
|
||||
public:
|
||||
explicit FakePeriodicVideoTrackSource(bool remote)
|
||||
: FakePeriodicVideoTrackSource(FakePeriodicVideoSource::Config(),
|
||||
remote) {}
|
||||
|
||||
FakePeriodicVideoTrackSource(FakePeriodicVideoSource::Config config,
|
||||
bool remote)
|
||||
: VideoTrackSource(remote), source_(config) {}
|
||||
|
||||
~FakePeriodicVideoTrackSource() = default;
|
||||
|
||||
FakePeriodicVideoSource& fake_periodic_source() { return source_; }
|
||||
const FakePeriodicVideoSource& fake_periodic_source() const {
|
||||
return source_;
|
||||
}
|
||||
|
||||
protected:
|
||||
rtc::VideoSourceInterface<VideoFrame>* source() override { return &source_; }
|
||||
|
||||
private:
|
||||
FakePeriodicVideoSource source_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_FAKE_PERIODIC_VIDEO_TRACK_SOURCE_H_
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* Copyright 2013 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_FAKE_RTC_CERTIFICATE_GENERATOR_H_
|
||||
#define PC_TEST_FAKE_RTC_CERTIFICATE_GENERATOR_H_
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/peer_connection_interface.h"
|
||||
#include "api/task_queue/task_queue_base.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "rtc_base/rtc_certificate.h"
|
||||
#include "rtc_base/rtc_certificate_generator.h"
|
||||
|
||||
// RSA with mod size 1024, pub exp 0x10001.
|
||||
static const rtc::RTCCertificatePEM kRsaPems[] = {
|
||||
rtc::RTCCertificatePEM(
|
||||
"-----BEGIN RSA PRIVATE KEY-----\n"
|
||||
"MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMYRkbhmI7kVA/rM\n"
|
||||
"czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n"
|
||||
"rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n"
|
||||
"5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAECgYAvgOs4FJcgvp+TuREx7YtiYVsH\n"
|
||||
"mwQPTum2z/8VzWGwR8BBHBvIpVe1MbD/Y4seyI2aco/7UaisatSgJhsU46/9Y4fq\n"
|
||||
"2TwXH9QANf4at4d9n/R6rzwpAJOpgwZgKvdQjkfrKTtgLV+/dawvpxUYkRH4JZM1\n"
|
||||
"CVGukMfKNrSVH4Ap4QJBAOJmGV1ASPnB4r4nc99at7JuIJmd7fmuVUwUgYi4XgaR\n"
|
||||
"WhScBsgYwZ/JoywdyZJgnbcrTDuVcWG56B3vXbhdpMsCQQDf9zeJrjnPZ3Cqm79y\n"
|
||||
"kdqANep0uwZciiNiWxsQrCHztywOvbFhdp8iYVFG9EK8DMY41Y5TxUwsHD+67zao\n"
|
||||
"ZNqJAkEA1suLUP/GvL8IwuRneQd2tWDqqRQ/Td3qq03hP7e77XtF/buya3Ghclo5\n"
|
||||
"54czUR89QyVfJEC6278nzA7n2h1uVQJAcG6mztNL6ja/dKZjYZye2CY44QjSlLo0\n"
|
||||
"MTgTSjdfg/28fFn2Jjtqf9Pi/X+50LWI/RcYMC2no606wRk9kyOuIQJBAK6VSAim\n"
|
||||
"1pOEjsYQn0X5KEIrz1G3bfCbB848Ime3U2/FWlCHMr6ch8kCZ5d1WUeJD3LbwMNG\n"
|
||||
"UCXiYxSsu20QNVw=\n"
|
||||
"-----END RSA PRIVATE KEY-----\n",
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBmTCCAQKgAwIBAgIEbzBSAjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDEwZX\n"
|
||||
"ZWJSVEMwHhcNMTQwMTAyMTgyNDQ3WhcNMTQwMjAxMTgyNDQ3WjARMQ8wDQYDVQQD\n"
|
||||
"EwZXZWJSVEMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYRkbhmI7kVA/rM\n"
|
||||
"czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n"
|
||||
"rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n"
|
||||
"5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAEwDQYJKoZIhvcNAQELBQADgYEAUflI\n"
|
||||
"VUe5Krqf5RVa5C3u/UTAOAUJBiDS3VANTCLBxjuMsvqOG0WvaYWP3HYPgrz0jXK2\n"
|
||||
"LJE/mGw3MyFHEqi81jh95J+ypl6xKW6Rm8jKLR87gUvCaVYn/Z4/P3AqcQTB7wOv\n"
|
||||
"UD0A8qfhfDM+LK6rPAnCsVN0NRDY3jvd6rzix9M=\n"
|
||||
"-----END CERTIFICATE-----\n"),
|
||||
rtc::RTCCertificatePEM(
|
||||
"-----BEGIN RSA PRIVATE KEY-----\n"
|
||||
"MIICXQIBAAKBgQDeYqlyJ1wuiMsi905e3X81/WA/G3ym50PIDZBVtSwZi7JVQPgj\n"
|
||||
"Bl8CPZMvDh9EwB4Ji9ytA8dZZbQ4WbJWPr73zPpJSCvQqz6sOXSlenBRi72acNaQ\n"
|
||||
"sOR/qPvviJx5I6Hqo4qemfnjZhAW85a5BpgrAwKgMLIQTHCTLWwVSyrDrwIDAQAB\n"
|
||||
"AoGARni9eY8/hv+SX+I+05EdXt6MQXNUbQ+cSykBNCfVccLzIFEWUQMT2IHqwl6X\n"
|
||||
"ShIXcq7/n1QzOAEiuzixauM3YHg4xZ1Um2Ha9a7ig5Xg4v6b43bmMkNE6LkoAtYs\n"
|
||||
"qnQdfMh442b1liDud6IMb1Qk0amt3fSrgRMc547TZQVx4QECQQDxUeDm94r3p4ng\n"
|
||||
"5rCLLC1K5/6HSTZsh7jatKPlz7GfP/IZlYV7iE5784/n0wRiCjZOS7hQRy/8m2Gp\n"
|
||||
"pf4aZq+DAkEA6+np4d36FYikydvUrupLT3FkdRHGn/v83qOll/VmeNh+L1xMZlIP\n"
|
||||
"tM26hAXCcQb7O5+J9y3cx2CAQsBS11ZXZQJAfGgTo76WG9p5UEJdXUInD2jOZPwv\n"
|
||||
"XIATolxh6kXKcijLLLlSmT7KB0inNYIpzkkpee+7U1d/u6B3FriGaSHq9QJBAM/J\n"
|
||||
"ICnDdLCgwNvWVraVQC3BpwSB2pswvCFwq7py94V60XFvbw80Ogc6qIv98qvQxVlX\n"
|
||||
"hJIEgA/PjEi+0ng94Q0CQQDm8XSDby35gmjO+6eRmJtAjtB7nguLvrPXM6CPXRmD\n"
|
||||
"sRoBocpHw6j9UdzZ6qYG0FkdXZghezXFY58ro2BYYRR3\n"
|
||||
"-----END RSA PRIVATE KEY-----\n",
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICWDCCAcGgAwIBAgIJALgDjxMbBOhbMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV\n"
|
||||
"BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
|
||||
"aWRnaXRzIFB0eSBMdGQwHhcNMTUxMTEzMjIzMjEzWhcNMTYxMTEyMjIzMjEzWjBF\n"
|
||||
"MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
|
||||
"ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
|
||||
"gQDeYqlyJ1wuiMsi905e3X81/WA/G3ym50PIDZBVtSwZi7JVQPgjBl8CPZMvDh9E\n"
|
||||
"wB4Ji9ytA8dZZbQ4WbJWPr73zPpJSCvQqz6sOXSlenBRi72acNaQsOR/qPvviJx5\n"
|
||||
"I6Hqo4qemfnjZhAW85a5BpgrAwKgMLIQTHCTLWwVSyrDrwIDAQABo1AwTjAdBgNV\n"
|
||||
"HQ4EFgQUx2tbJdlcSTCepn09UdYORXKuSTAwHwYDVR0jBBgwFoAUx2tbJdlcSTCe\n"
|
||||
"pn09UdYORXKuSTAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQAmp9Id\n"
|
||||
"E716gHMqeBG4S2FCgVFCr0a0ugkaneQAN/c2L9CbMemEN9W6jvucUIVOtYd90dDW\n"
|
||||
"lXuowWmT/JctPe3D2qt4yvYW3puECHk2tVQmrJOZiZiTRtWm6HxkmoUYHYp/DtaS\n"
|
||||
"1Xe29gSTnZtI5sQCrGMzk3SGRSSs7ejLKiVDBQ==\n"
|
||||
"-----END CERTIFICATE-----\n")};
|
||||
|
||||
// ECDSA with EC_NIST_P256.
|
||||
// These PEM strings were created by generating an identity with
|
||||
// `SSLIdentity::Create` and invoking `identity->PrivateKeyToPEMString()`,
|
||||
// `identity->PublicKeyToPEMString()` and
|
||||
// `identity->certificate().ToPEMString()`.
|
||||
static const rtc::RTCCertificatePEM kEcdsaPems[] = {
|
||||
rtc::RTCCertificatePEM(
|
||||
"-----BEGIN PRIVATE KEY-----\n"
|
||||
"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg+qaRsR5uHtqG689M\n"
|
||||
"A3PHSJNeVpyi5wUKCft62h0UWy+hRANCAAS5Mjc85q9fVq4ln+zOPlaEC/Rzj5Pb\n"
|
||||
"MVZtf1x/8k2KsbmyZoAMDX2yer/atEuXmItMe3yd6/DXnvboU//D3Lyt\n"
|
||||
"-----END PRIVATE KEY-----\n",
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBFTCBu6ADAgECAgkA30tGY5XG7oowCgYIKoZIzj0EAwIwEDEOMAwGA1UEAwwF\n"
|
||||
"dGVzdDMwHhcNMTYwNTA5MDkxODA4WhcNMTYwNjA5MDkxODA4WjAQMQ4wDAYDVQQD\n"
|
||||
"DAV0ZXN0MzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLkyNzzmr19WriWf7M4+\n"
|
||||
"VoQL9HOPk9sxVm1/XH/yTYqxubJmgAwNfbJ6v9q0S5eYi0x7fJ3r8Nee9uhT/8Pc\n"
|
||||
"vK0wCgYIKoZIzj0EAwIDSQAwRgIhAIIc3+CqfkZ9lLwTj1PvUtt3KhnqF2kD0War\n"
|
||||
"cCoTBbCxAiEAyp9Cn4vo2ZBhRIVDKyoxmwak8Z0PAVhJAQaWCgoY2D4=\n"
|
||||
"-----END CERTIFICATE-----\n"),
|
||||
rtc::RTCCertificatePEM(
|
||||
"-----BEGIN PRIVATE KEY-----\n"
|
||||
"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQghL/G4JRYnuDNbQuh\n"
|
||||
"LqkytcE39Alsq6FItDVFgOesfCmhRANCAATd53FjPLyVUcwYguEPbSJM03fP6Rx5\n"
|
||||
"GY1dEZ00+ZykjJI83VfDAyvmpRuGahNtBH0hc+7xkDCbeo6TM0tN35xr\n"
|
||||
"-----END PRIVATE KEY-----\n",
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBFDCBu6ADAgECAgkArZYdXMyJ5rswCgYIKoZIzj0EAwIwEDEOMAwGA1UEAwwF\n"
|
||||
"dGVzdDQwHhcNMTYwNTA5MDkxODA4WhcNMTYwNjA5MDkxODA4WjAQMQ4wDAYDVQQD\n"
|
||||
"DAV0ZXN0NDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABN3ncWM8vJVRzBiC4Q9t\n"
|
||||
"IkzTd8/pHHkZjV0RnTT5nKSMkjzdV8MDK+alG4ZqE20EfSFz7vGQMJt6jpMzS03f\n"
|
||||
"nGswCgYIKoZIzj0EAwIDSAAwRQIgb/LBc8OtsC5lEDyjCP6M9xt5mwzUNrQBOFWZ\n"
|
||||
"1fE/g68CIQD7uoFfbiq6dTp8ZwzbwQ8jJf08KjriamqA9OW/4268Dw==\n"
|
||||
"-----END CERTIFICATE-----\n")};
|
||||
|
||||
class FakeRTCCertificateGenerator
|
||||
: public rtc::RTCCertificateGeneratorInterface {
|
||||
public:
|
||||
FakeRTCCertificateGenerator() : should_fail_(false), should_wait_(false) {}
|
||||
|
||||
void set_should_fail(bool should_fail) { should_fail_ = should_fail; }
|
||||
|
||||
// If set to true, stalls the generation of the fake certificate until it is
|
||||
// set to false.
|
||||
void set_should_wait(bool should_wait) { should_wait_ = should_wait; }
|
||||
|
||||
void use_original_key() { key_index_ = 0; }
|
||||
void use_alternate_key() { key_index_ = 1; }
|
||||
|
||||
int generated_certificates() { return generated_certificates_; }
|
||||
int generated_failures() { return generated_failures_; }
|
||||
|
||||
void GenerateCertificateAsync(const rtc::KeyParams& key_params,
|
||||
const absl::optional<uint64_t>& expires_ms,
|
||||
Callback callback) override {
|
||||
// The certificates are created from constant PEM strings and use its coded
|
||||
// expiration time, we do not support modifying it.
|
||||
RTC_DCHECK(!expires_ms);
|
||||
|
||||
// Only supports RSA-1024-0x10001 and ECDSA-P256.
|
||||
if (key_params.type() == rtc::KT_RSA) {
|
||||
RTC_DCHECK_EQ(key_params.rsa_params().mod_size, 1024);
|
||||
RTC_DCHECK_EQ(key_params.rsa_params().pub_exp, 0x10001);
|
||||
} else {
|
||||
RTC_DCHECK_EQ(key_params.type(), rtc::KT_ECDSA);
|
||||
RTC_DCHECK_EQ(key_params.ec_curve(), rtc::EC_NIST_P256);
|
||||
}
|
||||
rtc::KeyType key_type = key_params.type();
|
||||
webrtc::TaskQueueBase::Current()->PostTask(
|
||||
[this, key_type, callback = std::move(callback)]() mutable {
|
||||
GenerateCertificate(key_type, std::move(callback));
|
||||
});
|
||||
}
|
||||
|
||||
static rtc::scoped_refptr<rtc::RTCCertificate> GenerateCertificate() {
|
||||
switch (rtc::KT_DEFAULT) {
|
||||
case rtc::KT_RSA:
|
||||
return rtc::RTCCertificate::FromPEM(kRsaPems[0]);
|
||||
case rtc::KT_ECDSA:
|
||||
return rtc::RTCCertificate::FromPEM(kEcdsaPems[0]);
|
||||
default:
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const rtc::RTCCertificatePEM& get_pem(const rtc::KeyType& key_type) const {
|
||||
switch (key_type) {
|
||||
case rtc::KT_RSA:
|
||||
return kRsaPems[key_index_];
|
||||
case rtc::KT_ECDSA:
|
||||
return kEcdsaPems[key_index_];
|
||||
default:
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return kEcdsaPems[key_index_];
|
||||
}
|
||||
}
|
||||
const std::string& get_key(const rtc::KeyType& key_type) const {
|
||||
return get_pem(key_type).private_key();
|
||||
}
|
||||
const std::string& get_cert(const rtc::KeyType& key_type) const {
|
||||
return get_pem(key_type).certificate();
|
||||
}
|
||||
|
||||
void GenerateCertificate(rtc::KeyType key_type, Callback callback) {
|
||||
// If the certificate generation should be stalled, re-post this same
|
||||
// message to the queue with a small delay so as to wait in a loop until
|
||||
// set_should_wait(false) is called.
|
||||
if (should_wait_) {
|
||||
webrtc::TaskQueueBase::Current()->PostDelayedTask(
|
||||
[this, key_type, callback = std::move(callback)]() mutable {
|
||||
GenerateCertificate(key_type, std::move(callback));
|
||||
},
|
||||
webrtc::TimeDelta::Millis(1));
|
||||
return;
|
||||
}
|
||||
if (should_fail_) {
|
||||
++generated_failures_;
|
||||
std::move(callback)(nullptr);
|
||||
} else {
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> certificate =
|
||||
rtc::RTCCertificate::FromPEM(get_pem(key_type));
|
||||
RTC_DCHECK(certificate);
|
||||
++generated_certificates_;
|
||||
std::move(callback)(std::move(certificate));
|
||||
}
|
||||
}
|
||||
|
||||
bool should_fail_;
|
||||
bool should_wait_;
|
||||
int key_index_ = 0;
|
||||
int generated_certificates_ = 0;
|
||||
int generated_failures_ = 0;
|
||||
};
|
||||
|
||||
#endif // PC_TEST_FAKE_RTC_CERTIFICATE_GENERATOR_H_
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright 2012 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_FAKE_VIDEO_TRACK_RENDERER_H_
|
||||
#define PC_TEST_FAKE_VIDEO_TRACK_RENDERER_H_
|
||||
|
||||
#include "api/media_stream_interface.h"
|
||||
#include "media/base/fake_video_renderer.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class FakeVideoTrackRenderer : public cricket::FakeVideoRenderer {
|
||||
public:
|
||||
explicit FakeVideoTrackRenderer(VideoTrackInterface* video_track)
|
||||
: video_track_(video_track) {
|
||||
video_track_->AddOrUpdateSink(this, rtc::VideoSinkWants());
|
||||
}
|
||||
~FakeVideoTrackRenderer() { video_track_->RemoveSink(this); }
|
||||
|
||||
private:
|
||||
rtc::scoped_refptr<VideoTrackInterface> video_track_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_FAKE_VIDEO_TRACK_RENDERER_H_
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2016 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_FAKE_VIDEO_TRACK_SOURCE_H_
|
||||
#define PC_TEST_FAKE_VIDEO_TRACK_SOURCE_H_
|
||||
|
||||
#include "api/media_stream_interface.h"
|
||||
#include "media/base/video_broadcaster.h"
|
||||
#include "pc/video_track_source.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// A minimal implementation of VideoTrackSource. Includes a VideoBroadcaster for
|
||||
// injection of frames.
|
||||
class FakeVideoTrackSource : public VideoTrackSource {
|
||||
public:
|
||||
static rtc::scoped_refptr<FakeVideoTrackSource> Create(bool is_screencast) {
|
||||
return rtc::make_ref_counted<FakeVideoTrackSource>(is_screencast);
|
||||
}
|
||||
|
||||
static rtc::scoped_refptr<FakeVideoTrackSource> Create() {
|
||||
return Create(false);
|
||||
}
|
||||
|
||||
bool is_screencast() const override { return is_screencast_; }
|
||||
|
||||
void InjectFrame(const VideoFrame& frame) {
|
||||
video_broadcaster_.OnFrame(frame);
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit FakeVideoTrackSource(bool is_screencast)
|
||||
: VideoTrackSource(false /* remote */), is_screencast_(is_screencast) {}
|
||||
~FakeVideoTrackSource() override = default;
|
||||
|
||||
rtc::VideoSourceInterface<VideoFrame>* source() override {
|
||||
return &video_broadcaster_;
|
||||
}
|
||||
|
||||
private:
|
||||
const bool is_screencast_;
|
||||
rtc::VideoBroadcaster video_broadcaster_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_FAKE_VIDEO_TRACK_SOURCE_H_
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_FRAME_GENERATOR_CAPTURER_VIDEO_TRACK_SOURCE_H_
|
||||
#define PC_TEST_FRAME_GENERATOR_CAPTURER_VIDEO_TRACK_SOURCE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "api/task_queue/default_task_queue_factory.h"
|
||||
#include "api/task_queue/task_queue_factory.h"
|
||||
#include "api/test/create_frame_generator.h"
|
||||
#include "pc/video_track_source.h"
|
||||
#include "test/frame_generator_capturer.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Implements a VideoTrackSourceInterface to be used for creating VideoTracks.
|
||||
// The video source is generated using a FrameGeneratorCapturer, specifically
|
||||
// a SquareGenerator that generates frames with randomly sized and colored
|
||||
// squares.
|
||||
class FrameGeneratorCapturerVideoTrackSource : public VideoTrackSource {
|
||||
public:
|
||||
static const int kDefaultFramesPerSecond = 30;
|
||||
static const int kDefaultWidth = 640;
|
||||
static const int kDefaultHeight = 480;
|
||||
static const int kNumSquaresGenerated = 50;
|
||||
|
||||
struct Config {
|
||||
int frames_per_second = kDefaultFramesPerSecond;
|
||||
int width = kDefaultWidth;
|
||||
int height = kDefaultHeight;
|
||||
int num_squares_generated = 50;
|
||||
};
|
||||
|
||||
FrameGeneratorCapturerVideoTrackSource(Config config,
|
||||
Clock* clock,
|
||||
bool is_screencast)
|
||||
: VideoTrackSource(false /* remote */),
|
||||
task_queue_factory_(CreateDefaultTaskQueueFactory()),
|
||||
is_screencast_(is_screencast) {
|
||||
video_capturer_ = std::make_unique<test::FrameGeneratorCapturer>(
|
||||
clock,
|
||||
test::CreateSquareFrameGenerator(config.width, config.height,
|
||||
absl::nullopt,
|
||||
config.num_squares_generated),
|
||||
config.frames_per_second, *task_queue_factory_);
|
||||
video_capturer_->Init();
|
||||
}
|
||||
|
||||
FrameGeneratorCapturerVideoTrackSource(
|
||||
std::unique_ptr<test::FrameGeneratorCapturer> video_capturer,
|
||||
bool is_screencast)
|
||||
: VideoTrackSource(false /* remote */),
|
||||
video_capturer_(std::move(video_capturer)),
|
||||
is_screencast_(is_screencast) {}
|
||||
|
||||
~FrameGeneratorCapturerVideoTrackSource() = default;
|
||||
|
||||
void Start() {
|
||||
SetState(kLive);
|
||||
video_capturer_->Start();
|
||||
}
|
||||
|
||||
void Stop() {
|
||||
SetState(kMuted);
|
||||
video_capturer_->Stop();
|
||||
}
|
||||
|
||||
bool is_screencast() const override { return is_screencast_; }
|
||||
|
||||
protected:
|
||||
rtc::VideoSourceInterface<VideoFrame>* source() override {
|
||||
return video_capturer_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
|
||||
std::unique_ptr<test::FrameGeneratorCapturer> video_capturer_;
|
||||
const bool is_screencast_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_FRAME_GENERATOR_CAPTURER_VIDEO_TRACK_SOURCE_H_
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright 2012 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 "pc/test/integration_test_helpers.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions() {
|
||||
PeerConnectionInterface::RTCOfferAnswerOptions options;
|
||||
options.ice_restart = true;
|
||||
return options;
|
||||
}
|
||||
|
||||
void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) {
|
||||
for (ContentInfo& content : desc->contents()) {
|
||||
content.media_description()->mutable_streams().clear();
|
||||
}
|
||||
desc->set_msid_signaling(0);
|
||||
}
|
||||
|
||||
void RemoveSsrcsAndKeepMsids(cricket::SessionDescription* desc) {
|
||||
for (ContentInfo& content : desc->contents()) {
|
||||
std::string track_id;
|
||||
std::vector<std::string> stream_ids;
|
||||
if (!content.media_description()->streams().empty()) {
|
||||
const StreamParams& first_stream =
|
||||
content.media_description()->streams()[0];
|
||||
track_id = first_stream.id;
|
||||
stream_ids = first_stream.stream_ids();
|
||||
}
|
||||
content.media_description()->mutable_streams().clear();
|
||||
StreamParams new_stream;
|
||||
new_stream.id = track_id;
|
||||
new_stream.set_stream_ids(stream_ids);
|
||||
content.media_description()->AddStream(new_stream);
|
||||
}
|
||||
}
|
||||
|
||||
int FindFirstMediaStatsIndexByKind(
|
||||
const std::string& kind,
|
||||
const std::vector<const RTCInboundRtpStreamStats*>& inbound_rtps) {
|
||||
for (size_t i = 0; i < inbound_rtps.size(); i++) {
|
||||
if (*inbound_rtps[i]->kind == kind) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ReplaceFirstSsrc(StreamParams& stream, uint32_t ssrc) {
|
||||
stream.ssrcs[0] = ssrc;
|
||||
for (auto& group : stream.ssrc_groups) {
|
||||
group.ssrcs[0] = ssrc;
|
||||
}
|
||||
}
|
||||
|
||||
TaskQueueMetronome::TaskQueueMetronome(TimeDelta tick_period)
|
||||
: tick_period_(tick_period) {}
|
||||
|
||||
TaskQueueMetronome::~TaskQueueMetronome() {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
}
|
||||
void TaskQueueMetronome::RequestCallOnNextTick(
|
||||
absl::AnyInvocable<void() &&> callback) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
callbacks_.push_back(std::move(callback));
|
||||
// Only schedule a tick callback for the first `callback` addition.
|
||||
// Schedule on the current task queue to comply with RequestCallOnNextTick
|
||||
// requirements.
|
||||
if (callbacks_.size() == 1) {
|
||||
TaskQueueBase::Current()->PostDelayedTask(
|
||||
SafeTask(safety_.flag(),
|
||||
[this] {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
std::vector<absl::AnyInvocable<void() &&>> callbacks;
|
||||
callbacks_.swap(callbacks);
|
||||
for (auto& callback : callbacks)
|
||||
std::move(callback)();
|
||||
}),
|
||||
tick_period_);
|
||||
}
|
||||
}
|
||||
|
||||
TimeDelta TaskQueueMetronome::TickPeriod() const {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
return tick_period_;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
1928
TMessagesProj/jni/voip/webrtc/pc/test/integration_test_helpers.h
Normal file
1928
TMessagesProj/jni/voip/webrtc/pc/test/integration_test_helpers.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_MOCK_CHANNEL_INTERFACE_H_
|
||||
#define PC_TEST_MOCK_CHANNEL_INTERFACE_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "media/base/media_channel.h"
|
||||
#include "pc/channel_interface.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
// Mock class for BaseChannel.
|
||||
// Use this class in unit tests to avoid dependecy on a specific
|
||||
// implementation of BaseChannel.
|
||||
class MockChannelInterface : public cricket::ChannelInterface {
|
||||
public:
|
||||
MOCK_METHOD(cricket::MediaType, media_type, (), (const, override));
|
||||
MOCK_METHOD(VideoChannel*, AsVideoChannel, (), (override));
|
||||
MOCK_METHOD(VoiceChannel*, AsVoiceChannel, (), (override));
|
||||
MOCK_METHOD(MediaSendChannelInterface*, media_send_channel, (), (override));
|
||||
MOCK_METHOD(VoiceMediaSendChannelInterface*,
|
||||
voice_media_send_channel,
|
||||
(),
|
||||
(override));
|
||||
MOCK_METHOD(VideoMediaSendChannelInterface*,
|
||||
video_media_send_channel,
|
||||
(),
|
||||
(override));
|
||||
MOCK_METHOD(MediaReceiveChannelInterface*,
|
||||
media_receive_channel,
|
||||
(),
|
||||
(override));
|
||||
MOCK_METHOD(VoiceMediaReceiveChannelInterface*,
|
||||
voice_media_receive_channel,
|
||||
(),
|
||||
(override));
|
||||
MOCK_METHOD(VideoMediaReceiveChannelInterface*,
|
||||
video_media_receive_channel,
|
||||
(),
|
||||
(override));
|
||||
MOCK_METHOD(absl::string_view, transport_name, (), (const, override));
|
||||
MOCK_METHOD(const std::string&, mid, (), (const, override));
|
||||
MOCK_METHOD(void, Enable, (bool), (override));
|
||||
MOCK_METHOD(void,
|
||||
SetFirstPacketReceivedCallback,
|
||||
(std::function<void()>),
|
||||
(override));
|
||||
MOCK_METHOD(bool,
|
||||
SetLocalContent,
|
||||
(const cricket::MediaContentDescription*,
|
||||
webrtc::SdpType,
|
||||
std::string&),
|
||||
(override));
|
||||
MOCK_METHOD(bool,
|
||||
SetRemoteContent,
|
||||
(const cricket::MediaContentDescription*,
|
||||
webrtc::SdpType,
|
||||
std::string&),
|
||||
(override));
|
||||
MOCK_METHOD(bool, SetPayloadTypeDemuxingEnabled, (bool), (override));
|
||||
MOCK_METHOD(const std::vector<StreamParams>&,
|
||||
local_streams,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(const std::vector<StreamParams>&,
|
||||
remote_streams,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(bool,
|
||||
SetRtpTransport,
|
||||
(webrtc::RtpTransportInternal*),
|
||||
(override));
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // PC_TEST_MOCK_CHANNEL_INTERFACE_H_
|
||||
79
TMessagesProj/jni/voip/webrtc/pc/test/mock_data_channel.h
Normal file
79
TMessagesProj/jni/voip/webrtc/pc/test/mock_data_channel.h
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright 2016 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_MOCK_DATA_CHANNEL_H_
|
||||
#define PC_TEST_MOCK_DATA_CHANNEL_H_
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "pc/sctp_data_channel.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class MockSctpDataChannel : public SctpDataChannel {
|
||||
public:
|
||||
MockSctpDataChannel(
|
||||
rtc::WeakPtr<SctpDataChannelControllerInterface> controller,
|
||||
int id,
|
||||
DataState state)
|
||||
: MockSctpDataChannel(std::move(controller),
|
||||
id,
|
||||
"MockSctpDataChannel",
|
||||
state,
|
||||
"someProtocol",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0) {}
|
||||
MockSctpDataChannel(
|
||||
rtc::WeakPtr<SctpDataChannelControllerInterface> controller,
|
||||
int id,
|
||||
const std::string& label,
|
||||
DataState state,
|
||||
const std::string& protocol,
|
||||
uint32_t messages_sent,
|
||||
uint64_t bytes_sent,
|
||||
uint32_t messages_received,
|
||||
uint64_t bytes_received,
|
||||
const InternalDataChannelInit& config = InternalDataChannelInit(),
|
||||
rtc::Thread* signaling_thread = rtc::Thread::Current(),
|
||||
rtc::Thread* network_thread = rtc::Thread::Current())
|
||||
: SctpDataChannel(config,
|
||||
std::move(controller),
|
||||
label,
|
||||
false,
|
||||
signaling_thread,
|
||||
network_thread) {
|
||||
EXPECT_CALL(*this, id()).WillRepeatedly(::testing::Return(id));
|
||||
EXPECT_CALL(*this, state()).WillRepeatedly(::testing::Return(state));
|
||||
EXPECT_CALL(*this, protocol()).WillRepeatedly(::testing::Return(protocol));
|
||||
EXPECT_CALL(*this, messages_sent())
|
||||
.WillRepeatedly(::testing::Return(messages_sent));
|
||||
EXPECT_CALL(*this, bytes_sent())
|
||||
.WillRepeatedly(::testing::Return(bytes_sent));
|
||||
EXPECT_CALL(*this, messages_received())
|
||||
.WillRepeatedly(::testing::Return(messages_received));
|
||||
EXPECT_CALL(*this, bytes_received())
|
||||
.WillRepeatedly(::testing::Return(bytes_received));
|
||||
}
|
||||
MOCK_METHOD(int, id, (), (const, override));
|
||||
MOCK_METHOD(DataState, state, (), (const, override));
|
||||
MOCK_METHOD(std::string, protocol, (), (const, override));
|
||||
MOCK_METHOD(uint32_t, messages_sent, (), (const, override));
|
||||
MOCK_METHOD(uint64_t, bytes_sent, (), (const, override));
|
||||
MOCK_METHOD(uint32_t, messages_received, (), (const, override));
|
||||
MOCK_METHOD(uint64_t, bytes_received, (), (const, override));
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_MOCK_DATA_CHANNEL_H_
|
||||
|
|
@ -0,0 +1,329 @@
|
|||
/*
|
||||
* Copyright 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_MOCK_PEER_CONNECTION_INTERNAL_H_
|
||||
#define PC_TEST_MOCK_PEER_CONNECTION_INTERNAL_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "modules/audio_device/include/audio_device.h"
|
||||
#include "pc/peer_connection_internal.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class MockPeerConnectionInternal : public PeerConnectionInternal {
|
||||
public:
|
||||
MockPeerConnectionInternal() {}
|
||||
~MockPeerConnectionInternal() = default;
|
||||
// PeerConnectionInterface
|
||||
MOCK_METHOD(rtc::scoped_refptr<StreamCollectionInterface>,
|
||||
local_streams,
|
||||
(),
|
||||
(override));
|
||||
MOCK_METHOD(rtc::scoped_refptr<StreamCollectionInterface>,
|
||||
remote_streams,
|
||||
(),
|
||||
(override));
|
||||
MOCK_METHOD(bool, AddStream, (MediaStreamInterface*), (override));
|
||||
MOCK_METHOD(void, RemoveStream, (MediaStreamInterface*), (override));
|
||||
MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>>,
|
||||
AddTrack,
|
||||
(rtc::scoped_refptr<MediaStreamTrackInterface>,
|
||||
const std::vector<std::string>&),
|
||||
(override));
|
||||
MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>>,
|
||||
AddTrack,
|
||||
(rtc::scoped_refptr<MediaStreamTrackInterface>,
|
||||
const std::vector<std::string>&,
|
||||
const std::vector<RtpEncodingParameters>&),
|
||||
(override));
|
||||
MOCK_METHOD(RTCError,
|
||||
RemoveTrackOrError,
|
||||
(rtc::scoped_refptr<RtpSenderInterface>),
|
||||
(override));
|
||||
MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>,
|
||||
AddTransceiver,
|
||||
(rtc::scoped_refptr<MediaStreamTrackInterface>),
|
||||
(override));
|
||||
MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>,
|
||||
AddTransceiver,
|
||||
(rtc::scoped_refptr<MediaStreamTrackInterface>,
|
||||
const RtpTransceiverInit&),
|
||||
(override));
|
||||
MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>,
|
||||
AddTransceiver,
|
||||
(cricket::MediaType),
|
||||
(override));
|
||||
MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>,
|
||||
AddTransceiver,
|
||||
(cricket::MediaType, const RtpTransceiverInit&),
|
||||
(override));
|
||||
MOCK_METHOD(rtc::scoped_refptr<RtpSenderInterface>,
|
||||
CreateSender,
|
||||
(const std::string&, const std::string&),
|
||||
(override));
|
||||
MOCK_METHOD(std::vector<rtc::scoped_refptr<RtpSenderInterface>>,
|
||||
GetSenders,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(std::vector<rtc::scoped_refptr<RtpReceiverInterface>>,
|
||||
GetReceivers,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>,
|
||||
GetTransceivers,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(bool,
|
||||
GetStats,
|
||||
(StatsObserver*, MediaStreamTrackInterface*, StatsOutputLevel),
|
||||
(override));
|
||||
MOCK_METHOD(void, GetStats, (RTCStatsCollectorCallback*), (override));
|
||||
MOCK_METHOD(void,
|
||||
GetStats,
|
||||
(rtc::scoped_refptr<RtpSenderInterface>,
|
||||
rtc::scoped_refptr<RTCStatsCollectorCallback>),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
GetStats,
|
||||
(rtc::scoped_refptr<RtpReceiverInterface>,
|
||||
rtc::scoped_refptr<RTCStatsCollectorCallback>),
|
||||
(override));
|
||||
MOCK_METHOD(void, ClearStatsCache, (), (override));
|
||||
MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<DataChannelInterface>>,
|
||||
CreateDataChannelOrError,
|
||||
(const std::string&, const DataChannelInit*),
|
||||
(override));
|
||||
MOCK_METHOD(SessionDescriptionInterface*,
|
||||
local_description,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(SessionDescriptionInterface*,
|
||||
remote_description,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(SessionDescriptionInterface*,
|
||||
current_local_description,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(SessionDescriptionInterface*,
|
||||
current_remote_description,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(SessionDescriptionInterface*,
|
||||
pending_local_description,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(SessionDescriptionInterface*,
|
||||
pending_remote_description,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(void, RestartIce, (), (override));
|
||||
MOCK_METHOD(void,
|
||||
CreateOffer,
|
||||
(CreateSessionDescriptionObserver*, const RTCOfferAnswerOptions&),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
CreateAnswer,
|
||||
(CreateSessionDescriptionObserver*, const RTCOfferAnswerOptions&),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void,
|
||||
SetLocalDescription,
|
||||
(SetSessionDescriptionObserver*, SessionDescriptionInterface*),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
SetRemoteDescription,
|
||||
(SetSessionDescriptionObserver*, SessionDescriptionInterface*),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
SetRemoteDescription,
|
||||
(std::unique_ptr<SessionDescriptionInterface>,
|
||||
rtc::scoped_refptr<SetRemoteDescriptionObserverInterface>),
|
||||
(override));
|
||||
MOCK_METHOD(PeerConnectionInterface::RTCConfiguration,
|
||||
GetConfiguration,
|
||||
(),
|
||||
(override));
|
||||
MOCK_METHOD(RTCError,
|
||||
SetConfiguration,
|
||||
(const PeerConnectionInterface::RTCConfiguration&),
|
||||
(override));
|
||||
MOCK_METHOD(bool,
|
||||
AddIceCandidate,
|
||||
(const IceCandidateInterface*),
|
||||
(override));
|
||||
MOCK_METHOD(bool,
|
||||
RemoveIceCandidates,
|
||||
(const std::vector<cricket::Candidate>&),
|
||||
(override));
|
||||
MOCK_METHOD(RTCError, SetBitrate, (const BitrateSettings&), (override));
|
||||
MOCK_METHOD(void,
|
||||
ReconfigureBandwidthEstimation,
|
||||
(const BandwidthEstimationSettings&),
|
||||
(override));
|
||||
MOCK_METHOD(void, SetAudioPlayout, (bool), (override));
|
||||
MOCK_METHOD(void, SetAudioRecording, (bool), (override));
|
||||
MOCK_METHOD(rtc::scoped_refptr<DtlsTransportInterface>,
|
||||
LookupDtlsTransportByMid,
|
||||
(const std::string&),
|
||||
(override));
|
||||
MOCK_METHOD(rtc::scoped_refptr<SctpTransportInterface>,
|
||||
GetSctpTransport,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(SignalingState, signaling_state, (), (override));
|
||||
MOCK_METHOD(IceConnectionState, ice_connection_state, (), (override));
|
||||
MOCK_METHOD(IceConnectionState,
|
||||
standardized_ice_connection_state,
|
||||
(),
|
||||
(override));
|
||||
MOCK_METHOD(PeerConnectionState, peer_connection_state, (), (override));
|
||||
MOCK_METHOD(IceGatheringState, ice_gathering_state, (), (override));
|
||||
MOCK_METHOD(absl::optional<bool>, can_trickle_ice_candidates, (), (override));
|
||||
MOCK_METHOD(bool,
|
||||
StartRtcEventLog,
|
||||
(std::unique_ptr<RtcEventLogOutput>, int64_t),
|
||||
(override));
|
||||
MOCK_METHOD(bool,
|
||||
StartRtcEventLog,
|
||||
(std::unique_ptr<RtcEventLogOutput>),
|
||||
(override));
|
||||
MOCK_METHOD(void, StopRtcEventLog, (), (override));
|
||||
MOCK_METHOD(void, Close, (), (override));
|
||||
MOCK_METHOD(rtc::Thread*, signaling_thread, (), (const, override));
|
||||
|
||||
// PeerConnectionSdpMethods
|
||||
MOCK_METHOD(std::string, session_id, (), (const, override));
|
||||
MOCK_METHOD(bool, NeedsIceRestart, (const std::string&), (const, override));
|
||||
MOCK_METHOD(absl::optional<std::string>, sctp_mid, (), (const, override));
|
||||
MOCK_METHOD(PeerConnectionInterface::RTCConfiguration*,
|
||||
configuration,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(void,
|
||||
ReportSdpBundleUsage,
|
||||
(const SessionDescriptionInterface&),
|
||||
(override));
|
||||
MOCK_METHOD(PeerConnectionMessageHandler*, message_handler, (), (override));
|
||||
MOCK_METHOD(RtpTransmissionManager*, rtp_manager, (), (override));
|
||||
MOCK_METHOD(const RtpTransmissionManager*,
|
||||
rtp_manager,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(bool, dtls_enabled, (), (const, override));
|
||||
MOCK_METHOD(const PeerConnectionFactoryInterface::Options*,
|
||||
options,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(CryptoOptions, GetCryptoOptions, (), (override));
|
||||
MOCK_METHOD(JsepTransportController*, transport_controller_s, (), (override));
|
||||
MOCK_METHOD(JsepTransportController*, transport_controller_n, (), (override));
|
||||
MOCK_METHOD(DataChannelController*, data_channel_controller, (), (override));
|
||||
MOCK_METHOD(cricket::PortAllocator*, port_allocator, (), (override));
|
||||
MOCK_METHOD(LegacyStatsCollector*, legacy_stats, (), (override));
|
||||
MOCK_METHOD(PeerConnectionObserver*, Observer, (), (const, override));
|
||||
MOCK_METHOD(absl::optional<rtc::SSLRole>, GetSctpSslRole_n, (), (override));
|
||||
MOCK_METHOD(PeerConnectionInterface::IceConnectionState,
|
||||
ice_connection_state_internal,
|
||||
(),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
SetIceConnectionState,
|
||||
(PeerConnectionInterface::IceConnectionState),
|
||||
(override));
|
||||
MOCK_METHOD(void, NoteUsageEvent, (UsageEvent), (override));
|
||||
MOCK_METHOD(bool, IsClosed, (), (const, override));
|
||||
MOCK_METHOD(bool, IsUnifiedPlan, (), (const, override));
|
||||
MOCK_METHOD(bool,
|
||||
ValidateBundleSettings,
|
||||
(const cricket::SessionDescription*,
|
||||
(const std::map<std::string, const cricket::ContentGroup*>&)),
|
||||
(override));
|
||||
MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>,
|
||||
AddTransceiver,
|
||||
(cricket::MediaType,
|
||||
rtc::scoped_refptr<MediaStreamTrackInterface>,
|
||||
const RtpTransceiverInit&,
|
||||
bool),
|
||||
(override));
|
||||
MOCK_METHOD(void, StartSctpTransport, (int, int, int), (override));
|
||||
MOCK_METHOD(void,
|
||||
AddRemoteCandidate,
|
||||
(const std::string&, const cricket::Candidate&),
|
||||
(override));
|
||||
MOCK_METHOD(Call*, call_ptr, (), (override));
|
||||
MOCK_METHOD(bool, SrtpRequired, (), (const, override));
|
||||
MOCK_METHOD(bool,
|
||||
CreateDataChannelTransport,
|
||||
(absl::string_view),
|
||||
(override));
|
||||
MOCK_METHOD(void, DestroyDataChannelTransport, (RTCError error), (override));
|
||||
MOCK_METHOD(const FieldTrialsView&, trials, (), (const, override));
|
||||
|
||||
// PeerConnectionInternal
|
||||
MOCK_METHOD(rtc::Thread*, network_thread, (), (const, override));
|
||||
MOCK_METHOD(rtc::Thread*, worker_thread, (), (const, override));
|
||||
MOCK_METHOD(bool, initial_offerer, (), (const, override));
|
||||
MOCK_METHOD(
|
||||
std::vector<
|
||||
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>,
|
||||
GetTransceiversInternal,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(std::vector<DataChannelStats>,
|
||||
GetDataChannelStats,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(absl::optional<std::string>,
|
||||
sctp_transport_name,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(cricket::CandidateStatsList,
|
||||
GetPooledCandidateStats,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD((std::map<std::string, cricket::TransportStats>),
|
||||
GetTransportStatsByNames,
|
||||
(const std::set<std::string>&),
|
||||
(override));
|
||||
MOCK_METHOD(Call::Stats, GetCallStats, (), (override));
|
||||
MOCK_METHOD(absl::optional<AudioDeviceModule::Stats>,
|
||||
GetAudioDeviceStats,
|
||||
(),
|
||||
(override));
|
||||
MOCK_METHOD(bool,
|
||||
GetLocalCertificate,
|
||||
(const std::string&, rtc::scoped_refptr<rtc::RTCCertificate>*),
|
||||
(override));
|
||||
MOCK_METHOD(std::unique_ptr<rtc::SSLCertChain>,
|
||||
GetRemoteSSLCertChain,
|
||||
(const std::string&),
|
||||
(override));
|
||||
MOCK_METHOD(bool, IceRestartPending, (const std::string&), (const, override));
|
||||
MOCK_METHOD(bool,
|
||||
GetSslRole,
|
||||
(const std::string&, rtc::SSLRole*),
|
||||
(override));
|
||||
MOCK_METHOD(void, NoteDataAddedEvent, (), (override));
|
||||
MOCK_METHOD(void,
|
||||
OnSctpDataChannelStateChanged,
|
||||
(int channel_id, DataChannelInterface::DataState),
|
||||
(override));
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_MOCK_PEER_CONNECTION_INTERNAL_H_
|
||||
|
|
@ -0,0 +1,598 @@
|
|||
/*
|
||||
* Copyright 2012 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.
|
||||
*/
|
||||
|
||||
// This file contains mock implementations of observers used in PeerConnection.
|
||||
// TODO(steveanton): These aren't really mocks and should be renamed.
|
||||
|
||||
#ifndef PC_TEST_MOCK_PEER_CONNECTION_OBSERVERS_H_
|
||||
#define PC_TEST_MOCK_PEER_CONNECTION_OBSERVERS_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "api/data_channel_interface.h"
|
||||
#include "api/jsep_ice_candidate.h"
|
||||
#include "pc/stream_collection.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class MockPeerConnectionObserver : public PeerConnectionObserver {
|
||||
public:
|
||||
struct AddTrackEvent {
|
||||
explicit AddTrackEvent(
|
||||
rtc::scoped_refptr<RtpReceiverInterface> event_receiver,
|
||||
std::vector<rtc::scoped_refptr<MediaStreamInterface>> event_streams)
|
||||
: receiver(std::move(event_receiver)),
|
||||
streams(std::move(event_streams)) {
|
||||
for (auto stream : streams) {
|
||||
std::vector<rtc::scoped_refptr<MediaStreamTrackInterface>> tracks;
|
||||
for (auto audio_track : stream->GetAudioTracks()) {
|
||||
tracks.push_back(audio_track);
|
||||
}
|
||||
for (auto video_track : stream->GetVideoTracks()) {
|
||||
tracks.push_back(video_track);
|
||||
}
|
||||
snapshotted_stream_tracks[stream] = tracks;
|
||||
}
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<RtpReceiverInterface> receiver;
|
||||
std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams;
|
||||
// This map records the tracks present in each stream at the time the
|
||||
// OnAddTrack callback was issued.
|
||||
std::map<rtc::scoped_refptr<MediaStreamInterface>,
|
||||
std::vector<rtc::scoped_refptr<MediaStreamTrackInterface>>>
|
||||
snapshotted_stream_tracks;
|
||||
};
|
||||
|
||||
MockPeerConnectionObserver() : remote_streams_(StreamCollection::Create()) {}
|
||||
virtual ~MockPeerConnectionObserver() {}
|
||||
void SetPeerConnectionInterface(PeerConnectionInterface* pc) {
|
||||
pc_ = pc;
|
||||
if (pc) {
|
||||
state_ = pc_->signaling_state();
|
||||
}
|
||||
}
|
||||
void OnSignalingChange(
|
||||
PeerConnectionInterface::SignalingState new_state) override {
|
||||
RTC_DCHECK(pc_);
|
||||
RTC_DCHECK(pc_->signaling_state() == new_state);
|
||||
state_ = new_state;
|
||||
}
|
||||
|
||||
MediaStreamInterface* RemoteStream(const std::string& label) {
|
||||
return remote_streams_->find(label);
|
||||
}
|
||||
StreamCollectionInterface* remote_streams() const {
|
||||
return remote_streams_.get();
|
||||
}
|
||||
void OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream) override {
|
||||
last_added_stream_ = stream;
|
||||
remote_streams_->AddStream(stream);
|
||||
}
|
||||
void OnRemoveStream(
|
||||
rtc::scoped_refptr<MediaStreamInterface> stream) override {
|
||||
last_removed_stream_ = stream;
|
||||
remote_streams_->RemoveStream(stream.get());
|
||||
}
|
||||
void OnRenegotiationNeeded() override { renegotiation_needed_ = true; }
|
||||
void OnNegotiationNeededEvent(uint32_t event_id) override {
|
||||
latest_negotiation_needed_event_ = event_id;
|
||||
}
|
||||
void OnDataChannel(
|
||||
rtc::scoped_refptr<DataChannelInterface> data_channel) override {
|
||||
last_datachannel_ = data_channel;
|
||||
}
|
||||
|
||||
void OnIceConnectionChange(
|
||||
PeerConnectionInterface::IceConnectionState new_state) override {
|
||||
RTC_DCHECK(pc_);
|
||||
RTC_DCHECK(pc_->ice_connection_state() == new_state);
|
||||
// When ICE is finished, the caller will get to a kIceConnectionCompleted
|
||||
// state, because it has the ICE controlling role, while the callee
|
||||
// will get to a kIceConnectionConnected state. This means that both ICE
|
||||
// and DTLS are connected.
|
||||
ice_connected_ =
|
||||
(new_state == PeerConnectionInterface::kIceConnectionConnected) ||
|
||||
(new_state == PeerConnectionInterface::kIceConnectionCompleted);
|
||||
callback_triggered_ = true;
|
||||
}
|
||||
void OnIceGatheringChange(
|
||||
PeerConnectionInterface::IceGatheringState new_state) override {
|
||||
RTC_DCHECK(pc_);
|
||||
RTC_DCHECK(pc_->ice_gathering_state() == new_state);
|
||||
ice_gathering_complete_ =
|
||||
new_state == PeerConnectionInterface::kIceGatheringComplete;
|
||||
callback_triggered_ = true;
|
||||
}
|
||||
void OnIceCandidate(const IceCandidateInterface* candidate) override {
|
||||
RTC_DCHECK(pc_);
|
||||
candidates_.push_back(std::make_unique<JsepIceCandidate>(
|
||||
candidate->sdp_mid(), candidate->sdp_mline_index(),
|
||||
candidate->candidate()));
|
||||
callback_triggered_ = true;
|
||||
}
|
||||
|
||||
void OnIceCandidatesRemoved(
|
||||
const std::vector<cricket::Candidate>& candidates) override {
|
||||
num_candidates_removed_++;
|
||||
callback_triggered_ = true;
|
||||
}
|
||||
|
||||
void OnIceConnectionReceivingChange(bool receiving) override {
|
||||
callback_triggered_ = true;
|
||||
}
|
||||
|
||||
void OnAddTrack(rtc::scoped_refptr<RtpReceiverInterface> receiver,
|
||||
const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
|
||||
streams) override {
|
||||
RTC_DCHECK(receiver);
|
||||
num_added_tracks_++;
|
||||
last_added_track_label_ = receiver->id();
|
||||
add_track_events_.push_back(AddTrackEvent(receiver, streams));
|
||||
}
|
||||
|
||||
void OnTrack(
|
||||
rtc::scoped_refptr<RtpTransceiverInterface> transceiver) override {
|
||||
on_track_transceivers_.push_back(transceiver);
|
||||
}
|
||||
|
||||
void OnRemoveTrack(
|
||||
rtc::scoped_refptr<RtpReceiverInterface> receiver) override {
|
||||
remove_track_events_.push_back(receiver);
|
||||
}
|
||||
|
||||
std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetAddTrackReceivers() {
|
||||
std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
|
||||
for (const AddTrackEvent& event : add_track_events_) {
|
||||
receivers.push_back(event.receiver);
|
||||
}
|
||||
return receivers;
|
||||
}
|
||||
|
||||
int CountAddTrackEventsForStream(const std::string& stream_id) {
|
||||
int found_tracks = 0;
|
||||
for (const AddTrackEvent& event : add_track_events_) {
|
||||
bool has_stream_id = false;
|
||||
for (auto stream : event.streams) {
|
||||
if (stream->id() == stream_id) {
|
||||
has_stream_id = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (has_stream_id) {
|
||||
++found_tracks;
|
||||
}
|
||||
}
|
||||
return found_tracks;
|
||||
}
|
||||
|
||||
// Returns the id of the last added stream.
|
||||
// Empty string if no stream have been added.
|
||||
std::string GetLastAddedStreamId() {
|
||||
if (last_added_stream_.get())
|
||||
return last_added_stream_->id();
|
||||
return "";
|
||||
}
|
||||
std::string GetLastRemovedStreamId() {
|
||||
if (last_removed_stream_.get())
|
||||
return last_removed_stream_->id();
|
||||
return "";
|
||||
}
|
||||
|
||||
IceCandidateInterface* last_candidate() {
|
||||
if (candidates_.empty()) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return candidates_.back().get();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<const IceCandidateInterface*> GetAllCandidates() {
|
||||
std::vector<const IceCandidateInterface*> candidates;
|
||||
for (const auto& candidate : candidates_) {
|
||||
candidates.push_back(candidate.get());
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
std::vector<IceCandidateInterface*> GetCandidatesByMline(int mline_index) {
|
||||
std::vector<IceCandidateInterface*> candidates;
|
||||
for (const auto& candidate : candidates_) {
|
||||
if (candidate->sdp_mline_index() == mline_index) {
|
||||
candidates.push_back(candidate.get());
|
||||
}
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
bool legacy_renegotiation_needed() const { return renegotiation_needed_; }
|
||||
void clear_legacy_renegotiation_needed() { renegotiation_needed_ = false; }
|
||||
|
||||
bool has_negotiation_needed_event() {
|
||||
return latest_negotiation_needed_event_.has_value();
|
||||
}
|
||||
uint32_t latest_negotiation_needed_event() {
|
||||
return latest_negotiation_needed_event_.value_or(0u);
|
||||
}
|
||||
void clear_latest_negotiation_needed_event() {
|
||||
latest_negotiation_needed_event_ = absl::nullopt;
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<PeerConnectionInterface> pc_;
|
||||
PeerConnectionInterface::SignalingState state_;
|
||||
std::vector<std::unique_ptr<IceCandidateInterface>> candidates_;
|
||||
rtc::scoped_refptr<DataChannelInterface> last_datachannel_;
|
||||
rtc::scoped_refptr<StreamCollection> remote_streams_;
|
||||
bool renegotiation_needed_ = false;
|
||||
absl::optional<uint32_t> latest_negotiation_needed_event_;
|
||||
bool ice_gathering_complete_ = false;
|
||||
bool ice_connected_ = false;
|
||||
bool callback_triggered_ = false;
|
||||
int num_added_tracks_ = 0;
|
||||
std::string last_added_track_label_;
|
||||
std::vector<AddTrackEvent> add_track_events_;
|
||||
std::vector<rtc::scoped_refptr<RtpReceiverInterface>> remove_track_events_;
|
||||
std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
|
||||
on_track_transceivers_;
|
||||
int num_candidates_removed_ = 0;
|
||||
|
||||
private:
|
||||
rtc::scoped_refptr<MediaStreamInterface> last_added_stream_;
|
||||
rtc::scoped_refptr<MediaStreamInterface> last_removed_stream_;
|
||||
};
|
||||
|
||||
class MockCreateSessionDescriptionObserver
|
||||
: public CreateSessionDescriptionObserver {
|
||||
public:
|
||||
MockCreateSessionDescriptionObserver()
|
||||
: called_(false),
|
||||
error_("MockCreateSessionDescriptionObserver not called") {}
|
||||
virtual ~MockCreateSessionDescriptionObserver() {}
|
||||
void OnSuccess(SessionDescriptionInterface* desc) override {
|
||||
MutexLock lock(&mutex_);
|
||||
called_ = true;
|
||||
error_ = "";
|
||||
desc_.reset(desc);
|
||||
}
|
||||
void OnFailure(RTCError error) override {
|
||||
MutexLock lock(&mutex_);
|
||||
called_ = true;
|
||||
error_ = error.message();
|
||||
}
|
||||
bool called() const {
|
||||
MutexLock lock(&mutex_);
|
||||
return called_;
|
||||
}
|
||||
bool result() const {
|
||||
MutexLock lock(&mutex_);
|
||||
return error_.empty();
|
||||
}
|
||||
const std::string& error() const {
|
||||
MutexLock lock(&mutex_);
|
||||
return error_;
|
||||
}
|
||||
std::unique_ptr<SessionDescriptionInterface> MoveDescription() {
|
||||
MutexLock lock(&mutex_);
|
||||
return std::move(desc_);
|
||||
}
|
||||
|
||||
private:
|
||||
mutable Mutex mutex_;
|
||||
bool called_ RTC_GUARDED_BY(mutex_);
|
||||
std::string error_ RTC_GUARDED_BY(mutex_);
|
||||
std::unique_ptr<SessionDescriptionInterface> desc_ RTC_GUARDED_BY(mutex_);
|
||||
};
|
||||
|
||||
class MockSetSessionDescriptionObserver : public SetSessionDescriptionObserver {
|
||||
public:
|
||||
static rtc::scoped_refptr<MockSetSessionDescriptionObserver> Create() {
|
||||
return rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
|
||||
}
|
||||
|
||||
MockSetSessionDescriptionObserver()
|
||||
: called_(false),
|
||||
error_("MockSetSessionDescriptionObserver not called") {}
|
||||
~MockSetSessionDescriptionObserver() override {}
|
||||
void OnSuccess() override {
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
called_ = true;
|
||||
error_ = "";
|
||||
}
|
||||
void OnFailure(RTCError error) override {
|
||||
MutexLock lock(&mutex_);
|
||||
called_ = true;
|
||||
error_ = error.message();
|
||||
}
|
||||
|
||||
bool called() const {
|
||||
MutexLock lock(&mutex_);
|
||||
return called_;
|
||||
}
|
||||
bool result() const {
|
||||
MutexLock lock(&mutex_);
|
||||
return error_.empty();
|
||||
}
|
||||
const std::string& error() const {
|
||||
MutexLock lock(&mutex_);
|
||||
return error_;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable Mutex mutex_;
|
||||
bool called_;
|
||||
std::string error_;
|
||||
};
|
||||
|
||||
class FakeSetLocalDescriptionObserver
|
||||
: public SetLocalDescriptionObserverInterface {
|
||||
public:
|
||||
bool called() const { return error_.has_value(); }
|
||||
RTCError& error() {
|
||||
RTC_DCHECK(error_.has_value());
|
||||
return *error_;
|
||||
}
|
||||
|
||||
// SetLocalDescriptionObserverInterface implementation.
|
||||
void OnSetLocalDescriptionComplete(RTCError error) override {
|
||||
error_ = std::move(error);
|
||||
}
|
||||
|
||||
private:
|
||||
// Set on complete, on success this is set to an RTCError::OK() error.
|
||||
absl::optional<RTCError> error_;
|
||||
};
|
||||
|
||||
class FakeSetRemoteDescriptionObserver
|
||||
: public SetRemoteDescriptionObserverInterface {
|
||||
public:
|
||||
bool called() const { return error_.has_value(); }
|
||||
RTCError& error() {
|
||||
RTC_DCHECK(error_.has_value());
|
||||
return *error_;
|
||||
}
|
||||
|
||||
// SetRemoteDescriptionObserverInterface implementation.
|
||||
void OnSetRemoteDescriptionComplete(RTCError error) override {
|
||||
error_ = std::move(error);
|
||||
}
|
||||
|
||||
private:
|
||||
// Set on complete, on success this is set to an RTCError::OK() error.
|
||||
absl::optional<RTCError> error_;
|
||||
};
|
||||
|
||||
class MockDataChannelObserver : public DataChannelObserver {
|
||||
public:
|
||||
struct Message {
|
||||
std::string data;
|
||||
bool binary;
|
||||
};
|
||||
|
||||
explicit MockDataChannelObserver(DataChannelInterface* channel)
|
||||
: channel_(channel) {
|
||||
channel_->RegisterObserver(this);
|
||||
states_.push_back(channel_->state());
|
||||
}
|
||||
virtual ~MockDataChannelObserver() { channel_->UnregisterObserver(); }
|
||||
|
||||
void OnBufferedAmountChange(uint64_t previous_amount) override {}
|
||||
|
||||
void OnStateChange() override { states_.push_back(channel_->state()); }
|
||||
void OnMessage(const DataBuffer& buffer) override {
|
||||
messages_.push_back(
|
||||
{std::string(buffer.data.data<char>(), buffer.data.size()),
|
||||
buffer.binary});
|
||||
}
|
||||
|
||||
bool IsOpen() const { return state() == DataChannelInterface::kOpen; }
|
||||
std::vector<Message> messages() const { return messages_; }
|
||||
std::string last_message() const {
|
||||
if (messages_.empty())
|
||||
return {};
|
||||
|
||||
return messages_.back().data;
|
||||
}
|
||||
bool last_message_is_binary() const {
|
||||
if (messages_.empty())
|
||||
return false;
|
||||
return messages_.back().binary;
|
||||
}
|
||||
size_t received_message_count() const { return messages_.size(); }
|
||||
|
||||
DataChannelInterface::DataState state() const { return states_.back(); }
|
||||
const std::vector<DataChannelInterface::DataState>& states() const {
|
||||
return states_;
|
||||
}
|
||||
|
||||
private:
|
||||
rtc::scoped_refptr<DataChannelInterface> channel_;
|
||||
std::vector<DataChannelInterface::DataState> states_;
|
||||
std::vector<Message> messages_;
|
||||
};
|
||||
|
||||
class MockStatsObserver : public StatsObserver {
|
||||
public:
|
||||
MockStatsObserver() : called_(false), stats_() {}
|
||||
virtual ~MockStatsObserver() {}
|
||||
|
||||
virtual void OnComplete(const StatsReports& reports) {
|
||||
RTC_CHECK(!called_);
|
||||
called_ = true;
|
||||
stats_.Clear();
|
||||
stats_.number_of_reports = reports.size();
|
||||
for (const auto* r : reports) {
|
||||
if (r->type() == StatsReport::kStatsReportTypeSsrc) {
|
||||
stats_.timestamp = r->timestamp();
|
||||
GetIntValue(r, StatsReport::kStatsValueNameAudioOutputLevel,
|
||||
&stats_.audio_output_level);
|
||||
GetIntValue(r, StatsReport::kStatsValueNameAudioInputLevel,
|
||||
&stats_.audio_input_level);
|
||||
GetIntValue(r, StatsReport::kStatsValueNameBytesReceived,
|
||||
&stats_.bytes_received);
|
||||
GetIntValue(r, StatsReport::kStatsValueNameBytesSent,
|
||||
&stats_.bytes_sent);
|
||||
GetInt64Value(r, StatsReport::kStatsValueNameCaptureStartNtpTimeMs,
|
||||
&stats_.capture_start_ntp_time);
|
||||
stats_.track_ids.emplace_back();
|
||||
GetStringValue(r, StatsReport::kStatsValueNameTrackId,
|
||||
&stats_.track_ids.back());
|
||||
} else if (r->type() == StatsReport::kStatsReportTypeBwe) {
|
||||
stats_.timestamp = r->timestamp();
|
||||
GetIntValue(r, StatsReport::kStatsValueNameAvailableReceiveBandwidth,
|
||||
&stats_.available_receive_bandwidth);
|
||||
} else if (r->type() == StatsReport::kStatsReportTypeComponent) {
|
||||
stats_.timestamp = r->timestamp();
|
||||
GetStringValue(r, StatsReport::kStatsValueNameDtlsCipher,
|
||||
&stats_.dtls_cipher);
|
||||
GetStringValue(r, StatsReport::kStatsValueNameSrtpCipher,
|
||||
&stats_.srtp_cipher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool called() const { return called_; }
|
||||
size_t number_of_reports() const { return stats_.number_of_reports; }
|
||||
double timestamp() const { return stats_.timestamp; }
|
||||
|
||||
int AudioOutputLevel() const {
|
||||
RTC_CHECK(called_);
|
||||
return stats_.audio_output_level;
|
||||
}
|
||||
|
||||
int AudioInputLevel() const {
|
||||
RTC_CHECK(called_);
|
||||
return stats_.audio_input_level;
|
||||
}
|
||||
|
||||
int BytesReceived() const {
|
||||
RTC_CHECK(called_);
|
||||
return stats_.bytes_received;
|
||||
}
|
||||
|
||||
int BytesSent() const {
|
||||
RTC_CHECK(called_);
|
||||
return stats_.bytes_sent;
|
||||
}
|
||||
|
||||
int64_t CaptureStartNtpTime() const {
|
||||
RTC_CHECK(called_);
|
||||
return stats_.capture_start_ntp_time;
|
||||
}
|
||||
|
||||
int AvailableReceiveBandwidth() const {
|
||||
RTC_CHECK(called_);
|
||||
return stats_.available_receive_bandwidth;
|
||||
}
|
||||
|
||||
std::string DtlsCipher() const {
|
||||
RTC_CHECK(called_);
|
||||
return stats_.dtls_cipher;
|
||||
}
|
||||
|
||||
std::string SrtpCipher() const {
|
||||
RTC_CHECK(called_);
|
||||
return stats_.srtp_cipher;
|
||||
}
|
||||
|
||||
std::vector<std::string> TrackIds() const {
|
||||
RTC_CHECK(called_);
|
||||
return stats_.track_ids;
|
||||
}
|
||||
|
||||
private:
|
||||
bool GetIntValue(const StatsReport* report,
|
||||
StatsReport::StatsValueName name,
|
||||
int* value) {
|
||||
const StatsReport::Value* v = report->FindValue(name);
|
||||
if (v) {
|
||||
// TODO(tommi): We should really just be using an int here :-/
|
||||
*value = rtc::FromString<int>(v->ToString());
|
||||
}
|
||||
return v != nullptr;
|
||||
}
|
||||
|
||||
bool GetInt64Value(const StatsReport* report,
|
||||
StatsReport::StatsValueName name,
|
||||
int64_t* value) {
|
||||
const StatsReport::Value* v = report->FindValue(name);
|
||||
if (v) {
|
||||
// TODO(tommi): We should really just be using an int here :-/
|
||||
*value = rtc::FromString<int64_t>(v->ToString());
|
||||
}
|
||||
return v != nullptr;
|
||||
}
|
||||
|
||||
bool GetStringValue(const StatsReport* report,
|
||||
StatsReport::StatsValueName name,
|
||||
std::string* value) {
|
||||
const StatsReport::Value* v = report->FindValue(name);
|
||||
if (v)
|
||||
*value = v->ToString();
|
||||
return v != nullptr;
|
||||
}
|
||||
|
||||
bool called_;
|
||||
struct {
|
||||
void Clear() {
|
||||
number_of_reports = 0;
|
||||
timestamp = 0;
|
||||
audio_output_level = 0;
|
||||
audio_input_level = 0;
|
||||
bytes_received = 0;
|
||||
bytes_sent = 0;
|
||||
capture_start_ntp_time = 0;
|
||||
available_receive_bandwidth = 0;
|
||||
dtls_cipher.clear();
|
||||
srtp_cipher.clear();
|
||||
track_ids.clear();
|
||||
}
|
||||
|
||||
size_t number_of_reports;
|
||||
double timestamp;
|
||||
int audio_output_level;
|
||||
int audio_input_level;
|
||||
int bytes_received;
|
||||
int bytes_sent;
|
||||
int64_t capture_start_ntp_time;
|
||||
int available_receive_bandwidth;
|
||||
std::string dtls_cipher;
|
||||
std::string srtp_cipher;
|
||||
std::vector<std::string> track_ids;
|
||||
} stats_;
|
||||
};
|
||||
|
||||
// Helper class that just stores the report from the callback.
|
||||
class MockRTCStatsCollectorCallback : public RTCStatsCollectorCallback {
|
||||
public:
|
||||
rtc::scoped_refptr<const RTCStatsReport> report() { return report_; }
|
||||
|
||||
bool called() const { return called_; }
|
||||
|
||||
protected:
|
||||
void OnStatsDelivered(
|
||||
const rtc::scoped_refptr<const RTCStatsReport>& report) override {
|
||||
report_ = report;
|
||||
called_ = true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool called_ = false;
|
||||
rtc::scoped_refptr<const RTCStatsReport> report_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_MOCK_PEER_CONNECTION_OBSERVERS_H_
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright 2016 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_MOCK_RTP_RECEIVER_INTERNAL_H_
|
||||
#define PC_TEST_MOCK_RTP_RECEIVER_INTERNAL_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "pc/rtp_receiver.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// The definition of MockRtpReceiver is copied in to avoid multiple inheritance.
|
||||
class MockRtpReceiverInternal : public RtpReceiverInternal {
|
||||
public:
|
||||
// RtpReceiverInterface methods.
|
||||
MOCK_METHOD(rtc::scoped_refptr<MediaStreamTrackInterface>,
|
||||
track,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(rtc::scoped_refptr<DtlsTransportInterface>,
|
||||
dtls_transport,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(std::vector<std::string>, stream_ids, (), (const, override));
|
||||
MOCK_METHOD(std::vector<rtc::scoped_refptr<MediaStreamInterface>>,
|
||||
streams,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(cricket::MediaType, media_type, (), (const, override));
|
||||
MOCK_METHOD(std::string, id, (), (const, override));
|
||||
MOCK_METHOD(RtpParameters, GetParameters, (), (const, override));
|
||||
MOCK_METHOD(void, SetObserver, (RtpReceiverObserverInterface*), (override));
|
||||
MOCK_METHOD(void,
|
||||
SetJitterBufferMinimumDelay,
|
||||
(absl::optional<double>),
|
||||
(override));
|
||||
MOCK_METHOD(std::vector<RtpSource>, GetSources, (), (const, override));
|
||||
MOCK_METHOD(void,
|
||||
SetFrameDecryptor,
|
||||
(rtc::scoped_refptr<FrameDecryptorInterface>),
|
||||
(override));
|
||||
MOCK_METHOD(rtc::scoped_refptr<FrameDecryptorInterface>,
|
||||
GetFrameDecryptor,
|
||||
(),
|
||||
(const, override));
|
||||
|
||||
// RtpReceiverInternal methods.
|
||||
MOCK_METHOD(void, Stop, (), (override));
|
||||
MOCK_METHOD(void,
|
||||
SetMediaChannel,
|
||||
(cricket::MediaReceiveChannelInterface*),
|
||||
(override));
|
||||
MOCK_METHOD(void, SetupMediaChannel, (uint32_t), (override));
|
||||
MOCK_METHOD(void, SetupUnsignaledMediaChannel, (), (override));
|
||||
MOCK_METHOD(absl::optional<uint32_t>, ssrc, (), (const, override));
|
||||
MOCK_METHOD(void, NotifyFirstPacketReceived, (), (override));
|
||||
MOCK_METHOD(void, set_stream_ids, (std::vector<std::string>), (override));
|
||||
MOCK_METHOD(void,
|
||||
set_transport,
|
||||
(rtc::scoped_refptr<DtlsTransportInterface>),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
SetStreams,
|
||||
(const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&),
|
||||
(override));
|
||||
MOCK_METHOD(int, AttachmentId, (), (const, override));
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_MOCK_RTP_RECEIVER_INTERNAL_H_
|
||||
112
TMessagesProj/jni/voip/webrtc/pc/test/mock_rtp_sender_internal.h
Normal file
112
TMessagesProj/jni/voip/webrtc/pc/test/mock_rtp_sender_internal.h
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright 2016 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_MOCK_RTP_SENDER_INTERNAL_H_
|
||||
#define PC_TEST_MOCK_RTP_SENDER_INTERNAL_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "pc/rtp_sender.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// The definition of MockRtpSender is copied in to avoid multiple inheritance.
|
||||
class MockRtpSenderInternal : public RtpSenderInternal {
|
||||
public:
|
||||
// RtpSenderInterface methods.
|
||||
MOCK_METHOD(bool, SetTrack, (MediaStreamTrackInterface*), (override));
|
||||
MOCK_METHOD(rtc::scoped_refptr<MediaStreamTrackInterface>,
|
||||
track,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(uint32_t, ssrc, (), (const, override));
|
||||
MOCK_METHOD(rtc::scoped_refptr<DtlsTransportInterface>,
|
||||
dtls_transport,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(cricket::MediaType, media_type, (), (const, override));
|
||||
MOCK_METHOD(std::string, id, (), (const, override));
|
||||
MOCK_METHOD(std::vector<std::string>, stream_ids, (), (const, override));
|
||||
MOCK_METHOD(std::vector<RtpEncodingParameters>,
|
||||
init_send_encodings,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(void,
|
||||
set_transport,
|
||||
(rtc::scoped_refptr<DtlsTransportInterface>),
|
||||
(override));
|
||||
MOCK_METHOD(RtpParameters, GetParameters, (), (const, override));
|
||||
MOCK_METHOD(RtpParameters, GetParametersInternal, (), (const, override));
|
||||
MOCK_METHOD(RtpParameters,
|
||||
GetParametersInternalWithAllLayers,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(RTCError, SetParameters, (const RtpParameters&), (override));
|
||||
MOCK_METHOD(void,
|
||||
SetParametersAsync,
|
||||
(const RtpParameters&, SetParametersCallback),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
SetParametersInternal,
|
||||
(const RtpParameters&, SetParametersCallback, bool blocking),
|
||||
(override));
|
||||
MOCK_METHOD(RTCError,
|
||||
SetParametersInternalWithAllLayers,
|
||||
(const RtpParameters&),
|
||||
(override));
|
||||
MOCK_METHOD(RTCError,
|
||||
CheckCodecParameters,
|
||||
(const RtpParameters&),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
SetCodecPreferences,
|
||||
(std::vector<cricket::VideoCodec>),
|
||||
(override));
|
||||
MOCK_METHOD(rtc::scoped_refptr<DtmfSenderInterface>,
|
||||
GetDtmfSender,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(void,
|
||||
SetFrameEncryptor,
|
||||
(rtc::scoped_refptr<FrameEncryptorInterface>),
|
||||
(override));
|
||||
MOCK_METHOD(rtc::scoped_refptr<FrameEncryptorInterface>,
|
||||
GetFrameEncryptor,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(void,
|
||||
SetEncoderToPacketizerFrameTransformer,
|
||||
(rtc::scoped_refptr<FrameTransformerInterface>),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
SetEncoderSelector,
|
||||
(std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface>),
|
||||
(override));
|
||||
|
||||
// RtpSenderInternal methods.
|
||||
MOCK_METHOD1(SetMediaChannel, void(cricket::MediaSendChannelInterface*));
|
||||
MOCK_METHOD1(SetSsrc, void(uint32_t));
|
||||
MOCK_METHOD1(set_stream_ids, void(const std::vector<std::string>&));
|
||||
MOCK_METHOD1(SetStreams, void(const std::vector<std::string>&));
|
||||
MOCK_METHOD1(set_init_send_encodings,
|
||||
void(const std::vector<RtpEncodingParameters>&));
|
||||
MOCK_METHOD0(Stop, void());
|
||||
MOCK_CONST_METHOD0(AttachmentId, int());
|
||||
MOCK_METHOD1(DisableEncodingLayers,
|
||||
RTCError(const std::vector<std::string>&));
|
||||
MOCK_METHOD0(SetTransceiverAsStopped, void());
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_MOCK_RTP_SENDER_INTERNAL_H_
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Copyright 2023 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.
|
||||
*/
|
||||
#ifndef PC_TEST_MOCK_VOICE_MEDIA_RECEIVE_CHANNEL_INTERFACE_H_
|
||||
#define PC_TEST_MOCK_VOICE_MEDIA_RECEIVE_CHANNEL_INTERFACE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "api/call/audio_sink.h"
|
||||
#include "media/base/media_channel.h"
|
||||
#include "media/base/media_channel_impl.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
class MockVoiceMediaReceiveChannelInterface
|
||||
: public VoiceMediaReceiveChannelInterface {
|
||||
public:
|
||||
MockVoiceMediaReceiveChannelInterface() {
|
||||
ON_CALL(*this, AsVoiceReceiveChannel).WillByDefault(testing::Return(this));
|
||||
}
|
||||
|
||||
// VoiceMediaReceiveChannelInterface
|
||||
MOCK_METHOD(bool,
|
||||
SetReceiverParameters,
|
||||
(const AudioReceiverParameters& params),
|
||||
(override));
|
||||
MOCK_METHOD(webrtc::RtpParameters,
|
||||
GetRtpReceiverParameters,
|
||||
(uint32_t ssrc),
|
||||
(const, override));
|
||||
MOCK_METHOD(std::vector<webrtc::RtpSource>,
|
||||
GetSources,
|
||||
(uint32_t ssrc),
|
||||
(const, override));
|
||||
MOCK_METHOD(webrtc::RtpParameters,
|
||||
GetDefaultRtpReceiveParameters,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(void, SetPlayout, (bool playout), (override));
|
||||
MOCK_METHOD(bool,
|
||||
SetOutputVolume,
|
||||
(uint32_t ssrc, double volume),
|
||||
(override));
|
||||
MOCK_METHOD(bool, SetDefaultOutputVolume, (double volume), (override));
|
||||
MOCK_METHOD(void,
|
||||
SetRawAudioSink,
|
||||
(uint32_t ssrc, std::unique_ptr<webrtc::AudioSinkInterface> sink),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
SetDefaultRawAudioSink,
|
||||
(std::unique_ptr<webrtc::AudioSinkInterface> sink),
|
||||
(override));
|
||||
MOCK_METHOD(bool,
|
||||
GetStats,
|
||||
(VoiceMediaReceiveInfo * stats, bool reset_legacy),
|
||||
(override));
|
||||
MOCK_METHOD(void, SetReceiveNackEnabled, (bool enabled), (override));
|
||||
MOCK_METHOD(void, SetReceiveNonSenderRttEnabled, (bool enabled), (override));
|
||||
|
||||
// MediaReceiveChannelInterface
|
||||
MOCK_METHOD(VideoMediaReceiveChannelInterface*,
|
||||
AsVideoReceiveChannel,
|
||||
(),
|
||||
(override));
|
||||
MOCK_METHOD(VoiceMediaReceiveChannelInterface*,
|
||||
AsVoiceReceiveChannel,
|
||||
(),
|
||||
(override));
|
||||
MOCK_METHOD(cricket::MediaType, media_type, (), (const, override));
|
||||
MOCK_METHOD(bool, AddRecvStream, (const StreamParams& sp), (override));
|
||||
MOCK_METHOD(bool, RemoveRecvStream, (uint32_t ssrc), (override));
|
||||
MOCK_METHOD(void, ResetUnsignaledRecvStream, (), (override));
|
||||
MOCK_METHOD(void,
|
||||
SetInterface,
|
||||
(MediaChannelNetworkInterface * iface),
|
||||
(override));
|
||||
MOCK_METHOD(void,
|
||||
OnPacketReceived,
|
||||
(const webrtc::RtpPacketReceived& packet),
|
||||
(override));
|
||||
MOCK_METHOD(absl::optional<uint32_t>,
|
||||
GetUnsignaledSsrc,
|
||||
(),
|
||||
(const, override));
|
||||
MOCK_METHOD(void,
|
||||
ChooseReceiverReportSsrc,
|
||||
(const std::set<uint32_t>& choices),
|
||||
(override));
|
||||
MOCK_METHOD(void, OnDemuxerCriteriaUpdatePending, (), (override));
|
||||
MOCK_METHOD(void, OnDemuxerCriteriaUpdateComplete, (), (override));
|
||||
MOCK_METHOD(
|
||||
void,
|
||||
SetFrameDecryptor,
|
||||
(uint32_t ssrc,
|
||||
rtc::scoped_refptr<webrtc::FrameDecryptorInterface> frame_decryptor),
|
||||
(override));
|
||||
MOCK_METHOD(
|
||||
void,
|
||||
SetDepacketizerToDecoderFrameTransformer,
|
||||
(uint32_t ssrc,
|
||||
rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer),
|
||||
(override));
|
||||
MOCK_METHOD(bool,
|
||||
SetBaseMinimumPlayoutDelayMs,
|
||||
(uint32_t ssrc, int delay_ms),
|
||||
(override));
|
||||
MOCK_METHOD(absl::optional<int>,
|
||||
GetBaseMinimumPlayoutDelayMs,
|
||||
(uint32_t ssrc),
|
||||
(const, override));
|
||||
};
|
||||
|
||||
static_assert(!std::is_abstract_v<MockVoiceMediaReceiveChannelInterface>, "");
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // PC_TEST_MOCK_VOICE_MEDIA_RECEIVE_CHANNEL_INTERFACE_H_
|
||||
|
|
@ -0,0 +1,429 @@
|
|||
/*
|
||||
* Copyright 2013 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 "pc/test/peer_connection_test_wrapper.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/audio/audio_mixer.h"
|
||||
#include "api/create_peerconnection_factory.h"
|
||||
#include "api/media_types.h"
|
||||
#include "api/sequence_checker.h"
|
||||
#include "api/video_codecs/video_decoder_factory.h"
|
||||
#include "api/video_codecs/video_decoder_factory_template.h"
|
||||
#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h"
|
||||
#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h"
|
||||
#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h"
|
||||
#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h"
|
||||
#include "api/video_codecs/video_encoder_factory.h"
|
||||
#include "api/video_codecs/video_encoder_factory_template.h"
|
||||
#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h"
|
||||
#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h"
|
||||
#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h"
|
||||
#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h"
|
||||
#include "media/engine/simulcast_encoder_adapter.h"
|
||||
#include "modules/audio_device/include/audio_device.h"
|
||||
#include "modules/audio_processing/include/audio_processing.h"
|
||||
#include "p2p/base/fake_port_allocator.h"
|
||||
#include "p2p/base/port_allocator.h"
|
||||
#include "pc/test/fake_periodic_video_source.h"
|
||||
#include "pc/test/fake_rtc_certificate_generator.h"
|
||||
#include "pc/test/mock_peer_connection_observers.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/rtc_certificate_generator.h"
|
||||
#include "rtc_base/string_encode.h"
|
||||
#include "rtc_base/time_utils.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
using webrtc::FakeVideoTrackRenderer;
|
||||
using webrtc::IceCandidateInterface;
|
||||
using webrtc::MediaStreamInterface;
|
||||
using webrtc::MediaStreamTrackInterface;
|
||||
using webrtc::MockSetSessionDescriptionObserver;
|
||||
using webrtc::PeerConnectionInterface;
|
||||
using webrtc::RtpReceiverInterface;
|
||||
using webrtc::SdpType;
|
||||
using webrtc::SessionDescriptionInterface;
|
||||
using webrtc::VideoTrackInterface;
|
||||
|
||||
namespace {
|
||||
const char kStreamIdBase[] = "stream_id";
|
||||
const char kVideoTrackLabelBase[] = "video_track";
|
||||
const char kAudioTrackLabelBase[] = "audio_track";
|
||||
constexpr int kMaxWait = 10000;
|
||||
constexpr int kTestAudioFrameCount = 3;
|
||||
constexpr int kTestVideoFrameCount = 3;
|
||||
|
||||
class FuzzyMatchedVideoEncoderFactory : public webrtc::VideoEncoderFactory {
|
||||
public:
|
||||
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override {
|
||||
return factory_.GetSupportedFormats();
|
||||
}
|
||||
|
||||
std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(
|
||||
const webrtc::SdpVideoFormat& format) override {
|
||||
if (absl::optional<webrtc::SdpVideoFormat> original_format =
|
||||
webrtc::FuzzyMatchSdpVideoFormat(factory_.GetSupportedFormats(),
|
||||
format)) {
|
||||
return std::make_unique<webrtc::SimulcastEncoderAdapter>(
|
||||
&factory_, *original_format);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CodecSupport QueryCodecSupport(
|
||||
const webrtc::SdpVideoFormat& format,
|
||||
absl::optional<std::string> scalability_mode) const override {
|
||||
return factory_.QueryCodecSupport(format, scalability_mode);
|
||||
}
|
||||
|
||||
private:
|
||||
webrtc::VideoEncoderFactoryTemplate<webrtc::LibvpxVp8EncoderTemplateAdapter,
|
||||
webrtc::LibvpxVp9EncoderTemplateAdapter,
|
||||
webrtc::OpenH264EncoderTemplateAdapter,
|
||||
webrtc::LibaomAv1EncoderTemplateAdapter>
|
||||
factory_;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
void PeerConnectionTestWrapper::Connect(PeerConnectionTestWrapper* caller,
|
||||
PeerConnectionTestWrapper* callee) {
|
||||
caller->SignalOnIceCandidateReady.connect(
|
||||
callee, &PeerConnectionTestWrapper::AddIceCandidate);
|
||||
callee->SignalOnIceCandidateReady.connect(
|
||||
caller, &PeerConnectionTestWrapper::AddIceCandidate);
|
||||
|
||||
caller->SignalOnSdpReady.connect(callee,
|
||||
&PeerConnectionTestWrapper::ReceiveOfferSdp);
|
||||
callee->SignalOnSdpReady.connect(
|
||||
caller, &PeerConnectionTestWrapper::ReceiveAnswerSdp);
|
||||
}
|
||||
|
||||
PeerConnectionTestWrapper::PeerConnectionTestWrapper(
|
||||
const std::string& name,
|
||||
rtc::SocketServer* socket_server,
|
||||
rtc::Thread* network_thread,
|
||||
rtc::Thread* worker_thread)
|
||||
: name_(name),
|
||||
socket_server_(socket_server),
|
||||
network_thread_(network_thread),
|
||||
worker_thread_(worker_thread),
|
||||
pending_negotiation_(false) {
|
||||
pc_thread_checker_.Detach();
|
||||
}
|
||||
|
||||
PeerConnectionTestWrapper::~PeerConnectionTestWrapper() {
|
||||
RTC_DCHECK_RUN_ON(&pc_thread_checker_);
|
||||
// To avoid flaky bot failures, make sure fake sources are stopped prior to
|
||||
// closing the peer connections. See https://crbug.com/webrtc/15018.
|
||||
StopFakeVideoSources();
|
||||
// Either network_thread or worker_thread might be active at this point.
|
||||
// Relying on ~PeerConnection to properly wait for them doesn't work,
|
||||
// as a vptr race might occur (before we enter the destruction body).
|
||||
// See: bugs.webrtc.org/9847
|
||||
if (pc()) {
|
||||
pc()->Close();
|
||||
}
|
||||
}
|
||||
|
||||
bool PeerConnectionTestWrapper::CreatePc(
|
||||
const webrtc::PeerConnectionInterface::RTCConfiguration& config,
|
||||
rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
|
||||
rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory) {
|
||||
std::unique_ptr<cricket::PortAllocator> port_allocator(
|
||||
new cricket::FakePortAllocator(
|
||||
network_thread_,
|
||||
std::make_unique<rtc::BasicPacketSocketFactory>(socket_server_),
|
||||
&field_trials_));
|
||||
|
||||
RTC_DCHECK_RUN_ON(&pc_thread_checker_);
|
||||
|
||||
fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
|
||||
if (fake_audio_capture_module_ == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
peer_connection_factory_ = webrtc::CreatePeerConnectionFactory(
|
||||
network_thread_, worker_thread_, rtc::Thread::Current(),
|
||||
rtc::scoped_refptr<webrtc::AudioDeviceModule>(fake_audio_capture_module_),
|
||||
audio_encoder_factory, audio_decoder_factory,
|
||||
std::make_unique<FuzzyMatchedVideoEncoderFactory>(),
|
||||
std::make_unique<webrtc::VideoDecoderFactoryTemplate<
|
||||
webrtc::LibvpxVp8DecoderTemplateAdapter,
|
||||
webrtc::LibvpxVp9DecoderTemplateAdapter,
|
||||
webrtc::OpenH264DecoderTemplateAdapter,
|
||||
webrtc::Dav1dDecoderTemplateAdapter>>(),
|
||||
nullptr /* audio_mixer */, nullptr /* audio_processing */);
|
||||
if (!peer_connection_factory_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator(
|
||||
new FakeRTCCertificateGenerator());
|
||||
webrtc::PeerConnectionDependencies deps(this);
|
||||
deps.allocator = std::move(port_allocator);
|
||||
deps.cert_generator = std::move(cert_generator);
|
||||
auto result = peer_connection_factory_->CreatePeerConnectionOrError(
|
||||
config, std::move(deps));
|
||||
if (result.ok()) {
|
||||
peer_connection_ = result.MoveValue();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<webrtc::DataChannelInterface>
|
||||
PeerConnectionTestWrapper::CreateDataChannel(
|
||||
const std::string& label,
|
||||
const webrtc::DataChannelInit& init) {
|
||||
auto result = peer_connection_->CreateDataChannelOrError(label, &init);
|
||||
if (!result.ok()) {
|
||||
RTC_LOG(LS_ERROR) << "CreateDataChannel failed: "
|
||||
<< ToString(result.error().type()) << " "
|
||||
<< result.error().message();
|
||||
return nullptr;
|
||||
}
|
||||
return result.MoveValue();
|
||||
}
|
||||
|
||||
absl::optional<webrtc::RtpCodecCapability>
|
||||
PeerConnectionTestWrapper::FindFirstSendCodecWithName(
|
||||
cricket::MediaType media_type,
|
||||
const std::string& name) const {
|
||||
std::vector<webrtc::RtpCodecCapability> codecs =
|
||||
peer_connection_factory_->GetRtpSenderCapabilities(media_type).codecs;
|
||||
for (const auto& codec : codecs) {
|
||||
if (absl::EqualsIgnoreCase(codec.name, name)) {
|
||||
return codec;
|
||||
}
|
||||
}
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::WaitForNegotiation() {
|
||||
EXPECT_TRUE_WAIT(!pending_negotiation_, kMaxWait);
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::OnSignalingChange(
|
||||
webrtc::PeerConnectionInterface::SignalingState new_state) {
|
||||
if (new_state == webrtc::PeerConnectionInterface::SignalingState::kStable) {
|
||||
pending_negotiation_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::OnAddTrack(
|
||||
rtc::scoped_refptr<RtpReceiverInterface> receiver,
|
||||
const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
|
||||
RTC_LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_ << ": OnAddTrack";
|
||||
if (receiver->track()->kind() == MediaStreamTrackInterface::kVideoKind) {
|
||||
auto* video_track =
|
||||
static_cast<VideoTrackInterface*>(receiver->track().get());
|
||||
renderer_ = std::make_unique<FakeVideoTrackRenderer>(video_track);
|
||||
}
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::OnIceCandidate(
|
||||
const IceCandidateInterface* candidate) {
|
||||
std::string sdp;
|
||||
EXPECT_TRUE(candidate->ToString(&sdp));
|
||||
SignalOnIceCandidateReady(candidate->sdp_mid(), candidate->sdp_mline_index(),
|
||||
sdp);
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::OnDataChannel(
|
||||
rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) {
|
||||
SignalOnDataChannel(data_channel.get());
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::OnSuccess(SessionDescriptionInterface* desc) {
|
||||
// This callback should take the ownership of `desc`.
|
||||
std::unique_ptr<SessionDescriptionInterface> owned_desc(desc);
|
||||
std::string sdp;
|
||||
EXPECT_TRUE(desc->ToString(&sdp));
|
||||
|
||||
RTC_LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_ << ": "
|
||||
<< webrtc::SdpTypeToString(desc->GetType())
|
||||
<< " sdp created: " << sdp;
|
||||
|
||||
SetLocalDescription(desc->GetType(), sdp);
|
||||
|
||||
SignalOnSdpReady(sdp);
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::CreateOffer(
|
||||
const webrtc::PeerConnectionInterface::RTCOfferAnswerOptions& options) {
|
||||
RTC_LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_ << ": CreateOffer.";
|
||||
pending_negotiation_ = true;
|
||||
peer_connection_->CreateOffer(this, options);
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::CreateAnswer(
|
||||
const webrtc::PeerConnectionInterface::RTCOfferAnswerOptions& options) {
|
||||
RTC_LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
|
||||
<< ": CreateAnswer.";
|
||||
pending_negotiation_ = true;
|
||||
peer_connection_->CreateAnswer(this, options);
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::ReceiveOfferSdp(const std::string& sdp) {
|
||||
SetRemoteDescription(SdpType::kOffer, sdp);
|
||||
CreateAnswer(webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::ReceiveAnswerSdp(const std::string& sdp) {
|
||||
SetRemoteDescription(SdpType::kAnswer, sdp);
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::SetLocalDescription(SdpType type,
|
||||
const std::string& sdp) {
|
||||
RTC_LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
|
||||
<< ": SetLocalDescription " << webrtc::SdpTypeToString(type)
|
||||
<< " " << sdp;
|
||||
|
||||
auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
|
||||
peer_connection_->SetLocalDescription(
|
||||
observer.get(), webrtc::CreateSessionDescription(type, sdp).release());
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::SetRemoteDescription(SdpType type,
|
||||
const std::string& sdp) {
|
||||
RTC_LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
|
||||
<< ": SetRemoteDescription " << webrtc::SdpTypeToString(type)
|
||||
<< " " << sdp;
|
||||
|
||||
auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
|
||||
peer_connection_->SetRemoteDescription(
|
||||
observer.get(), webrtc::CreateSessionDescription(type, sdp).release());
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::AddIceCandidate(const std::string& sdp_mid,
|
||||
int sdp_mline_index,
|
||||
const std::string& candidate) {
|
||||
std::unique_ptr<webrtc::IceCandidateInterface> owned_candidate(
|
||||
webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, candidate, NULL));
|
||||
EXPECT_TRUE(peer_connection_->AddIceCandidate(owned_candidate.get()));
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::WaitForCallEstablished() {
|
||||
WaitForConnection();
|
||||
WaitForAudio();
|
||||
WaitForVideo();
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::WaitForConnection() {
|
||||
EXPECT_TRUE_WAIT(CheckForConnection(), kMaxWait);
|
||||
RTC_LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_ << ": Connected.";
|
||||
}
|
||||
|
||||
bool PeerConnectionTestWrapper::CheckForConnection() {
|
||||
return (peer_connection_->ice_connection_state() ==
|
||||
PeerConnectionInterface::kIceConnectionConnected) ||
|
||||
(peer_connection_->ice_connection_state() ==
|
||||
PeerConnectionInterface::kIceConnectionCompleted);
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::WaitForAudio() {
|
||||
EXPECT_TRUE_WAIT(CheckForAudio(), kMaxWait);
|
||||
RTC_LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
|
||||
<< ": Got enough audio frames.";
|
||||
}
|
||||
|
||||
bool PeerConnectionTestWrapper::CheckForAudio() {
|
||||
return (fake_audio_capture_module_->frames_received() >=
|
||||
kTestAudioFrameCount);
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::WaitForVideo() {
|
||||
EXPECT_TRUE_WAIT(CheckForVideo(), kMaxWait);
|
||||
RTC_LOG(LS_INFO) << "PeerConnectionTestWrapper " << name_
|
||||
<< ": Got enough video frames.";
|
||||
}
|
||||
|
||||
bool PeerConnectionTestWrapper::CheckForVideo() {
|
||||
if (!renderer_) {
|
||||
return false;
|
||||
}
|
||||
return (renderer_->num_rendered_frames() >= kTestVideoFrameCount);
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::GetAndAddUserMedia(
|
||||
bool audio,
|
||||
const cricket::AudioOptions& audio_options,
|
||||
bool video) {
|
||||
rtc::scoped_refptr<webrtc::MediaStreamInterface> stream =
|
||||
GetUserMedia(audio, audio_options, video);
|
||||
for (const auto& audio_track : stream->GetAudioTracks()) {
|
||||
EXPECT_TRUE(peer_connection_->AddTrack(audio_track, {stream->id()}).ok());
|
||||
}
|
||||
for (const auto& video_track : stream->GetVideoTracks()) {
|
||||
EXPECT_TRUE(peer_connection_->AddTrack(video_track, {stream->id()}).ok());
|
||||
}
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<webrtc::MediaStreamInterface>
|
||||
PeerConnectionTestWrapper::GetUserMedia(
|
||||
bool audio,
|
||||
const cricket::AudioOptions& audio_options,
|
||||
bool video,
|
||||
webrtc::Resolution resolution) {
|
||||
std::string stream_id =
|
||||
kStreamIdBase + rtc::ToString(num_get_user_media_calls_++);
|
||||
rtc::scoped_refptr<webrtc::MediaStreamInterface> stream =
|
||||
peer_connection_factory_->CreateLocalMediaStream(stream_id);
|
||||
|
||||
if (audio) {
|
||||
cricket::AudioOptions options = audio_options;
|
||||
// Disable highpass filter so that we can get all the test audio frames.
|
||||
options.highpass_filter = false;
|
||||
rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
|
||||
peer_connection_factory_->CreateAudioSource(options);
|
||||
rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
|
||||
peer_connection_factory_->CreateAudioTrack(kAudioTrackLabelBase,
|
||||
source.get()));
|
||||
stream->AddTrack(audio_track);
|
||||
}
|
||||
|
||||
if (video) {
|
||||
// Set max frame rate to 10fps to reduce the risk of the tests to be flaky.
|
||||
webrtc::FakePeriodicVideoSource::Config config;
|
||||
config.frame_interval_ms = 100;
|
||||
config.timestamp_offset_ms = rtc::TimeMillis();
|
||||
config.width = resolution.width;
|
||||
config.height = resolution.height;
|
||||
|
||||
auto source = rtc::make_ref_counted<webrtc::FakePeriodicVideoTrackSource>(
|
||||
config, /* remote */ false);
|
||||
fake_video_sources_.push_back(source);
|
||||
|
||||
std::string videotrack_label = stream_id + kVideoTrackLabelBase;
|
||||
rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
|
||||
peer_connection_factory_->CreateVideoTrack(source, videotrack_label));
|
||||
|
||||
stream->AddTrack(video_track);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
void PeerConnectionTestWrapper::StopFakeVideoSources() {
|
||||
for (const auto& fake_video_source : fake_video_sources_) {
|
||||
fake_video_source->fake_periodic_source().Stop();
|
||||
}
|
||||
fake_video_sources_.clear();
|
||||
}
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright 2013 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_PEER_CONNECTION_TEST_WRAPPER_H_
|
||||
#define PC_TEST_PEER_CONNECTION_TEST_WRAPPER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "api/audio_codecs/audio_decoder_factory.h"
|
||||
#include "api/audio_codecs/audio_encoder_factory.h"
|
||||
#include "api/audio_options.h"
|
||||
#include "api/data_channel_interface.h"
|
||||
#include "api/jsep.h"
|
||||
#include "api/media_stream_interface.h"
|
||||
#include "api/peer_connection_interface.h"
|
||||
#include "api/rtc_error.h"
|
||||
#include "api/rtp_parameters.h"
|
||||
#include "api/rtp_receiver_interface.h"
|
||||
#include "api/scoped_refptr.h"
|
||||
#include "api/sequence_checker.h"
|
||||
#include "api/video/resolution.h"
|
||||
#include "pc/test/fake_audio_capture_module.h"
|
||||
#include "pc/test/fake_periodic_video_source.h"
|
||||
#include "pc/test/fake_periodic_video_track_source.h"
|
||||
#include "pc/test/fake_video_track_renderer.h"
|
||||
#include "rtc_base/third_party/sigslot/sigslot.h"
|
||||
#include "rtc_base/thread.h"
|
||||
#include "test/scoped_key_value_config.h"
|
||||
|
||||
class PeerConnectionTestWrapper
|
||||
: public webrtc::PeerConnectionObserver,
|
||||
public webrtc::CreateSessionDescriptionObserver,
|
||||
public sigslot::has_slots<> {
|
||||
public:
|
||||
static void Connect(PeerConnectionTestWrapper* caller,
|
||||
PeerConnectionTestWrapper* callee);
|
||||
|
||||
PeerConnectionTestWrapper(const std::string& name,
|
||||
rtc::SocketServer* socket_server,
|
||||
rtc::Thread* network_thread,
|
||||
rtc::Thread* worker_thread);
|
||||
virtual ~PeerConnectionTestWrapper();
|
||||
|
||||
bool CreatePc(
|
||||
const webrtc::PeerConnectionInterface::RTCConfiguration& config,
|
||||
rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
|
||||
rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory);
|
||||
|
||||
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory()
|
||||
const {
|
||||
return peer_connection_factory_;
|
||||
}
|
||||
webrtc::PeerConnectionInterface* pc() { return peer_connection_.get(); }
|
||||
|
||||
rtc::scoped_refptr<webrtc::DataChannelInterface> CreateDataChannel(
|
||||
const std::string& label,
|
||||
const webrtc::DataChannelInit& init);
|
||||
|
||||
absl::optional<webrtc::RtpCodecCapability> FindFirstSendCodecWithName(
|
||||
cricket::MediaType media_type,
|
||||
const std::string& name) const;
|
||||
|
||||
void WaitForNegotiation();
|
||||
|
||||
// Implements PeerConnectionObserver.
|
||||
void OnSignalingChange(
|
||||
webrtc::PeerConnectionInterface::SignalingState new_state) override;
|
||||
void OnAddTrack(
|
||||
rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
|
||||
const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&
|
||||
streams) override;
|
||||
void OnDataChannel(
|
||||
rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) override;
|
||||
void OnRenegotiationNeeded() override {}
|
||||
void OnIceConnectionChange(
|
||||
webrtc::PeerConnectionInterface::IceConnectionState new_state) override {}
|
||||
void OnIceGatheringChange(
|
||||
webrtc::PeerConnectionInterface::IceGatheringState new_state) override {}
|
||||
void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override;
|
||||
|
||||
// Implements CreateSessionDescriptionObserver.
|
||||
void OnSuccess(webrtc::SessionDescriptionInterface* desc) override;
|
||||
void OnFailure(webrtc::RTCError) override {}
|
||||
|
||||
void CreateOffer(
|
||||
const webrtc::PeerConnectionInterface::RTCOfferAnswerOptions& options);
|
||||
void CreateAnswer(
|
||||
const webrtc::PeerConnectionInterface::RTCOfferAnswerOptions& options);
|
||||
void ReceiveOfferSdp(const std::string& sdp);
|
||||
void ReceiveAnswerSdp(const std::string& sdp);
|
||||
void AddIceCandidate(const std::string& sdp_mid,
|
||||
int sdp_mline_index,
|
||||
const std::string& candidate);
|
||||
void WaitForCallEstablished();
|
||||
void WaitForConnection();
|
||||
void WaitForAudio();
|
||||
void WaitForVideo();
|
||||
void GetAndAddUserMedia(bool audio,
|
||||
const cricket::AudioOptions& audio_options,
|
||||
bool video);
|
||||
|
||||
// sigslots
|
||||
sigslot::signal3<const std::string&, int, const std::string&>
|
||||
SignalOnIceCandidateReady;
|
||||
sigslot::signal1<const std::string&> SignalOnSdpReady;
|
||||
sigslot::signal1<webrtc::DataChannelInterface*> SignalOnDataChannel;
|
||||
|
||||
rtc::scoped_refptr<webrtc::MediaStreamInterface> GetUserMedia(
|
||||
bool audio,
|
||||
const cricket::AudioOptions& audio_options,
|
||||
bool video,
|
||||
webrtc::Resolution resolution = {
|
||||
.width = webrtc::FakePeriodicVideoSource::kDefaultWidth,
|
||||
.height = webrtc::FakePeriodicVideoSource::kDefaultHeight});
|
||||
void StopFakeVideoSources();
|
||||
|
||||
private:
|
||||
void SetLocalDescription(webrtc::SdpType type, const std::string& sdp);
|
||||
void SetRemoteDescription(webrtc::SdpType type, const std::string& sdp);
|
||||
bool CheckForConnection();
|
||||
bool CheckForAudio();
|
||||
bool CheckForVideo();
|
||||
|
||||
webrtc::test::ScopedKeyValueConfig field_trials_;
|
||||
std::string name_;
|
||||
rtc::SocketServer* const socket_server_;
|
||||
rtc::Thread* const network_thread_;
|
||||
rtc::Thread* const worker_thread_;
|
||||
webrtc::SequenceChecker pc_thread_checker_;
|
||||
rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
|
||||
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
|
||||
peer_connection_factory_;
|
||||
rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
|
||||
std::unique_ptr<webrtc::FakeVideoTrackRenderer> renderer_;
|
||||
int num_get_user_media_calls_ = 0;
|
||||
bool pending_negotiation_;
|
||||
std::vector<rtc::scoped_refptr<webrtc::FakePeriodicVideoTrackSource>>
|
||||
fake_video_sources_;
|
||||
};
|
||||
|
||||
#endif // PC_TEST_PEER_CONNECTION_TEST_WRAPPER_H_
|
||||
55
TMessagesProj/jni/voip/webrtc/pc/test/rtc_stats_obtainer.h
Normal file
55
TMessagesProj/jni/voip/webrtc/pc/test/rtc_stats_obtainer.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 2016 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_RTC_STATS_OBTAINER_H_
|
||||
#define PC_TEST_RTC_STATS_OBTAINER_H_
|
||||
|
||||
#include "api/make_ref_counted.h"
|
||||
#include "api/sequence_checker.h"
|
||||
#include "api/stats/rtc_stats_collector_callback.h"
|
||||
#include "api/stats/rtc_stats_report.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class RTCStatsObtainer : public RTCStatsCollectorCallback {
|
||||
public:
|
||||
static rtc::scoped_refptr<RTCStatsObtainer> Create(
|
||||
rtc::scoped_refptr<const RTCStatsReport>* report_ptr = nullptr) {
|
||||
return rtc::make_ref_counted<RTCStatsObtainer>(report_ptr);
|
||||
}
|
||||
|
||||
void OnStatsDelivered(
|
||||
const rtc::scoped_refptr<const RTCStatsReport>& report) override {
|
||||
EXPECT_TRUE(thread_checker_.IsCurrent());
|
||||
report_ = report;
|
||||
if (report_ptr_)
|
||||
*report_ptr_ = report_;
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<const RTCStatsReport> report() const {
|
||||
EXPECT_TRUE(thread_checker_.IsCurrent());
|
||||
return report_;
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit RTCStatsObtainer(
|
||||
rtc::scoped_refptr<const RTCStatsReport>* report_ptr)
|
||||
: report_ptr_(report_ptr) {}
|
||||
|
||||
private:
|
||||
SequenceChecker thread_checker_;
|
||||
rtc::scoped_refptr<const RTCStatsReport> report_;
|
||||
rtc::scoped_refptr<const RTCStatsReport>* report_ptr_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_RTC_STATS_OBTAINER_H_
|
||||
109
TMessagesProj/jni/voip/webrtc/pc/test/rtp_transport_test_util.h
Normal file
109
TMessagesProj/jni/voip/webrtc/pc/test/rtp_transport_test_util.h
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright 2017 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_RTP_TRANSPORT_TEST_UTIL_H_
|
||||
#define PC_TEST_RTP_TRANSPORT_TEST_UTIL_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "call/rtp_packet_sink_interface.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
||||
#include "pc/rtp_transport_internal.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Used to handle the signals when the RtpTransport receives an RTP/RTCP packet.
|
||||
// Used in Rtp/Srtp/DtlsTransport unit tests.
|
||||
class TransportObserver : public RtpPacketSinkInterface {
|
||||
public:
|
||||
TransportObserver() {}
|
||||
|
||||
explicit TransportObserver(RtpTransportInternal* rtp_transport) {
|
||||
rtp_transport->SubscribeRtcpPacketReceived(
|
||||
this, [this](rtc::CopyOnWriteBuffer* buffer, int64_t packet_time_ms) {
|
||||
OnRtcpPacketReceived(buffer, packet_time_ms);
|
||||
});
|
||||
rtp_transport->SubscribeReadyToSend(
|
||||
this, [this](bool arg) { OnReadyToSend(arg); });
|
||||
rtp_transport->SetUnDemuxableRtpPacketReceivedHandler(
|
||||
[this](RtpPacketReceived& packet) { OnUndemuxableRtpPacket(packet); });
|
||||
rtp_transport->SubscribeSentPacket(this,
|
||||
[this](const rtc::SentPacket& packet) {
|
||||
sent_packet_count_++;
|
||||
if (action_on_sent_packet_) {
|
||||
action_on_sent_packet_();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// RtpPacketInterface override.
|
||||
void OnRtpPacket(const RtpPacketReceived& packet) override {
|
||||
rtp_count_++;
|
||||
last_recv_rtp_packet_ = packet.Buffer();
|
||||
}
|
||||
|
||||
void OnUndemuxableRtpPacket(const RtpPacketReceived& packet) {
|
||||
un_demuxable_rtp_count_++;
|
||||
}
|
||||
|
||||
void OnRtcpPacketReceived(rtc::CopyOnWriteBuffer* packet,
|
||||
int64_t packet_time_us) {
|
||||
rtcp_count_++;
|
||||
last_recv_rtcp_packet_ = *packet;
|
||||
}
|
||||
|
||||
int rtp_count() const { return rtp_count_; }
|
||||
int un_demuxable_rtp_count() const { return un_demuxable_rtp_count_; }
|
||||
int rtcp_count() const { return rtcp_count_; }
|
||||
int sent_packet_count() const { return sent_packet_count_; }
|
||||
|
||||
rtc::CopyOnWriteBuffer last_recv_rtp_packet() {
|
||||
return last_recv_rtp_packet_;
|
||||
}
|
||||
|
||||
rtc::CopyOnWriteBuffer last_recv_rtcp_packet() {
|
||||
return last_recv_rtcp_packet_;
|
||||
}
|
||||
|
||||
void OnReadyToSend(bool ready) {
|
||||
if (action_on_ready_to_send_) {
|
||||
action_on_ready_to_send_(ready);
|
||||
}
|
||||
ready_to_send_signal_count_++;
|
||||
ready_to_send_ = ready;
|
||||
}
|
||||
|
||||
bool ready_to_send() { return ready_to_send_; }
|
||||
|
||||
int ready_to_send_signal_count() { return ready_to_send_signal_count_; }
|
||||
|
||||
void SetActionOnReadyToSend(absl::AnyInvocable<void(bool)> action) {
|
||||
action_on_ready_to_send_ = std::move(action);
|
||||
}
|
||||
void SetActionOnSentPacket(absl::AnyInvocable<void()> action) {
|
||||
action_on_sent_packet_ = std::move(action);
|
||||
}
|
||||
|
||||
private:
|
||||
bool ready_to_send_ = false;
|
||||
int rtp_count_ = 0;
|
||||
int un_demuxable_rtp_count_ = 0;
|
||||
int rtcp_count_ = 0;
|
||||
int sent_packet_count_ = 0;
|
||||
int ready_to_send_signal_count_ = 0;
|
||||
rtc::CopyOnWriteBuffer last_recv_rtp_packet_;
|
||||
rtc::CopyOnWriteBuffer last_recv_rtcp_packet_;
|
||||
absl::AnyInvocable<void(bool)> action_on_ready_to_send_;
|
||||
absl::AnyInvocable<void()> action_on_sent_packet_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_RTP_TRANSPORT_TEST_UTIL_H_
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 2023 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 "pc/test/simulcast_layer_util.h"
|
||||
|
||||
#include "absl/algorithm/container.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::vector<cricket::SimulcastLayer> CreateLayers(
|
||||
const std::vector<std::string>& rids,
|
||||
const std::vector<bool>& active) {
|
||||
RTC_DCHECK_EQ(rids.size(), active.size());
|
||||
std::vector<cricket::SimulcastLayer> result;
|
||||
absl::c_transform(rids, active, std::back_inserter(result),
|
||||
[](const std::string& rid, bool is_active) {
|
||||
return cricket::SimulcastLayer(rid, !is_active);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<cricket::SimulcastLayer> CreateLayers(
|
||||
const std::vector<std::string>& rids,
|
||||
bool active) {
|
||||
return CreateLayers(rids, std::vector<bool>(rids.size(), active));
|
||||
}
|
||||
|
||||
RtpTransceiverInit CreateTransceiverInit(
|
||||
const std::vector<cricket::SimulcastLayer>& layers) {
|
||||
RtpTransceiverInit init;
|
||||
for (const cricket::SimulcastLayer& layer : layers) {
|
||||
RtpEncodingParameters encoding;
|
||||
encoding.rid = layer.rid;
|
||||
encoding.active = !layer.is_paused;
|
||||
init.send_encodings.push_back(encoding);
|
||||
}
|
||||
return init;
|
||||
}
|
||||
|
||||
cricket::SimulcastDescription RemoveSimulcast(SessionDescriptionInterface* sd) {
|
||||
auto mcd = sd->description()->contents()[0].media_description();
|
||||
auto result = mcd->simulcast_description();
|
||||
mcd->set_simulcast_description(cricket::SimulcastDescription());
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
39
TMessagesProj/jni/voip/webrtc/pc/test/simulcast_layer_util.h
Normal file
39
TMessagesProj/jni/voip/webrtc/pc/test/simulcast_layer_util.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2023 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_SIMULCAST_LAYER_UTIL_H_
|
||||
#define PC_TEST_SIMULCAST_LAYER_UTIL_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "api/jsep.h"
|
||||
#include "api/rtp_transceiver_interface.h"
|
||||
#include "pc/session_description.h"
|
||||
#include "pc/simulcast_description.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::vector<cricket::SimulcastLayer> CreateLayers(
|
||||
const std::vector<std::string>& rids,
|
||||
const std::vector<bool>& active);
|
||||
|
||||
std::vector<cricket::SimulcastLayer> CreateLayers(
|
||||
const std::vector<std::string>& rids,
|
||||
bool active);
|
||||
|
||||
RtpTransceiverInit CreateTransceiverInit(
|
||||
const std::vector<cricket::SimulcastLayer>& layers);
|
||||
|
||||
cricket::SimulcastDescription RemoveSimulcast(SessionDescriptionInterface* sd);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_SIMULCAST_LAYER_UTIL_H_
|
||||
45
TMessagesProj/jni/voip/webrtc/pc/test/srtp_test_util.h
Normal file
45
TMessagesProj/jni/voip/webrtc/pc/test/srtp_test_util.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 2017 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_TEST_SRTP_TEST_UTIL_H_
|
||||
#define PC_TEST_SRTP_TEST_UTIL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
extern const char kCsAesCm128HmacSha1_32[];
|
||||
extern const char kCsAeadAes128Gcm[];
|
||||
extern const char kCsAeadAes256Gcm[];
|
||||
|
||||
static const uint8_t kTestKey1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234";
|
||||
static const uint8_t kTestKey2[] = "4321ZYXWVUTSRQPONMLKJIHGFEDCBA";
|
||||
static const int kTestKeyLen = 30;
|
||||
|
||||
static int rtp_auth_tag_len(const std::string& cs) {
|
||||
if (cs == kCsAesCm128HmacSha1_32) {
|
||||
return 4;
|
||||
} else if (cs == kCsAeadAes128Gcm || cs == kCsAeadAes256Gcm) {
|
||||
return 16;
|
||||
} else {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
static int rtcp_auth_tag_len(const std::string& cs) {
|
||||
if (cs == kCsAeadAes128Gcm || cs == kCsAeadAes256Gcm) {
|
||||
return 16;
|
||||
} else {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // PC_TEST_SRTP_TEST_UTIL_H_
|
||||
507
TMessagesProj/jni/voip/webrtc/pc/test/svc_e2e_tests.cc
Normal file
507
TMessagesProj/jni/voip/webrtc/pc/test/svc_e2e_tests.cc
Normal file
|
|
@ -0,0 +1,507 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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 <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "api/media_stream_interface.h"
|
||||
#include "api/stats/rtcstats_objects.h"
|
||||
#include "api/test/create_network_emulation_manager.h"
|
||||
#include "api/test/create_peer_connection_quality_test_frame_generator.h"
|
||||
#include "api/test/create_peerconnection_quality_test_fixture.h"
|
||||
#include "api/test/frame_generator_interface.h"
|
||||
#include "api/test/metrics/global_metrics_logger_and_exporter.h"
|
||||
#include "api/test/network_emulation_manager.h"
|
||||
#include "api/test/pclf/media_configuration.h"
|
||||
#include "api/test/pclf/media_quality_test_params.h"
|
||||
#include "api/test/pclf/peer_configurer.h"
|
||||
#include "api/test/peerconnection_quality_test_fixture.h"
|
||||
#include "api/test/simulated_network.h"
|
||||
#include "api/test/time_controller.h"
|
||||
#include "api/video_codecs/vp9_profile.h"
|
||||
#include "call/simulated_network.h"
|
||||
#include "modules/video_coding/codecs/vp9/include/vp9.h"
|
||||
#include "modules/video_coding/svc/scalability_mode_util.h"
|
||||
#include "rtc_base/containers/flat_map.h"
|
||||
#include "system_wrappers/include/field_trial.h"
|
||||
#include "test/field_trial.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
#include "test/pc/e2e/analyzer/video/default_video_quality_analyzer.h"
|
||||
#include "test/pc/e2e/network_quality_metrics_reporter.h"
|
||||
#include "test/testsupport/file_utils.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
|
||||
using ::cricket::kAv1CodecName;
|
||||
using ::cricket::kH264CodecName;
|
||||
using ::cricket::kVp8CodecName;
|
||||
using ::cricket::kVp9CodecName;
|
||||
using ::testing::Combine;
|
||||
using ::testing::Optional;
|
||||
using ::testing::UnitTest;
|
||||
using ::testing::Values;
|
||||
using ::testing::ValuesIn;
|
||||
using ::webrtc::webrtc_pc_e2e::EmulatedSFUConfig;
|
||||
using ::webrtc::webrtc_pc_e2e::PeerConfigurer;
|
||||
using ::webrtc::webrtc_pc_e2e::RunParams;
|
||||
using ::webrtc::webrtc_pc_e2e::ScreenShareConfig;
|
||||
using ::webrtc::webrtc_pc_e2e::VideoCodecConfig;
|
||||
using ::webrtc::webrtc_pc_e2e::VideoConfig;
|
||||
|
||||
std::unique_ptr<webrtc_pc_e2e::PeerConnectionE2EQualityTestFixture>
|
||||
CreateTestFixture(absl::string_view test_case_name,
|
||||
TimeController& time_controller,
|
||||
std::pair<EmulatedNetworkManagerInterface*,
|
||||
EmulatedNetworkManagerInterface*> network_links,
|
||||
rtc::FunctionView<void(PeerConfigurer*)> alice_configurer,
|
||||
rtc::FunctionView<void(PeerConfigurer*)> bob_configurer,
|
||||
std::unique_ptr<VideoQualityAnalyzerInterface>
|
||||
video_quality_analyzer = nullptr) {
|
||||
auto fixture = webrtc_pc_e2e::CreatePeerConnectionE2EQualityTestFixture(
|
||||
std::string(test_case_name), time_controller, nullptr,
|
||||
std::move(video_quality_analyzer));
|
||||
auto alice = std::make_unique<PeerConfigurer>(
|
||||
network_links.first->network_dependencies());
|
||||
auto bob = std::make_unique<PeerConfigurer>(
|
||||
network_links.second->network_dependencies());
|
||||
alice_configurer(alice.get());
|
||||
bob_configurer(bob.get());
|
||||
fixture->AddPeer(std::move(alice));
|
||||
fixture->AddPeer(std::move(bob));
|
||||
return fixture;
|
||||
}
|
||||
|
||||
// Takes the current active field trials set, and appends some new trials.
|
||||
std::string AppendFieldTrials(std::string new_trial_string) {
|
||||
return std::string(field_trial::GetFieldTrialString()) + new_trial_string;
|
||||
}
|
||||
|
||||
enum class UseDependencyDescriptor {
|
||||
Enabled,
|
||||
Disabled,
|
||||
};
|
||||
|
||||
struct SvcTestParameters {
|
||||
static SvcTestParameters Create(const std::string& codec_name,
|
||||
const std::string& scalability_mode_str) {
|
||||
absl::optional<ScalabilityMode> scalability_mode =
|
||||
ScalabilityModeFromString(scalability_mode_str);
|
||||
RTC_CHECK(scalability_mode.has_value())
|
||||
<< "Unsupported scalability mode: " << scalability_mode_str;
|
||||
|
||||
int num_spatial_layers =
|
||||
ScalabilityModeToNumSpatialLayers(*scalability_mode);
|
||||
int num_temporal_layers =
|
||||
ScalabilityModeToNumTemporalLayers(*scalability_mode);
|
||||
|
||||
return SvcTestParameters{codec_name, scalability_mode_str,
|
||||
num_spatial_layers, num_temporal_layers};
|
||||
}
|
||||
|
||||
std::string codec_name;
|
||||
std::string scalability_mode;
|
||||
int expected_spatial_layers;
|
||||
int expected_temporal_layers;
|
||||
};
|
||||
|
||||
class SvcTest : public testing::TestWithParam<
|
||||
std::tuple<SvcTestParameters, UseDependencyDescriptor>> {
|
||||
public:
|
||||
SvcTest()
|
||||
: video_codec_config(ToVideoCodecConfig(SvcTestParameters().codec_name)) {
|
||||
}
|
||||
|
||||
static VideoCodecConfig ToVideoCodecConfig(absl::string_view codec) {
|
||||
if (codec == cricket::kVp9CodecName) {
|
||||
return VideoCodecConfig(
|
||||
cricket::kVp9CodecName,
|
||||
{{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile0)}});
|
||||
}
|
||||
|
||||
return VideoCodecConfig(codec);
|
||||
}
|
||||
|
||||
const SvcTestParameters& SvcTestParameters() const {
|
||||
return std::get<0>(GetParam());
|
||||
}
|
||||
|
||||
bool UseDependencyDescriptor() const {
|
||||
return std::get<1>(GetParam()) == UseDependencyDescriptor::Enabled;
|
||||
}
|
||||
|
||||
bool IsSMode() const {
|
||||
return SvcTestParameters().scalability_mode[0] == 'S';
|
||||
}
|
||||
|
||||
protected:
|
||||
VideoCodecConfig video_codec_config;
|
||||
};
|
||||
|
||||
std::string SvcTestNameGenerator(
|
||||
const testing::TestParamInfo<SvcTest::ParamType>& info) {
|
||||
return std::get<0>(info.param).scalability_mode +
|
||||
(std::get<1>(info.param) == UseDependencyDescriptor::Enabled ? "_DD"
|
||||
: "");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Records how many frames are seen for each spatial and temporal index at the
|
||||
// encoder and decoder level.
|
||||
class SvcVideoQualityAnalyzer : public DefaultVideoQualityAnalyzer {
|
||||
public:
|
||||
using SpatialTemporalLayerCounts = flat_map<int, flat_map<int, int>>;
|
||||
|
||||
explicit SvcVideoQualityAnalyzer(Clock* clock)
|
||||
: DefaultVideoQualityAnalyzer(clock,
|
||||
test::GetGlobalMetricsLogger(),
|
||||
DefaultVideoQualityAnalyzerOptions{
|
||||
.compute_psnr = false,
|
||||
.compute_ssim = false,
|
||||
}) {}
|
||||
~SvcVideoQualityAnalyzer() override = default;
|
||||
|
||||
void OnFrameEncoded(absl::string_view peer_name,
|
||||
uint16_t frame_id,
|
||||
const EncodedImage& encoded_image,
|
||||
const EncoderStats& stats,
|
||||
bool discarded) override {
|
||||
absl::optional<int> spatial_id = encoded_image.SpatialIndex();
|
||||
absl::optional<int> temporal_id = encoded_image.TemporalIndex();
|
||||
encoder_layers_seen_[spatial_id.value_or(0)][temporal_id.value_or(0)]++;
|
||||
DefaultVideoQualityAnalyzer::OnFrameEncoded(
|
||||
peer_name, frame_id, encoded_image, stats, discarded);
|
||||
}
|
||||
|
||||
void OnFramePreDecode(absl::string_view peer_name,
|
||||
uint16_t frame_id,
|
||||
const EncodedImage& input_image) override {
|
||||
absl::optional<int> spatial_id = input_image.SpatialIndex();
|
||||
absl::optional<int> temporal_id = input_image.TemporalIndex();
|
||||
if (!spatial_id) {
|
||||
decoder_layers_seen_[0][temporal_id.value_or(0)]++;
|
||||
} else {
|
||||
for (int i = 0; i <= *spatial_id; ++i) {
|
||||
// If there are no spatial layers (for example VP8), we still want to
|
||||
// record the temporal index for pseudo-layer "0" frames.
|
||||
if (*spatial_id == 0 ||
|
||||
input_image.SpatialLayerFrameSize(i).value_or(0) > 0) {
|
||||
decoder_layers_seen_[i][temporal_id.value_or(0)]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
DefaultVideoQualityAnalyzer::OnFramePreDecode(peer_name, frame_id,
|
||||
input_image);
|
||||
}
|
||||
|
||||
void OnStatsReports(
|
||||
absl::string_view pc_label,
|
||||
const rtc::scoped_refptr<const RTCStatsReport>& report) override {
|
||||
// Extract the scalability mode reported in the stats.
|
||||
auto outbound_stats = report->GetStatsOfType<RTCOutboundRtpStreamStats>();
|
||||
for (const auto& stat : outbound_stats) {
|
||||
if (stat->scalability_mode.has_value()) {
|
||||
reported_scalability_mode_ = *stat->scalability_mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const SpatialTemporalLayerCounts& encoder_layers_seen() const {
|
||||
return encoder_layers_seen_;
|
||||
}
|
||||
const SpatialTemporalLayerCounts& decoder_layers_seen() const {
|
||||
return decoder_layers_seen_;
|
||||
}
|
||||
const absl::optional<std::string> reported_scalability_mode() const {
|
||||
return reported_scalability_mode_;
|
||||
}
|
||||
|
||||
private:
|
||||
SpatialTemporalLayerCounts encoder_layers_seen_;
|
||||
SpatialTemporalLayerCounts decoder_layers_seen_;
|
||||
absl::optional<std::string> reported_scalability_mode_;
|
||||
};
|
||||
|
||||
MATCHER_P2(HasSpatialAndTemporalLayers,
|
||||
expected_spatial_layers,
|
||||
expected_temporal_layers,
|
||||
"") {
|
||||
if (arg.size() != static_cast<size_t>(expected_spatial_layers)) {
|
||||
*result_listener << "spatial layer count mismatch expected "
|
||||
<< expected_spatial_layers << " but got " << arg.size();
|
||||
return false;
|
||||
}
|
||||
for (const auto& [spatial_layer_index, temporal_layers] : arg) {
|
||||
if (spatial_layer_index < 0 ||
|
||||
spatial_layer_index >= expected_spatial_layers) {
|
||||
*result_listener << "spatial layer index is not in range [0,"
|
||||
<< expected_spatial_layers << "[.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (temporal_layers.size() !=
|
||||
static_cast<size_t>(expected_temporal_layers)) {
|
||||
*result_listener << "temporal layer count mismatch on spatial layer "
|
||||
<< spatial_layer_index << ", expected "
|
||||
<< expected_temporal_layers << " but got "
|
||||
<< temporal_layers.size();
|
||||
return false;
|
||||
}
|
||||
for (const auto& [temporal_layer_index, temporal_layer_frame_count] :
|
||||
temporal_layers) {
|
||||
if (temporal_layer_index < 0 ||
|
||||
temporal_layer_index >= expected_temporal_layers) {
|
||||
*result_listener << "temporal layer index on spatial layer "
|
||||
<< spatial_layer_index << " is not in range [0,"
|
||||
<< expected_temporal_layers << "[.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MATCHER_P2(HasSpatialAndTemporalLayersSMode,
|
||||
expected_spatial_layers,
|
||||
expected_temporal_layers,
|
||||
"") {
|
||||
if (arg.size() != 1) {
|
||||
*result_listener << "spatial layer count mismatch expected 1 but got "
|
||||
<< arg.size();
|
||||
return false;
|
||||
}
|
||||
for (const auto& [spatial_layer_index, temporal_layers] : arg) {
|
||||
if (spatial_layer_index != expected_spatial_layers - 1) {
|
||||
*result_listener << "spatial layer index is not equal to "
|
||||
<< expected_spatial_layers - 1 << ".";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (temporal_layers.size() !=
|
||||
static_cast<size_t>(expected_temporal_layers)) {
|
||||
*result_listener << "temporal layer count mismatch on spatial layer "
|
||||
<< spatial_layer_index << ", expected "
|
||||
<< expected_temporal_layers << " but got "
|
||||
<< temporal_layers.size();
|
||||
return false;
|
||||
}
|
||||
for (const auto& [temporal_layer_index, temporal_layer_frame_count] :
|
||||
temporal_layers) {
|
||||
if (temporal_layer_index < 0 ||
|
||||
temporal_layer_index >= expected_temporal_layers) {
|
||||
*result_listener << "temporal layer index on spatial layer "
|
||||
<< spatial_layer_index << " is not in range [0,"
|
||||
<< expected_temporal_layers << "[.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_P(SvcTest, ScalabilityModeSupported) {
|
||||
std::string trials;
|
||||
if (UseDependencyDescriptor()) {
|
||||
trials += "WebRTC-DependencyDescriptorAdvertised/Enabled/";
|
||||
}
|
||||
test::ScopedFieldTrials override_trials(AppendFieldTrials(trials));
|
||||
std::unique_ptr<NetworkEmulationManager> network_emulation_manager =
|
||||
CreateNetworkEmulationManager(TimeMode::kSimulated);
|
||||
auto analyzer = std::make_unique<SvcVideoQualityAnalyzer>(
|
||||
network_emulation_manager->time_controller()->GetClock());
|
||||
SvcVideoQualityAnalyzer* analyzer_ptr = analyzer.get();
|
||||
auto fixture = CreateTestFixture(
|
||||
UnitTest::GetInstance()->current_test_info()->name(),
|
||||
*network_emulation_manager->time_controller(),
|
||||
network_emulation_manager->CreateEndpointPairWithTwoWayRoutes(
|
||||
BuiltInNetworkBehaviorConfig()),
|
||||
[this](PeerConfigurer* alice) {
|
||||
VideoConfig video(/*stream_label=*/"alice-video", /*width=*/1850,
|
||||
/*height=*/1110, /*fps=*/30);
|
||||
if (IsSMode()) {
|
||||
video.emulated_sfu_config = EmulatedSFUConfig(
|
||||
SvcTestParameters().expected_spatial_layers - 1,
|
||||
SvcTestParameters().expected_temporal_layers - 1);
|
||||
}
|
||||
RtpEncodingParameters parameters;
|
||||
parameters.scalability_mode = SvcTestParameters().scalability_mode;
|
||||
video.encoding_params.push_back(parameters);
|
||||
auto generator = CreateScreenShareFrameGenerator(
|
||||
video, ScreenShareConfig(TimeDelta::Seconds(5)));
|
||||
alice->AddVideoConfig(std::move(video), std::move(generator));
|
||||
alice->SetVideoCodecs({video_codec_config});
|
||||
},
|
||||
[](PeerConfigurer* bob) {}, std::move(analyzer));
|
||||
fixture->Run(RunParams(TimeDelta::Seconds(10)));
|
||||
EXPECT_THAT(analyzer_ptr->encoder_layers_seen(),
|
||||
HasSpatialAndTemporalLayers(
|
||||
SvcTestParameters().expected_spatial_layers,
|
||||
SvcTestParameters().expected_temporal_layers));
|
||||
if (IsSMode()) {
|
||||
EXPECT_THAT(analyzer_ptr->decoder_layers_seen(),
|
||||
HasSpatialAndTemporalLayersSMode(
|
||||
SvcTestParameters().expected_spatial_layers,
|
||||
SvcTestParameters().expected_temporal_layers));
|
||||
} else {
|
||||
EXPECT_THAT(analyzer_ptr->decoder_layers_seen(),
|
||||
HasSpatialAndTemporalLayers(
|
||||
SvcTestParameters().expected_spatial_layers,
|
||||
SvcTestParameters().expected_temporal_layers));
|
||||
}
|
||||
EXPECT_THAT(analyzer_ptr->reported_scalability_mode(),
|
||||
Optional(SvcTestParameters().scalability_mode));
|
||||
|
||||
RTC_LOG(LS_INFO) << "Encoder layers seen: "
|
||||
<< analyzer_ptr->encoder_layers_seen().size();
|
||||
for (auto& [spatial_index, temporal_layers] :
|
||||
analyzer_ptr->encoder_layers_seen()) {
|
||||
for (auto& [temporal_index, frame_count] : temporal_layers) {
|
||||
RTC_LOG(LS_INFO) << " Layer: " << spatial_index << "," << temporal_index
|
||||
<< " frames: " << frame_count;
|
||||
}
|
||||
}
|
||||
RTC_LOG(LS_INFO) << "Decoder layers seen: "
|
||||
<< analyzer_ptr->decoder_layers_seen().size();
|
||||
for (auto& [spatial_index, temporal_layers] :
|
||||
analyzer_ptr->decoder_layers_seen()) {
|
||||
for (auto& [temporal_index, frame_count] : temporal_layers) {
|
||||
RTC_LOG(LS_INFO) << " Layer: " << spatial_index << "," << temporal_index
|
||||
<< " frames: " << frame_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SvcTestVP8,
|
||||
SvcTest,
|
||||
Combine(Values(SvcTestParameters::Create(kVp8CodecName, "L1T1"),
|
||||
SvcTestParameters::Create(kVp8CodecName, "L1T2"),
|
||||
SvcTestParameters::Create(kVp8CodecName, "L1T3")),
|
||||
Values(UseDependencyDescriptor::Disabled,
|
||||
UseDependencyDescriptor::Enabled)),
|
||||
SvcTestNameGenerator);
|
||||
|
||||
#if defined(WEBRTC_USE_H264)
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SvcTestH264,
|
||||
SvcTest,
|
||||
Combine(ValuesIn({
|
||||
SvcTestParameters::Create(kH264CodecName, "L1T1"),
|
||||
SvcTestParameters::Create(kH264CodecName, "L1T2"),
|
||||
SvcTestParameters::Create(kH264CodecName, "L1T3"),
|
||||
}),
|
||||
// Like AV1, H.264 RTP format does not include SVC related
|
||||
// information, so always use Dependency Descriptor.
|
||||
Values(UseDependencyDescriptor::Enabled)),
|
||||
SvcTestNameGenerator);
|
||||
#endif
|
||||
|
||||
#if defined(RTC_ENABLE_VP9)
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SvcTestVP9,
|
||||
SvcTest,
|
||||
Combine(
|
||||
// TODO(bugs.webrtc.org/13960): Fix and enable remaining VP9 modes
|
||||
ValuesIn({
|
||||
SvcTestParameters::Create(kVp9CodecName, "L1T1"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L1T2"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L1T3"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L2T1"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L2T1h"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L2T1_KEY"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L2T2"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L2T2h"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L2T2_KEY"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L2T2_KEY_SHIFT"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L2T3"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L2T3h"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L2T3_KEY"),
|
||||
// SvcTestParameters::Create(kVp9CodecName, "L2T3_KEY_SHIFT"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L3T1"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L3T1h"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L3T1_KEY"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L3T2"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L3T2h"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L3T2_KEY"),
|
||||
// SvcTestParameters::Create(kVp9CodecName, "L3T2_KEY_SHIFT"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L3T3"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L3T3h"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "L3T3_KEY"),
|
||||
// SvcTestParameters::Create(kVp9CodecName, "L3T3_KEY_SHIFT"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "S2T1"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "S2T1h"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "S2T2"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "S2T2h"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "S2T3"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "S2T3h"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "S3T1"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "S3T1h"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "S3T2"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "S3T2h"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "S3T3"),
|
||||
SvcTestParameters::Create(kVp9CodecName, "S3T3h"),
|
||||
}),
|
||||
Values(UseDependencyDescriptor::Disabled,
|
||||
UseDependencyDescriptor::Enabled)),
|
||||
SvcTestNameGenerator);
|
||||
#endif
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SvcTestAV1,
|
||||
SvcTest,
|
||||
Combine(ValuesIn({
|
||||
SvcTestParameters::Create(kAv1CodecName, "L1T1"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "L1T2"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "L1T3"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "L2T1"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "L2T1h"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "L2T1_KEY"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "L2T2"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "L2T2h"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "L2T2_KEY"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "L2T2_KEY_SHIFT"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "L2T3"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "L2T3h"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "L2T3_KEY"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "L2T3_KEY_SHIFT"),
|
||||
// TODO(bugs.webrtc.org/15666): Investigate and reenable AV1
|
||||
// L3 tests. SvcTestParameters::Create(kAv1CodecName, "L3T1"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "L3T1h"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "L3T1_KEY"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "L3T2"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "L3T2h"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "L3T2_KEY"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "L3T2_KEY_SHIFT"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "L3T3"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "L3T3h"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "L3T3_KEY"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "L3T3_KEY_SHIFT"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "S2T1"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "S2T1h"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "S2T2"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "S2T2h"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "S2T3"),
|
||||
SvcTestParameters::Create(kAv1CodecName, "S2T3h"),
|
||||
// TODO(bugs.webrtc.org/15666): Investigate and reenable AV1
|
||||
// S3 tests.
|
||||
// SvcTestParameters::Create(kAv1CodecName, "S3T1"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "S3T1h"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "S3T2"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "S3T2h"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "S3T3"),
|
||||
// SvcTestParameters::Create(kAv1CodecName, "S3T3h"),
|
||||
}),
|
||||
Values(UseDependencyDescriptor::Enabled)),
|
||||
SvcTestNameGenerator);
|
||||
|
||||
} // namespace webrtc
|
||||
184
TMessagesProj/jni/voip/webrtc/pc/test/test_sdp_strings.h
Normal file
184
TMessagesProj/jni/voip/webrtc/pc/test/test_sdp_strings.h
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Copyright 2012 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.
|
||||
*/
|
||||
|
||||
// This file contain SDP strings used for testing.
|
||||
|
||||
#ifndef PC_TEST_TEST_SDP_STRINGS_H_
|
||||
#define PC_TEST_TEST_SDP_STRINGS_H_
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// SDP offer string from a Nightly FireFox build.
|
||||
static const char kFireFoxSdpOffer[] =
|
||||
"v=0\r\n"
|
||||
"o=Mozilla-SIPUA 23551 0 IN IP4 0.0.0.0\r\n"
|
||||
"s=SIP Call\r\n"
|
||||
"t=0 0\r\n"
|
||||
"a=ice-ufrag:e5785931\r\n"
|
||||
"a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n"
|
||||
"a=fingerprint:sha-256 A7:24:72:CA:6E:02:55:39:BA:66:DF:6E:CC:4C:D8:B0:1A:"
|
||||
"BF:1A:56:65:7D:F4:03:AD:7E:77:43:2A:29:EC:93\r\n"
|
||||
"m=audio 36993 RTP/SAVPF 109 0 8 101\r\n"
|
||||
"c=IN IP4 74.95.2.170\r\n"
|
||||
"a=rtpmap:109 opus/48000/2\r\n"
|
||||
"a=ptime:20\r\n"
|
||||
"a=rtcp-mux\r\n"
|
||||
"a=rtpmap:0 PCMU/8000\r\n"
|
||||
"a=rtpmap:8 PCMA/8000\r\n"
|
||||
"a=rtpmap:101 telephone-event/8000\r\n"
|
||||
"a=fmtp:101 0-15\r\n"
|
||||
"a=sendrecv\r\n"
|
||||
"a=candidate:0 1 UDP 2112946431 172.16.191.1 61725 typ host\r\n"
|
||||
"a=candidate:2 1 UDP 2112487679 172.16.131.1 58798 typ host\r\n"
|
||||
"a=candidate:4 1 UDP 2113667327 10.0.254.2 58122 typ host\r\n"
|
||||
"a=candidate:5 1 UDP 1694302207 74.95.2.170 36993 typ srflx raddr "
|
||||
"10.0.254.2 rport 58122\r\n"
|
||||
"a=candidate:0 2 UDP 2112946430 172.16.191.1 55025 typ host\r\n"
|
||||
"a=candidate:2 2 UDP 2112487678 172.16.131.1 63576 typ host\r\n"
|
||||
"a=candidate:4 2 UDP 2113667326 10.0.254.2 50962 typ host\r\n"
|
||||
"a=candidate:5 2 UDP 1694302206 74.95.2.170 41028 typ srflx raddr"
|
||||
" 10.0.254.2 rport 50962\r\n"
|
||||
"m=video 38826 RTP/SAVPF 120\r\n"
|
||||
"c=IN IP4 74.95.2.170\r\n"
|
||||
"a=rtcp-mux\r\n"
|
||||
"a=rtpmap:120 VP8/90000\r\n"
|
||||
"a=sendrecv\r\n"
|
||||
"a=candidate:0 1 UDP 2112946431 172.16.191.1 62017 typ host\r\n"
|
||||
"a=candidate:2 1 UDP 2112487679 172.16.131.1 59741 typ host\r\n"
|
||||
"a=candidate:4 1 UDP 2113667327 10.0.254.2 62652 typ host\r\n"
|
||||
"a=candidate:5 1 UDP 1694302207 74.95.2.170 38826 typ srflx raddr"
|
||||
" 10.0.254.2 rport 62652\r\n"
|
||||
"a=candidate:0 2 UDP 2112946430 172.16.191.1 63440 typ host\r\n"
|
||||
"a=candidate:2 2 UDP 2112487678 172.16.131.1 51847 typ host\r\n"
|
||||
"a=candidate:4 2 UDP 2113667326 10.0.254.2 58890 typ host\r\n"
|
||||
"a=candidate:5 2 UDP 1694302206 74.95.2.170 33611 typ srflx raddr"
|
||||
" 10.0.254.2 rport 58890\r\n"
|
||||
#ifdef WEBRTC_HAVE_SCTP
|
||||
"m=application 45536 DTLS/SCTP 5000\r\n"
|
||||
"c=IN IP4 74.95.2.170\r\n"
|
||||
"a=fmtp:5000 protocol=webrtc-datachannel;streams=16\r\n"
|
||||
"a=sendrecv\r\n"
|
||||
"a=candidate:0 1 UDP 2112946431 172.16.191.1 60248 typ host\r\n"
|
||||
"a=candidate:2 1 UDP 2112487679 172.16.131.1 55925 typ host\r\n"
|
||||
"a=candidate:4 1 UDP 2113667327 10.0.254.2 65268 typ host\r\n"
|
||||
"a=candidate:5 1 UDP 1694302207 74.95.2.170 45536 typ srflx raddr"
|
||||
" 10.0.254.2 rport 65268\r\n"
|
||||
"a=candidate:0 2 UDP 2112946430 172.16.191.1 49162 typ host\r\n"
|
||||
"a=candidate:2 2 UDP 2112487678 172.16.131.1 59635 typ host\r\n"
|
||||
"a=candidate:4 2 UDP 2113667326 10.0.254.2 61232 typ host\r\n"
|
||||
"a=candidate:5 2 UDP 1694302206 74.95.2.170 45468 typ srflx raddr"
|
||||
" 10.0.254.2 rport 61232\r\n"
|
||||
#endif
|
||||
; // NOLINT(whitespace/semicolon)
|
||||
|
||||
// Audio SDP with a limited set of audio codecs.
|
||||
static const char kAudioSdpPlanB[] =
|
||||
"v=0\r\n"
|
||||
"o=- 7859371131 2 IN IP4 192.168.30.208\r\n"
|
||||
"s=-\r\n"
|
||||
"c=IN IP4 192.168.30.208\r\n"
|
||||
"t=0 0\r\n"
|
||||
"m=audio 16000 RTP/SAVPF 0 8 126\r\n"
|
||||
"a=rtpmap:0 PCMU/8000\r\n"
|
||||
"a=rtpmap:8 PCMA/8000\r\n"
|
||||
"a=rtpmap:126 telephone-event/8000\r\n"
|
||||
"a=sendrecv\r\n"
|
||||
"a=rtcp:16000 IN IP4 192.168.30.208\r\n"
|
||||
"a=rtcp-mux\r\n"
|
||||
"a=crypto:0 AES_CM_128_HMAC_SHA1_80 "
|
||||
"inline:tvKIFjbMQ7W0/C2RzhwN0oQglj/7GJg+frdsNRxt\r\n"
|
||||
"a=ice-ufrag:AI2sRT3r\r\n"
|
||||
"a=ice-pwd:lByS9z2RSQlSE9XurlvjYmEm\r\n"
|
||||
"a=ssrc:4227871655 cname:GeAAgb6XCPNLVMX5\r\n"
|
||||
"a=ssrc:4227871655 msid:1NFAV3iD08ioO2339rQS9pfOI9mDf6GeG9F4 a0\r\n"
|
||||
"a=ssrc:4227871655 mslabel:1NFAV3iD08ioO2339rQS9pfOI9mDf6GeG9F4\r\n"
|
||||
"a=ssrc:4227871655 label:1NFAV3iD08ioO2339rQS9pfOI9mDf6GeG9F4a0\r\n"
|
||||
"a=mid:audio\r\n";
|
||||
// Same string as above but with the MID changed to the Unified Plan default.
|
||||
// This is needed so that this SDP can be used as an answer for a Unified Plan
|
||||
// offer.
|
||||
static const char kAudioSdpUnifiedPlan[] =
|
||||
"v=0\r\n"
|
||||
"o=- 7859371131 2 IN IP4 192.168.30.208\r\n"
|
||||
"s=-\r\n"
|
||||
"c=IN IP4 192.168.30.208\r\n"
|
||||
"t=0 0\r\n"
|
||||
"m=audio 16000 RTP/SAVPF 0 8 126\r\n"
|
||||
"a=rtpmap:0 PCMU/8000\r\n"
|
||||
"a=rtpmap:8 PCMA/8000\r\n"
|
||||
"a=rtpmap:126 telephone-event/8000\r\n"
|
||||
"a=sendrecv\r\n"
|
||||
"a=rtcp:16000 IN IP4 192.168.30.208\r\n"
|
||||
"a=rtcp-mux\r\n"
|
||||
"a=crypto:0 AES_CM_128_HMAC_SHA1_80 "
|
||||
"inline:tvKIFjbMQ7W0/C2RzhwN0oQglj/7GJg+frdsNRxt\r\n"
|
||||
"a=ice-ufrag:AI2sRT3r\r\n"
|
||||
"a=ice-pwd:lByS9z2RSQlSE9XurlvjYmEm\r\n"
|
||||
"a=ssrc:4227871655 cname:GeAAgb6XCPNLVMX5\r\n"
|
||||
"a=ssrc:4227871655 msid:1NFAV3iD08ioO2339rQS9pfOI9mDf6GeG9F4 a0\r\n"
|
||||
"a=ssrc:4227871655 mslabel:1NFAV3iD08ioO2339rQS9pfOI9mDf6GeG9F4\r\n"
|
||||
"a=ssrc:4227871655 label:1NFAV3iD08ioO2339rQS9pfOI9mDf6GeG9F4a0\r\n"
|
||||
"a=mid:0\r\n";
|
||||
|
||||
static const char kAudioSdpWithUnsupportedCodecsPlanB[] =
|
||||
"v=0\r\n"
|
||||
"o=- 6858750541 2 IN IP4 192.168.30.208\r\n"
|
||||
"s=-\r\n"
|
||||
"c=IN IP4 192.168.30.208\r\n"
|
||||
"t=0 0\r\n"
|
||||
"m=audio 16000 RTP/SAVPF 0 8 109 110 126\r\n"
|
||||
"a=rtpmap:0 PCMU/8000\r\n"
|
||||
"a=rtpmap:8 PCMA/8000\r\n"
|
||||
"a=rtpmap:109 WeirdCodec1/8000\r\n"
|
||||
"a=rtpmap:110 WeirdCodec2/8000\r\n"
|
||||
"a=rtpmap:126 telephone-event/8000\r\n"
|
||||
"a=sendonly\r\n"
|
||||
"a=rtcp:16000 IN IP4 192.168.30.208\r\n"
|
||||
"a=rtcp-mux\r\n"
|
||||
"a=crypto:0 AES_CM_128_HMAC_SHA1_80 "
|
||||
"inline:tvKIFjbMQ7W0/C2RzhwN0oQglj/7GJg+frdsNRxt\r\n"
|
||||
"a=ice-ufrag:AI2sRT3r\r\n"
|
||||
"a=ice-pwd:lByS9z2RSQlSE9XurlvjYmEm\r\n"
|
||||
"a=ssrc:4227871655 cname:TsmD02HRfhkJBm4m\r\n"
|
||||
"a=ssrc:4227871655 msid:7nU0TApbB-n4dfPlCplWT9QTEsbBDS1IlpW3 a0\r\n"
|
||||
"a=ssrc:4227871655 mslabel:7nU0TApbB-n4dfPlCplWT9QTEsbBDS1IlpW3\r\n"
|
||||
"a=ssrc:4227871655 label:7nU0TApbB-n4dfPlCplWT9QTEsbBDS1IlpW3a0\r\n"
|
||||
"a=mid:audio\r\n";
|
||||
// Same string as above but with the MID changed to the Unified Plan default.
|
||||
// This is needed so that this SDP can be used as an answer for a Unified Plan
|
||||
// offer.
|
||||
static const char kAudioSdpWithUnsupportedCodecsUnifiedPlan[] =
|
||||
"v=0\r\n"
|
||||
"o=- 6858750541 2 IN IP4 192.168.30.208\r\n"
|
||||
"s=-\r\n"
|
||||
"c=IN IP4 192.168.30.208\r\n"
|
||||
"t=0 0\r\n"
|
||||
"m=audio 16000 RTP/SAVPF 0 8 109 110 126\r\n"
|
||||
"a=rtpmap:0 PCMU/8000\r\n"
|
||||
"a=rtpmap:8 PCMA/8000\r\n"
|
||||
"a=rtpmap:109 WeirdCodec1/8000\r\n"
|
||||
"a=rtpmap:110 WeirdCodec2/8000\r\n"
|
||||
"a=rtpmap:126 telephone-event/8000\r\n"
|
||||
"a=sendonly\r\n"
|
||||
"a=rtcp:16000 IN IP4 192.168.30.208\r\n"
|
||||
"a=rtcp-mux\r\n"
|
||||
"a=crypto:0 AES_CM_128_HMAC_SHA1_80 "
|
||||
"inline:tvKIFjbMQ7W0/C2RzhwN0oQglj/7GJg+frdsNRxt\r\n"
|
||||
"a=ice-ufrag:AI2sRT3r\r\n"
|
||||
"a=ice-pwd:lByS9z2RSQlSE9XurlvjYmEm\r\n"
|
||||
"a=ssrc:4227871655 cname:TsmD02HRfhkJBm4m\r\n"
|
||||
"a=ssrc:4227871655 msid:7nU0TApbB-n4dfPlCplWT9QTEsbBDS1IlpW3 a0\r\n"
|
||||
"a=ssrc:4227871655 mslabel:7nU0TApbB-n4dfPlCplWT9QTEsbBDS1IlpW3\r\n"
|
||||
"a=ssrc:4227871655 label:7nU0TApbB-n4dfPlCplWT9QTEsbBDS1IlpW3a0\r\n"
|
||||
"a=mid:0\r\n";
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // PC_TEST_TEST_SDP_STRINGS_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue