15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/pepper_platform_audio_input.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/child_process.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/renderer/media/audio_input_message_filter.h" 13558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/pepper_audio_input_host.h" 14558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/pepper_media_device_manager.h" 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/renderer/render_frame_impl.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/render_thread_impl.h" 17558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/render_view_impl.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/audio/audio_manager_base.h" 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ppapi/shared_impl/ppb_audio_config_shared.h" 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 25558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPepperPlatformAudioInput* PepperPlatformAudioInput::Create( 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int render_frame_id, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& device_id, 287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const GURL& document_url, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sample_rate, 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames_per_buffer, 31558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PepperAudioInputHost* client) { 32558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_refptr<PepperPlatformAudioInput> audio_input( 33558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch new PepperPlatformAudioInput()); 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (audio_input->Initialize(render_frame_id, 35a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch device_id, 36a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch document_url, 37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch sample_rate, 38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch frames_per_buffer, 39a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch client)) { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Balanced by Release invoked in 41558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // PepperPlatformAudioInput::ShutDownOnIOThread(). 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_input->AddRef(); 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return audio_input.get(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::StartCapture() { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(main_message_loop_proxy_->BelongsToCurrentThread()); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch io_message_loop_proxy_->PostTask( 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 53558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::Bind(&PepperPlatformAudioInput::StartCaptureOnIOThread, this)); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::StopCapture() { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(main_message_loop_proxy_->BelongsToCurrentThread()); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch io_message_loop_proxy_->PostTask( 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::Bind(&PepperPlatformAudioInput::StopCaptureOnIOThread, this)); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::ShutDown() { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(main_message_loop_proxy_->BelongsToCurrentThread()); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure we don't call shutdown more than once. 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!client_) 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called on the main thread to stop all audio callbacks. We must only change 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the client on the main thread, and the delegates from the I/O thread. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_ = NULL; 74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch io_message_loop_proxy_->PostTask( 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 76558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::Bind(&PepperPlatformAudioInput::ShutDownOnIOThread, this)); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::OnStreamCreated( 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle handle, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SyncSocket::Handle socket_handle, 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int length, 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int total_segments) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(handle); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(socket_handle); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(-1, handle.fd); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(-1, socket_handle); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(length); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(yzshen): Make use of circular buffer scheme. crbug.com/181449. 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(1, total_segments); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (base::MessageLoopProxy::current().get() != 967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) main_message_loop_proxy_.get()) { 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If shutdown has occurred, |client_| will be NULL and the handles will be 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // cleaned up on the main thread. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) main_message_loop_proxy_->PostTask( 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&PepperPlatformAudioInput::OnStreamCreated, 102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch this, 103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch handle, 104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch socket_handle, 105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch length, 106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch total_segments)); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Must dereference the client only on the main thread. Shutdown may have 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // occurred while the request was in-flight, so we need to NULL check. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (client_) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_->StreamCreated(handle, length, socket_handle); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clean up the handles. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SyncSocket temp_socket(socket_handle); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemory temp_shared_memory(handle, false); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 120558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::OnVolume(double volume) {} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 122558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::OnStateChanged( 123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch media::AudioInputIPCDelegate::State state) {} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid PepperPlatformAudioInput::OnIPCClosed() { ipc_.reset(); } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 127558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPepperPlatformAudioInput::~PepperPlatformAudioInput() { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure we have been shut down. Warning: this may happen on the I/O 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread! 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Although these members should be accessed on a specific thread (either the 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // main thread or the I/O thread), it should be fine to examine their value 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here. 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!ipc_); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!client_); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(label_.empty()); 136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(!pending_open_device_); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 139558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPepperPlatformAudioInput::PepperPlatformAudioInput() 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : client_(NULL), 1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) main_message_loop_proxy_(base::MessageLoopProxy::current()), 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch io_message_loop_proxy_(ChildProcess::current()->io_message_loop_proxy()), 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch render_frame_id_(MSG_ROUTING_NONE), 144ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch create_stream_sent_(false), 145ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pending_open_device_(false), 146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pending_open_device_id_(-1) {} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 148558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbool PepperPlatformAudioInput::Initialize( 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int render_frame_id, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& device_id, 1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const GURL& document_url, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sample_rate, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames_per_buffer, 154558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PepperAudioInputHost* client) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(main_message_loop_proxy_->BelongsToCurrentThread()); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RenderFrameImpl* const render_frame = 158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RenderFrameImpl::FromRoutingID(render_frame_id); 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!render_frame || !client) 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch render_frame_id_ = render_frame_id; 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch client_ = client; 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!GetMediaDeviceManager()) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 168a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ipc_ = RenderThreadImpl::current() 169a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ->audio_input_message_filter() 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ->CreateAudioInputIPC(render_frame->render_view()->GetRoutingID()); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_.Reset(media::AudioParameters::AUDIO_PCM_LINEAR, 173a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch media::CHANNEL_LAYOUT_MONO, 174a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ppapi::kAudioInputChannels, 175a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch sample_rate, 176a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ppapi::kBitsPerAudioInputSample, 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch frames_per_buffer); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We need to open the device and obtain the label and session ID before 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // initializing. 181558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch pending_open_device_id_ = GetMediaDeviceManager()->OpenDevice( 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PP_DEVICETYPE_DEV_AUDIOCAPTURE, 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_id.empty() ? media::AudioManagerBase::kDefaultDeviceId : device_id, 1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) document_url, 185558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::Bind(&PepperPlatformAudioInput::OnDeviceOpened, this)); 186ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pending_open_device_ = true; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 191558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::InitializeOnIOThread(int session_id) { 192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!ipc_) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We will be notified by OnStreamCreated(). 1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) create_stream_sent_ = true; 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ipc_->CreateStream(this, session_id, params_, false, 1); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 202558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::StartCaptureOnIOThread() { 203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ipc_) 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ipc_->RecordStream(); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 209558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::StopCaptureOnIOThread() { 210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(yzshen): We cannot re-start capturing if the stream is closed. 2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (ipc_ && create_stream_sent_) { 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ipc_->CloseStream(); 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ipc_.reset(); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 219558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::ShutDownOnIOThread() { 220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StopCaptureOnIOThread(); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) main_message_loop_proxy_->PostTask( 225a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FROM_HERE, base::Bind(&PepperPlatformAudioInput::CloseDevice, this)); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); // Release for the delegate, balances out the reference taken in 228558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // PepperPlatformAudioInput::Create. 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 231558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::OnDeviceOpened(int request_id, 232558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch bool succeeded, 233558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const std::string& label) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(main_message_loop_proxy_->BelongsToCurrentThread()); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pending_open_device_ = false; 237ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pending_open_device_id_ = -1; 238ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager(); 240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (succeeded && device_manager) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!label.empty()); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_ = label; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (client_) { 245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int session_id = device_manager->GetSessionID( 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_DEVICETYPE_DEV_AUDIOCAPTURE, label); 247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch io_message_loop_proxy_->PostTask( 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 249558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::Bind(&PepperPlatformAudioInput::InitializeOnIOThread, 250a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch this, 251a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch session_id)); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shutdown has occurred. 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseDevice(); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyStreamCreationFailed(); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 261558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::CloseDevice() { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(main_message_loop_proxy_->BelongsToCurrentThread()); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!label_.empty()) { 265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager(); 266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (device_manager) 267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch device_manager->CloseDevice(label_); 268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch label_.clear(); 269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (pending_open_device_) { 271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager(); 272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (device_manager) 273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch device_manager->CancelOpenDevice(pending_open_device_id_); 274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pending_open_device_ = false; 275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pending_open_device_id_ = -1; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 279558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::NotifyStreamCreationFailed() { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(main_message_loop_proxy_->BelongsToCurrentThread()); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (client_) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_->StreamCreationFailed(); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 286558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPepperMediaDeviceManager* PepperPlatformAudioInput::GetMediaDeviceManager() { 287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(main_message_loop_proxy_->BelongsToCurrentThread()); 288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RenderFrameImpl* const render_frame = 290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RenderFrameImpl::FromRoutingID(render_frame_id_); 291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return render_frame ? 292ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch PepperMediaDeviceManager::GetForRenderFrame(render_frame).get() : NULL; 293558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 294558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 296