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

Side by Side Diff: content/renderer/pepper/pepper_platform_audio_input_impl.cc

Issue 12383016: Merge AssociateStreamWithProducer message into CreateStream message for both audio output and input. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 8 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 "content/renderer/pepper/pepper_platform_audio_input_impl.h" 5 #include "content/renderer/pepper/pepper_platform_audio_input_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop_proxy.h" 9 #include "base/message_loop_proxy.h"
10 #include "build/build_config.h" 10 #include "build/build_config.h"
11 #include "content/common/child_process.h" 11 #include "content/common/child_process.h"
12 #include "content/common/media/audio_messages.h"
13 #include "content/renderer/media/audio_input_message_filter.h" 12 #include "content/renderer/media/audio_input_message_filter.h"
14 #include "content/renderer/pepper/pepper_plugin_delegate_impl.h" 13 #include "content/renderer/pepper/pepper_plugin_delegate_impl.h"
15 #include "content/renderer/render_thread_impl.h" 14 #include "content/renderer/render_thread_impl.h"
16 #include "media/audio/audio_manager_base.h" 15 #include "media/audio/audio_manager_base.h"
17 16
18 namespace content { 17 namespace content {
19 18
20 // static 19 // static
21 PepperPlatformAudioInputImpl* PepperPlatformAudioInputImpl::Create( 20 PepperPlatformAudioInputImpl* PepperPlatformAudioInputImpl::Create(
22 const base::WeakPtr<PepperPluginDelegateImpl>& plugin_delegate, 21 const base::WeakPtr<PepperPluginDelegateImpl>& plugin_delegate,
(...skipping 25 matching lines...) Expand all
48 DCHECK(main_message_loop_proxy_->BelongsToCurrentThread()); 47 DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
49 48
50 ChildProcess::current()->io_message_loop()->PostTask( 49 ChildProcess::current()->io_message_loop()->PostTask(
51 FROM_HERE, 50 FROM_HERE,
52 base::Bind(&PepperPlatformAudioInputImpl::StopCaptureOnIOThread, this)); 51 base::Bind(&PepperPlatformAudioInputImpl::StopCaptureOnIOThread, this));
53 } 52 }
54 53
55 void PepperPlatformAudioInputImpl::ShutDown() { 54 void PepperPlatformAudioInputImpl::ShutDown() {
56 DCHECK(main_message_loop_proxy_->BelongsToCurrentThread()); 55 DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
57 56
57 // Make sure we don't call shutdown more than once.
58 if (!client_)
59 return;
60
58 // Called on the main thread to stop all audio callbacks. We must only change 61 // Called on the main thread to stop all audio callbacks. We must only change
59 // the client on the main thread, and the delegates from the I/O thread. 62 // the client on the main thread, and the delegates from the I/O thread.
60 client_ = NULL; 63 client_ = NULL;
61 ChildProcess::current()->io_message_loop()->PostTask( 64 ChildProcess::current()->io_message_loop()->PostTask(
62 FROM_HERE, 65 FROM_HERE,
63 base::Bind(&PepperPlatformAudioInputImpl::ShutDownOnIOThread, this)); 66 base::Bind(&PepperPlatformAudioInputImpl::ShutDownOnIOThread, this));
64 } 67 }
65 68
66 void PepperPlatformAudioInputImpl::OnStreamCreated( 69 void PepperPlatformAudioInputImpl::OnStreamCreated(
67 base::SharedMemoryHandle handle, 70 base::SharedMemoryHandle handle,
68 base::SyncSocket::Handle socket_handle, 71 base::SyncSocket::Handle socket_handle,
69 int length, 72 int length,
70 int total_segments) { 73 int total_segments) {
71 #if defined(OS_WIN) 74 #if defined(OS_WIN)
72 DCHECK(handle); 75 DCHECK(handle);
73 DCHECK(socket_handle); 76 DCHECK(socket_handle);
74 #else 77 #else
75 DCHECK_NE(-1, handle.fd); 78 DCHECK_NE(-1, handle.fd);
76 DCHECK_NE(-1, socket_handle); 79 DCHECK_NE(-1, socket_handle);
77 #endif 80 #endif
78 DCHECK(length); 81 DCHECK(length);
79 // TODO(yzshen): Make use of circular buffer scheme. crbug.com/181449. 82 // TODO(yzshen): Make use of circular buffer scheme. crbug.com/181449.
80 DCHECK_EQ(1, total_segments); 83 DCHECK_EQ(1, total_segments);
81 84
82 if (base::MessageLoopProxy::current() != main_message_loop_proxy_) { 85 if (base::MessageLoopProxy::current() != main_message_loop_proxy_) {
83 // No need to check |shutdown_called_| here. If shutdown has occurred, 86 // If shutdown has occurred, |client_| will be NULL and the handles will be
84 // |client_| will be NULL and the handles will be cleaned up on the main 87 // cleaned up on the main thread.
85 // thread.
86 main_message_loop_proxy_->PostTask( 88 main_message_loop_proxy_->PostTask(
87 FROM_HERE, 89 FROM_HERE,
88 base::Bind(&PepperPlatformAudioInputImpl::OnStreamCreated, this, 90 base::Bind(&PepperPlatformAudioInputImpl::OnStreamCreated, this,
89 handle, socket_handle, length, total_segments)); 91 handle, socket_handle, length, total_segments));
90 } else { 92 } else {
91 // Must dereference the client only on the main thread. Shutdown may have 93 // Must dereference the client only on the main thread. Shutdown may have
92 // occurred while the request was in-flight, so we need to NULL check. 94 // occurred while the request was in-flight, so we need to NULL check.
93 if (client_) { 95 if (client_) {
94 client_->StreamCreated(handle, length, socket_handle); 96 client_->StreamCreated(handle, length, socket_handle);
95 } else { 97 } else {
96 // Clean up the handles. 98 // Clean up the handles.
97 base::SyncSocket temp_socket(socket_handle); 99 base::SyncSocket temp_socket(socket_handle);
98 base::SharedMemory temp_shared_memory(handle, false); 100 base::SharedMemory temp_shared_memory(handle, false);
99 } 101 }
100 } 102 }
101 } 103 }
102 104
103 void PepperPlatformAudioInputImpl::OnVolume(double volume) {} 105 void PepperPlatformAudioInputImpl::OnVolume(double volume) {}
104 106
105 void PepperPlatformAudioInputImpl::OnStateChanged( 107 void PepperPlatformAudioInputImpl::OnStateChanged(
106 media::AudioInputIPCDelegate::State state) { 108 media::AudioInputIPCDelegate::State state) {
107 } 109 }
108 110
109 void PepperPlatformAudioInputImpl::OnIPCClosed() { 111 void PepperPlatformAudioInputImpl::OnIPCClosed() {
110 ipc_ = NULL; 112 ipc_.reset();
111 } 113 }
112 114
113 PepperPlatformAudioInputImpl::~PepperPlatformAudioInputImpl() { 115 PepperPlatformAudioInputImpl::~PepperPlatformAudioInputImpl() {
114 // Make sure we have been shut down. Warning: this may happen on the I/O 116 // Make sure we have been shut down. Warning: this may happen on the I/O
115 // thread! 117 // thread!
116 // Although these members should be accessed on a specific thread (either the 118 // Although these members should be accessed on a specific thread (either the
117 // main thread or the I/O thread), it should be fine to examine their value 119 // main thread or the I/O thread), it should be fine to examine their value
118 // here. 120 // here.
119 DCHECK_EQ(0, stream_id_); 121 DCHECK(!ipc_);
120 DCHECK(!client_); 122 DCHECK(!client_);
121 DCHECK(label_.empty()); 123 DCHECK(label_.empty());
122 DCHECK(shutdown_called_);
123 } 124 }
124 125
125 PepperPlatformAudioInputImpl::PepperPlatformAudioInputImpl() 126 PepperPlatformAudioInputImpl::PepperPlatformAudioInputImpl()
126 : client_(NULL), 127 : client_(NULL),
127 stream_id_(0), 128 main_message_loop_proxy_(base::MessageLoopProxy::current()) {
128 render_view_id_(MSG_ROUTING_NONE),
129 main_message_loop_proxy_(base::MessageLoopProxy::current()),
130 shutdown_called_(false) {
131 ipc_ = RenderThreadImpl::current()->audio_input_message_filter();
132 } 129 }
133 130
134 bool PepperPlatformAudioInputImpl::Initialize( 131 bool PepperPlatformAudioInputImpl::Initialize(
135 const base::WeakPtr<PepperPluginDelegateImpl>& plugin_delegate, 132 const base::WeakPtr<PepperPluginDelegateImpl>& plugin_delegate,
136 const std::string& device_id, 133 const std::string& device_id,
137 int sample_rate, 134 int sample_rate,
138 int frames_per_buffer, 135 int frames_per_buffer,
139 webkit::ppapi::PluginDelegate::PlatformAudioInputClient* client) { 136 webkit::ppapi::PluginDelegate::PlatformAudioInputClient* client) {
140 DCHECK(main_message_loop_proxy_->BelongsToCurrentThread()); 137 DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
141 138
142 if (!plugin_delegate || !client) 139 if (!plugin_delegate || !client)
143 return false; 140 return false;
144 141
142 ipc_ = RenderThreadImpl::current()->audio_input_message_filter()->
143 CreateAudioInputIPC(plugin_delegate->GetRoutingID());
144
145 plugin_delegate_ = plugin_delegate; 145 plugin_delegate_ = plugin_delegate;
146 render_view_id_ = plugin_delegate_->GetRoutingID();
147 client_ = client; 146 client_ = client;
148 147
149 params_.Reset(media::AudioParameters::AUDIO_PCM_LINEAR, 148 params_.Reset(media::AudioParameters::AUDIO_PCM_LINEAR,
150 media::CHANNEL_LAYOUT_MONO, 1, 0, 149 media::CHANNEL_LAYOUT_MONO, 1, 0,
151 sample_rate, 16, frames_per_buffer); 150 sample_rate, 16, frames_per_buffer);
152 151
153 // We need to open the device and obtain the label and session ID before 152 // We need to open the device and obtain the label and session ID before
154 // initializing. 153 // initializing.
155 plugin_delegate_->OpenDevice( 154 plugin_delegate_->OpenDevice(
156 PP_DEVICETYPE_DEV_AUDIOCAPTURE, 155 PP_DEVICETYPE_DEV_AUDIOCAPTURE,
157 device_id.empty() ? media::AudioManagerBase::kDefaultDeviceId : device_id, 156 device_id.empty() ? media::AudioManagerBase::kDefaultDeviceId : device_id,
158 base::Bind(&PepperPlatformAudioInputImpl::OnDeviceOpened, this)); 157 base::Bind(&PepperPlatformAudioInputImpl::OnDeviceOpened, this));
159 158
160 return true; 159 return true;
161 } 160 }
162 161
163 void PepperPlatformAudioInputImpl::InitializeOnIOThread(int session_id) { 162 void PepperPlatformAudioInputImpl::InitializeOnIOThread(int session_id) {
164 DCHECK(ChildProcess::current()->io_message_loop_proxy()-> 163 DCHECK(ChildProcess::current()->io_message_loop_proxy()->
165 BelongsToCurrentThread()); 164 BelongsToCurrentThread());
166 165
167 if (shutdown_called_) 166 if (!ipc_)
168 return; 167 return;
169 168
170 // Make sure we don't call init more than once.
171 DCHECK_EQ(0, stream_id_);
172 stream_id_ = ipc_->AddDelegate(this);
173 DCHECK_NE(0, stream_id_);
174
175 // We will be notified by OnStreamCreated(). 169 // We will be notified by OnStreamCreated().
176 ipc_->CreateStream(stream_id_, session_id, params_, false, 1); 170 ipc_->CreateStream(this, session_id, params_, false, 1);
177 } 171 }
178 172
179 void PepperPlatformAudioInputImpl::StartCaptureOnIOThread() { 173 void PepperPlatformAudioInputImpl::StartCaptureOnIOThread() {
180 DCHECK(ChildProcess::current()->io_message_loop_proxy()-> 174 DCHECK(ChildProcess::current()->io_message_loop_proxy()->
181 BelongsToCurrentThread()); 175 BelongsToCurrentThread());
182 176
183 if (stream_id_) { 177 if (ipc_)
184 ipc_->AssociateStreamWithConsumer(stream_id_, render_view_id_); 178 ipc_->RecordStream();
185 ipc_->RecordStream(stream_id_);
186 }
187 } 179 }
188 180
189 void PepperPlatformAudioInputImpl::StopCaptureOnIOThread() { 181 void PepperPlatformAudioInputImpl::StopCaptureOnIOThread() {
190 DCHECK(ChildProcess::current()->io_message_loop_proxy()-> 182 DCHECK(ChildProcess::current()->io_message_loop_proxy()->
191 BelongsToCurrentThread()); 183 BelongsToCurrentThread());
192 184
193 // TODO(yzshen): We cannot re-start capturing if the stream is closed. 185 // TODO(yzshen): We cannot re-start capturing if the stream is closed.
194 if (stream_id_) 186 if (ipc_) {
195 ipc_->CloseStream(stream_id_); 187 ipc_->CloseStream();
188 ipc_.reset();
189 }
196 } 190 }
197 191
198 void PepperPlatformAudioInputImpl::ShutDownOnIOThread() { 192 void PepperPlatformAudioInputImpl::ShutDownOnIOThread() {
199 DCHECK(ChildProcess::current()->io_message_loop_proxy()-> 193 DCHECK(ChildProcess::current()->io_message_loop_proxy()->
200 BelongsToCurrentThread()); 194 BelongsToCurrentThread());
201 195
202 // Make sure we don't call shutdown more than once. 196 StopCaptureOnIOThread();
203 if (shutdown_called_)
204 return;
205 shutdown_called_ = true;
206
207 if (stream_id_) {
208 ipc_->CloseStream(stream_id_);
209 ipc_->RemoveDelegate(stream_id_);
210 stream_id_ = 0;
211 }
212 197
213 main_message_loop_proxy_->PostTask( 198 main_message_loop_proxy_->PostTask(
214 FROM_HERE, 199 FROM_HERE,
215 base::Bind(&PepperPlatformAudioInputImpl::CloseDevice, this)); 200 base::Bind(&PepperPlatformAudioInputImpl::CloseDevice, this));
216 201
217 Release(); // Release for the delegate, balances out the reference taken in 202 Release(); // Release for the delegate, balances out the reference taken in
218 // PepperPluginDelegateImpl::CreateAudioInput. 203 // PepperPluginDelegateImpl::CreateAudioInput.
219 } 204 }
220 205
221 void PepperPlatformAudioInputImpl::OnDeviceOpened(int request_id, 206 void PepperPlatformAudioInputImpl::OnDeviceOpened(int request_id,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 } 238 }
254 239
255 void PepperPlatformAudioInputImpl::NotifyStreamCreationFailed() { 240 void PepperPlatformAudioInputImpl::NotifyStreamCreationFailed() {
256 DCHECK(main_message_loop_proxy_->BelongsToCurrentThread()); 241 DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
257 242
258 if (client_) 243 if (client_)
259 client_->StreamCreationFailed(); 244 client_->StreamCreationFailed();
260 } 245 }
261 246
262 } // namespace content 247 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698