Add CriticalSection to fakeaudiocapturemodule to protect the variables which will be accessed from process_thread_ and the main thread.
TEST=try bots BUG=1205 R=henrike@webrtc.org, kjellander@webrtc.org Review URL: https://webrtc-codereview.appspot.com/2419004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5019 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -52,6 +52,7 @@ static const int kClockDriftMs = 0;
|
|||||||
static const uint32_t kMaxVolume = 14392;
|
static const uint32_t kMaxVolume = 14392;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
MSG_START_PROCESS,
|
||||||
MSG_RUN_PROCESS,
|
MSG_RUN_PROCESS,
|
||||||
MSG_STOP_PROCESS,
|
MSG_STOP_PROCESS,
|
||||||
};
|
};
|
||||||
@ -89,6 +90,7 @@ talk_base::scoped_refptr<FakeAudioCaptureModule> FakeAudioCaptureModule::Create(
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FakeAudioCaptureModule::frames_received() const {
|
int FakeAudioCaptureModule::frames_received() const {
|
||||||
|
talk_base::CritScope cs(&crit_);
|
||||||
return frames_received_;
|
return frames_received_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +144,7 @@ int32_t FakeAudioCaptureModule::RegisterEventObserver(
|
|||||||
|
|
||||||
int32_t FakeAudioCaptureModule::RegisterAudioCallback(
|
int32_t FakeAudioCaptureModule::RegisterAudioCallback(
|
||||||
webrtc::AudioTransport* audio_callback) {
|
webrtc::AudioTransport* audio_callback) {
|
||||||
|
talk_base::CritScope cs(&crit_callback_);
|
||||||
audio_callback_ = audio_callback;
|
audio_callback_ = audio_callback;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -245,18 +248,28 @@ int32_t FakeAudioCaptureModule::StartPlayout() {
|
|||||||
if (!play_is_initialized_) {
|
if (!play_is_initialized_) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
talk_base::CritScope cs(&crit_);
|
||||||
playing_ = true;
|
playing_ = true;
|
||||||
UpdateProcessing();
|
}
|
||||||
|
bool start = true;
|
||||||
|
UpdateProcessing(start);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t FakeAudioCaptureModule::StopPlayout() {
|
int32_t FakeAudioCaptureModule::StopPlayout() {
|
||||||
|
bool start = false;
|
||||||
|
{
|
||||||
|
talk_base::CritScope cs(&crit_);
|
||||||
playing_ = false;
|
playing_ = false;
|
||||||
UpdateProcessing();
|
start = ShouldStartProcessing();
|
||||||
|
}
|
||||||
|
UpdateProcessing(start);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FakeAudioCaptureModule::Playing() const {
|
bool FakeAudioCaptureModule::Playing() const {
|
||||||
|
talk_base::CritScope cs(&crit_);
|
||||||
return playing_;
|
return playing_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,18 +277,28 @@ int32_t FakeAudioCaptureModule::StartRecording() {
|
|||||||
if (!rec_is_initialized_) {
|
if (!rec_is_initialized_) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
talk_base::CritScope cs(&crit_);
|
||||||
recording_ = true;
|
recording_ = true;
|
||||||
UpdateProcessing();
|
}
|
||||||
|
bool start = true;
|
||||||
|
UpdateProcessing(start);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t FakeAudioCaptureModule::StopRecording() {
|
int32_t FakeAudioCaptureModule::StopRecording() {
|
||||||
|
bool start = false;
|
||||||
|
{
|
||||||
|
talk_base::CritScope cs(&crit_);
|
||||||
recording_ = false;
|
recording_ = false;
|
||||||
UpdateProcessing();
|
start = ShouldStartProcessing();
|
||||||
|
}
|
||||||
|
UpdateProcessing(start);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FakeAudioCaptureModule::Recording() const {
|
bool FakeAudioCaptureModule::Recording() const {
|
||||||
|
talk_base::CritScope cs(&crit_);
|
||||||
return recording_;
|
return recording_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,12 +396,14 @@ int32_t FakeAudioCaptureModule::MicrophoneVolumeIsAvailable(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t FakeAudioCaptureModule::SetMicrophoneVolume(uint32_t /*volume*/) {
|
int32_t FakeAudioCaptureModule::SetMicrophoneVolume(uint32_t volume) {
|
||||||
ASSERT(false);
|
talk_base::CritScope cs(&crit_);
|
||||||
|
current_mic_level_ = volume;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t FakeAudioCaptureModule::MicrophoneVolume(uint32_t* volume) const {
|
int32_t FakeAudioCaptureModule::MicrophoneVolume(uint32_t* volume) const {
|
||||||
|
talk_base::CritScope cs(&crit_);
|
||||||
*volume = current_mic_level_;
|
*volume = current_mic_level_;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -594,6 +619,9 @@ int32_t FakeAudioCaptureModule::GetLoudspeakerStatus(bool* /*enabled*/) const {
|
|||||||
|
|
||||||
void FakeAudioCaptureModule::OnMessage(talk_base::Message* msg) {
|
void FakeAudioCaptureModule::OnMessage(talk_base::Message* msg) {
|
||||||
switch (msg->message_id) {
|
switch (msg->message_id) {
|
||||||
|
case MSG_START_PROCESS:
|
||||||
|
StartProcessP();
|
||||||
|
break;
|
||||||
case MSG_RUN_PROCESS:
|
case MSG_RUN_PROCESS:
|
||||||
ProcessFrameP();
|
ProcessFrameP();
|
||||||
break;
|
break;
|
||||||
@ -640,17 +668,25 @@ bool FakeAudioCaptureModule::CheckRecBuffer(int value) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeAudioCaptureModule::UpdateProcessing() {
|
bool FakeAudioCaptureModule::ShouldStartProcessing() {
|
||||||
const bool process = recording_ || playing_;
|
return recording_ || playing_;
|
||||||
if (process) {
|
}
|
||||||
|
|
||||||
|
void FakeAudioCaptureModule::UpdateProcessing(bool start) {
|
||||||
|
if (start) {
|
||||||
|
process_thread_->Post(this, MSG_START_PROCESS);
|
||||||
|
} else {
|
||||||
|
process_thread_->Send(this, MSG_STOP_PROCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeAudioCaptureModule::StartProcessP() {
|
||||||
|
ASSERT(talk_base::Thread::Current() == process_thread_);
|
||||||
if (started_) {
|
if (started_) {
|
||||||
// Already started.
|
// Already started.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
process_thread_->Post(this, MSG_RUN_PROCESS);
|
ProcessFrameP();
|
||||||
} else {
|
|
||||||
process_thread_->Send(this, MSG_STOP_PROCESS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeAudioCaptureModule::ProcessFrameP() {
|
void FakeAudioCaptureModule::ProcessFrameP() {
|
||||||
@ -659,15 +695,22 @@ void FakeAudioCaptureModule::ProcessFrameP() {
|
|||||||
next_frame_time_ = talk_base::Time();
|
next_frame_time_ = talk_base::Time();
|
||||||
started_ = true;
|
started_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool playing;
|
||||||
|
bool recording;
|
||||||
|
{
|
||||||
|
talk_base::CritScope cs(&crit_);
|
||||||
|
playing = playing_;
|
||||||
|
recording = recording_;
|
||||||
|
}
|
||||||
|
|
||||||
// Receive and send frames every kTimePerFrameMs.
|
// Receive and send frames every kTimePerFrameMs.
|
||||||
if (audio_callback_ != NULL) {
|
if (playing) {
|
||||||
if (playing_) {
|
|
||||||
ReceiveFrameP();
|
ReceiveFrameP();
|
||||||
}
|
}
|
||||||
if (recording_) {
|
if (recording) {
|
||||||
SendFrameP();
|
SendFrameP();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
next_frame_time_ += kTimePerFrameMs;
|
next_frame_time_ += kTimePerFrameMs;
|
||||||
const uint32 current_time = talk_base::Time();
|
const uint32 current_time = talk_base::Time();
|
||||||
@ -678,6 +721,11 @@ void FakeAudioCaptureModule::ProcessFrameP() {
|
|||||||
|
|
||||||
void FakeAudioCaptureModule::ReceiveFrameP() {
|
void FakeAudioCaptureModule::ReceiveFrameP() {
|
||||||
ASSERT(talk_base::Thread::Current() == process_thread_);
|
ASSERT(talk_base::Thread::Current() == process_thread_);
|
||||||
|
{
|
||||||
|
talk_base::CritScope cs(&crit_callback_);
|
||||||
|
if (!audio_callback_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
ResetRecBuffer();
|
ResetRecBuffer();
|
||||||
uint32_t nSamplesOut = 0;
|
uint32_t nSamplesOut = 0;
|
||||||
if (audio_callback_->NeedMorePlayData(kNumberSamples, kNumberBytesPerSample,
|
if (audio_callback_->NeedMorePlayData(kNumberSamples, kNumberBytesPerSample,
|
||||||
@ -686,27 +734,38 @@ void FakeAudioCaptureModule::ReceiveFrameP() {
|
|||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
}
|
}
|
||||||
ASSERT(nSamplesOut == kNumberSamples);
|
ASSERT(nSamplesOut == kNumberSamples);
|
||||||
|
}
|
||||||
// The SetBuffer() function ensures that after decoding, the audio buffer
|
// The SetBuffer() function ensures that after decoding, the audio buffer
|
||||||
// should contain samples of similar magnitude (there is likely to be some
|
// should contain samples of similar magnitude (there is likely to be some
|
||||||
// distortion due to the audio pipeline). If one sample is detected to
|
// 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
|
// 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
|
// has been received from the remote side (i.e. faked frames are not being
|
||||||
// pulled).
|
// pulled).
|
||||||
if (CheckRecBuffer(kHighSampleValue)) ++frames_received_;
|
if (CheckRecBuffer(kHighSampleValue)) {
|
||||||
|
talk_base::CritScope cs(&crit_);
|
||||||
|
++frames_received_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeAudioCaptureModule::SendFrameP() {
|
void FakeAudioCaptureModule::SendFrameP() {
|
||||||
ASSERT(talk_base::Thread::Current() == process_thread_);
|
ASSERT(talk_base::Thread::Current() == process_thread_);
|
||||||
|
talk_base::CritScope cs(&crit_callback_);
|
||||||
|
if (!audio_callback_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
bool key_pressed = false;
|
bool key_pressed = false;
|
||||||
|
uint32_t current_mic_level = 0;
|
||||||
|
MicrophoneVolume(¤t_mic_level);
|
||||||
if (audio_callback_->RecordedDataIsAvailable(send_buffer_, kNumberSamples,
|
if (audio_callback_->RecordedDataIsAvailable(send_buffer_, kNumberSamples,
|
||||||
kNumberBytesPerSample,
|
kNumberBytesPerSample,
|
||||||
kNumberOfChannels,
|
kNumberOfChannels,
|
||||||
kSamplesPerSecond, kTotalDelayMs,
|
kSamplesPerSecond, kTotalDelayMs,
|
||||||
kClockDriftMs, current_mic_level_,
|
kClockDriftMs, current_mic_level,
|
||||||
key_pressed,
|
key_pressed,
|
||||||
current_mic_level_) != 0) {
|
current_mic_level) != 0) {
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
}
|
}
|
||||||
|
SetMicrophoneVolume(current_mic_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeAudioCaptureModule::StopProcessP() {
|
void FakeAudioCaptureModule::StopProcessP() {
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#define TALK_APP_WEBRTC_TEST_FAKEAUDIOCAPTUREMODULE_H_
|
#define TALK_APP_WEBRTC_TEST_FAKEAUDIOCAPTUREMODULE_H_
|
||||||
|
|
||||||
#include "talk/base/basictypes.h"
|
#include "talk/base/basictypes.h"
|
||||||
|
#include "talk/base/criticalsection.h"
|
||||||
#include "talk/base/messagehandler.h"
|
#include "talk/base/messagehandler.h"
|
||||||
#include "talk/base/scoped_ref_ptr.h"
|
#include "talk/base/scoped_ref_ptr.h"
|
||||||
#include "webrtc/common_types.h"
|
#include "webrtc/common_types.h"
|
||||||
@ -88,6 +89,7 @@ class FakeAudioCaptureModule
|
|||||||
virtual int32_t RegisterEventObserver(
|
virtual int32_t RegisterEventObserver(
|
||||||
webrtc::AudioDeviceObserver* event_callback);
|
webrtc::AudioDeviceObserver* event_callback);
|
||||||
|
|
||||||
|
// Note: Calling this method from a callback may result in deadlock.
|
||||||
virtual int32_t RegisterAudioCallback(webrtc::AudioTransport* audio_callback);
|
virtual int32_t RegisterAudioCallback(webrtc::AudioTransport* audio_callback);
|
||||||
|
|
||||||
virtual int32_t Init();
|
virtual int32_t Init();
|
||||||
@ -225,10 +227,15 @@ class FakeAudioCaptureModule
|
|||||||
// equal to |value|.
|
// equal to |value|.
|
||||||
bool CheckRecBuffer(int value);
|
bool CheckRecBuffer(int value);
|
||||||
|
|
||||||
// Starts or stops the pushing and pulling of audio frames depending on if
|
// Returns true/false depending on if recording or playback has been
|
||||||
// recording or playback has been enabled/started.
|
// enabled/started.
|
||||||
void UpdateProcessing();
|
bool ShouldStartProcessing();
|
||||||
|
|
||||||
|
// Starts or stops the pushing and pulling of audio frames.
|
||||||
|
void UpdateProcessing(bool start);
|
||||||
|
|
||||||
|
// Starts the periodic calling of ProcessFrame() in a thread safe way.
|
||||||
|
void StartProcessP();
|
||||||
// Periodcally called function that ensures that frames are pulled and pushed
|
// Periodcally called function that ensures that frames are pulled and pushed
|
||||||
// periodically if enabled/started.
|
// periodically if enabled/started.
|
||||||
void ProcessFrameP();
|
void ProcessFrameP();
|
||||||
@ -275,6 +282,13 @@ class FakeAudioCaptureModule
|
|||||||
// indicate that the frames are not faked somewhere in the audio pipeline
|
// indicate that the frames are not faked somewhere in the audio pipeline
|
||||||
// (e.g. by a jitter buffer).
|
// (e.g. by a jitter buffer).
|
||||||
int frames_received_;
|
int frames_received_;
|
||||||
|
|
||||||
|
// Protects variables that are accessed from process_thread_ and
|
||||||
|
// the main thread.
|
||||||
|
mutable talk_base::CriticalSection crit_;
|
||||||
|
// Protects |audio_callback_| that is accessed from process_thread_ and
|
||||||
|
// the main thread.
|
||||||
|
talk_base::CriticalSection crit_callback_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TALK_APP_WEBRTC_TEST_FAKEAUDIOCAPTUREMODULE_H_
|
#endif // TALK_APP_WEBRTC_TEST_FAKEAUDIOCAPTUREMODULE_H_
|
||||||
|
@ -11,10 +11,6 @@ race:webrtc/modules/audio_processing/aec/aec_rdft.c
|
|||||||
# See https://code.google.com/p/webrtc/issues/detail?id=2484 for details.
|
# See https://code.google.com/p/webrtc/issues/detail?id=2484 for details.
|
||||||
# race:webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc
|
# race:webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc
|
||||||
|
|
||||||
# libjingle_peerconnection_unittest
|
|
||||||
# See https://code.google.com/p/webrtc/issues/detail?id=1205
|
|
||||||
race:talk/app/webrtc/test/fakeaudiocapturemodule.cc
|
|
||||||
|
|
||||||
# libjingle_p2p_unittest
|
# libjingle_p2p_unittest
|
||||||
# See https://code.google.com/p/webrtc/issues/detail?id=2079
|
# See https://code.google.com/p/webrtc/issues/detail?id=2079
|
||||||
race:talk/base/messagequeue.cc
|
race:talk/base/messagequeue.cc
|
||||||
|
Reference in New Issue
Block a user