In PeerConnectionTestWrapper, put audio input on a separate thread.
This will prevent it from blocking network input when it falls behind, which is happening when running with ThreadSanitizer. BUG=webrtc:4663 Review URL: https://codereview.webrtc.org/1236023010 Cr-Commit-Position: refs/heads/master@{#9707}
This commit is contained in:
@ -518,8 +518,7 @@ class PeerConnectionTestClientBase
|
|||||||
if (!allocator_factory_) {
|
if (!allocator_factory_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fake_audio_capture_module_ = FakeAudioCaptureModule::Create(
|
fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
|
||||||
rtc::Thread::Current());
|
|
||||||
|
|
||||||
if (fake_audio_capture_module_ == NULL) {
|
if (fake_audio_capture_module_ == NULL) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -268,17 +268,7 @@ class PeerConnectionEndToEndTest
|
|||||||
DataChannelList callee_signaled_data_channels_;
|
DataChannelList callee_signaled_data_channels_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Disable for TSan v2, see
|
TEST_F(PeerConnectionEndToEndTest, Call) {
|
||||||
// https://code.google.com/p/webrtc/issues/detail?id=1205 for details.
|
|
||||||
#if !defined(THREAD_SANITIZER)
|
|
||||||
|
|
||||||
// Flaky on Windows. Disabled per issue 4464.
|
|
||||||
#ifdef WEBRTC_WIN
|
|
||||||
#define MAYBE_Call DISABLED_Call
|
|
||||||
#else
|
|
||||||
#define MAYBE_Call Call
|
|
||||||
#endif
|
|
||||||
TEST_F(PeerConnectionEndToEndTest, MAYBE_Call) {
|
|
||||||
CreatePcs();
|
CreatePcs();
|
||||||
GetAndAddUserMedia();
|
GetAndAddUserMedia();
|
||||||
Negotiate();
|
Negotiate();
|
||||||
@ -427,4 +417,3 @@ TEST_F(PeerConnectionEndToEndTest,
|
|||||||
EXPECT_EQ(1U, dc_1_observer->received_message_count());
|
EXPECT_EQ(1U, dc_1_observer->received_message_count());
|
||||||
EXPECT_EQ(1U, dc_2_observer->received_message_count());
|
EXPECT_EQ(1U, dc_2_observer->received_message_count());
|
||||||
}
|
}
|
||||||
#endif // if !defined(THREAD_SANITIZER)
|
|
||||||
|
@ -54,13 +54,11 @@ static const uint32_t kMaxVolume = 14392;
|
|||||||
enum {
|
enum {
|
||||||
MSG_START_PROCESS,
|
MSG_START_PROCESS,
|
||||||
MSG_RUN_PROCESS,
|
MSG_RUN_PROCESS,
|
||||||
MSG_STOP_PROCESS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
FakeAudioCaptureModule::FakeAudioCaptureModule(
|
FakeAudioCaptureModule::FakeAudioCaptureModule()
|
||||||
rtc::Thread* process_thread)
|
|
||||||
: last_process_time_ms_(0),
|
: last_process_time_ms_(0),
|
||||||
audio_callback_(NULL),
|
audio_callback_(nullptr),
|
||||||
recording_(false),
|
recording_(false),
|
||||||
playing_(false),
|
playing_(false),
|
||||||
play_is_initialized_(false),
|
play_is_initialized_(false),
|
||||||
@ -68,23 +66,20 @@ FakeAudioCaptureModule::FakeAudioCaptureModule(
|
|||||||
current_mic_level_(kMaxVolume),
|
current_mic_level_(kMaxVolume),
|
||||||
started_(false),
|
started_(false),
|
||||||
next_frame_time_(0),
|
next_frame_time_(0),
|
||||||
process_thread_(process_thread),
|
|
||||||
frames_received_(0) {
|
frames_received_(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FakeAudioCaptureModule::~FakeAudioCaptureModule() {
|
FakeAudioCaptureModule::~FakeAudioCaptureModule() {
|
||||||
// Ensure that thread stops calling ProcessFrame().
|
if (process_thread_) {
|
||||||
process_thread_->Send(this, MSG_STOP_PROCESS);
|
process_thread_->Stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc::scoped_refptr<FakeAudioCaptureModule> FakeAudioCaptureModule::Create(
|
rtc::scoped_refptr<FakeAudioCaptureModule> FakeAudioCaptureModule::Create() {
|
||||||
rtc::Thread* process_thread) {
|
|
||||||
if (process_thread == NULL) return NULL;
|
|
||||||
|
|
||||||
rtc::scoped_refptr<FakeAudioCaptureModule> capture_module(
|
rtc::scoped_refptr<FakeAudioCaptureModule> capture_module(
|
||||||
new rtc::RefCountedObject<FakeAudioCaptureModule>(process_thread));
|
new rtc::RefCountedObject<FakeAudioCaptureModule>());
|
||||||
if (!capture_module->Initialize()) {
|
if (!capture_module->Initialize()) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return capture_module;
|
return capture_module;
|
||||||
}
|
}
|
||||||
@ -601,9 +596,6 @@ void FakeAudioCaptureModule::OnMessage(rtc::Message* msg) {
|
|||||||
case MSG_RUN_PROCESS:
|
case MSG_RUN_PROCESS:
|
||||||
ProcessFrameP();
|
ProcessFrameP();
|
||||||
break;
|
break;
|
||||||
case MSG_STOP_PROCESS:
|
|
||||||
StopProcessP();
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
// All existing messages should be caught. Getting here should never
|
// All existing messages should be caught. Getting here should never
|
||||||
// happen.
|
// happen.
|
||||||
@ -650,14 +642,22 @@ bool FakeAudioCaptureModule::ShouldStartProcessing() {
|
|||||||
|
|
||||||
void FakeAudioCaptureModule::UpdateProcessing(bool start) {
|
void FakeAudioCaptureModule::UpdateProcessing(bool start) {
|
||||||
if (start) {
|
if (start) {
|
||||||
|
if (!process_thread_) {
|
||||||
|
process_thread_.reset(new rtc::Thread());
|
||||||
|
process_thread_->Start();
|
||||||
|
}
|
||||||
process_thread_->Post(this, MSG_START_PROCESS);
|
process_thread_->Post(this, MSG_START_PROCESS);
|
||||||
} else {
|
} else {
|
||||||
process_thread_->Send(this, MSG_STOP_PROCESS);
|
if (process_thread_) {
|
||||||
|
process_thread_->Stop();
|
||||||
|
process_thread_.reset(nullptr);
|
||||||
|
}
|
||||||
|
started_ = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeAudioCaptureModule::StartProcessP() {
|
void FakeAudioCaptureModule::StartProcessP() {
|
||||||
ASSERT(rtc::Thread::Current() == process_thread_);
|
ASSERT(process_thread_->IsCurrent());
|
||||||
if (started_) {
|
if (started_) {
|
||||||
// Already started.
|
// Already started.
|
||||||
return;
|
return;
|
||||||
@ -666,27 +666,22 @@ void FakeAudioCaptureModule::StartProcessP() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FakeAudioCaptureModule::ProcessFrameP() {
|
void FakeAudioCaptureModule::ProcessFrameP() {
|
||||||
ASSERT(rtc::Thread::Current() == process_thread_);
|
ASSERT(process_thread_->IsCurrent());
|
||||||
if (!started_) {
|
if (!started_) {
|
||||||
next_frame_time_ = rtc::Time();
|
next_frame_time_ = rtc::Time();
|
||||||
started_ = true;
|
started_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool playing;
|
|
||||||
bool recording;
|
|
||||||
{
|
{
|
||||||
rtc::CritScope cs(&crit_);
|
rtc::CritScope cs(&crit_);
|
||||||
playing = playing_;
|
|
||||||
recording = recording_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive and send frames every kTimePerFrameMs.
|
// Receive and send frames every kTimePerFrameMs.
|
||||||
if (playing) {
|
if (playing_) {
|
||||||
ReceiveFrameP();
|
ReceiveFrameP();
|
||||||
}
|
}
|
||||||
if (recording) {
|
if (recording_) {
|
||||||
SendFrameP();
|
SendFrameP();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
next_frame_time_ += kTimePerFrameMs;
|
next_frame_time_ += kTimePerFrameMs;
|
||||||
const uint32 current_time = rtc::Time();
|
const uint32 current_time = rtc::Time();
|
||||||
@ -696,7 +691,7 @@ void FakeAudioCaptureModule::ProcessFrameP() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FakeAudioCaptureModule::ReceiveFrameP() {
|
void FakeAudioCaptureModule::ReceiveFrameP() {
|
||||||
ASSERT(rtc::Thread::Current() == process_thread_);
|
ASSERT(process_thread_->IsCurrent());
|
||||||
{
|
{
|
||||||
rtc::CritScope cs(&crit_callback_);
|
rtc::CritScope cs(&crit_callback_);
|
||||||
if (!audio_callback_) {
|
if (!audio_callback_) {
|
||||||
@ -727,7 +722,7 @@ void FakeAudioCaptureModule::ReceiveFrameP() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FakeAudioCaptureModule::SendFrameP() {
|
void FakeAudioCaptureModule::SendFrameP() {
|
||||||
ASSERT(rtc::Thread::Current() == process_thread_);
|
ASSERT(process_thread_->IsCurrent());
|
||||||
rtc::CritScope cs(&crit_callback_);
|
rtc::CritScope cs(&crit_callback_);
|
||||||
if (!audio_callback_) {
|
if (!audio_callback_) {
|
||||||
return;
|
return;
|
||||||
@ -747,8 +742,3 @@ void FakeAudioCaptureModule::SendFrameP() {
|
|||||||
SetMicrophoneVolume(current_mic_level);
|
SetMicrophoneVolume(current_mic_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeAudioCaptureModule::StopProcessP() {
|
|
||||||
ASSERT(rtc::Thread::Current() == process_thread_);
|
|
||||||
started_ = false;
|
|
||||||
process_thread_->Clear(this);
|
|
||||||
}
|
|
||||||
|
@ -40,14 +40,13 @@
|
|||||||
#include "webrtc/base/basictypes.h"
|
#include "webrtc/base/basictypes.h"
|
||||||
#include "webrtc/base/criticalsection.h"
|
#include "webrtc/base/criticalsection.h"
|
||||||
#include "webrtc/base/messagehandler.h"
|
#include "webrtc/base/messagehandler.h"
|
||||||
|
#include "webrtc/base/scoped_ptr.h"
|
||||||
#include "webrtc/base/scoped_ref_ptr.h"
|
#include "webrtc/base/scoped_ref_ptr.h"
|
||||||
#include "webrtc/common_types.h"
|
#include "webrtc/common_types.h"
|
||||||
#include "webrtc/modules/audio_device/include/audio_device.h"
|
#include "webrtc/modules/audio_device/include/audio_device.h"
|
||||||
|
|
||||||
namespace rtc {
|
namespace rtc {
|
||||||
|
|
||||||
class Thread;
|
class Thread;
|
||||||
|
|
||||||
} // namespace rtc
|
} // namespace rtc
|
||||||
|
|
||||||
class FakeAudioCaptureModule
|
class FakeAudioCaptureModule
|
||||||
@ -62,10 +61,7 @@ class FakeAudioCaptureModule
|
|||||||
static const int kNumberBytesPerSample = sizeof(Sample);
|
static const int kNumberBytesPerSample = sizeof(Sample);
|
||||||
|
|
||||||
// Creates a FakeAudioCaptureModule or returns NULL on failure.
|
// Creates a FakeAudioCaptureModule or returns NULL on failure.
|
||||||
// |process_thread| is used to push and pull audio frames to and from the
|
static rtc::scoped_refptr<FakeAudioCaptureModule> Create();
|
||||||
// returned instance. Note: ownership of |process_thread| is not handed over.
|
|
||||||
static rtc::scoped_refptr<FakeAudioCaptureModule> Create(
|
|
||||||
rtc::Thread* process_thread);
|
|
||||||
|
|
||||||
// Returns the number of frames that have been successfully pulled by the
|
// Returns the number of frames that have been successfully pulled by the
|
||||||
// instance. Note that correctly detecting success can only be done if the
|
// instance. Note that correctly detecting success can only be done if the
|
||||||
@ -206,7 +202,7 @@ class FakeAudioCaptureModule
|
|||||||
// exposed in which case the burden of proper instantiation would be put on
|
// exposed in which case the burden of proper instantiation would be put on
|
||||||
// the creator of a FakeAudioCaptureModule instance. To create an instance of
|
// the creator of a FakeAudioCaptureModule instance. To create an instance of
|
||||||
// this class use the Create(..) API.
|
// this class use the Create(..) API.
|
||||||
explicit FakeAudioCaptureModule(rtc::Thread* process_thread);
|
explicit FakeAudioCaptureModule();
|
||||||
// The destructor is protected because it is reference counted and should not
|
// The destructor is protected because it is reference counted and should not
|
||||||
// be deleted directly.
|
// be deleted directly.
|
||||||
virtual ~FakeAudioCaptureModule();
|
virtual ~FakeAudioCaptureModule();
|
||||||
@ -239,8 +235,6 @@ class FakeAudioCaptureModule
|
|||||||
void ReceiveFrameP();
|
void ReceiveFrameP();
|
||||||
// Pushes frames to the registered webrtc::AudioTransport.
|
// Pushes frames to the registered webrtc::AudioTransport.
|
||||||
void SendFrameP();
|
void SendFrameP();
|
||||||
// Stops the periodic calling of ProcessFrame() in a thread safe way.
|
|
||||||
void StopProcessP();
|
|
||||||
|
|
||||||
// The time in milliseconds when Process() was last called or 0 if no call
|
// The time in milliseconds when Process() was last called or 0 if no call
|
||||||
// has been made.
|
// has been made.
|
||||||
@ -266,8 +260,7 @@ class FakeAudioCaptureModule
|
|||||||
bool started_;
|
bool started_;
|
||||||
uint32 next_frame_time_;
|
uint32 next_frame_time_;
|
||||||
|
|
||||||
// User provided thread context.
|
rtc::scoped_ptr<rtc::Thread> process_thread_;
|
||||||
rtc::Thread* process_thread_;
|
|
||||||
|
|
||||||
// Buffer for storing samples received from the webrtc::AudioTransport.
|
// Buffer for storing samples received from the webrtc::AudioTransport.
|
||||||
char rec_buffer_[kNumberSamples * kNumberBytesPerSample];
|
char rec_buffer_[kNumberSamples * kNumberBytesPerSample];
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "webrtc/base/criticalsection.h"
|
||||||
#include "webrtc/base/gunit.h"
|
#include "webrtc/base/gunit.h"
|
||||||
#include "webrtc/base/scoped_ref_ptr.h"
|
#include "webrtc/base/scoped_ref_ptr.h"
|
||||||
#include "webrtc/base/thread.h"
|
#include "webrtc/base/thread.h"
|
||||||
@ -48,8 +49,7 @@ class FakeAdmTest : public testing::Test,
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
fake_audio_capture_module_ = FakeAudioCaptureModule::Create(
|
fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
|
||||||
rtc::Thread::Current());
|
|
||||||
EXPECT_TRUE(fake_audio_capture_module_.get() != NULL);
|
EXPECT_TRUE(fake_audio_capture_module_.get() != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +65,7 @@ class FakeAdmTest : public testing::Test,
|
|||||||
const uint32_t currentMicLevel,
|
const uint32_t currentMicLevel,
|
||||||
const bool keyPressed,
|
const bool keyPressed,
|
||||||
uint32_t& newMicLevel) override {
|
uint32_t& newMicLevel) override {
|
||||||
|
rtc::CritScope cs(&crit_);
|
||||||
rec_buffer_bytes_ = nSamples * nBytesPerSample;
|
rec_buffer_bytes_ = nSamples * nBytesPerSample;
|
||||||
if ((rec_buffer_bytes_ == 0) ||
|
if ((rec_buffer_bytes_ == 0) ||
|
||||||
(rec_buffer_bytes_ > FakeAudioCaptureModule::kNumberSamples *
|
(rec_buffer_bytes_ > FakeAudioCaptureModule::kNumberSamples *
|
||||||
@ -87,6 +88,7 @@ class FakeAdmTest : public testing::Test,
|
|||||||
uint32_t& nSamplesOut,
|
uint32_t& nSamplesOut,
|
||||||
int64_t* elapsed_time_ms,
|
int64_t* elapsed_time_ms,
|
||||||
int64_t* ntp_time_ms) override {
|
int64_t* ntp_time_ms) override {
|
||||||
|
rtc::CritScope cs(&crit_);
|
||||||
++pull_iterations_;
|
++pull_iterations_;
|
||||||
const uint32_t audio_buffer_size = nSamples * nBytesPerSample;
|
const uint32_t audio_buffer_size = nSamples * nBytesPerSample;
|
||||||
const uint32_t bytes_out = RecordedDataReceived() ?
|
const uint32_t bytes_out = RecordedDataReceived() ?
|
||||||
@ -98,8 +100,14 @@ class FakeAdmTest : public testing::Test,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int push_iterations() const { return push_iterations_; }
|
int push_iterations() const {
|
||||||
int pull_iterations() const { return pull_iterations_; }
|
rtc::CritScope cs(&crit_);
|
||||||
|
return push_iterations_;
|
||||||
|
}
|
||||||
|
int pull_iterations() const {
|
||||||
|
rtc::CritScope cs(&crit_);
|
||||||
|
return pull_iterations_;
|
||||||
|
}
|
||||||
|
|
||||||
rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
|
rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
|
||||||
|
|
||||||
@ -118,6 +126,8 @@ class FakeAdmTest : public testing::Test,
|
|||||||
return min_buffer_size;
|
return min_buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutable rtc::CriticalSection crit_;
|
||||||
|
|
||||||
int push_iterations_;
|
int push_iterations_;
|
||||||
int pull_iterations_;
|
int pull_iterations_;
|
||||||
|
|
||||||
|
@ -75,8 +75,7 @@ bool PeerConnectionTestWrapper::CreatePc(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fake_audio_capture_module_ = FakeAudioCaptureModule::Create(
|
fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
|
||||||
rtc::Thread::Current());
|
|
||||||
if (fake_audio_capture_module_ == NULL) {
|
if (fake_audio_capture_module_ == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
#include "talk/app/webrtc/test/fakeconstraints.h"
|
#include "talk/app/webrtc/test/fakeconstraints.h"
|
||||||
#include "talk/app/webrtc/test/fakevideotrackrenderer.h"
|
#include "talk/app/webrtc/test/fakevideotrackrenderer.h"
|
||||||
#include "webrtc/base/sigslot.h"
|
#include "webrtc/base/sigslot.h"
|
||||||
#include "webrtc/base/thread.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
class DtlsIdentityStoreInterface;
|
class DtlsIdentityStoreInterface;
|
||||||
|
Reference in New Issue
Block a user