Update stable to r5019.
git-svn-id: http://webrtc.googlecode.com/svn/stable/talk@5022 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/app/webrtc/java/jni/peerconnection_jni.cc b/app/webrtc/java/jni/peerconnection_jni.cc
index 218864c..0b7c78b 100644
--- a/app/webrtc/java/jni/peerconnection_jni.cc
+++ b/app/webrtc/java/jni/peerconnection_jni.cc
@@ -72,6 +72,7 @@
#include "talk/media/devices/videorendererfactory.h"
#include "talk/media/webrtc/webrtcvideocapturer.h"
#include "third_party/icu/source/common/unicode/unistr.h"
+#include "webrtc/system_wrappers/interface/compile_assert.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "webrtc/video_engine/include/vie_base.h"
#include "webrtc/voice_engine/include/voe_base.h"
@@ -135,12 +136,6 @@
CHECK(!count, "Unexpected refcount"); \
} while (0)
-// Lifted from chromium's base/basictypes.h.
-template <bool>
-struct CompileAssert {};
-#define COMPILE_ASSERT(expr, msg) \
- typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
-
namespace {
static JavaVM* g_jvm = NULL; // Set in JNI_OnLoad().
diff --git a/app/webrtc/peerconnection_unittest.cc b/app/webrtc/peerconnection_unittest.cc
index 74f420b..9de6ec9 100644
--- a/app/webrtc/peerconnection_unittest.cc
+++ b/app/webrtc/peerconnection_unittest.cc
@@ -1065,7 +1065,7 @@
// This test sets up a audio call initially and then upgrades to audio/video,
// using DTLS.
-TEST_F(JsepPeerConnectionP2PTestClient, DISABLED_LocalP2PTestDtlsRenegotiate) {
+TEST_F(JsepPeerConnectionP2PTestClient, LocalP2PTestDtlsRenegotiate) {
MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
FakeConstraints setup_constraints;
setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
diff --git a/app/webrtc/test/fakeaudiocapturemodule.cc b/app/webrtc/test/fakeaudiocapturemodule.cc
index 4bdaf89..3b36163 100644
--- a/app/webrtc/test/fakeaudiocapturemodule.cc
+++ b/app/webrtc/test/fakeaudiocapturemodule.cc
@@ -52,6 +52,7 @@
static const uint32_t kMaxVolume = 14392;
enum {
+ MSG_START_PROCESS,
MSG_RUN_PROCESS,
MSG_STOP_PROCESS,
};
@@ -89,6 +90,7 @@
}
int FakeAudioCaptureModule::frames_received() const {
+ talk_base::CritScope cs(&crit_);
return frames_received_;
}
@@ -142,6 +144,7 @@
int32_t FakeAudioCaptureModule::RegisterAudioCallback(
webrtc::AudioTransport* audio_callback) {
+ talk_base::CritScope cs(&crit_callback_);
audio_callback_ = audio_callback;
return 0;
}
@@ -245,18 +248,28 @@
if (!play_is_initialized_) {
return -1;
}
- playing_ = true;
- UpdateProcessing();
+ {
+ talk_base::CritScope cs(&crit_);
+ playing_ = true;
+ }
+ bool start = true;
+ UpdateProcessing(start);
return 0;
}
int32_t FakeAudioCaptureModule::StopPlayout() {
- playing_ = false;
- UpdateProcessing();
+ bool start = false;
+ {
+ talk_base::CritScope cs(&crit_);
+ playing_ = false;
+ start = ShouldStartProcessing();
+ }
+ UpdateProcessing(start);
return 0;
}
bool FakeAudioCaptureModule::Playing() const {
+ talk_base::CritScope cs(&crit_);
return playing_;
}
@@ -264,18 +277,28 @@
if (!rec_is_initialized_) {
return -1;
}
- recording_ = true;
- UpdateProcessing();
+ {
+ talk_base::CritScope cs(&crit_);
+ recording_ = true;
+ }
+ bool start = true;
+ UpdateProcessing(start);
return 0;
}
int32_t FakeAudioCaptureModule::StopRecording() {
- recording_ = false;
- UpdateProcessing();
+ bool start = false;
+ {
+ talk_base::CritScope cs(&crit_);
+ recording_ = false;
+ start = ShouldStartProcessing();
+ }
+ UpdateProcessing(start);
return 0;
}
bool FakeAudioCaptureModule::Recording() const {
+ talk_base::CritScope cs(&crit_);
return recording_;
}
@@ -373,12 +396,14 @@
return 0;
}
-int32_t FakeAudioCaptureModule::SetMicrophoneVolume(uint32_t /*volume*/) {
- ASSERT(false);
+int32_t FakeAudioCaptureModule::SetMicrophoneVolume(uint32_t volume) {
+ talk_base::CritScope cs(&crit_);
+ current_mic_level_ = volume;
return 0;
}
int32_t FakeAudioCaptureModule::MicrophoneVolume(uint32_t* volume) const {
+ talk_base::CritScope cs(&crit_);
*volume = current_mic_level_;
return 0;
}
@@ -594,6 +619,9 @@
void FakeAudioCaptureModule::OnMessage(talk_base::Message* msg) {
switch (msg->message_id) {
+ case MSG_START_PROCESS:
+ StartProcessP();
+ break;
case MSG_RUN_PROCESS:
ProcessFrameP();
break;
@@ -640,33 +668,48 @@
return false;
}
-void FakeAudioCaptureModule::UpdateProcessing() {
- const bool process = recording_ || playing_;
- if (process) {
- if (started_) {
- // Already started.
- return;
- }
- process_thread_->Post(this, MSG_RUN_PROCESS);
+bool FakeAudioCaptureModule::ShouldStartProcessing() {
+ return recording_ || playing_;
+}
+
+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_) {
+ // Already started.
+ return;
+ }
+ ProcessFrameP();
+}
+
void FakeAudioCaptureModule::ProcessFrameP() {
ASSERT(talk_base::Thread::Current() == process_thread_);
if (!started_) {
next_frame_time_ = talk_base::Time();
started_ = true;
}
+
+ bool playing;
+ bool recording;
+ {
+ talk_base::CritScope cs(&crit_);
+ playing = playing_;
+ recording = recording_;
+ }
+
// Receive and send frames every kTimePerFrameMs.
- if (audio_callback_ != NULL) {
- if (playing_) {
- ReceiveFrameP();
- }
- if (recording_) {
- SendFrameP();
- }
+ if (playing) {
+ ReceiveFrameP();
+ }
+ if (recording) {
+ SendFrameP();
}
next_frame_time_ += kTimePerFrameMs;
@@ -678,35 +721,51 @@
void FakeAudioCaptureModule::ReceiveFrameP() {
ASSERT(talk_base::Thread::Current() == process_thread_);
- ResetRecBuffer();
- uint32_t nSamplesOut = 0;
- if (audio_callback_->NeedMorePlayData(kNumberSamples, kNumberBytesPerSample,
- kNumberOfChannels, kSamplesPerSecond,
- rec_buffer_, nSamplesOut) != 0) {
- ASSERT(false);
+ {
+ talk_base::CritScope cs(&crit_callback_);
+ if (!audio_callback_) {
+ return;
+ }
+ ResetRecBuffer();
+ uint32_t nSamplesOut = 0;
+ if (audio_callback_->NeedMorePlayData(kNumberSamples, kNumberBytesPerSample,
+ kNumberOfChannels, kSamplesPerSecond,
+ rec_buffer_, nSamplesOut) != 0) {
+ ASSERT(false);
+ }
+ ASSERT(nSamplesOut == kNumberSamples);
}
- ASSERT(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_;
+ if (CheckRecBuffer(kHighSampleValue)) {
+ talk_base::CritScope cs(&crit_);
+ ++frames_received_;
+ }
}
void FakeAudioCaptureModule::SendFrameP() {
ASSERT(talk_base::Thread::Current() == process_thread_);
+ talk_base::CritScope cs(&crit_callback_);
+ if (!audio_callback_) {
+ return;
+ }
bool key_pressed = false;
+ uint32_t current_mic_level = 0;
+ MicrophoneVolume(¤t_mic_level);
if (audio_callback_->RecordedDataIsAvailable(send_buffer_, kNumberSamples,
kNumberBytesPerSample,
kNumberOfChannels,
kSamplesPerSecond, kTotalDelayMs,
- kClockDriftMs, current_mic_level_,
+ kClockDriftMs, current_mic_level,
key_pressed,
- current_mic_level_) != 0) {
+ current_mic_level) != 0) {
ASSERT(false);
}
+ SetMicrophoneVolume(current_mic_level);
}
void FakeAudioCaptureModule::StopProcessP() {
diff --git a/app/webrtc/test/fakeaudiocapturemodule.h b/app/webrtc/test/fakeaudiocapturemodule.h
index c32fa1f..2267902 100644
--- a/app/webrtc/test/fakeaudiocapturemodule.h
+++ b/app/webrtc/test/fakeaudiocapturemodule.h
@@ -38,6 +38,7 @@
#define TALK_APP_WEBRTC_TEST_FAKEAUDIOCAPTUREMODULE_H_
#include "talk/base/basictypes.h"
+#include "talk/base/criticalsection.h"
#include "talk/base/messagehandler.h"
#include "talk/base/scoped_ref_ptr.h"
#include "webrtc/common_types.h"
@@ -88,6 +89,7 @@
virtual int32_t RegisterEventObserver(
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 Init();
@@ -225,10 +227,15 @@
// equal to |value|.
bool CheckRecBuffer(int value);
- // Starts or stops the pushing and pulling of audio frames depending on if
- // recording or playback has been enabled/started.
- void UpdateProcessing();
+ // Returns true/false depending on if recording or playback has been
+ // enabled/started.
+ 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
// periodically if enabled/started.
void ProcessFrameP();
@@ -275,6 +282,13 @@
// 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 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_
diff --git a/base/cpumonitor_unittest.cc b/base/cpumonitor_unittest.cc
index 952b89e..b9f5ba3 100644
--- a/base/cpumonitor_unittest.cc
+++ b/base/cpumonitor_unittest.cc
@@ -54,6 +54,9 @@
BusyThread(double load, double duration, double interval) :
load_(load), duration_(duration), interval_(interval) {
}
+ virtual ~BusyThread() {
+ Stop();
+ }
void Run() {
Timing time;
double busy_time = interval_ * load_ / 100.0;
diff --git a/base/dbus.cc b/base/dbus.cc
index 8e071c7..78e717a 100644
--- a/base/dbus.cc
+++ b/base/dbus.cc
@@ -158,6 +158,10 @@
ASSERT(filter_list_);
}
+ virtual ~DBusMonitoringThread() {
+ Stop();
+ }
+
// Override virtual method of Thread. Context: worker-thread.
virtual void Run() {
ASSERT(NULL == connection_);
diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc
index b0c219f..53cab66 100644
--- a/base/logging_unittest.cc
+++ b/base/logging_unittest.cc
@@ -87,6 +87,12 @@
// Ensure we don't crash when adding/removing streams while threads are going.
// We should restore the correct global state at the end.
class LogThread : public Thread {
+ public:
+ virtual ~LogThread() {
+ Stop();
+ }
+
+ private:
void Run() {
// LS_SENSITIVE to avoid cluttering up any real logging going on
LOG(LS_SENSITIVE) << "LOG";
diff --git a/base/maccocoasocketserver_unittest.mm b/base/maccocoasocketserver_unittest.mm
index d6f4b2c..818c30d 100644
--- a/base/maccocoasocketserver_unittest.mm
+++ b/base/maccocoasocketserver_unittest.mm
@@ -36,6 +36,9 @@
public:
WakeThread(SocketServer* ss) : ss_(ss) {
}
+ virtual ~WakeThread() {
+ Stop();
+ }
void Run() {
ss_->WakeUp();
}
diff --git a/base/macsocketserver_unittest.cc b/base/macsocketserver_unittest.cc
index a4a7101..f10aebc 100644
--- a/base/macsocketserver_unittest.cc
+++ b/base/macsocketserver_unittest.cc
@@ -37,6 +37,9 @@
public:
WakeThread(SocketServer* ss) : ss_(ss) {
}
+ virtual ~WakeThread() {
+ Stop();
+ }
void Run() {
ss_->WakeUp();
}
diff --git a/base/signalthread.h b/base/signalthread.h
index 79c00be..46dd0a3 100644
--- a/base/signalthread.h
+++ b/base/signalthread.h
@@ -123,6 +123,7 @@
class Worker : public Thread {
public:
explicit Worker(SignalThread* parent) : parent_(parent) {}
+ virtual ~Worker() { Stop(); }
virtual void Run() { parent_->Run(); }
private:
diff --git a/base/signalthread_unittest.cc b/base/signalthread_unittest.cc
index 4458f52..e5734d4 100644
--- a/base/signalthread_unittest.cc
+++ b/base/signalthread_unittest.cc
@@ -120,6 +120,10 @@
has_run_(false) {
}
+ virtual ~OwnerThread() {
+ Stop();
+ }
+
virtual void Run() {
SignalThreadTest::SlowSignalThread* signal_thread =
new SignalThreadTest::SlowSignalThread(harness_);
diff --git a/base/thread.cc b/base/thread.cc
index 316e14b..d07efb5 100644
--- a/base/thread.cc
+++ b/base/thread.cc
@@ -557,6 +557,7 @@
}
AutoThread::~AutoThread() {
+ Stop();
if (ThreadManager::Instance()->CurrentThread() == this) {
ThreadManager::Instance()->SetCurrentThread(NULL);
}
diff --git a/base/thread.h b/base/thread.h
index e679ea4..4dc09f6 100644
--- a/base/thread.h
+++ b/base/thread.h
@@ -111,9 +111,15 @@
DISALLOW_COPY_AND_ASSIGN(Runnable);
};
+// WARNING! SUBCLASSES MUST CALL Stop() IN THEIR DESTRUCTORS! See ~Thread().
+
class Thread : public MessageQueue {
public:
explicit Thread(SocketServer* ss = NULL);
+ // NOTE: ALL SUBCLASSES OF Thread MUST CALL Stop() IN THEIR DESTRUCTORS (or
+ // guarantee Stop() is explicitly called before the subclass is destroyed).
+ // This is required to avoid a data race between the destructor modifying the
+ // vtable, and the Thread::PreRun calling the virtual method Run().
virtual ~Thread();
static Thread* Current();
@@ -291,6 +297,7 @@
class ComThread : public Thread {
public:
ComThread() {}
+ virtual ~ComThread() { Stop(); }
protected:
virtual void Run();
diff --git a/base/thread_unittest.cc b/base/thread_unittest.cc
index 148e27b..d6af17a 100644
--- a/base/thread_unittest.cc
+++ b/base/thread_unittest.cc
@@ -122,7 +122,7 @@
class CustomThread : public talk_base::Thread {
public:
CustomThread() {}
- virtual ~CustomThread() {}
+ virtual ~CustomThread() { Stop(); }
bool Start() { return false; }
};
@@ -136,6 +136,7 @@
}
virtual ~SignalWhenDestroyedThread() {
+ Stop();
event_->Set();
}
diff --git a/base/win32socketserver.h b/base/win32socketserver.h
index 1fa6523..3459879 100644
--- a/base/win32socketserver.h
+++ b/base/win32socketserver.h
@@ -156,6 +156,7 @@
set_socketserver(&ss_);
}
virtual ~Win32Thread() {
+ Stop();
set_socketserver(NULL);
}
virtual void Run() {
diff --git a/examples/android/AndroidManifest.xml b/examples/android/AndroidManifest.xml
index 52e67a2..59974f7 100644
--- a/examples/android/AndroidManifest.xml
+++ b/examples/android/AndroidManifest.xml
@@ -13,7 +13,6 @@
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:label="@string/app_name"
diff --git a/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java b/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java
index 81c5ba9..c1dff74 100644
--- a/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java
+++ b/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java
@@ -34,7 +34,6 @@
import android.graphics.Point;
import android.media.AudioManager;
import android.os.Bundle;
-import android.os.PowerManager;
import android.util.Log;
import android.view.WindowManager;
import android.webkit.JavascriptInterface;
@@ -88,7 +87,6 @@
// Synchronize on quit[0] to avoid teardown-related crashes.
private final Boolean[] quit = new Boolean[] { false };
private MediaConstraints sdpMediaConstraints;
- private PowerManager.WakeLock wakeLock;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -547,7 +545,6 @@
factory.dispose();
factory = null;
}
- wakeLock.release();
finish();
}
}
diff --git a/media/base/filemediaengine.cc b/media/base/filemediaengine.cc
index 1a3547c..e5183f6 100644
--- a/media/base/filemediaengine.cc
+++ b/media/base/filemediaengine.cc
@@ -125,6 +125,7 @@
RtpSenderReceiver(MediaChannel* channel,
talk_base::StreamInterface* input_file_stream,
talk_base::StreamInterface* output_file_stream);
+ virtual ~RtpSenderReceiver();
// Called by media channel. Context: media channel thread.
bool SetSend(bool send);
@@ -183,6 +184,10 @@
}
}
+RtpSenderReceiver::~RtpSenderReceiver() {
+ Stop();
+}
+
bool RtpSenderReceiver::SetSend(bool send) {
bool was_sending = sending_;
sending_ = send;
diff --git a/media/devices/filevideocapturer.cc b/media/devices/filevideocapturer.cc
index 1747816..f5c078d 100644
--- a/media/devices/filevideocapturer.cc
+++ b/media/devices/filevideocapturer.cc
@@ -28,6 +28,7 @@
#include "talk/media/devices/filevideocapturer.h"
#include "talk/base/bytebuffer.h"
+#include "talk/base/criticalsection.h"
#include "talk/base/logging.h"
#include "talk/base/thread.h"
@@ -108,6 +109,10 @@
finished_(false) {
}
+ virtual ~FileReadThread() {
+ Stop();
+ }
+
// Override virtual method of parent Thread. Context: Worker Thread.
virtual void Run() {
// Read the first frame and start the message pump. The pump runs until
@@ -117,6 +122,8 @@
PostDelayed(waiting_time_ms, this);
Thread::Run();
}
+
+ talk_base::CritScope cs(&crit_);
finished_ = true;
}
@@ -131,10 +138,14 @@
}
// Check if Run() is finished.
- bool Finished() const { return finished_; }
+ bool Finished() const {
+ talk_base::CritScope cs(&crit_);
+ return finished_;
+ }
private:
FileVideoCapturer* capturer_;
+ mutable talk_base::CriticalSection crit_;
bool finished_;
DISALLOW_COPY_AND_ASSIGN(FileReadThread);
@@ -224,9 +235,9 @@
SetCaptureFormat(&capture_format);
// Create a thread to read the file.
file_read_thread_ = new FileReadThread(this);
- bool ret = file_read_thread_->Start();
start_time_ns_ = kNumNanoSecsPerMilliSec *
static_cast<int64>(talk_base::Time());
+ bool ret = file_read_thread_->Start();
if (ret) {
LOG(LS_INFO) << "File video capturer '" << GetId() << "' started";
return CS_RUNNING;
diff --git a/media/devices/gdivideorenderer.cc b/media/devices/gdivideorenderer.cc
index d5edfc6..c8024b7 100755
--- a/media/devices/gdivideorenderer.cc
+++ b/media/devices/gdivideorenderer.cc
@@ -69,6 +69,10 @@
public:
explicit WindowThread(VideoWindow* window) : window_(window) {}
+ virtual ~WindowThread() {
+ Stop();
+ }
+
// Override virtual method of talk_base::Thread. Context: worker Thread.
virtual void Run() {
// Initialize the window
diff --git a/xmllite/xmlelement_unittest.cc b/xmllite/xmlelement_unittest.cc
index 6d488fa..3c31ce4 100644
--- a/xmllite/xmlelement_unittest.cc
+++ b/xmllite/xmlelement_unittest.cc
@@ -235,6 +235,10 @@
XmlElementCreatorThread(int count, buzz::QName qname) :
count_(count), qname_(qname) {}
+ virtual ~XmlElementCreatorThread() {
+ Stop();
+ }
+
virtual void Run() {
std::vector<buzz::XmlElement*> elems;
for (int i = 0; i < count_; i++) {
diff --git a/xmpp/xmppthread.cc b/xmpp/xmppthread.cc
index 43dded8..716aaf8 100644
--- a/xmpp/xmppthread.cc
+++ b/xmpp/xmppthread.cc
@@ -50,6 +50,7 @@
}
XmppThread::~XmppThread() {
+ Stop();
delete pump_;
}