Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/audio/audio_device_thread.h" | 5 #include "media/audio/audio_device_thread.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 // The actual worker thread implementation. It's very bare bones and much | 22 // The actual worker thread implementation. It's very bare bones and much |
| 23 // simpler than SimpleThread (no synchronization in Start, etc) and supports | 23 // simpler than SimpleThread (no synchronization in Start, etc) and supports |
| 24 // joining the thread handle asynchronously via a provided message loop even | 24 // joining the thread handle asynchronously via a provided message loop even |
| 25 // after the Thread object itself has been deleted. | 25 // after the Thread object itself has been deleted. |
| 26 class AudioDeviceThread::Thread | 26 class AudioDeviceThread::Thread |
| 27 : public PlatformThread::Delegate, | 27 : public PlatformThread::Delegate, |
| 28 public base::RefCountedThreadSafe<AudioDeviceThread::Thread> { | 28 public base::RefCountedThreadSafe<AudioDeviceThread::Thread> { |
| 29 public: | 29 public: |
| 30 Thread(AudioDeviceThread::Callback* callback, | 30 Thread(AudioDeviceThread::Callback* callback, |
| 31 base::SyncSocket::Handle socket, | 31 base::SyncSocket::Handle socket, |
| 32 const char* thread_name); | 32 const char* thread_name, |
| 33 bool synchronized_buffers); | |
| 33 | 34 |
| 34 void Start(); | 35 void Start(); |
| 35 | 36 |
| 36 // Stops the thread. If |loop_for_join| is non-NULL, the function posts | 37 // Stops the thread. If |loop_for_join| is non-NULL, the function posts |
| 37 // a task to join (close) the thread handle later instead of waiting for | 38 // a task to join (close) the thread handle later instead of waiting for |
| 38 // the thread. If loop_for_join is NULL, then the function waits | 39 // the thread. If loop_for_join is NULL, then the function waits |
| 39 // synchronously for the thread to terminate. | 40 // synchronously for the thread to terminate. |
| 40 void Stop(base::MessageLoop* loop_for_join); | 41 void Stop(base::MessageLoop* loop_for_join); |
| 41 | 42 |
| 42 private: | 43 private: |
| 43 friend class base::RefCountedThreadSafe<AudioDeviceThread::Thread>; | 44 friend class base::RefCountedThreadSafe<AudioDeviceThread::Thread>; |
| 44 virtual ~Thread(); | 45 virtual ~Thread(); |
| 45 | 46 |
| 46 // Overrides from PlatformThread::Delegate. | 47 // Overrides from PlatformThread::Delegate. |
| 47 virtual void ThreadMain() OVERRIDE; | 48 virtual void ThreadMain() OVERRIDE; |
| 48 | 49 |
| 49 // Runs the loop that reads from the socket. | 50 // Runs the loop that reads from the socket. |
| 50 void Run(); | 51 void Run(); |
| 51 | 52 |
| 52 private: | 53 private: |
| 53 base::PlatformThreadHandle thread_; | 54 base::PlatformThreadHandle thread_; |
| 54 AudioDeviceThread::Callback* callback_; | 55 AudioDeviceThread::Callback* callback_; |
| 55 base::CancelableSyncSocket socket_; | 56 base::CancelableSyncSocket socket_; |
| 56 base::Lock callback_lock_; | 57 base::Lock callback_lock_; |
| 57 const char* thread_name_; | 58 const char* thread_name_; |
| 59 const bool synchronized_buffers_; | |
| 58 | 60 |
| 59 DISALLOW_COPY_AND_ASSIGN(Thread); | 61 DISALLOW_COPY_AND_ASSIGN(Thread); |
| 60 }; | 62 }; |
| 61 | 63 |
| 62 // AudioDeviceThread implementation | 64 // AudioDeviceThread implementation |
| 63 | 65 |
| 64 AudioDeviceThread::AudioDeviceThread() { | 66 AudioDeviceThread::AudioDeviceThread() { |
| 65 } | 67 } |
| 66 | 68 |
| 67 AudioDeviceThread::~AudioDeviceThread() { DCHECK(!thread_.get()); } | 69 AudioDeviceThread::~AudioDeviceThread() { DCHECK(!thread_.get()); } |
| 68 | 70 |
| 69 void AudioDeviceThread::Start(AudioDeviceThread::Callback* callback, | 71 void AudioDeviceThread::Start(AudioDeviceThread::Callback* callback, |
| 70 base::SyncSocket::Handle socket, | 72 base::SyncSocket::Handle socket, |
| 71 const char* thread_name) { | 73 const char* thread_name, |
| 74 bool synchronized_buffers) { | |
| 72 base::AutoLock auto_lock(thread_lock_); | 75 base::AutoLock auto_lock(thread_lock_); |
| 73 CHECK(thread_.get() == NULL); | 76 CHECK(!thread_); |
| 74 thread_ = new AudioDeviceThread::Thread(callback, socket, thread_name); | 77 thread_ = new AudioDeviceThread::Thread( |
| 78 callback, socket, thread_name, synchronized_buffers); | |
| 75 thread_->Start(); | 79 thread_->Start(); |
| 76 } | 80 } |
| 77 | 81 |
| 78 void AudioDeviceThread::Stop(base::MessageLoop* loop_for_join) { | 82 void AudioDeviceThread::Stop(base::MessageLoop* loop_for_join) { |
| 79 base::AutoLock auto_lock(thread_lock_); | 83 base::AutoLock auto_lock(thread_lock_); |
| 80 if (thread_.get()) { | 84 if (thread_.get()) { |
| 81 thread_->Stop(loop_for_join); | 85 thread_->Stop(loop_for_join); |
| 82 thread_ = NULL; | 86 thread_ = NULL; |
| 83 } | 87 } |
| 84 } | 88 } |
| 85 | 89 |
| 86 bool AudioDeviceThread::IsStopped() { | 90 bool AudioDeviceThread::IsStopped() { |
| 87 base::AutoLock auto_lock(thread_lock_); | 91 base::AutoLock auto_lock(thread_lock_); |
| 88 return thread_.get() == NULL; | 92 return !thread_; |
| 89 } | 93 } |
| 90 | 94 |
| 91 // AudioDeviceThread::Thread implementation | 95 // AudioDeviceThread::Thread implementation |
| 92 AudioDeviceThread::Thread::Thread(AudioDeviceThread::Callback* callback, | 96 AudioDeviceThread::Thread::Thread(AudioDeviceThread::Callback* callback, |
| 93 base::SyncSocket::Handle socket, | 97 base::SyncSocket::Handle socket, |
| 94 const char* thread_name) | 98 const char* thread_name, |
| 99 bool synchronized_buffers) | |
| 95 : thread_(), | 100 : thread_(), |
| 96 callback_(callback), | 101 callback_(callback), |
| 97 socket_(socket), | 102 socket_(socket), |
| 98 thread_name_(thread_name) { | 103 thread_name_(thread_name), |
| 104 synchronized_buffers_(synchronized_buffers) { | |
| 99 } | 105 } |
| 100 | 106 |
| 101 AudioDeviceThread::Thread::~Thread() { | 107 AudioDeviceThread::Thread::~Thread() { |
| 102 DCHECK(thread_.is_null()); | 108 DCHECK(thread_.is_null()); |
| 103 } | 109 } |
| 104 | 110 |
| 105 void AudioDeviceThread::Thread::Start() { | 111 void AudioDeviceThread::Thread::Start() { |
| 106 base::AutoLock auto_lock(callback_lock_); | 112 base::AutoLock auto_lock(callback_lock_); |
| 107 DCHECK(thread_.is_null()); | 113 DCHECK(thread_.is_null()); |
| 108 // This reference will be released when the thread exists. | 114 // This reference will be released when the thread exists. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 150 } | 156 } |
| 151 | 157 |
| 152 Run(); | 158 Run(); |
| 153 | 159 |
| 154 // Release the reference for the thread. Note that after this, the Thread | 160 // Release the reference for the thread. Note that after this, the Thread |
| 155 // instance will most likely be deleted. | 161 // instance will most likely be deleted. |
| 156 Release(); | 162 Release(); |
| 157 } | 163 } |
| 158 | 164 |
| 159 void AudioDeviceThread::Thread::Run() { | 165 void AudioDeviceThread::Thread::Run() { |
| 166 uint32 buffer_index = 0; | |
| 160 while (true) { | 167 while (true) { |
| 161 int pending_data = 0; | 168 int pending_data = 0; |
| 162 size_t bytes_read = socket_.Receive(&pending_data, sizeof(pending_data)); | 169 size_t bytes_read = socket_.Receive(&pending_data, sizeof(pending_data)); |
| 163 if (bytes_read != sizeof(pending_data)) { | 170 if (bytes_read != sizeof(pending_data)) { |
| 164 DCHECK_EQ(bytes_read, 0U); | 171 DCHECK_EQ(bytes_read, 0U); |
| 165 break; | 172 break; |
| 166 } | 173 } |
| 167 | 174 |
| 168 base::AutoLock auto_lock(callback_lock_); | 175 { |
| 169 if (callback_) | 176 base::AutoLock auto_lock(callback_lock_); |
| 170 callback_->Process(pending_data); | 177 if (callback_) |
| 178 callback_->Process(pending_data); | |
| 179 } | |
| 180 | |
| 181 // Let the other end know which buffer we just filled. | |
|
henrika (OOO until Aug 14)
2013/09/13 10:25:44
Can you add a line about how the renderer and brow
DaleCurtis
2013/10/22 23:13:49
Done.
| |
| 182 if (synchronized_buffers_) { | |
| 183 ++buffer_index; | |
| 184 size_t bytes_sent = socket_.Send(&buffer_index, sizeof(buffer_index)); | |
| 185 if (bytes_sent != sizeof(buffer_index)) | |
| 186 break; | |
| 187 } | |
| 171 } | 188 } |
| 172 } | 189 } |
| 173 | 190 |
| 174 // AudioDeviceThread::Callback implementation | 191 // AudioDeviceThread::Callback implementation |
| 175 | 192 |
| 176 AudioDeviceThread::Callback::Callback( | 193 AudioDeviceThread::Callback::Callback( |
| 177 const AudioParameters& audio_parameters, | 194 const AudioParameters& audio_parameters, |
| 178 base::SharedMemoryHandle memory, | 195 base::SharedMemoryHandle memory, |
| 179 int memory_length, | 196 int memory_length, |
| 180 int total_segments) | 197 int total_segments) |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 194 } | 211 } |
| 195 | 212 |
| 196 AudioDeviceThread::Callback::~Callback() {} | 213 AudioDeviceThread::Callback::~Callback() {} |
| 197 | 214 |
| 198 void AudioDeviceThread::Callback::InitializeOnAudioThread() { | 215 void AudioDeviceThread::Callback::InitializeOnAudioThread() { |
| 199 MapSharedMemory(); | 216 MapSharedMemory(); |
| 200 CHECK(shared_memory_.memory()); | 217 CHECK(shared_memory_.memory()); |
| 201 } | 218 } |
| 202 | 219 |
| 203 } // namespace media. | 220 } // namespace media. |
| OLD | NEW |