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:
deadbeef
2015-08-13 14:27:18 -07:00
committed by Commit bot
parent 7437588168
commit ee8c6d3273
7 changed files with 49 additions and 70 deletions

View File

@ -518,8 +518,7 @@ class PeerConnectionTestClientBase
if (!allocator_factory_) {
return false;
}
fake_audio_capture_module_ = FakeAudioCaptureModule::Create(
rtc::Thread::Current());
fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
if (fake_audio_capture_module_ == NULL) {
return false;

View File

@ -268,17 +268,7 @@ class PeerConnectionEndToEndTest
DataChannelList callee_signaled_data_channels_;
};
// Disable for TSan v2, see
// 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) {
TEST_F(PeerConnectionEndToEndTest, Call) {
CreatePcs();
GetAndAddUserMedia();
Negotiate();
@ -427,4 +417,3 @@ TEST_F(PeerConnectionEndToEndTest,
EXPECT_EQ(1U, dc_1_observer->received_message_count());
EXPECT_EQ(1U, dc_2_observer->received_message_count());
}
#endif // if !defined(THREAD_SANITIZER)

View File

@ -54,13 +54,11 @@ static const uint32_t kMaxVolume = 14392;
enum {
MSG_START_PROCESS,
MSG_RUN_PROCESS,
MSG_STOP_PROCESS,
};
FakeAudioCaptureModule::FakeAudioCaptureModule(
rtc::Thread* process_thread)
FakeAudioCaptureModule::FakeAudioCaptureModule()
: last_process_time_ms_(0),
audio_callback_(NULL),
audio_callback_(nullptr),
recording_(false),
playing_(false),
play_is_initialized_(false),
@ -68,23 +66,20 @@ FakeAudioCaptureModule::FakeAudioCaptureModule(
current_mic_level_(kMaxVolume),
started_(false),
next_frame_time_(0),
process_thread_(process_thread),
frames_received_(0) {
}
FakeAudioCaptureModule::~FakeAudioCaptureModule() {
// Ensure that thread stops calling ProcessFrame().
process_thread_->Send(this, MSG_STOP_PROCESS);
if (process_thread_) {
process_thread_->Stop();
}
}
rtc::scoped_refptr<FakeAudioCaptureModule> FakeAudioCaptureModule::Create(
rtc::Thread* process_thread) {
if (process_thread == NULL) return NULL;
rtc::scoped_refptr<FakeAudioCaptureModule> FakeAudioCaptureModule::Create() {
rtc::scoped_refptr<FakeAudioCaptureModule> capture_module(
new rtc::RefCountedObject<FakeAudioCaptureModule>(process_thread));
new rtc::RefCountedObject<FakeAudioCaptureModule>());
if (!capture_module->Initialize()) {
return NULL;
return nullptr;
}
return capture_module;
}
@ -601,9 +596,6 @@ void FakeAudioCaptureModule::OnMessage(rtc::Message* msg) {
case MSG_RUN_PROCESS:
ProcessFrameP();
break;
case MSG_STOP_PROCESS:
StopProcessP();
break;
default:
// All existing messages should be caught. Getting here should never
// happen.
@ -650,14 +642,22 @@ bool FakeAudioCaptureModule::ShouldStartProcessing() {
void FakeAudioCaptureModule::UpdateProcessing(bool start) {
if (start) {
if (!process_thread_) {
process_thread_.reset(new rtc::Thread());
process_thread_->Start();
}
process_thread_->Post(this, MSG_START_PROCESS);
} else {
process_thread_->Send(this, MSG_STOP_PROCESS);
if (process_thread_) {
process_thread_->Stop();
process_thread_.reset(nullptr);
}
started_ = false;
}
}
void FakeAudioCaptureModule::StartProcessP() {
ASSERT(rtc::Thread::Current() == process_thread_);
ASSERT(process_thread_->IsCurrent());
if (started_) {
// Already started.
return;
@ -666,27 +666,22 @@ void FakeAudioCaptureModule::StartProcessP() {
}
void FakeAudioCaptureModule::ProcessFrameP() {
ASSERT(rtc::Thread::Current() == process_thread_);
ASSERT(process_thread_->IsCurrent());
if (!started_) {
next_frame_time_ = rtc::Time();
started_ = true;
}
bool playing;
bool recording;
{
rtc::CritScope cs(&crit_);
playing = playing_;
recording = recording_;
}
// Receive and send frames every kTimePerFrameMs.
if (playing) {
if (playing_) {
ReceiveFrameP();
}
if (recording) {
if (recording_) {
SendFrameP();
}
}
next_frame_time_ += kTimePerFrameMs;
const uint32 current_time = rtc::Time();
@ -696,7 +691,7 @@ void FakeAudioCaptureModule::ProcessFrameP() {
}
void FakeAudioCaptureModule::ReceiveFrameP() {
ASSERT(rtc::Thread::Current() == process_thread_);
ASSERT(process_thread_->IsCurrent());
{
rtc::CritScope cs(&crit_callback_);
if (!audio_callback_) {
@ -727,7 +722,7 @@ void FakeAudioCaptureModule::ReceiveFrameP() {
}
void FakeAudioCaptureModule::SendFrameP() {
ASSERT(rtc::Thread::Current() == process_thread_);
ASSERT(process_thread_->IsCurrent());
rtc::CritScope cs(&crit_callback_);
if (!audio_callback_) {
return;
@ -747,8 +742,3 @@ void FakeAudioCaptureModule::SendFrameP() {
SetMicrophoneVolume(current_mic_level);
}
void FakeAudioCaptureModule::StopProcessP() {
ASSERT(rtc::Thread::Current() == process_thread_);
started_ = false;
process_thread_->Clear(this);
}

View File

@ -40,14 +40,13 @@
#include "webrtc/base/basictypes.h"
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/messagehandler.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/scoped_ref_ptr.h"
#include "webrtc/common_types.h"
#include "webrtc/modules/audio_device/include/audio_device.h"
namespace rtc {
class Thread;
} // namespace rtc
class FakeAudioCaptureModule
@ -62,10 +61,7 @@ class FakeAudioCaptureModule
static const int kNumberBytesPerSample = sizeof(Sample);
// Creates a FakeAudioCaptureModule or returns NULL on failure.
// |process_thread| is used to push and pull audio frames to and from the
// returned instance. Note: ownership of |process_thread| is not handed over.
static rtc::scoped_refptr<FakeAudioCaptureModule> Create(
rtc::Thread* process_thread);
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
@ -206,7 +202,7 @@ class FakeAudioCaptureModule
// 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.
explicit FakeAudioCaptureModule(rtc::Thread* process_thread);
explicit FakeAudioCaptureModule();
// The destructor is protected because it is reference counted and should not
// be deleted directly.
virtual ~FakeAudioCaptureModule();
@ -239,8 +235,6 @@ class FakeAudioCaptureModule
void ReceiveFrameP();
// Pushes frames to the registered webrtc::AudioTransport.
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
// has been made.
@ -266,8 +260,7 @@ class FakeAudioCaptureModule
bool started_;
uint32 next_frame_time_;
// User provided thread context.
rtc::Thread* process_thread_;
rtc::scoped_ptr<rtc::Thread> process_thread_;
// Buffer for storing samples received from the webrtc::AudioTransport.
char rec_buffer_[kNumberSamples * kNumberBytesPerSample];

View File

@ -29,6 +29,7 @@
#include <algorithm>
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/scoped_ref_ptr.h"
#include "webrtc/base/thread.h"
@ -48,8 +49,7 @@ class FakeAdmTest : public testing::Test,
}
virtual void SetUp() {
fake_audio_capture_module_ = FakeAudioCaptureModule::Create(
rtc::Thread::Current());
fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
EXPECT_TRUE(fake_audio_capture_module_.get() != NULL);
}
@ -65,6 +65,7 @@ class FakeAdmTest : public testing::Test,
const uint32_t currentMicLevel,
const bool keyPressed,
uint32_t& newMicLevel) override {
rtc::CritScope cs(&crit_);
rec_buffer_bytes_ = nSamples * nBytesPerSample;
if ((rec_buffer_bytes_ == 0) ||
(rec_buffer_bytes_ > FakeAudioCaptureModule::kNumberSamples *
@ -87,6 +88,7 @@ class FakeAdmTest : public testing::Test,
uint32_t& nSamplesOut,
int64_t* elapsed_time_ms,
int64_t* ntp_time_ms) override {
rtc::CritScope cs(&crit_);
++pull_iterations_;
const uint32_t audio_buffer_size = nSamples * nBytesPerSample;
const uint32_t bytes_out = RecordedDataReceived() ?
@ -98,8 +100,14 @@ class FakeAdmTest : public testing::Test,
return 0;
}
int push_iterations() const { return push_iterations_; }
int pull_iterations() const { return pull_iterations_; }
int push_iterations() const {
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_;
@ -118,6 +126,8 @@ class FakeAdmTest : public testing::Test,
return min_buffer_size;
}
mutable rtc::CriticalSection crit_;
int push_iterations_;
int pull_iterations_;

View File

@ -75,8 +75,7 @@ bool PeerConnectionTestWrapper::CreatePc(
return false;
}
fake_audio_capture_module_ = FakeAudioCaptureModule::Create(
rtc::Thread::Current());
fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
if (fake_audio_capture_module_ == NULL) {
return false;
}

View File

@ -33,7 +33,6 @@
#include "talk/app/webrtc/test/fakeconstraints.h"
#include "talk/app/webrtc/test/fakevideotrackrenderer.h"
#include "webrtc/base/sigslot.h"
#include "webrtc/base/thread.h"
namespace webrtc {
class DtlsIdentityStoreInterface;