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 "ppapi/shared_impl/ppb_audio_shared.h" | 5 #include "ppapi/shared_impl/ppb_audio_shared.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "ppapi/shared_impl/ppapi_globals.h" | 8 #include "ppapi/shared_impl/ppapi_globals.h" |
9 #include "ppapi/shared_impl/ppb_audio_config_shared.h" | 9 #include "ppapi/shared_impl/ppb_audio_config_shared.h" |
10 #include "ppapi/shared_impl/proxy_lock.h" | 10 #include "ppapi/shared_impl/proxy_lock.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 socket_->Shutdown(); | 66 socket_->Shutdown(); |
67 StopThread(); | 67 StopThread(); |
68 } | 68 } |
69 | 69 |
70 void PPB_Audio_Shared::SetCallback(const AudioCallbackCombined& callback, | 70 void PPB_Audio_Shared::SetCallback(const AudioCallbackCombined& callback, |
71 void* user_data) { | 71 void* user_data) { |
72 callback_ = callback; | 72 callback_ = callback; |
73 user_data_ = user_data; | 73 user_data_ = user_data; |
74 } | 74 } |
75 | 75 |
76 void PPB_Audio_Shared::SetStartPlaybackState() { | 76 bool PPB_Audio_Shared::SetStartPlaybackState() { |
77 DCHECK(!playing_); | 77 DCHECK(!playing_); |
78 #if !defined(OS_NACL) | 78 #if !defined(OS_NACL) |
79 DCHECK(!audio_thread_.get()); | 79 DCHECK(!audio_thread_.get()); |
80 #else | 80 #else |
81 DCHECK(!thread_active_); | 81 DCHECK(!thread_active_); |
82 #endif | 82 #endif |
83 // If the socket doesn't exist, that means that the plugin has started before | 83 // If the socket doesn't exist, that means that the plugin has started before |
84 // the browser has had a chance to create all the shared memory info and | 84 // the browser has had a chance to create all the shared memory info and |
85 // notify us. This is a common case. In this case, we just set the playing_ | 85 // notify us. This is a common case. In this case, we just set the playing_ |
86 // flag and the playback will automatically start when that data is available | 86 // flag and the playback will automatically start when that data is available |
87 // in SetStreamInfo. | 87 // in SetStreamInfo. |
88 playing_ = true; | 88 playing_ = true; |
89 StartThread(); | 89 if (!StartThread()) |
90 playing_ = false; | |
bbudge
2014/04/17 21:44:27
This makes the comment above false. It seems like
hidehiko
2014/04/17 23:03:37
The comment above is true. StartThread() returns f
bbudge
2014/04/18 13:27:25
Ah, I see now.
| |
91 return playing_; | |
90 } | 92 } |
91 | 93 |
92 void PPB_Audio_Shared::SetStopPlaybackState() { | 94 void PPB_Audio_Shared::SetStopPlaybackState() { |
93 DCHECK(playing_); | 95 DCHECK(playing_); |
94 StopThread(); | 96 StopThread(); |
95 playing_ = false; | 97 playing_ = false; |
96 } | 98 } |
97 | 99 |
98 void PPB_Audio_Shared::SetStreamInfo( | 100 void PPB_Audio_Shared::SetStreamInfo( |
99 PP_Instance instance, | 101 PP_Instance instance, |
(...skipping 20 matching lines...) Expand all Loading... | |
120 kAudioOutputChannels, sample_frame_count, shared_memory_->memory()); | 122 kAudioOutputChannels, sample_frame_count, shared_memory_->memory()); |
121 // Setup integer audio buffer for user audio data. | 123 // Setup integer audio buffer for user audio data. |
122 client_buffer_size_bytes_ = audio_bus_->frames() * audio_bus_->channels() * | 124 client_buffer_size_bytes_ = audio_bus_->frames() * audio_bus_->channels() * |
123 kBitsPerAudioOutputSample / 8; | 125 kBitsPerAudioOutputSample / 8; |
124 client_buffer_.reset(new uint8_t[client_buffer_size_bytes_]); | 126 client_buffer_.reset(new uint8_t[client_buffer_size_bytes_]); |
125 } | 127 } |
126 | 128 |
127 StartThread(); | 129 StartThread(); |
128 } | 130 } |
129 | 131 |
130 void PPB_Audio_Shared::StartThread() { | 132 bool PPB_Audio_Shared::StartThread() { |
133 #if defined(OS_NACL) | |
134 // Use NaCl's special API for IRT code that creates threads that call back | |
135 // into user code. | |
136 if (NULL == thread_functions.thread_create || | |
137 NULL == thread_functions.thread_join) | |
138 return false; | |
139 #endif | |
140 | |
131 // Don't start the thread unless all our state is set up correctly. | 141 // Don't start the thread unless all our state is set up correctly. |
132 if (!playing_ || !callback_.IsValid() || !socket_.get() || | 142 if (!playing_ || !callback_.IsValid() || !socket_.get() || |
133 !shared_memory_->memory() || !audio_bus_.get() || !client_buffer_.get() || | 143 !shared_memory_->memory() || !audio_bus_.get() || !client_buffer_.get() || |
134 bytes_per_second_ == 0) | 144 bytes_per_second_ == 0) |
135 return; | 145 return true; |
146 | |
136 // Clear contents of shm buffer before starting audio thread. This will | 147 // Clear contents of shm buffer before starting audio thread. This will |
137 // prevent a burst of static if for some reason the audio thread doesn't | 148 // prevent a burst of static if for some reason the audio thread doesn't |
138 // start up quickly enough. | 149 // start up quickly enough. |
139 memset(shared_memory_->memory(), 0, shared_memory_size_); | 150 memset(shared_memory_->memory(), 0, shared_memory_size_); |
140 memset(client_buffer_.get(), 0, client_buffer_size_bytes_); | 151 memset(client_buffer_.get(), 0, client_buffer_size_bytes_); |
141 #if !defined(OS_NACL) | 152 #if !defined(OS_NACL) |
142 DCHECK(!audio_thread_.get()); | 153 DCHECK(!audio_thread_.get()); |
143 audio_thread_.reset( | 154 audio_thread_.reset( |
144 new base::DelegateSimpleThread(this, "plugin_audio_thread")); | 155 new base::DelegateSimpleThread(this, "plugin_audio_thread")); |
145 audio_thread_->Start(); | 156 audio_thread_->Start(); |
146 #else | 157 #else |
147 // Use NaCl's special API for IRT code that creates threads that call back | 158 DCHECK(!thread_active_); |
148 // into user code. | |
149 if (NULL == thread_functions.thread_create || | |
150 NULL == thread_functions.thread_join) | |
151 return; | |
152 | |
153 int result = thread_functions.thread_create(&thread_id_, CallRun, this); | 159 int result = thread_functions.thread_create(&thread_id_, CallRun, this); |
154 DCHECK_EQ(result, 0); | 160 DCHECK_EQ(result, 0); |
155 thread_active_ = true; | 161 thread_active_ = true; |
156 #endif | 162 #endif |
163 return true; | |
157 } | 164 } |
158 | 165 |
159 void PPB_Audio_Shared::StopThread() { | 166 void PPB_Audio_Shared::StopThread() { |
160 #if !defined(OS_NACL) | 167 #if !defined(OS_NACL) |
161 if (audio_thread_.get()) { | 168 if (audio_thread_.get()) { |
162 // In general, the audio thread should not do Pepper calls, but it might | 169 // In general, the audio thread should not do Pepper calls, but it might |
163 // anyway (for example, our Audio test does CallOnMainThread). If it did | 170 // anyway (for example, our Audio test does CallOnMainThread). If it did |
164 // a pepper call which acquires the lock (most of them do), and we try to | 171 // a pepper call which acquires the lock (most of them do), and we try to |
165 // shut down the thread and Join it while holding the lock, we would | 172 // shut down the thread and Join it while holding the lock, we would |
166 // deadlock. So we give up the lock here so that the thread at least _can_ | 173 // deadlock. So we give up the lock here so that the thread at least _can_ |
167 // make Pepper calls without causing deadlock. | 174 // make Pepper calls without causing deadlock. |
168 CallWhileUnlocked(base::Bind(&base::DelegateSimpleThread::Join, | 175 CallWhileUnlocked(base::Bind(&base::DelegateSimpleThread::Join, |
169 base::Unretained(audio_thread_.get()))); | 176 base::Unretained(audio_thread_.get()))); |
170 audio_thread_.reset(); | 177 audio_thread_.reset(); |
171 } | 178 } |
172 #else | 179 #else |
173 if (thread_active_) { | 180 if (thread_active_) { |
174 // See comment above about why we unlock here. | 181 // See comment above about why we unlock here. |
175 int result = CallWhileUnlocked(thread_functions.thread_join, thread_id_); | 182 int result = CallWhileUnlocked(thread_functions.thread_join, thread_id_); |
176 DCHECK_EQ(0, result); | 183 DCHECK_EQ(0, result); |
177 thread_active_ = false; | 184 thread_active_ = false; |
178 } | 185 } |
179 #endif | 186 #endif |
180 } | 187 } |
181 | 188 |
182 #if defined(OS_NACL) | 189 #if defined(OS_NACL) |
183 // static | 190 // static |
184 void PPB_Audio_Shared::SetThreadFunctions( | 191 void PPB_Audio_Shared::SetThreadFunctions( |
185 const struct PP_ThreadFunctions* functions) { | 192 const struct PP_ThreadFunctions* functions) { |
186 DCHECK(thread_functions.thread_create == NULL); | |
187 DCHECK(thread_functions.thread_join == NULL); | |
188 thread_functions = *functions; | 193 thread_functions = *functions; |
189 } | 194 } |
190 | 195 |
191 // static | 196 // static |
192 void PPB_Audio_Shared::CallRun(void* self) { | 197 void PPB_Audio_Shared::CallRun(void* self) { |
193 PPB_Audio_Shared* audio = static_cast<PPB_Audio_Shared*>(self); | 198 PPB_Audio_Shared* audio = static_cast<PPB_Audio_Shared*>(self); |
194 audio->Run(); | 199 audio->Run(); |
195 } | 200 } |
196 #endif | 201 #endif |
197 | 202 |
(...skipping 20 matching lines...) Expand all Loading... | |
218 // Let the other end know which buffer we just filled. The buffer index is | 223 // Let the other end know which buffer we just filled. The buffer index is |
219 // used to ensure the other end is getting the buffer it expects. For more | 224 // used to ensure the other end is getting the buffer it expects. For more |
220 // details on how this works see AudioSyncReader::WaitUntilDataIsReady(). | 225 // details on how this works see AudioSyncReader::WaitUntilDataIsReady(). |
221 size_t bytes_sent = socket_->Send(&buffer_index_, sizeof(buffer_index_)); | 226 size_t bytes_sent = socket_->Send(&buffer_index_, sizeof(buffer_index_)); |
222 if (bytes_sent != sizeof(buffer_index_)) | 227 if (bytes_sent != sizeof(buffer_index_)) |
223 break; | 228 break; |
224 } | 229 } |
225 } | 230 } |
226 | 231 |
227 } // namespace ppapi | 232 } // namespace ppapi |
OLD | NEW |