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

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

Issue 12379071: Use multiple shared memory buffers cyclically for audio capture. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: rebase Created 7 years, 9 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 10 matching lines...) Expand all
21 21
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 bool need_read_index,
31 base::SyncSocket::Handle socket, 32 base::SyncSocket::Handle socket,
32 const char* thread_name); 33 const char* thread_name);
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(MessageLoop* loop_for_join); 41 void Stop(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_;
56 bool need_read_index_;
55 base::CancelableSyncSocket socket_; 57 base::CancelableSyncSocket socket_;
56 base::Lock callback_lock_; 58 base::Lock callback_lock_;
57 const char* thread_name_; 59 const char* thread_name_;
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(bool need_read_index)
67 : need_read_index_(need_read_index) {
65 } 68 }
66 69
67 AudioDeviceThread::~AudioDeviceThread() { 70 AudioDeviceThread::~AudioDeviceThread() {
68 DCHECK(!thread_); 71 DCHECK(!thread_);
69 } 72 }
70 73
71 void AudioDeviceThread::Start(AudioDeviceThread::Callback* callback, 74 void AudioDeviceThread::Start(AudioDeviceThread::Callback* callback,
72 base::SyncSocket::Handle socket, 75 base::SyncSocket::Handle socket,
73 const char* thread_name) { 76 const char* thread_name) {
74 base::AutoLock auto_lock(thread_lock_); 77 base::AutoLock auto_lock(thread_lock_);
75 CHECK(thread_ == NULL); 78 CHECK(thread_ == NULL);
76 thread_ = new AudioDeviceThread::Thread(callback, socket, thread_name); 79 thread_ = new AudioDeviceThread::Thread(
80 callback, need_read_index_, socket, thread_name);
77 thread_->Start(); 81 thread_->Start();
78 } 82 }
79 83
80 void AudioDeviceThread::Stop(MessageLoop* loop_for_join) { 84 void AudioDeviceThread::Stop(MessageLoop* loop_for_join) {
81 base::AutoLock auto_lock(thread_lock_); 85 base::AutoLock auto_lock(thread_lock_);
82 if (thread_) { 86 if (thread_) {
83 thread_->Stop(loop_for_join); 87 thread_->Stop(loop_for_join);
84 thread_ = NULL; 88 thread_ = NULL;
85 } 89 }
86 } 90 }
87 91
88 bool AudioDeviceThread::IsStopped() { 92 bool AudioDeviceThread::IsStopped() {
89 base::AutoLock auto_lock(thread_lock_); 93 base::AutoLock auto_lock(thread_lock_);
90 return thread_ == NULL; 94 return thread_ == NULL;
91 } 95 }
92 96
93 // AudioDeviceThread::Thread implementation 97 // AudioDeviceThread::Thread implementation
94 AudioDeviceThread::Thread::Thread(AudioDeviceThread::Callback* callback, 98 AudioDeviceThread::Thread::Thread(AudioDeviceThread::Callback* callback,
99 bool need_read_index,
95 base::SyncSocket::Handle socket, 100 base::SyncSocket::Handle socket,
96 const char* thread_name) 101 const char* thread_name)
97 : thread_(base::kNullThreadHandle), 102 : thread_(base::kNullThreadHandle),
98 callback_(callback), 103 callback_(callback),
104 need_read_index_(need_read_index),
99 socket_(socket), 105 socket_(socket),
100 thread_name_(thread_name) { 106 thread_name_(thread_name) {
101 } 107 }
102 108
103 AudioDeviceThread::Thread::~Thread() { 109 AudioDeviceThread::Thread::~Thread() {
104 DCHECK_EQ(thread_, base::kNullThreadHandle) << "Stop wasn't called"; 110 DCHECK_EQ(thread_, base::kNullThreadHandle) << "Stop wasn't called";
105 } 111 }
106 112
107 void AudioDeviceThread::Thread::Start() { 113 void AudioDeviceThread::Thread::Start() {
108 base::AutoLock auto_lock(callback_lock_); 114 base::AutoLock auto_lock(callback_lock_);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 Run(); 160 Run();
155 161
156 // Release the reference for the thread. Note that after this, the Thread 162 // Release the reference for the thread. Note that after this, the Thread
157 // instance will most likely be deleted. 163 // instance will most likely be deleted.
158 Release(); 164 Release();
159 } 165 }
160 166
161 void AudioDeviceThread::Thread::Run() { 167 void AudioDeviceThread::Thread::Run() {
162 while (true) { 168 while (true) {
163 int pending_data = 0; 169 int pending_data = 0;
170 int pending_id = 0;
164 size_t bytes_read = socket_.Receive(&pending_data, sizeof(pending_data)); 171 size_t bytes_read = socket_.Receive(&pending_data, sizeof(pending_data));
165 if (bytes_read != sizeof(pending_data)) { 172 if (bytes_read != sizeof(pending_data)) {
166 DCHECK_EQ(bytes_read, 0U); 173 DCHECK_EQ(bytes_read, 0U);
167 break; 174 break;
168 } 175 }
169 176
177 if (need_read_index_) {
178 size_t bytes_read = socket_.Receive(&pending_id, sizeof(pending_id));
179 if (bytes_read != sizeof(pending_id)) {
180 DCHECK_EQ(bytes_read, 0U);
181 break;
182 }
183 }
184
170 base::AutoLock auto_lock(callback_lock_); 185 base::AutoLock auto_lock(callback_lock_);
171 if (callback_) 186 if (callback_)
172 callback_->Process(pending_data); 187 callback_->Process(pending_data, pending_id);
173 } 188 }
174 } 189 }
175 190
176 // AudioDeviceThread::Callback implementation 191 // AudioDeviceThread::Callback implementation
177 192
178 AudioDeviceThread::Callback::Callback( 193 AudioDeviceThread::Callback::Callback(
179 const AudioParameters& audio_parameters, 194 const AudioParameters& audio_parameters,
180 base::SharedMemoryHandle memory, int memory_length) 195 SharedMemoryHandleVector& memory,
196 int memory_length)
181 : audio_parameters_(audio_parameters), 197 : audio_parameters_(audio_parameters),
182 samples_per_ms_(audio_parameters.sample_rate() / 1000), 198 samples_per_ms_(audio_parameters.sample_rate() / 1000),
183 bytes_per_ms_(audio_parameters.channels() * 199 bytes_per_ms_(audio_parameters.channels() *
184 (audio_parameters_.bits_per_sample() / 8) * 200 (audio_parameters_.bits_per_sample() / 8) *
185 samples_per_ms_), 201 samples_per_ms_),
186 shared_memory_(memory, false),
187 memory_length_(memory_length) { 202 memory_length_(memory_length) {
188 CHECK_NE(bytes_per_ms_, 0); // Catch division by zero early. 203 CHECK_NE(bytes_per_ms_, 0); // Catch division by zero early.
189 CHECK_NE(samples_per_ms_, 0); 204 CHECK_NE(samples_per_ms_, 0);
205 shared_memory_.resize(memory.size());
206 for (size_t id = 0; id < shared_memory_.size(); ++id)
207 shared_memory_[id] = new base::SharedMemory(memory[id], false);
190 } 208 }
191 209
192 AudioDeviceThread::Callback::~Callback() {} 210 AudioDeviceThread::Callback::~Callback() {}
193 211
194 void AudioDeviceThread::Callback::InitializeOnAudioThread() { 212 void AudioDeviceThread::Callback::InitializeOnAudioThread() {
195 MapSharedMemory(); 213 MapSharedMemory();
196 CHECK(shared_memory_.memory()); 214 for (size_t id = 0; id < shared_memory_.size(); ++id)
215 CHECK(shared_memory_[id]->memory());
197 } 216 }
198 217
199 } // namespace media. 218 } // namespace media.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698