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
3 // found in the LICENSE file.
5 #include "media/audio/audio_device_thread.h"
10 #include "base/logging.h"
11 #include "base/memory/aligned_memory.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/numerics/safe_conversions.h"
14 #include "base/threading/platform_thread.h"
15 #include "base/threading/thread_restrictions.h"
16 #include "media/base/audio_bus.h"
18 using base::PlatformThread
;
22 // The actual worker thread implementation. It's very bare bones and much
23 // simpler than SimpleThread (no synchronization in Start, etc) and supports
24 // joining the thread handle asynchronously via a provided message loop even
25 // after the Thread object itself has been deleted.
26 class AudioDeviceThread::Thread
27 : public PlatformThread::Delegate
,
28 public base::RefCountedThreadSafe
<AudioDeviceThread::Thread
> {
30 Thread(AudioDeviceThread::Callback
* callback
,
31 base::SyncSocket::Handle socket
,
32 const char* thread_name
,
33 bool synchronized_buffers
);
37 // Stops the thread. If |loop_for_join| is non-NULL, the function posts
38 // a task to join (close) the thread handle later instead of waiting for
39 // the thread. If loop_for_join is NULL, then the function waits
40 // synchronously for the thread to terminate.
41 void Stop(base::MessageLoop
* loop_for_join
);
44 friend class base::RefCountedThreadSafe
<AudioDeviceThread::Thread
>;
47 // Overrides from PlatformThread::Delegate.
48 void ThreadMain() override
;
50 // Runs the loop that reads from the socket.
54 base::PlatformThreadHandle thread_
;
55 AudioDeviceThread::Callback
* callback_
;
56 base::CancelableSyncSocket socket_
;
57 base::Lock callback_lock_
;
58 const char* thread_name_
;
59 const bool synchronized_buffers_
;
61 DISALLOW_COPY_AND_ASSIGN(Thread
);
64 // AudioDeviceThread implementation
66 AudioDeviceThread::AudioDeviceThread() {
69 AudioDeviceThread::~AudioDeviceThread() { DCHECK(!thread_
.get()); }
71 void AudioDeviceThread::Start(AudioDeviceThread::Callback
* callback
,
72 base::SyncSocket::Handle socket
,
73 const char* thread_name
,
74 bool synchronized_buffers
) {
75 base::AutoLock
auto_lock(thread_lock_
);
76 CHECK(!thread_
.get());
77 thread_
= new AudioDeviceThread::Thread(
78 callback
, socket
, thread_name
, synchronized_buffers
);
82 void AudioDeviceThread::Stop(base::MessageLoop
* loop_for_join
) {
83 base::AutoLock
auto_lock(thread_lock_
);
85 thread_
->Stop(loop_for_join
);
90 bool AudioDeviceThread::IsStopped() {
91 base::AutoLock
auto_lock(thread_lock_
);
92 return !thread_
.get();
95 // AudioDeviceThread::Thread implementation
96 AudioDeviceThread::Thread::Thread(AudioDeviceThread::Callback
* callback
,
97 base::SyncSocket::Handle socket
,
98 const char* thread_name
,
99 bool synchronized_buffers
)
103 thread_name_(thread_name
),
104 synchronized_buffers_(synchronized_buffers
) {
107 AudioDeviceThread::Thread::~Thread() {
108 DCHECK(thread_
.is_null());
111 void AudioDeviceThread::Thread::Start() {
112 base::AutoLock
auto_lock(callback_lock_
);
113 DCHECK(thread_
.is_null());
114 // This reference will be released when the thread exists.
117 PlatformThread::CreateWithPriority(0, this, &thread_
,
118 base::ThreadPriority::REALTIME_AUDIO
);
119 CHECK(!thread_
.is_null());
122 void AudioDeviceThread::Thread::Stop(base::MessageLoop
* loop_for_join
) {
125 base::PlatformThreadHandle thread
= base::PlatformThreadHandle();
128 base::AutoLock
auto_lock(callback_lock_
);
130 std::swap(thread
, thread_
);
133 if (!thread
.is_null()) {
135 loop_for_join
->PostTask(FROM_HERE
,
136 base::Bind(&base::PlatformThread::Join
, thread
));
138 base::PlatformThread::Join(thread
);
143 void AudioDeviceThread::Thread::ThreadMain() {
144 PlatformThread::SetName(thread_name_
);
146 // Singleton access is safe from this thread as long as callback is non-NULL.
147 // The callback is the only point where the thread calls out to 'unknown' code
148 // that might touch singletons and the lifetime of the callback is controlled
149 // by another thread on which singleton access is OK as well.
150 base::ThreadRestrictions::SetSingletonAllowed(true);
153 base::AutoLock
auto_lock(callback_lock_
);
155 callback_
->InitializeOnAudioThread();
160 // Release the reference for the thread. Note that after this, the Thread
161 // instance will most likely be deleted.
165 void AudioDeviceThread::Thread::Run() {
166 uint32 buffer_index
= 0;
168 uint32 pending_data
= 0;
169 size_t bytes_read
= socket_
.Receive(&pending_data
, sizeof(pending_data
));
170 if (bytes_read
!= sizeof(pending_data
))
173 // kuint32max is a special signal which is returned after the browser
174 // stops the output device in response to a renderer side request.
176 // Avoid running Process() for the paused signal, we still need to update
177 // the buffer index if |synchronized_buffers_| is true though.
179 // See comments in AudioOutputController::DoPause() for details on why.
180 if (pending_data
!= kuint32max
) {
181 base::AutoLock
auto_lock(callback_lock_
);
183 callback_
->Process(pending_data
);
186 // Let the other end know which buffer we just filled. The buffer index is
187 // used to ensure the other end is getting the buffer it expects. For more
188 // details on how this works see AudioSyncReader::WaitUntilDataIsReady().
189 if (synchronized_buffers_
) {
191 size_t bytes_sent
= socket_
.Send(&buffer_index
, sizeof(buffer_index
));
192 if (bytes_sent
!= sizeof(buffer_index
))
198 // AudioDeviceThread::Callback implementation
200 AudioDeviceThread::Callback::Callback(
201 const AudioParameters
& audio_parameters
,
202 base::SharedMemoryHandle memory
,
205 : audio_parameters_(audio_parameters
),
206 samples_per_ms_(audio_parameters
.sample_rate() / 1000),
207 bytes_per_ms_(audio_parameters
.channels() *
208 (audio_parameters_
.bits_per_sample() / 8) *
210 shared_memory_(memory
, false),
211 memory_length_(memory_length
),
212 total_segments_(total_segments
) {
213 CHECK_NE(bytes_per_ms_
, 0); // Catch division by zero early.
214 CHECK_NE(samples_per_ms_
, 0);
215 CHECK_GT(total_segments_
, 0);
216 CHECK_EQ(memory_length_
% total_segments_
, 0);
217 segment_length_
= memory_length_
/ total_segments_
;
220 AudioDeviceThread::Callback::~Callback() {}
222 void AudioDeviceThread::Callback::InitializeOnAudioThread() {
224 CHECK(shared_memory_
.memory());
227 } // namespace media.