Disable ContentSettingBubbleModelTest.RPHAllow which is flaky.
[chromium-blink-merge.git] / content / renderer / pepper / pepper_platform_audio_output_impl.cc
blob8b8c47058c74a126eec59b4a68819f7895f6f1a2
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.
5 #include "content/renderer/pepper/pepper_platform_audio_output_impl.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/logging.h"
10 #include "base/message_loop_proxy.h"
11 #include "build/build_config.h"
12 #include "content/common/child_process.h"
13 #include "content/common/media/audio_messages.h"
14 #include "content/renderer/media/audio_message_filter.h"
15 #include "content/renderer/render_thread_impl.h"
16 #include "media/base/audio_hardware_config.h"
17 #include "media/base/media_switches.h"
19 namespace content {
21 // static
22 PepperPlatformAudioOutputImpl* PepperPlatformAudioOutputImpl::Create(
23 int sample_rate,
24 int frames_per_buffer,
25 int source_render_view_id,
26 webkit::ppapi::PluginDelegate::PlatformAudioOutputClient* client) {
27 scoped_refptr<PepperPlatformAudioOutputImpl> audio_output(
28 new PepperPlatformAudioOutputImpl());
29 if (audio_output->Initialize(sample_rate, frames_per_buffer,
30 source_render_view_id, client)) {
31 // Balanced by Release invoked in
32 // PepperPlatformAudioOutputImpl::ShutDownOnIOThread().
33 audio_output->AddRef();
34 return audio_output.get();
36 return NULL;
39 bool PepperPlatformAudioOutputImpl::StartPlayback() {
40 if (ipc_) {
41 ChildProcess::current()->io_message_loop()->PostTask(
42 FROM_HERE,
43 base::Bind(&PepperPlatformAudioOutputImpl::StartPlaybackOnIOThread,
44 this));
45 return true;
47 return false;
50 bool PepperPlatformAudioOutputImpl::StopPlayback() {
51 if (ipc_) {
52 ChildProcess::current()->io_message_loop()->PostTask(
53 FROM_HERE,
54 base::Bind(&PepperPlatformAudioOutputImpl::StopPlaybackOnIOThread,
55 this));
56 return true;
58 return false;
61 void PepperPlatformAudioOutputImpl::ShutDown() {
62 // Called on the main thread to stop all audio callbacks. We must only change
63 // the client on the main thread, and the delegates from the I/O thread.
64 client_ = NULL;
65 ChildProcess::current()->io_message_loop()->PostTask(
66 FROM_HERE,
67 base::Bind(&PepperPlatformAudioOutputImpl::ShutDownOnIOThread, this));
70 void PepperPlatformAudioOutputImpl::OnStateChanged(
71 media::AudioOutputIPCDelegate::State state) {
74 void PepperPlatformAudioOutputImpl::OnStreamCreated(
75 base::SharedMemoryHandle handle,
76 base::SyncSocket::Handle socket_handle,
77 int length) {
78 #if defined(OS_WIN)
79 DCHECK(handle);
80 DCHECK(socket_handle);
81 #else
82 DCHECK_NE(-1, handle.fd);
83 DCHECK_NE(-1, socket_handle);
84 #endif
85 DCHECK(length);
87 if (base::MessageLoopProxy::current() == main_message_loop_proxy_) {
88 // Must dereference the client only on the main thread. Shutdown may have
89 // occurred while the request was in-flight, so we need to NULL check.
90 if (client_)
91 client_->StreamCreated(handle, length, socket_handle);
92 } else {
93 main_message_loop_proxy_->PostTask(FROM_HERE,
94 base::Bind(&PepperPlatformAudioOutputImpl::OnStreamCreated, this,
95 handle, socket_handle, length));
99 void PepperPlatformAudioOutputImpl::OnIPCClosed() {
100 ipc_.reset();
103 PepperPlatformAudioOutputImpl::~PepperPlatformAudioOutputImpl() {
104 // Make sure we have been shut down. Warning: this will usually happen on
105 // the I/O thread!
106 DCHECK(!ipc_);
107 DCHECK(!client_);
110 PepperPlatformAudioOutputImpl::PepperPlatformAudioOutputImpl()
111 : client_(NULL),
112 main_message_loop_proxy_(base::MessageLoopProxy::current()) {
115 bool PepperPlatformAudioOutputImpl::Initialize(
116 int sample_rate,
117 int frames_per_buffer,
118 int source_render_view_id,
119 webkit::ppapi::PluginDelegate::PlatformAudioOutputClient* client) {
120 DCHECK(client);
121 client_ = client;
123 RenderThreadImpl* const render_thread = RenderThreadImpl::current();
124 ipc_ = render_thread->audio_message_filter()->
125 CreateAudioOutputIPC(source_render_view_id);
126 CHECK(ipc_);
128 media::AudioParameters::Format format;
129 const int kMaxFramesForLowLatency = 2047;
131 media::AudioHardwareConfig* hardware_config =
132 render_thread->GetAudioHardwareConfig();
134 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
135 if (!cmd_line->HasSwitch(switches::kDisableAudioOutputResampler)) {
136 // Rely on AudioOutputResampler to handle any inconsistencies between the
137 // hardware params required for low latency and the requested params.
138 format = media::AudioParameters::AUDIO_PCM_LOW_LATENCY;
139 } else if (sample_rate == hardware_config->GetOutputSampleRate() &&
140 frames_per_buffer <= kMaxFramesForLowLatency &&
141 frames_per_buffer % hardware_config->GetOutputBufferSize() == 0) {
142 // Use the low latency back end if the client request is compatible, and
143 // the sample count is low enough to justify using AUDIO_PCM_LOW_LATENCY.
144 format = media::AudioParameters::AUDIO_PCM_LOW_LATENCY;
145 } else {
146 format = media::AudioParameters::AUDIO_PCM_LINEAR;
149 media::AudioParameters params(format, media::CHANNEL_LAYOUT_STEREO,
150 sample_rate, 16, frames_per_buffer);
152 ChildProcess::current()->io_message_loop()->PostTask(
153 FROM_HERE,
154 base::Bind(&PepperPlatformAudioOutputImpl::InitializeOnIOThread,
155 this, params));
156 return true;
159 void PepperPlatformAudioOutputImpl::InitializeOnIOThread(
160 const media::AudioParameters& params) {
161 DCHECK(ChildProcess::current()->io_message_loop_proxy()->
162 BelongsToCurrentThread());
163 if (ipc_)
164 ipc_->CreateStream(this, params);
167 void PepperPlatformAudioOutputImpl::StartPlaybackOnIOThread() {
168 DCHECK(ChildProcess::current()->io_message_loop_proxy()->
169 BelongsToCurrentThread());
170 if (ipc_)
171 ipc_->PlayStream();
174 void PepperPlatformAudioOutputImpl::StopPlaybackOnIOThread() {
175 DCHECK(ChildProcess::current()->io_message_loop_proxy()->
176 BelongsToCurrentThread());
177 if (ipc_)
178 ipc_->PauseStream();
181 void PepperPlatformAudioOutputImpl::ShutDownOnIOThread() {
182 DCHECK(ChildProcess::current()->io_message_loop_proxy()->
183 BelongsToCurrentThread());
185 // Make sure we don't call shutdown more than once.
186 if (!ipc_)
187 return;
189 ipc_->CloseStream();
190 ipc_.reset();
192 Release(); // Release for the delegate, balances out the reference taken in
193 // PepperPluginDelegateImpl::CreateAudio.
196 } // namespace content