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

Side by Side Diff: ppapi/proxy/audio_input_resource.cc

Issue 11366038: Rewrite PPB_AudioInput_Dev to use the new-style host/resource. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 1 month 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 | « ppapi/proxy/audio_input_resource.h ('k') | ppapi/proxy/interface_list.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include "ppapi/proxy/audio_input_resource.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "ipc/ipc_platform_file.h"
10 #include "media/audio/audio_parameters.h"
11 #include "media/audio/shared_memory_util.h"
12 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/proxy/ppapi_messages.h"
14 #include "ppapi/proxy/resource_message_params.h"
15 #include "ppapi/proxy/serialized_structs.h"
16 #include "ppapi/shared_impl/ppapi_globals.h"
17 #include "ppapi/shared_impl/ppb_device_ref_shared.h"
18 #include "ppapi/shared_impl/resource_tracker.h"
19 #include "ppapi/shared_impl/tracked_callback.h"
20 #include "ppapi/thunk/enter.h"
21 #include "ppapi/thunk/ppb_audio_config_api.h"
22
23 namespace ppapi {
24 namespace proxy {
25
26 AudioInputResource::AudioInputResource(
27 Connection connection,
28 PP_Instance instance)
29 : PluginResource(connection, instance),
30 open_state_(BEFORE_OPEN),
31 capturing_(false),
32 shared_memory_size_(0),
33 audio_input_callback_(NULL),
34 user_data_(NULL),
35 pending_enumerate_devices_(false) {
36 SendCreate(RENDERER, PpapiHostMsg_AudioInput_Create());
37 }
38
39 AudioInputResource::~AudioInputResource() {
40 Close();
41 }
42
43 thunk::PPB_AudioInput_API* AudioInputResource::AsPPB_AudioInput_API() {
44 return this;
45 }
46
47 int32_t AudioInputResource::EnumerateDevices(
48 PP_Resource* devices,
49 scoped_refptr<TrackedCallback> callback) {
50 if (pending_enumerate_devices_)
51 return PP_ERROR_INPROGRESS;
52 if (!devices)
53 return PP_ERROR_BADARGUMENT;
54
55 pending_enumerate_devices_ = true;
56 PpapiHostMsg_AudioInput_EnumerateDevices msg;
57 Call<PpapiPluginMsg_AudioInput_EnumerateDevicesReply>(
58 RENDERER, msg,
59 base::Bind(&AudioInputResource::OnPluginMsgEnumerateDevicesReply,
60 base::Unretained(this), devices, callback));
61 return PP_OK_COMPLETIONPENDING;
62 }
63
64 int32_t AudioInputResource::Open(const std::string& device_id,
65 PP_Resource config,
66 PPB_AudioInput_Callback audio_input_callback,
67 void* user_data,
68 scoped_refptr<TrackedCallback> callback) {
69 if (TrackedCallback::IsPending(open_callback_))
70 return PP_ERROR_INPROGRESS;
71 if (open_state_ != BEFORE_OPEN)
72 return PP_ERROR_FAILED;
73
74 if (!audio_input_callback)
75 return PP_ERROR_BADARGUMENT;
76 thunk::EnterResourceNoLock<thunk::PPB_AudioConfig_API> enter_config(config,
77 true);
78 if (enter_config.failed())
79 return PP_ERROR_BADARGUMENT;
80
81 config_ = config;
82 audio_input_callback_ = audio_input_callback;
83 user_data_ = user_data;
84 open_callback_ = callback;
85
86 PpapiHostMsg_AudioInput_Open msg(
87 device_id, enter_config.object()->GetSampleRate(),
88 enter_config.object()->GetSampleFrameCount());
89 Call<PpapiPluginMsg_AudioInput_OpenReply>(
90 RENDERER, msg,
91 base::Bind(&AudioInputResource::OnPluginMsgOpenReply,
92 base::Unretained(this)));
93 return PP_OK_COMPLETIONPENDING;
94 }
95
96 PP_Resource AudioInputResource::GetCurrentConfig() {
97 // AddRef for the caller.
98 if (config_.get())
99 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(config_);
100 return config_;
101 }
102
103 PP_Bool AudioInputResource::StartCapture() {
104 if (open_state_ == CLOSED || (open_state_ == BEFORE_OPEN &&
105 !TrackedCallback::IsPending(open_callback_))) {
106 return PP_FALSE;
107 }
108 if (capturing_)
109 return PP_TRUE;
110
111 capturing_ = true;
112 // Return directly if the audio input device hasn't been opened. Capturing
113 // will be started once the open operation is completed.
114 if (open_state_ == BEFORE_OPEN)
115 return PP_TRUE;
116
117 StartThread();
118
119 Post(RENDERER, PpapiHostMsg_AudioInput_StartOrStop(true));
120 return PP_TRUE;
121 }
122
123 PP_Bool AudioInputResource::StopCapture() {
124 if (open_state_ == CLOSED)
125 return PP_FALSE;
126 if (!capturing_)
127 return PP_TRUE;
128
129 // If the audio input device hasn't been opened, set |capturing_| to false and
130 // return directly.
131 if (open_state_ == BEFORE_OPEN) {
132 capturing_ = false;
133 return PP_TRUE;
134 }
135
136 Post(RENDERER, PpapiHostMsg_AudioInput_StartOrStop(false));
137
138 StopThread();
139 capturing_ = false;
140
141 return PP_TRUE;
142 }
143
144 void AudioInputResource::Close() {
145 if (open_state_ == CLOSED)
146 return;
147
148 open_state_ = CLOSED;
149 Post(RENDERER, PpapiHostMsg_AudioInput_Close());
150 StopThread();
151
152 if (TrackedCallback::IsPending(open_callback_))
153 open_callback_->PostAbort();
154 }
155
156 void AudioInputResource::OnPluginMsgEnumerateDevicesReply(
157 PP_Resource* devices_resource,
158 scoped_refptr<TrackedCallback> callback,
159 const ResourceMessageReplyParams& params,
160 const std::vector<DeviceRefData>& devices) {
161 pending_enumerate_devices_ = false;
162
163 // We shouldn't access |devices_resource| if the callback has been called,
164 // which is possible if the last plugin reference to this resource has gone
165 // away, and the callback has been aborted.
166 if (!TrackedCallback::IsPending(callback))
167 return;
168
169 if (params.result() == PP_OK) {
170 *devices_resource = PPB_DeviceRef_Shared::CreateResourceArray(
171 OBJECT_IS_PROXY, pp_instance(), devices);
172 }
173
174 callback->Run(params.result());
175 }
176
177 void AudioInputResource::OnPluginMsgOpenReply(
178 const ResourceMessageReplyParams& params) {
179 if (open_state_ == BEFORE_OPEN && params.result() == PP_OK) {
180 IPC::PlatformFileForTransit socket_handle_for_transit =
181 IPC::InvalidPlatformFileForTransit();
182 params.TakeSocketHandleAtIndex(0, &socket_handle_for_transit);
183 base::SyncSocket::Handle socket_handle =
184 IPC::PlatformFileForTransitToPlatformFile(socket_handle_for_transit);
185 CHECK(socket_handle != base::SyncSocket::kInvalidHandle);
186
187 SerializedHandle serialized_shared_memory_handle =
188 params.TakeHandleOfTypeAtIndex(1, SerializedHandle::SHARED_MEMORY);
189 CHECK(serialized_shared_memory_handle.IsHandleValid());
190
191 // See the comment in pepper_audio_input_host.cc about how we must call
192 // TotalSharedMemorySizeInBytes to get the actual size of the buffer. Here,
193 // we must call PacketSizeInBytes to get back the size of the audio buffer,
194 // excluding the bytes that audio uses for book-keeping.
195 size_t shared_memory_size = media::PacketSizeInBytes(
196 serialized_shared_memory_handle.size());
197
198 open_state_ = OPENED;
199 SetStreamInfo(serialized_shared_memory_handle.shmem(), shared_memory_size,
200 socket_handle);
201 } else {
202 capturing_ = false;
203 }
204
205 // The callback may have been aborted by Close().
206 if (TrackedCallback::IsPending(open_callback_))
207 open_callback_->Run(params.result());
208 }
209
210 void AudioInputResource::SetStreamInfo(
211 base::SharedMemoryHandle shared_memory_handle,
212 size_t shared_memory_size,
213 base::SyncSocket::Handle socket_handle) {
214 socket_.reset(new base::CancelableSyncSocket(socket_handle));
215 shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false));
216 shared_memory_size_ = shared_memory_size;
217
218 if (!shared_memory_->Map(shared_memory_size_)) {
219 PpapiGlobals::Get()->LogWithSource(pp_instance(), PP_LOGLEVEL_WARNING, "",
220 "Failed to map shared memory for PPB_AudioInput_Shared.");
221 }
222
223 // There is a pending capture request before SetStreamInfo().
224 if (capturing_) {
225 // Set |capturing_| to false so that the state looks consistent to
226 // StartCapture(), which will reset it to true.
227 capturing_ = false;
228 StartCapture();
229 }
230 }
231
232 void AudioInputResource::StartThread() {
233 // Don't start the thread unless all our state is set up correctly.
234 if (!audio_input_callback_ || !socket_.get() || !capturing_ ||
235 !shared_memory_->memory()) {
236 return;
237 }
238 DCHECK(!audio_input_thread_.get());
239 audio_input_thread_.reset(new base::DelegateSimpleThread(
240 this, "plugin_audio_input_thread"));
241 audio_input_thread_->Start();
242 }
243
244 void AudioInputResource::StopThread() {
245 // Shut down the socket to escape any hanging |Receive|s.
246 if (socket_.get())
247 socket_->Shutdown();
248 if (audio_input_thread_.get()) {
249 audio_input_thread_->Join();
250 audio_input_thread_.reset();
251 }
252 }
253
254 void AudioInputResource::Run() {
255 // The shared memory represents AudioInputBufferParameters and the actual data
256 // buffer.
257 media::AudioInputBuffer* buffer =
258 static_cast<media::AudioInputBuffer*>(shared_memory_->memory());
259 uint32_t data_buffer_size =
260 shared_memory_size_ - sizeof(media::AudioInputBufferParameters);
261 int pending_data;
262
263 while (sizeof(pending_data) == socket_->Receive(&pending_data,
264 sizeof(pending_data)) &&
265 pending_data >= 0) {
266 // While closing the stream, we may receive buffers whose size is different
267 // from |data_buffer_size|.
268 CHECK_LE(buffer->params.size, data_buffer_size);
269 if (buffer->params.size > 0)
270 audio_input_callback_(&buffer->audio[0], buffer->params.size, user_data_);
271 }
272 }
273
274 } // namespace proxy
brettw 2012/11/08 00:20:32 Nit: 2 spaces before //
yzshen1 2012/11/08 18:57:30 Done.
275 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/proxy/audio_input_resource.h ('k') | ppapi/proxy/interface_list.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698