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 |