This source file includes following definitions.
- Create
- StartCapture
- StopCapture
- ShutDown
- OnStreamCreated
- OnVolume
- OnStateChanged
- OnIPCClosed
- pending_open_device_id_
- Initialize
- InitializeOnIOThread
- StartCaptureOnIOThread
- StopCaptureOnIOThread
- ShutDownOnIOThread
- OnDeviceOpened
- CloseDevice
- NotifyStreamCreationFailed
- GetMediaDeviceManager
#include "content/renderer/pepper/pepper_platform_audio_input.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop/message_loop_proxy.h"
#include "build/build_config.h"
#include "content/child/child_process.h"
#include "content/renderer/media/audio_input_message_filter.h"
#include "content/renderer/pepper/pepper_audio_input_host.h"
#include "content/renderer/pepper/pepper_media_device_manager.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_view_impl.h"
#include "media/audio/audio_manager_base.h"
#include "ppapi/shared_impl/ppb_audio_config_shared.h"
#include "url/gurl.h"
namespace content {
PepperPlatformAudioInput* PepperPlatformAudioInput::Create(
const base::WeakPtr<RenderViewImpl>& render_view,
const std::string& device_id,
const GURL& document_url,
int sample_rate,
int frames_per_buffer,
PepperAudioInputHost* client) {
scoped_refptr<PepperPlatformAudioInput> audio_input(
new PepperPlatformAudioInput());
if (audio_input->Initialize(render_view, device_id, document_url,
sample_rate, frames_per_buffer, client)) {
audio_input->AddRef();
return audio_input.get();
}
return NULL;
}
void PepperPlatformAudioInput::StartCapture() {
DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
io_message_loop_proxy_->PostTask(
FROM_HERE,
base::Bind(&PepperPlatformAudioInput::StartCaptureOnIOThread, this));
}
void PepperPlatformAudioInput::StopCapture() {
DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
io_message_loop_proxy_->PostTask(
FROM_HERE,
base::Bind(&PepperPlatformAudioInput::StopCaptureOnIOThread, this));
}
void PepperPlatformAudioInput::ShutDown() {
DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
if (!client_)
return;
client_ = NULL;
io_message_loop_proxy_->PostTask(
FROM_HERE,
base::Bind(&PepperPlatformAudioInput::ShutDownOnIOThread, this));
}
void PepperPlatformAudioInput::OnStreamCreated(
base::SharedMemoryHandle handle,
base::SyncSocket::Handle socket_handle,
int length,
int total_segments) {
#if defined(OS_WIN)
DCHECK(handle);
DCHECK(socket_handle);
#else
DCHECK_NE(-1, handle.fd);
DCHECK_NE(-1, socket_handle);
#endif
DCHECK(length);
DCHECK_EQ(1, total_segments);
if (base::MessageLoopProxy::current().get() !=
main_message_loop_proxy_.get()) {
main_message_loop_proxy_->PostTask(
FROM_HERE,
base::Bind(&PepperPlatformAudioInput::OnStreamCreated, this,
handle, socket_handle, length, total_segments));
} else {
if (client_) {
client_->StreamCreated(handle, length, socket_handle);
} else {
base::SyncSocket temp_socket(socket_handle);
base::SharedMemory temp_shared_memory(handle, false);
}
}
}
void PepperPlatformAudioInput::OnVolume(double volume) {}
void PepperPlatformAudioInput::OnStateChanged(
media::AudioInputIPCDelegate::State state) {
}
void PepperPlatformAudioInput::OnIPCClosed() {
ipc_.reset();
}
PepperPlatformAudioInput::~PepperPlatformAudioInput() {
DCHECK(!ipc_);
DCHECK(!client_);
DCHECK(label_.empty());
DCHECK(!pending_open_device_);
}
PepperPlatformAudioInput::PepperPlatformAudioInput()
: client_(NULL),
main_message_loop_proxy_(base::MessageLoopProxy::current()),
io_message_loop_proxy_(ChildProcess::current()->io_message_loop_proxy()),
create_stream_sent_(false),
pending_open_device_(false),
pending_open_device_id_(-1) {
}
bool PepperPlatformAudioInput::Initialize(
const base::WeakPtr<RenderViewImpl>& render_view,
const std::string& device_id,
const GURL& document_url,
int sample_rate,
int frames_per_buffer,
PepperAudioInputHost* client) {
DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
if (!render_view.get() || !client)
return false;
ipc_ = RenderThreadImpl::current()->audio_input_message_filter()->
CreateAudioInputIPC(render_view->GetRoutingID());
render_view_ = render_view;
client_ = client;
params_.Reset(media::AudioParameters::AUDIO_PCM_LINEAR,
media::CHANNEL_LAYOUT_MONO, ppapi::kAudioInputChannels, 0,
sample_rate, ppapi::kBitsPerAudioInputSample,
frames_per_buffer);
pending_open_device_id_ = GetMediaDeviceManager()->OpenDevice(
PP_DEVICETYPE_DEV_AUDIOCAPTURE,
device_id.empty() ? media::AudioManagerBase::kDefaultDeviceId : device_id,
document_url,
base::Bind(&PepperPlatformAudioInput::OnDeviceOpened, this));
pending_open_device_ = true;
return true;
}
void PepperPlatformAudioInput::InitializeOnIOThread(int session_id) {
DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
if (!ipc_)
return;
create_stream_sent_ = true;
ipc_->CreateStream(this, session_id, params_, false, 1);
}
void PepperPlatformAudioInput::StartCaptureOnIOThread() {
DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
if (ipc_)
ipc_->RecordStream();
}
void PepperPlatformAudioInput::StopCaptureOnIOThread() {
DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
if (ipc_ && create_stream_sent_) {
ipc_->CloseStream();
}
ipc_.reset();
}
void PepperPlatformAudioInput::ShutDownOnIOThread() {
DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
StopCaptureOnIOThread();
main_message_loop_proxy_->PostTask(
FROM_HERE,
base::Bind(&PepperPlatformAudioInput::CloseDevice, this));
Release();
}
void PepperPlatformAudioInput::OnDeviceOpened(int request_id,
bool succeeded,
const std::string& label) {
DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
pending_open_device_ = false;
pending_open_device_id_ = -1;
if (succeeded && render_view_.get()) {
DCHECK(!label.empty());
label_ = label;
if (client_) {
int session_id = GetMediaDeviceManager()->GetSessionID(
PP_DEVICETYPE_DEV_AUDIOCAPTURE, label);
io_message_loop_proxy_->PostTask(
FROM_HERE,
base::Bind(&PepperPlatformAudioInput::InitializeOnIOThread,
this, session_id));
} else {
CloseDevice();
}
} else {
NotifyStreamCreationFailed();
}
}
void PepperPlatformAudioInput::CloseDevice() {
DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
if (render_view_.get()) {
if (!label_.empty()) {
GetMediaDeviceManager()->CloseDevice(label_);
label_.clear();
}
if (pending_open_device_) {
GetMediaDeviceManager()->CancelOpenDevice(pending_open_device_id_);
pending_open_device_ = false;
pending_open_device_id_ = -1;
}
}
}
void PepperPlatformAudioInput::NotifyStreamCreationFailed() {
DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
if (client_)
client_->StreamCreationFailed();
}
PepperMediaDeviceManager* PepperPlatformAudioInput::GetMediaDeviceManager() {
return PepperMediaDeviceManager::GetForRenderView(render_view_.get());
}
}