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

Side by Side Diff: media/audio/audio_device_thread.cc

Issue 22886005: Switch audio synchronization from sleep() based to select() based. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments. Split out base/ changes. Created 7 years, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698