Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2017)

Unified Diff: content/renderer/media/audio_input_device.cc

Issue 9121045: Switch AudioDevice classes from SyncSocket to CancelableSyncSocket. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments, add temporary ScopedAllowIO for the audio thread cleanup+TODO for next cl. Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/renderer/media/audio_input_device.cc
diff --git a/content/renderer/media/audio_input_device.cc b/content/renderer/media/audio_input_device.cc
index 71a15f4fbf0adb375f03278f622e8913d06756e3..14cdf90858491ffcb8d97a43092dda0482fad37d 100644
--- a/content/renderer/media/audio_input_device.cc
+++ b/content/renderer/media/audio_input_device.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/message_loop.h"
+#include "base/threading/thread_restrictions.h"
#include "base/time.h"
#include "content/common/child_process.h"
#include "content/common/media/audio_messages.h"
@@ -27,7 +28,6 @@ AudioInputDevice::AudioInputDevice(size_t buffer_size,
session_id_(0),
pending_device_ready_(false),
shared_memory_handle_(base::SharedMemory::NULLHandle()),
- socket_handle_(base::SyncSocket::kInvalidHandle),
memory_length_(0) {
filter_ = RenderThreadImpl::current()->audio_input_message_filter();
audio_data_.reserve(channels);
@@ -77,13 +77,8 @@ void AudioInputDevice::SetDevice(int session_id) {
void AudioInputDevice::Stop() {
DCHECK(MessageLoop::current() != ChildProcess::current()->io_message_loop());
VLOG(1) << "Stop()";
- // Max waiting time for Stop() to complete. If this time limit is passed,
- // we will stop waiting and return false. It ensures that Stop() can't block
- // the calling thread forever.
- const base::TimeDelta kMaxTimeOut = base::TimeDelta::FromMilliseconds(1000);
base::WaitableEvent completion(false, false);
-
ChildProcess::current()->io_message_loop()->PostTask(
FROM_HERE,
base::Bind(&AudioInputDevice::ShutDownOnIOThread, this,
@@ -92,20 +87,7 @@ void AudioInputDevice::Stop() {
// We wait here for the IO task to be completed to remove race conflicts
// with OnLowLatencyCreated() and to ensure that Stop() acts as a synchronous
// function call.
- if (!completion.TimedWait(kMaxTimeOut)) {
- LOG(ERROR) << "Failed to shut down audio input on IO thread";
- }
-
- if (audio_thread_.get()) {
- // Terminate the main thread function in the audio thread.
- {
- base::SyncSocket socket(socket_handle_);
- }
- // Wait for the audio thread to exit.
- audio_thread_->Join();
- // Ensures that we can call Stop() multiple times.
- audio_thread_.reset(NULL);
- }
+ completion.Wait();
}
bool AudioInputDevice::SetVolume(double volume) {
@@ -161,6 +143,8 @@ void AudioInputDevice::ShutDownOnIOThread(base::WaitableEvent* completion) {
filter_->RemoveDelegate(stream_id_);
Send(new AudioInputHostMsg_CloseStream(stream_id_));
+ ShutDownAudioThread();
+
stream_id_ = 0;
session_id_ = 0;
pending_device_ready_ = false;
@@ -200,8 +184,7 @@ void AudioInputDevice::OnLowLatencyCreated(
shared_memory_handle_ = handle;
memory_length_ = length;
-
- socket_handle_ = socket_handle;
+ audio_socket_.reset(new base::CancelableSyncSocket(socket_handle));
audio_thread_.reset(
new base::DelegateSimpleThread(this, "RendererAudioInputThread"));
@@ -220,21 +203,15 @@ void AudioInputDevice::OnStateChanged(AudioStreamState state) {
DCHECK(MessageLoop::current() == ChildProcess::current()->io_message_loop());
switch (state) {
case kAudioStreamPaused:
+ // TODO(xians): Should we just call ShutDownOnIOThread here instead?
+
// Do nothing if the stream has been closed.
if (!stream_id_)
return;
filter_->RemoveDelegate(stream_id_);
- // Joining the audio thread will be quite soon, since the stream has
- // been closed before.
- if (audio_thread_.get()) {
- {
- base::SyncSocket socket(socket_handle_);
- }
- audio_thread_->Join();
- audio_thread_.reset(NULL);
- }
+ ShutDownAudioThread();
if (event_handler_)
event_handler_->OnDeviceStopped();
@@ -268,8 +245,8 @@ void AudioInputDevice::OnDeviceReady(const std::string& device_id) {
filter_->RemoveDelegate(stream_id_);
stream_id_ = 0;
} else {
- Send(new AudioInputHostMsg_CreateStream(
- stream_id_, audio_parameters_, true, device_id));
+ Send(new AudioInputHostMsg_CreateStream(stream_id_, audio_parameters_,
+ true, device_id));
}
pending_device_ready_ = false;
@@ -290,17 +267,20 @@ void AudioInputDevice::Run() {
base::SharedMemory shared_memory(shared_memory_handle_, false);
shared_memory.Map(memory_length_);
- base::SyncSocket socket(socket_handle_);
+ base::CancelableSyncSocket* socket = audio_socket_.get();
scherkus (not reviewing) 2012/01/30 19:10:57 nit: do we need this line of code?
tommi (sloooow) - chröme 2012/01/30 21:53:14 yup (different than before)
- int pending_data;
const int samples_per_ms =
static_cast<int>(audio_parameters_.sample_rate) / 1000;
const int bytes_per_ms = audio_parameters_.channels *
(audio_parameters_.bits_per_sample / 8) * samples_per_ms;
- while ((sizeof(pending_data) == socket.Receive(&pending_data,
- sizeof(pending_data))) &&
- (pending_data >= 0)) {
+ while (true) {
+ uint32 pending_data = 0;
+ size_t received = socket->Receive(&pending_data, sizeof(pending_data));
+ if (received != sizeof(pending_data)) {
+ DCHECK(received == 0U);
+ break;
+ }
// TODO(henrika): investigate the provided |pending_data| value
// and ensure that it is actually an accurate delay estimation.
@@ -314,7 +294,7 @@ void AudioInputDevice::Run() {
void AudioInputDevice::FireCaptureCallback(int16* input_audio) {
if (!callback_)
- return;
+ return;
const size_t number_of_frames = audio_parameters_.samples_per_packet;
@@ -338,3 +318,22 @@ void AudioInputDevice::FireCaptureCallback(int16* input_audio) {
number_of_frames,
audio_delay_milliseconds_);
}
+
+void AudioInputDevice::ShutDownAudioThread() {
+ DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop());
+
+ // TODO(tommi): This is a copy/paste of the same method in AudioDevice.
+ // We could extract the worker thread+socket bits out to a separate
+ // class to avoid having to fix the same issues twice in these classes.
+
+ if (audio_thread_.get()) {
+ // Close the socket to terminate the main thread function in the
+ // audio thread.
+ audio_socket_->Shutdown(); // Stops blocking Receive calls.
+ // TODO(tommi): We must not do this from the IO thread. Fix.
+ base::ThreadRestrictions::ScopedAllowIO allow_wait;
+ audio_thread_->Join();
+ audio_thread_.reset(NULL);
+ audio_socket_.reset();
+ }
+}
« content/renderer/media/audio_device.cc ('K') | « content/renderer/media/audio_input_device.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698