| Index: content/renderer/media/audio_device_thread.cc
|
| ===================================================================
|
| --- content/renderer/media/audio_device_thread.cc (revision 148738)
|
| +++ content/renderer/media/audio_device_thread.cc (working copy)
|
| @@ -1,202 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "content/renderer/media/audio_device_thread.h"
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/logging.h"
|
| -#include "base/message_loop.h"
|
| -#include "base/threading/platform_thread.h"
|
| -#include "base/threading/thread_restrictions.h"
|
| -#include "media/audio/audio_util.h"
|
| -
|
| -using base::PlatformThread;
|
| -
|
| -// The actual worker thread implementation. It's very bare bones and much
|
| -// simpler than SimpleThread (no synchronization in Start, etc) and supports
|
| -// joining the thread handle asynchronously via a provided message loop even
|
| -// after the Thread object itself has been deleted.
|
| -class AudioDeviceThread::Thread
|
| - : public PlatformThread::Delegate,
|
| - public base::RefCountedThreadSafe<AudioDeviceThread::Thread> {
|
| - public:
|
| - Thread(AudioDeviceThread::Callback* callback,
|
| - base::SyncSocket::Handle socket,
|
| - const char* thread_name);
|
| -
|
| - void Start();
|
| -
|
| - // Stops the thread. If |loop_for_join| is non-NULL, the function posts
|
| - // a task to join (close) the thread handle later instead of waiting for
|
| - // the thread. If loop_for_join is NULL, then the function waits
|
| - // synchronously for the thread to terminate.
|
| - void Stop(MessageLoop* loop_for_join);
|
| -
|
| - private:
|
| - friend class base::RefCountedThreadSafe<AudioDeviceThread::Thread>;
|
| - virtual ~Thread();
|
| -
|
| - // Overrides from PlatformThread::Delegate.
|
| - virtual void ThreadMain() OVERRIDE;
|
| -
|
| - // Runs the loop that reads from the socket.
|
| - void Run();
|
| -
|
| - private:
|
| - base::PlatformThreadHandle thread_;
|
| - AudioDeviceThread::Callback* callback_;
|
| - base::CancelableSyncSocket socket_;
|
| - base::Lock callback_lock_;
|
| - const char* thread_name_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(Thread);
|
| -};
|
| -
|
| -// AudioDeviceThread implementation
|
| -
|
| -AudioDeviceThread::AudioDeviceThread() {
|
| -}
|
| -
|
| -AudioDeviceThread::~AudioDeviceThread() {
|
| - DCHECK(!thread_);
|
| -}
|
| -
|
| -void AudioDeviceThread::Start(AudioDeviceThread::Callback* callback,
|
| - base::SyncSocket::Handle socket,
|
| - const char* thread_name) {
|
| - base::AutoLock auto_lock(thread_lock_);
|
| - CHECK(thread_ == NULL);
|
| - thread_ = new AudioDeviceThread::Thread(callback, socket, thread_name);
|
| - thread_->Start();
|
| -}
|
| -
|
| -void AudioDeviceThread::Stop(MessageLoop* loop_for_join) {
|
| - base::AutoLock auto_lock(thread_lock_);
|
| - if (thread_) {
|
| - thread_->Stop(loop_for_join);
|
| - thread_ = NULL;
|
| - }
|
| -}
|
| -
|
| -bool AudioDeviceThread::IsStopped() {
|
| - base::AutoLock auto_lock(thread_lock_);
|
| - return thread_ == NULL;
|
| -}
|
| -
|
| -// AudioDeviceThread::Thread implementation
|
| -AudioDeviceThread::Thread::Thread(AudioDeviceThread::Callback* callback,
|
| - base::SyncSocket::Handle socket,
|
| - const char* thread_name)
|
| - : thread_(base::kNullThreadHandle),
|
| - callback_(callback),
|
| - socket_(socket),
|
| - thread_name_(thread_name) {
|
| -}
|
| -
|
| -AudioDeviceThread::Thread::~Thread() {
|
| - DCHECK_EQ(thread_, base::kNullThreadHandle) << "Stop wasn't called";
|
| -}
|
| -
|
| -void AudioDeviceThread::Thread::Start() {
|
| - base::AutoLock auto_lock(callback_lock_);
|
| - DCHECK_EQ(thread_, base::kNullThreadHandle);
|
| - // This reference will be released when the thread exists.
|
| - AddRef();
|
| -
|
| - PlatformThread::CreateWithPriority(0, this, &thread_,
|
| - base::kThreadPriority_RealtimeAudio);
|
| - CHECK(thread_ != base::kNullThreadHandle);
|
| -}
|
| -
|
| -void AudioDeviceThread::Thread::Stop(MessageLoop* loop_for_join) {
|
| - socket_.Shutdown();
|
| -
|
| - base::PlatformThreadHandle thread = base::kNullThreadHandle;
|
| -
|
| - { // NOLINT
|
| - base::AutoLock auto_lock(callback_lock_);
|
| - callback_ = NULL;
|
| - std::swap(thread, thread_);
|
| - }
|
| -
|
| - if (thread != base::kNullThreadHandle) {
|
| - if (loop_for_join) {
|
| - loop_for_join->PostTask(FROM_HERE,
|
| - base::Bind(&base::PlatformThread::Join, thread));
|
| - } else {
|
| - base::PlatformThread::Join(thread);
|
| - }
|
| - }
|
| -}
|
| -
|
| -void AudioDeviceThread::Thread::ThreadMain() {
|
| - PlatformThread::SetName(thread_name_);
|
| -
|
| - // Singleton access is safe from this thread as long as callback is non-NULL.
|
| - // The callback is the only point where the thread calls out to 'unknown' code
|
| - // that might touch singletons and the lifetime of the callback is controlled
|
| - // by another thread on which singleton access is OK as well.
|
| - base::ThreadRestrictions::SetSingletonAllowed(true);
|
| -
|
| - { // NOLINT
|
| - base::AutoLock auto_lock(callback_lock_);
|
| - if (callback_)
|
| - callback_->InitializeOnAudioThread();
|
| - }
|
| -
|
| - Run();
|
| -
|
| - // Release the reference for the thread. Note that after this, the Thread
|
| - // instance will most likely be deleted.
|
| - Release();
|
| -}
|
| -
|
| -void AudioDeviceThread::Thread::Run() {
|
| - while (true) {
|
| - int pending_data = 0;
|
| - size_t bytes_read = socket_.Receive(&pending_data, sizeof(pending_data));
|
| - if (bytes_read != sizeof(pending_data)) {
|
| - DCHECK_EQ(bytes_read, 0U);
|
| - break;
|
| - }
|
| -
|
| - base::AutoLock auto_lock(callback_lock_);
|
| - if (callback_)
|
| - callback_->Process(pending_data);
|
| - }
|
| -}
|
| -
|
| -// AudioDeviceThread::Callback implementation
|
| -
|
| -AudioDeviceThread::Callback::Callback(
|
| - const media::AudioParameters& audio_parameters,
|
| - base::SharedMemoryHandle memory, int memory_length)
|
| - : audio_parameters_(audio_parameters),
|
| - samples_per_ms_(audio_parameters.sample_rate() / 1000),
|
| - bytes_per_ms_(audio_parameters.channels() *
|
| - (audio_parameters_.bits_per_sample() / 8) *
|
| - samples_per_ms_),
|
| - shared_memory_(memory, false),
|
| - memory_length_(memory_length) {
|
| - CHECK_NE(bytes_per_ms_, 0); // Catch division by zero early.
|
| - CHECK_NE(samples_per_ms_, 0);
|
| -}
|
| -
|
| -AudioDeviceThread::Callback::~Callback() {
|
| - for (size_t i = 0; i < audio_data_.size(); ++i)
|
| - delete [] audio_data_[i];
|
| -}
|
| -
|
| -void AudioDeviceThread::Callback::InitializeOnAudioThread() {
|
| - DCHECK(audio_data_.empty());
|
| -
|
| - MapSharedMemory();
|
| - DCHECK(shared_memory_.memory() != NULL);
|
| -
|
| - audio_data_.reserve(audio_parameters_.channels());
|
| - for (int i = 0; i < audio_parameters_.channels(); ++i) {
|
| - float* channel_data = new float[audio_parameters_.frames_per_buffer()];
|
| - audio_data_.push_back(channel_data);
|
| - }
|
| -}
|
|
|