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

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: Fix DCHECK. Created 7 years, 2 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
« no previous file with comments | « media/audio/audio_device_thread.h ('k') | media/audio/audio_input_device.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 10 matching lines...) Expand all
21 // The actual worker thread implementation. It's very bare bones and much 21 // The actual worker thread implementation. It's very bare bones and much
22 // simpler than SimpleThread (no synchronization in Start, etc) and supports 22 // simpler than SimpleThread (no synchronization in Start, etc) and supports
23 // joining the thread handle asynchronously via a provided message loop even 23 // joining the thread handle asynchronously via a provided message loop even
24 // after the Thread object itself has been deleted. 24 // after the Thread object itself has been deleted.
25 class AudioDeviceThread::Thread 25 class AudioDeviceThread::Thread
26 : public PlatformThread::Delegate, 26 : public PlatformThread::Delegate,
27 public base::RefCountedThreadSafe<AudioDeviceThread::Thread> { 27 public base::RefCountedThreadSafe<AudioDeviceThread::Thread> {
28 public: 28 public:
29 Thread(AudioDeviceThread::Callback* callback, 29 Thread(AudioDeviceThread::Callback* callback,
30 base::SyncSocket::Handle socket, 30 base::SyncSocket::Handle socket,
31 const char* thread_name); 31 const char* thread_name,
32 bool synchronized_buffers);
32 33
33 void Start(); 34 void Start();
34 35
35 // Stops the thread. If |loop_for_join| is non-NULL, the function posts 36 // Stops the thread. If |loop_for_join| is non-NULL, the function posts
36 // a task to join (close) the thread handle later instead of waiting for 37 // a task to join (close) the thread handle later instead of waiting for
37 // the thread. If loop_for_join is NULL, then the function waits 38 // the thread. If loop_for_join is NULL, then the function waits
38 // synchronously for the thread to terminate. 39 // synchronously for the thread to terminate.
39 void Stop(base::MessageLoop* loop_for_join); 40 void Stop(base::MessageLoop* loop_for_join);
40 41
41 private: 42 private:
42 friend class base::RefCountedThreadSafe<AudioDeviceThread::Thread>; 43 friend class base::RefCountedThreadSafe<AudioDeviceThread::Thread>;
43 virtual ~Thread(); 44 virtual ~Thread();
44 45
45 // Overrides from PlatformThread::Delegate. 46 // Overrides from PlatformThread::Delegate.
46 virtual void ThreadMain() OVERRIDE; 47 virtual void ThreadMain() OVERRIDE;
47 48
48 // Runs the loop that reads from the socket. 49 // Runs the loop that reads from the socket.
49 void Run(); 50 void Run();
50 51
51 private: 52 private:
52 base::PlatformThreadHandle thread_; 53 base::PlatformThreadHandle thread_;
53 AudioDeviceThread::Callback* callback_; 54 AudioDeviceThread::Callback* callback_;
54 base::CancelableSyncSocket socket_; 55 base::CancelableSyncSocket socket_;
55 base::Lock callback_lock_; 56 base::Lock callback_lock_;
56 const char* thread_name_; 57 const char* thread_name_;
58 const bool synchronized_buffers_;
57 59
58 DISALLOW_COPY_AND_ASSIGN(Thread); 60 DISALLOW_COPY_AND_ASSIGN(Thread);
59 }; 61 };
60 62
61 // AudioDeviceThread implementation 63 // AudioDeviceThread implementation
62 64
63 AudioDeviceThread::AudioDeviceThread() { 65 AudioDeviceThread::AudioDeviceThread() {
64 } 66 }
65 67
66 AudioDeviceThread::~AudioDeviceThread() { DCHECK(!thread_.get()); } 68 AudioDeviceThread::~AudioDeviceThread() { DCHECK(!thread_.get()); }
67 69
68 void AudioDeviceThread::Start(AudioDeviceThread::Callback* callback, 70 void AudioDeviceThread::Start(AudioDeviceThread::Callback* callback,
69 base::SyncSocket::Handle socket, 71 base::SyncSocket::Handle socket,
70 const char* thread_name) { 72 const char* thread_name,
73 bool synchronized_buffers) {
71 base::AutoLock auto_lock(thread_lock_); 74 base::AutoLock auto_lock(thread_lock_);
72 CHECK(thread_.get() == NULL); 75 CHECK(!thread_);
73 thread_ = new AudioDeviceThread::Thread(callback, socket, thread_name); 76 thread_ = new AudioDeviceThread::Thread(
77 callback, socket, thread_name, synchronized_buffers);
74 thread_->Start(); 78 thread_->Start();
75 } 79 }
76 80
77 void AudioDeviceThread::Stop(base::MessageLoop* loop_for_join) { 81 void AudioDeviceThread::Stop(base::MessageLoop* loop_for_join) {
78 base::AutoLock auto_lock(thread_lock_); 82 base::AutoLock auto_lock(thread_lock_);
79 if (thread_.get()) { 83 if (thread_.get()) {
80 thread_->Stop(loop_for_join); 84 thread_->Stop(loop_for_join);
81 thread_ = NULL; 85 thread_ = NULL;
82 } 86 }
83 } 87 }
84 88
85 bool AudioDeviceThread::IsStopped() { 89 bool AudioDeviceThread::IsStopped() {
86 base::AutoLock auto_lock(thread_lock_); 90 base::AutoLock auto_lock(thread_lock_);
87 return thread_.get() == NULL; 91 return !thread_;
88 } 92 }
89 93
90 // AudioDeviceThread::Thread implementation 94 // AudioDeviceThread::Thread implementation
91 AudioDeviceThread::Thread::Thread(AudioDeviceThread::Callback* callback, 95 AudioDeviceThread::Thread::Thread(AudioDeviceThread::Callback* callback,
92 base::SyncSocket::Handle socket, 96 base::SyncSocket::Handle socket,
93 const char* thread_name) 97 const char* thread_name,
98 bool synchronized_buffers)
94 : thread_(), 99 : thread_(),
95 callback_(callback), 100 callback_(callback),
96 socket_(socket), 101 socket_(socket),
97 thread_name_(thread_name) { 102 thread_name_(thread_name),
103 synchronized_buffers_(synchronized_buffers) {
98 } 104 }
99 105
100 AudioDeviceThread::Thread::~Thread() { 106 AudioDeviceThread::Thread::~Thread() {
101 DCHECK(thread_.is_null()); 107 DCHECK(thread_.is_null());
102 } 108 }
103 109
104 void AudioDeviceThread::Thread::Start() { 110 void AudioDeviceThread::Thread::Start() {
105 base::AutoLock auto_lock(callback_lock_); 111 base::AutoLock auto_lock(callback_lock_);
106 DCHECK(thread_.is_null()); 112 DCHECK(thread_.is_null());
107 // This reference will be released when the thread exists. 113 // This reference will be released when the thread exists.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 } 155 }
150 156
151 Run(); 157 Run();
152 158
153 // Release the reference for the thread. Note that after this, the Thread 159 // Release the reference for the thread. Note that after this, the Thread
154 // instance will most likely be deleted. 160 // instance will most likely be deleted.
155 Release(); 161 Release();
156 } 162 }
157 163
158 void AudioDeviceThread::Thread::Run() { 164 void AudioDeviceThread::Thread::Run() {
165 uint32 buffer_index = 0;
159 while (true) { 166 while (true) {
160 int pending_data = 0; 167 int pending_data = 0;
161 size_t bytes_read = socket_.Receive(&pending_data, sizeof(pending_data)); 168 size_t bytes_read = socket_.Receive(&pending_data, sizeof(pending_data));
162 if (bytes_read != sizeof(pending_data)) { 169 if (bytes_read != sizeof(pending_data)) {
163 DCHECK_EQ(bytes_read, 0U); 170 DCHECK_EQ(bytes_read, 0U);
164 break; 171 break;
165 } 172 }
166 173
167 base::AutoLock auto_lock(callback_lock_); 174 {
168 if (callback_) 175 base::AutoLock auto_lock(callback_lock_);
169 callback_->Process(pending_data); 176 if (callback_)
177 callback_->Process(pending_data);
178 }
179
180 // Let the other end know which buffer we just filled. The buffer index is
181 // used to ensure the other end is getting the buffer it expects. For more
182 // details on how this works see AudioSyncReader::WaitUntilDataIsReady().
183 if (synchronized_buffers_) {
184 ++buffer_index;
185 size_t bytes_sent = socket_.Send(&buffer_index, sizeof(buffer_index));
186 if (bytes_sent != sizeof(buffer_index))
187 break;
188 }
170 } 189 }
171 } 190 }
172 191
173 // AudioDeviceThread::Callback implementation 192 // AudioDeviceThread::Callback implementation
174 193
175 AudioDeviceThread::Callback::Callback( 194 AudioDeviceThread::Callback::Callback(
176 const AudioParameters& audio_parameters, 195 const AudioParameters& audio_parameters,
177 base::SharedMemoryHandle memory, 196 base::SharedMemoryHandle memory,
178 int memory_length, 197 int memory_length,
179 int total_segments) 198 int total_segments)
(...skipping 13 matching lines...) Expand all
193 } 212 }
194 213
195 AudioDeviceThread::Callback::~Callback() {} 214 AudioDeviceThread::Callback::~Callback() {}
196 215
197 void AudioDeviceThread::Callback::InitializeOnAudioThread() { 216 void AudioDeviceThread::Callback::InitializeOnAudioThread() {
198 MapSharedMemory(); 217 MapSharedMemory();
199 CHECK(shared_memory_.memory()); 218 CHECK(shared_memory_.memory());
200 } 219 }
201 220
202 } // namespace media. 221 } // namespace media.
OLDNEW
« no previous file with comments | « media/audio/audio_device_thread.h ('k') | media/audio/audio_input_device.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698