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

Side by Side Diff: ppapi/shared_impl/ppb_audio_input_shared.cc

Issue 9557007: PPB_AudioInput_Dev: support multiple audio input devices - Part 1. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Changes in response to Trung's comments. Created 8 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
« no previous file with comments | « ppapi/shared_impl/ppb_audio_input_shared.h ('k') | ppapi/thunk/interfaces_ppb_public_dev.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 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_input_shared.h" 5 #include "ppapi/shared_impl/ppb_audio_input_shared.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "ppapi/c/pp_errors.h"
9 #include "ppapi/shared_impl/ppapi_globals.h"
10 #include "ppapi/shared_impl/ppb_device_ref_shared.h"
11 #include "ppapi/shared_impl/resource_tracker.h"
12 #include "ppapi/thunk/enter.h"
13 #include "ppapi/thunk/ppb_audio_config_api.h"
8 14
9 namespace ppapi { 15 namespace ppapi {
10 16
11 PPB_AudioInput_Shared::PPB_AudioInput_Shared() 17 namespace {
12 : capturing_(false), 18
19 void IgnoredCompletionCallback(void* user_data, int32_t result) {
20 // Do nothing.
21 }
22
23 } // namespace
24
25 PPB_AudioInput_Shared::PPB_AudioInput_Shared(const HostResource& audio_input)
26 : Resource(OBJECT_IS_PROXY, audio_input),
27 open_state_(BEFORE_OPEN),
28 capturing_(false),
13 shared_memory_size_(0), 29 shared_memory_size_(0),
14 callback_(NULL), 30 audio_input_callback_(NULL),
15 user_data_(NULL) { 31 user_data_(NULL),
32 devices_(NULL),
33 resource_object_type_(OBJECT_IS_PROXY) {
34 }
35
36 PPB_AudioInput_Shared::PPB_AudioInput_Shared(PP_Instance instance)
37 : Resource(OBJECT_IS_IMPL, instance),
38 open_state_(BEFORE_OPEN),
39 capturing_(false),
40 shared_memory_size_(0),
41 audio_input_callback_(NULL),
42 user_data_(NULL),
43 devices_(NULL),
44 resource_object_type_(OBJECT_IS_IMPL) {
16 } 45 }
17 46
18 PPB_AudioInput_Shared::~PPB_AudioInput_Shared() { 47 PPB_AudioInput_Shared::~PPB_AudioInput_Shared() {
48 DCHECK(open_state_ == CLOSED);
49 }
50
51 thunk::PPB_AudioInput_API* PPB_AudioInput_Shared::AsPPB_AudioInput_API() {
52 return this;
53 }
54
55 int32_t PPB_AudioInput_Shared::EnumerateDevices(
56 PP_Resource* devices,
57 PP_CompletionCallback callback) {
58 if (!callback.func)
59 return PP_ERROR_BLOCKS_MAIN_THREAD;
60 if (TrackedCallback::IsPending(enumerate_devices_callback_))
61 return PP_ERROR_INPROGRESS;
62
63 return InternalEnumerateDevices(devices, callback);
64 }
65
66 int32_t PPB_AudioInput_Shared::Open(
67 const std::string& device_id,
68 PP_Resource config,
69 PPB_AudioInput_Callback audio_input_callback,
70 void* user_data,
71 PP_CompletionCallback callback) {
72 if (!audio_input_callback)
73 return PP_ERROR_BADARGUMENT;
74
75 return CommonOpen(device_id, config, audio_input_callback, user_data,
76 callback);
77 }
78
79 PP_Resource PPB_AudioInput_Shared::GetCurrentConfig() {
80 // AddRef for the caller.
81 if (config_.get())
82 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(config_);
83 return config_;
84 }
85
86 PP_Bool PPB_AudioInput_Shared::StartCapture() {
87 if (open_state_ == CLOSED || (open_state_ == BEFORE_OPEN &&
88 !TrackedCallback::IsPending(open_callback_))) {
89 return PP_FALSE;
90 }
91 if (capturing_)
92 return PP_TRUE;
93
94 return InternalStartCapture();
95 }
96
97 PP_Bool PPB_AudioInput_Shared::StopCapture() {
98 if (open_state_ == CLOSED || (open_state_ == BEFORE_OPEN &&
99 !TrackedCallback::IsPending(open_callback_))) {
100 return PP_FALSE;
101 }
102 if (!capturing_)
103 return PP_TRUE;
104
105 return InternalStopCapture();
106 }
107
108 void PPB_AudioInput_Shared::Close() {
109 if (open_state_ == CLOSED)
110 return;
111
112 open_state_ = CLOSED;
113 InternalClose();
114
19 // Closing the socket causes the thread to exit - wait for it. 115 // Closing the socket causes the thread to exit - wait for it.
20 if (socket_.get()) 116 if (socket_.get())
21 socket_->Close(); 117 socket_->Close();
22 if (audio_input_thread_.get()) { 118 if (audio_input_thread_.get()) {
23 audio_input_thread_->Join(); 119 audio_input_thread_->Join();
24 audio_input_thread_.reset(); 120 audio_input_thread_.reset();
25 } 121 }
122
123 if (TrackedCallback::IsPending(open_callback_))
124 open_callback_->PostAbort();
26 } 125 }
27 126
28 void PPB_AudioInput_Shared::SetCallback(PPB_AudioInput_Callback callback, 127 void PPB_AudioInput_Shared::OnEnumerateDevicesComplete(
29 void* user_data) { 128 int32_t result,
30 callback_ = callback; 129 const std::vector<DeviceRefData>& devices) {
31 user_data_ = user_data; 130 DCHECK(TrackedCallback::IsPending(enumerate_devices_callback_));
131
132 if (result == PP_OK && devices_) {
133 *devices_ = PPB_DeviceRef_Shared::CreateResourceArray(
134 resource_object_type_, pp_instance(), devices);
135 }
136 devices_ = NULL;
137
138 TrackedCallback::ClearAndRun(&enumerate_devices_callback_, result);
139 }
140
141 void PPB_AudioInput_Shared::OnOpenComplete(
142 int32_t result,
143 base::SharedMemoryHandle shared_memory_handle,
144 size_t shared_memory_size,
145 base::SyncSocket::Handle socket_handle) {
146 if (open_state_ == BEFORE_OPEN && result == PP_OK) {
147 open_state_ = OPENED;
148 SetStreamInfo(shared_memory_handle, shared_memory_size, socket_handle);
149 } else {
150 // Clean up the handles.
151 base::SyncSocket temp_socket(socket_handle);
152 base::SharedMemory temp_mem(shared_memory_handle, false);
153 }
154
155 // The callback may have been aborted by Close().
156 if (TrackedCallback::IsPending(open_callback_))
157 TrackedCallback::ClearAndRun(&open_callback_, result);
158 }
159
160 // static
161 PP_CompletionCallback PPB_AudioInput_Shared::MakeIgnoredCompletionCallback() {
162 return PP_MakeCompletionCallback(&IgnoredCompletionCallback, NULL);
32 } 163 }
33 164
34 void PPB_AudioInput_Shared::SetStartCaptureState() { 165 void PPB_AudioInput_Shared::SetStartCaptureState() {
35 DCHECK(!capturing_); 166 DCHECK(!capturing_);
36 DCHECK(!audio_input_thread_.get()); 167 DCHECK(!audio_input_thread_.get());
37 168
38 // If the socket doesn't exist, that means that the plugin has started before 169 // If the socket doesn't exist, that means that the plugin has started before
39 // the browser has had a chance to create all the shared memory info and 170 // the browser has had a chance to create all the shared memory info and
40 // notify us. This is a common case. In this case, we just set the playing_ 171 // notify us. This is a common case. In this case, we just set the capturing_
41 // flag and the capture will automatically start when that data is available 172 // flag and the capture will automatically start when that data is available
42 // in SetStreamInfo. 173 // in SetStreamInfo.
43 if (socket_.get()) 174 if (audio_input_callback_ && socket_.get())
44 StartThread(); 175 StartThread();
45 capturing_ = true; 176 capturing_ = true;
46 } 177 }
47 178
48 void PPB_AudioInput_Shared::SetStopCaptureState() { 179 void PPB_AudioInput_Shared::SetStopCaptureState() {
49 DCHECK(capturing_); 180 DCHECK(capturing_);
50 181
51 if (audio_input_thread_.get()) { 182 if (audio_input_thread_.get()) {
52 audio_input_thread_->Join(); 183 audio_input_thread_->Join();
53 audio_input_thread_.reset(); 184 audio_input_thread_.reset();
54 } 185 }
55 capturing_ = false; 186 capturing_ = false;
56 } 187 }
57 188
58 void PPB_AudioInput_Shared::SetStreamInfo( 189 void PPB_AudioInput_Shared::SetStreamInfo(
59 base::SharedMemoryHandle shared_memory_handle, 190 base::SharedMemoryHandle shared_memory_handle,
60 size_t shared_memory_size, 191 size_t shared_memory_size,
61 base::SyncSocket::Handle socket_handle) { 192 base::SyncSocket::Handle socket_handle) {
62 socket_.reset(new base::SyncSocket(socket_handle)); 193 socket_.reset(new base::SyncSocket(socket_handle));
63 shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false)); 194 shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false));
64 shared_memory_size_ = shared_memory_size; 195 shared_memory_size_ = shared_memory_size;
65 196
66 if (callback_) { 197 if (audio_input_callback_) {
67 shared_memory_->Map(shared_memory_size_); 198 shared_memory_->Map(shared_memory_size_);
68 199
69 // In common case StartCapture() was called before StreamCreated(). 200 // StartCapture() may be called before SetSreamInfo().
70 if (capturing_) 201 if (capturing_)
71 StartThread(); 202 StartThread();
72 } 203 }
73 } 204 }
74 205
75 void PPB_AudioInput_Shared::StartThread() { 206 void PPB_AudioInput_Shared::StartThread() {
76 DCHECK(callback_); 207 DCHECK(audio_input_callback_);
77 DCHECK(!audio_input_thread_.get()); 208 DCHECK(!audio_input_thread_.get());
78 audio_input_thread_.reset(new base::DelegateSimpleThread( 209 audio_input_thread_.reset(new base::DelegateSimpleThread(
79 this, "plugin_audio_input_thread")); 210 this, "plugin_audio_input_thread"));
80 audio_input_thread_->Start(); 211 audio_input_thread_->Start();
81 } 212 }
82 213
83 void PPB_AudioInput_Shared::Run() { 214 void PPB_AudioInput_Shared::Run() {
84 int pending_data; 215 int pending_data;
85 void* buffer = shared_memory_->memory(); 216 void* buffer = shared_memory_->memory();
86 217
87 while (sizeof(pending_data) == socket_->Receive(&pending_data, 218 while (sizeof(pending_data) == socket_->Receive(&pending_data,
88 sizeof(pending_data)) && 219 sizeof(pending_data)) &&
89 pending_data >= 0) { 220 pending_data >= 0) {
90 callback_(buffer, shared_memory_size_, user_data_); 221 audio_input_callback_(buffer, shared_memory_size_, user_data_);
91 } 222 }
92 } 223 }
93 224
225 int32_t PPB_AudioInput_Shared::CommonOpen(
226 const std::string& device_id,
227 PP_Resource config,
228 PPB_AudioInput_Callback audio_input_callback,
229 void* user_data,
230 PP_CompletionCallback callback) {
231 if (open_state_ != BEFORE_OPEN)
232 return PP_ERROR_FAILED;
233
234 thunk::EnterResourceNoLock<thunk::PPB_AudioConfig_API> enter_config(config,
235 true);
236 if (enter_config.failed())
237 return PP_ERROR_BADARGUMENT;
238
239 if (!callback.func)
240 return PP_ERROR_BLOCKS_MAIN_THREAD;
241
242 if (TrackedCallback::IsPending(open_callback_))
243 return PP_ERROR_INPROGRESS;
244
245 config_ = config;
246 audio_input_callback_ = audio_input_callback;
247 user_data_ = user_data;
248
249 return InternalOpen(device_id, enter_config.object()->GetSampleRate(),
250 enter_config.object()->GetSampleFrameCount(), callback);
251 }
252
94 } // namespace ppapi 253 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/shared_impl/ppb_audio_input_shared.h ('k') | ppapi/thunk/interfaces_ppb_public_dev.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698